TransWikia.com

shell command to get pixel size of an image

Unix & Linux Asked on December 12, 2021

Is there a shell command that returns the pixel size of an image?

I’m trying to produce an animated gif starting from different gifs with different sizes using convert (e.g. convert -delay 50 1.gif 2.gif -loop 0 animated.gif).

The problem is that convert simply overlaps the images using the first image’s size as the size of the animated gif, and since they have different sizes the result is a bit of a mess, with bits of the old frames showing under the new ones.

9 Answers

It's been added to act:

$ npm install @lancejpollard/act -g
$ act read image.png --size

    2000x2000

Answered by Lance Pollard on December 12, 2021

For those like me who want the size in megapixels :

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

Answered by SebMa on December 12, 2021

This was a helpful snippet (I didn't write) that does returns dimensions for every png and jpg in the folder:

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

Answered by ArleyM on December 12, 2021

Rather than parsing the output of identify by eye, or by text utilities, you can use its -format option to output the width and height in whatever format suits you best. For example:

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

A list of image properties that you can output can be found on this page, but for the question here, it seems all you need are %w and %h, which give the image's width and height, respectively, in pixels.


The flexibility afforded by -format came in handy for me in finding the largest images in terms of pixels, by outputting %[fx:w*h] for a number of images and sorting the output.

You might want to specify the -ping option if you're processing many images, using more complicated escapes, and want to make sure the program doesn't waste time loading the entire images. With simple escapes, -ping should be the default. More information on the choice between -ping and +ping can be found here.

Answered by Dan Getz on December 12, 2021

You can also try GraphicsMagick, which is a well maintained fork of ImageMagick used at e.g. Flickr and Etsy:

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

It is faster than ImageMagick's identify (in my tests about twice).

Answered by Jerry Epas on December 12, 2021

Use identify to see the sizes :

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

Extract value via cut | sed, from field 3:

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

Asign to 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

Answered by Hugolpz on December 12, 2021

Both display and file are quite slow, and have the potential to bring even quite capable systems to their knees dealing with many multiple files. A small 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

By reading only the bytes necessary, this operation can be significantly sped up.

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

Here is pngsize:

#include <stdlib.h>
#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%dn", htonl(w), htonl(h));
        if (close(fd) == -1) oops("close");
    }
    return 0;
}

This method is much faster than using a library which loads the PNG forwards, backwards and sideways just to get the image size :P (Consider the code carefully before feeding it a directory full of arbitrary PNGs of course.)

The code uses inet.h for htonl() to de-endian-ize the header byte ordering.

Answered by i336_ on December 12, 2021

you can just use the command "file" to get the informations you need:

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

Answered by Pascal Schmiel on December 12, 2021

found a solution: identify, part of the imagemagick package, does exactly what I need

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

Answered by blue on December 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP