I wanted to find the type of an image as a part of upload script I am working on.

instead of having to use a module that is not pre-installed with perl or a module that requires some libraries to be installed on the server, I used this method.

sub imgtype { my $file = shift; my %types = ( 'BMP' => qr/^BM/, 'GIF' => qr/^GIF8[79]a/, 'JPEG' => qr/^\xFF\xD8/, 'PNG' => qr/^\x89PNG\x0d\x0a\x1a\x0a/, 'PPM' => qr/^P[1-6]/, 'SVG' => qr/^<\?xml/, 'TIFF' => qr/^MM\x00\x2a|^II\x2a\x00/, 'XBM' => qr/^#define\s+/, 'XPM' => qr/(^\/\* XPM \*\/)|(static\s+char\s+\*\w+\[\]\s*= +\s*{\s*"\d+)/, ); if (-e $file ) { open(my $fh, '<', $file) or die $!; read($fh,my $head,11); close($fh); while ( my ($type,$match) = each %types ) { if ( $head=~m/$match/ ) { return $type; } } return undef; }else{ return undef; } }

You can use it to check against a hash of allowed file types like this

my %ALLOWED = ('GIF' => 1 ,'JPEG' => 1 ); # can be called like this my $Type = imgtype('some/location/image'); if ( defined $Type && $ALLOWED{$Type} ) { # process image }else{ # delete it or do whatever you want with it }

Replies are listed 'Best First'.
Re: How do I find the type of an image?
by JavaFan (Canon) on Dec 28, 2009 at 13:11 UTC
    I think it's quite optimistic to classify any file that starts with <?xml as an SVG file, and any file that starts with #define\s as an XBM file. I've many files on my system that match one of the patterns, and are neither SVG or XBM files.

    I would use the (external) commands file (standard Unix tool) and/or identify (from the ImageMagick suite) to determine file types.

      ...try
      #!/usr/bin/perl -w use strict; use Image::Info qw(image_info); use Data::Dumper; while (@ARGV) { print Dumper(image_info(shift)), "\n"; }

      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku
Re: How do I find the type of an image?
by ahmad (Hermit) on Dec 28, 2009 at 15:55 UTC

    Actually, I've had the same idea of using 'file' command but it's not available on windows OS which will make my script unmovable

    Image::Magick uses Image::Info module which uses the exact same regexp I've used.

    It might sound very optimistic for those two matches, but what i am actually interested in and will use it for is just (png,gif,jpeg) and it all depends on the way you use it.

    Finally, the main intention behind writing it, is not relying on file extensions to determine if a file is an image or not as extensions are useless in Linux

      Finally, the main intention behind writing it, is not relying on file extensions to determine if a file is an image or not as extensions are useless in Linux

      ... that is not true..... .htm, .html, .jpg,. gif,.bmp,.png,...etc..extensions...etc....are all very important in the linux file system..... what is useless in linux is the old 8.3 MSDOS file types by extension.... where executables or text type is set by the 8.3 conventions

      ...... in linux, if i try to open a JPG named "somejpeg" it will not be recognized without expensive calles to mime type programs...... even in linux you need "someimage.jpg" for it to be recognized

      .....only in disk filesystem forensics (like recovering data from a broken filesystem) would you really need to manually ascertain file type


      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku

        what I meant by 'File extensions is useless in Linux is this

        pico -w my.anything ======= write inside it #!/usr/bin/perl print "Hello world\n"; === close it (CTRL + X) & save it. chmod +x my.anything now you can run it ./my.anything and it will execute your perl script. * you can even name it my.jpg & it will execute your perl script

        I am using Ubuntu Netbook, I have many images saved without extensions ... and it works that way.

      Actually, I've had the same idea of using 'file' command but it's not available on windows OS which will make my script unmovable
      I think you are confusing "not available" with "not installed by default". But if the latter is a reason for you script to be unmoveable, I urge you to not write your program in Perl. After all, perl is as unavailable on Windows as file is: neither comes by default with the OS. But both have been ported to the platform.
Re: How do I find the type of an image?
by doug (Pilgrim) on Dec 28, 2009 at 17:14 UTC

    It looks like you're just looking at the magic number to determine what type of file you're dealing with. Can't you just use the existing magic infrastructure? That has been around for decades, and should have all of those file types. At the simplest form, simply capture the output from

    file $filename

    and grab whatever you're looking for from that output. There is also a perl module for using magic without launching file as new process, but I've never used it. I believe it is  File::LibMagic.

    - doug