comando de shell para obtener el tamaño de píxel de una imagen

44

¿Hay un comando de shell que devuelve el tamaño de píxel de una imagen?

Estoy tratando de producir un gif animado a partir de diferentes gifs con diferentes tamaños usando convert(por ejemplo convert -delay 50 1.gif 2.gif -loop 0 animated.gif).

El problema es que la conversión simplemente se superpone a las imágenes usando el tamaño de la primera imagen como el tamaño del gif animado, y dado que tienen tamaños diferentes, el resultado es un poco desordenado, con fragmentos de los marcos antiguos que se muestran debajo de los nuevos.

azul
fuente
¿Qué es el "tamaño de píxel"? ¿Bits por píxel (profundidad) o recuento de píxeles?
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

50

encontré una solución: identifyparte del paquete imagemagick, hace exactamente lo que necesito

$ identify color.jpg 
> color.jpg JPEG 1980x650 1980x650+0+0 8-bit DirectClass 231KB 0.000u 0:00.000
azul
fuente
¿Podría explicar por qué obtuve varias filas cuando corro identify imagename.ico? Like todour.ico[0] ICO 32x32 32x32+0+0 4-bit sRGB 0.000u 0:00.000 todour.ico[1] ICO 16x16 16x16+0+0 4-bit sRGB 0.000u 0:00.000 todour.ico[2] ICO 48x48 48x48+0+0 8-bit sRGB 0.000u 0:00.000
roachsinai
45

En lugar de analizar la salida identifypor ojo o por las utilidades de texto, puede usar su -formatopción para generar el ancho y la altura en el formato que más le convenga. Por ejemplo:

$ identify -format '%w %h' img.png
100 200
$ identify -format '%wx%h' img.png
100x200

Puede encontrar una lista de propiedades de imagen que puede generar en esta página , pero para la pregunta aquí, parece que todo lo que necesita son , %wy %hque dan el ancho y alto de la imagen, respectivamente, en píxeles.


La flexibilidad que me brindó -formatfue útil para encontrar las imágenes más grandes en términos de píxeles, al generar %[fx:w*h]una cantidad de imágenes y ordenar la salida.

Es posible que desee especificar la -pingopción si está procesando muchas imágenes, utilizando escapes más complicados, y desea asegurarse de que el programa no pierda el tiempo cargando las imágenes completas. Con escapes simples, -pingdebería ser el valor predeterminado. Puede encontrar más información sobre la elección entre -pingy aquí .+ping

Dan Getz
fuente
15

simplemente puede usar el comando "archivo" para obtener la información que necesita:

~# file cha_2.png 
cha_2.png: PNG image data, 656 x 464, 8-bit/color RGB, non-interlaced
Pascal Schmiel
fuente
1
Esto NO informa el tamaño para otros tipos de imágenes (que no sean png) ... file taylor-swift-money-makers-990.jpg->taylor-swift-money-makers-990.jpg: JPEG image data, JFIF standard 1.01, comment: "CREATOR: gd-jpeg v1.0 (using IJ"
alex gray
No es cierto, al menos en versiones recientes de macOS.
rien333
5

Use identifypara ver los tamaños:

$ identify color.jpg 
> color.jpg JPEG 1980x650 1980x650+0+0 8-bit DirectClass 231KB 0.000u 0:00.000

Extraer valor a través cut | seddel campo 3:

identify ./color.jpg | cut -f 3 -d " " | sed s/x.*// #width
identify ./color.jpg | cut -f 3 -d " " | sed s/.*x// #height

Asignar a variable:

W=`identify ./color.jpg | cut -f 3 -d " " | sed s/x.*//` #width
H=`identify ./color.jpg | cut -f 3 -d " " | sed s/.*x//` #height
echo $W
> 1980
echo $H
> 650
Hugolpz
fuente
2

Ambos displayy fileson bastante lentos, y tienen el potencial de poner de rodillas incluso a sistemas bastante capaces que manejan muchos archivos múltiples. Una pequeña prueba:

     $ du -h *.png --total | tail -n 1
     9.2M    total

     $ ls -l *.png | wc -l
     107

     $ /usr/bin/time file *.png
-->  0.37user 0.26system 0:06.93elapsed 9%CPU (0avgtext+0avgdata 37232maxresident)k
     22624inputs+0outputs (9major+2883minor)pagefaults 0swaps

     $ /usr/bin/time identify *.png
-->  0.56user 0.22system 0:06.77elapsed 11%CPU (0avgtext+0avgdata 25648maxresident)k
     34256inputs+0outputs (119major+2115minor)pagefaults 0swaps

Al leer solo los bytes necesarios, esta operación se puede acelerar significativamente.

     $ /usr/bin/time ./pngsize *.png
-->  0.00user 0.00system 0:00.03elapsed 12%CPU (0avgtext+0avgdata 1904maxresident)k
     0inputs+0outputs (0major+160minor)pagefaults 0swaps

Aquí está pngsize:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <err.h>
#define oops(syscall) { printf("error processing %s: ", argv[i]); \
        fflush(0); perror(syscall"()"); continue; }
int main(int argc, char **argv) {
    int fd, i;
    uint32_t h, w;
    if (argc < 2) { printf("%s <pngfile> [pngfile ...]\n", argv[0]); exit(0); }
    for (i = 1; i < argc; i++) {
        if (argc > 2) printf("%s: ", argv[i]);
        if ((fd = open(argv[i], O_RDONLY)) == -1) oops("open");
        if (lseek(fd, 16, SEEK_SET) == -1) oops("lseek");
        if (read(fd, &w, 4) < 1) oops("read");
        if (read(fd, &h, 4) < 1) oops("read");
        printf("%dx%d\n", htonl(w), htonl(h));
        if (close(fd) == -1) oops("close");
    }
    return 0;
}

Este método es mucho más rápido que usar una biblioteca que carga el PNG hacia adelante, hacia atrás y hacia los lados solo para obtener el tamaño de la imagen: P (Considere el código cuidadosamente antes de alimentarlo en un directorio lleno de PNG arbitrarios, por supuesto).

Los usos de código inet.h para htonl () para de- endian -ize el orden de los bytes de cabecera.

i336_
fuente
0

También puede probar GraphicsMagick , que es una bifurcación bien mantenida de ImageMagick utilizada, por ejemplo, en Flickr y Etsy:

$ gm identify a.jpg
a.jpg JPEG 480x309+0+0 DirectClass 8-bit 25.2K 0.000u 0:01

Es más rápido que la identificación de ImageMagick (en mis pruebas aproximadamente dos veces).

Jerry Epas
fuente
0

Este fue un fragmento útil (no escribí) que devuelve dimensiones para cada png y jpg en la carpeta:

file ./* | perl -ne '@m = /^.*.jpg|^.*.png|[0-9][0-9]*[ ]?x[ ]?[0-9][0-9]*/g; print "@m\n"'
ArleyM
fuente
0

Para aquellos como yo que quieren el tamaño en megapíxeles:

perl -le "printf \"=> fileName = %s size = %.2f Mpix\n\", \"$fileName\", $(identify -format '%w*%h/10**6' $fileName)"
SebMa
fuente