views:

2758

answers:

6

I'm currently using ImageMagick to determine the resolution of images uploaded to the website. By calling ImageMagick's "identify" on the command line it takes about 0.42 seconds to determine a 1MB JPEG's resolution along with the fact that it's a JPEG. I find that a bit slow.

Using the Imagick PHP library is even slower as it attemps to load the whole 1MB in memory before doing any treatment to the image (in this case, simply determining its size and type).

Are there any solutions to speed up this process of determining which file type and which image resolution an arbitrary image file has? I can live with it only supporting JPEG and PNG. It's important to me that the file type is determined by looking at the file's headers and not simply the extension.

Edit: The solution can be a command-line tool UNIX called by PHP, much like the way I'm using ImageMagick at the moment

+7  A: 

If you're using PHP with GD support, you can try getimagesize().

J D OConal
GD will probably suffer from the same speed issue, since it will load the image in memory...
Gilles
True. I don't know way other than writing it yourself and storing only part of the image in memory at a time, but this would be dependent on the image type.
J D OConal
+1  A: 

It's important to me that the file type is determined by looking at the file's headers and not simply the extension.

For that you can use 'file' unix command (orsome php function that implements the same functionality).

/tmp$ file stackoverflow-logo-250.png
stackoverflow-logo-250.png: PNG image data, 250 x 70, 8-bit colormap, non-interlaced

Kasprzol
I've just tested this quickly in the command line and it seems quite slow as well, took a good second to determine the file type of the JPG. It does seem to cache the result but that's of little interest, as I'll test the image only once.
Gilles
Part of it is probably the time it takes to parse the magic file. You can run file on a whole bunch of images at once. Or you could create a smaller magic file with just the common image file types.
palm3D
+1  A: 

Have you tried

identify -ping filename.png

?

Vinko Vrsalovic
Good call, it's about 20 times faster :) The description of that option makes me wonder why it's not the default behavior of identify? Anyway, problem solved and many thanks.
Gilles
+2  A: 

Actually, to use getimagesize(), you do NOT need to have GD compiled in.

You can also use mime_content_type() to get the MIME type.

William Macdonald
+2  A: 

Sorry I can't add this as a comment to a previous answer but I don't have the rep. Doing some quick and dirty testing I also found that exec("identify -ping... is about 20 times faster than without the -ping. But getimagesize() appears to be about 200 times faster still.

So I would say getimagesize() is the faster method. I only tested on jpg and not on png.

the test is just

$files = array('2819547919_db7466149b_o_d.jpg', 'GP1-green2.jpg', 'aegeri-lake-switzerland.JPG');
foreach($files as $file){
  $size2 = array();
  $size3 = array();
  $time1 = microtime();
  $size = getimagesize($file);
  $time1 = microtime() - $time1;
  print "$time1 \n";
  $time2 = microtime();
  exec("identify -ping $file", $size2);
  $time2 = microtime() - $time2;
  print $time2/$time1 . "\n";
  $time2 = microtime();
  exec("identify $file", $size3);
  $time2 = microtime() - $time2;
  print $time2/$time1 . "\n";
  print_r($size);
  print_r($size2);
  print_r($size3);
}
Steven Noble
But does GD provide a way to determine a file type according to its contents (and not its assigned extension)? Also you have to measure the time taken to load the image into GD too, as I'm not doing any processing other than determining the file size.
Gilles
I've added the test to my answer. I don't know if GD loads the image file completely into memory or not as I'm not watching memory. But I am catching the complete time it takes for the command to run. Also getimagesize() also returns the mime type.
Steven Noble
Thanks for all the efforts, I've tested it live and it's indeed 250 times faster than the -ping solution. So about 5000 times faster than the original method I was using, not bad :)
Gilles
+1  A: 
jproffer