web-dev-qa-db-fra.com

commande shell pour obtenir la taille en pixels d'une image

Existe-t-il une commande Shell qui renvoie la taille en pixels d'une image?

J'essaie de produire un gif animé à partir de différents gifs de différentes tailles en utilisant convert (par exemple convert -delay 50 1.gif 2.gif -loop 0 animated.gif).

Le problème est que la conversion chevauche simplement les images en utilisant la taille de la première image comme taille du gif animé, et comme elles ont des tailles différentes, le résultat est un peu compliqué, avec des morceaux des anciennes images affichés sous les nouvelles.

56
blue

trouvé une solution: identify, qui fait partie du paquet imagemagick, fait exactement ce dont j'ai besoin

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

Plutôt que d'analyser la sortie de identify à l'œil nu ou à l'aide d'utilitaires de texte, vous pouvez utiliser son -format option pour afficher la largeur et la hauteur dans le format qui vous convient le mieux. Par exemple:

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

Une liste des propriétés d'image que vous pouvez afficher peut être trouvée sur cette page , mais pour la question ici, il semble que tout ce dont vous avez besoin soit %w et %h, qui donnent respectivement la largeur et la hauteur de l'image en pixels.


La flexibilité offerte par -format m'a été utile pour trouver les plus grandes images en termes de pixels, en affichant %[fx:w*h] pour un certain nombre d'images et le tri de la sortie.

Vous voudrez peut-être spécifier le -ping option si vous traitez de nombreuses images, en utilisant des échappements plus compliqués et que vous voulez vous assurer que le programme ne perd pas de temps à charger les images entières. Avec des évasions simples, -ping devrait être la valeur par défaut. Plus d'informations sur le choix entre -ping et +ping peut être trouvé ici .

53
Dan Getz

vous pouvez simplement utiliser la commande "fichier" pour obtenir les informations dont vous avez besoin:

~# file cha_2.png 
cha_2.png: PNG image data, 656 x 464, 8-bit/color RGB, non-interlaced
17
Pascal Schmiel

tilisez identify pour voir les tailles:

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

Extraire la valeur via cut | sed, du champ 3:

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

Affecter à la 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
5
Hugolpz

display et file sont tous deux assez lents et ont le potentiel de mettre à genoux des systèmes même assez performants traitant de nombreux fichiers multiples. Un petit test:

     $ 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

En lisant uniquement les octets nécessaires, cette opération peut être considérablement accélérée.

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

Voici 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;
}

Cette méthode est beaucoup plus rapide que d'utiliser une bibliothèque qui charge le PNG vers l'avant, vers l'arrière et latéralement juste pour obtenir la taille de l'image: P (Considérez attentivement le code avant en lui fournissant un répertoire plein de PNG arbitraires bien sûr.)

Le code utilise inet.h pour htonl () à de - endian - ize l'ordre des octets d'en-tête.

2
i336_

Vous pouvez également essayer GraphicsMagick , qui est un fork bien maintenu d'ImageMagick utilisé par ex. Flickr et Etsy:

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

C'est plus rapide que l'identification d'ImageMagick (dans mes tests environ deux fois).

0
Jerry Epas

C'était un extrait utile (je n'ai pas écrit) qui renvoie les dimensions pour chaque png et jpg dans le dossier:

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

Pour ceux comme moi qui veulent la taille en mégapixels:

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