FREE THOUGHT · FREE SOFTWARE · FREE WORLD

Home  »  PHP  »  Getting the Mimetype of an Image with PHP

by comment

Getting the Mimetype of an Image with PHP

This is awesome. I was so fed up with trying to find a fail-proof, cross-platform way to find the mime type of an image using PHP that I wrote a quick function that utilizes the same technology as the exif_imagetype, getimagesize, and finfo functions do.

Basically, the method is the exact same as that used by all magic file type enumerators. Just open the file/stream in read-binary mode and grab the file header (the first few bytes). I opted to keep it simple and super-fast and just used ==, otherwise you can use preg_match with the /s.

This is also the same method used by imagemagick, Apache, really everything that does it low-level.

Use the return as the arg to image_type_to_mime_type to get the mime string.

function askapache_get_image_filetype( $file ) {
  if ( ! is_file( $file ) || ! is_readable( $file ) )
    return false;
    
  if ( false === $fp = fopen( $file, 'rb' ) )
    return false;
 
  if ( false === $file_size = filesize( $file ) )
    return false;
    
  if ( $file_size < 13 )
    return false;
  
  if ( false === $line = fread( $fp, 12 ) )
    return false;
    
  fclose( $fp );
  
  $l2 = substr( $line, 0, 2 );
  $l3 = substr( $line, 0, 3 );
  $l4 = substr( $line, 0, 4 );
  $l7 = substr( $line, 0, 7 );
  $l8 = substr( $line, 0, 8 );
  
  
  static $define_imagetypes = false;
  if ( ! $define_imagetypes ) {
    ! defined( 'IMAGETYPE_UNKNOWN' ) && define( 'IMAGETYPE_UNKNOWN', 0 );
    ! defined( 'IMAGETYPE_GIF' ) && define( 'IMAGETYPE_GIF', 1 );
    ! defined( 'IMAGETYPE_JPEG' ) && define( 'IMAGETYPE_JPEG', 2 );
    ! defined( 'IMAGETYPE_PNG' ) && define( 'IMAGETYPE_PNG', 3 );
    ! defined( 'IMAGETYPE_SWF' ) && define( 'IMAGETYPE_SWF', 4 );
    ! defined( 'IMAGETYPE_PSD' ) && define( 'IMAGETYPE_PSD', 5 );
    ! defined( 'IMAGETYPE_BMP' ) && define( 'IMAGETYPE_BMP', 6 );
    ! defined( 'IMAGETYPE_TIFF_II' ) && define( 'IMAGETYPE_TIFF_II', 7 );
    ! defined( 'IMAGETYPE_TIFF_MM' ) && define( 'IMAGETYPE_TIFF_MM', 8 );
    ! defined( 'IMAGETYPE_JPC' ) && define( 'IMAGETYPE_JPC', 9 );
    ! defined( 'IMAGETYPE_JP2' ) && define( 'IMAGETYPE_JP2', 10 );
    ! defined( 'IMAGETYPE_JPX' ) && define( 'IMAGETYPE_JPX', 11 );
    ! defined( 'IMAGETYPE_JB2' ) && define( 'IMAGETYPE_JB2', 12 );
    ! defined( 'IMAGETYPE_SWC' ) && define( 'IMAGETYPE_SWC', 13 );
    ! defined( 'IMAGETYPE_IFF' ) && define( 'IMAGETYPE_IFF', 14 );
    ! defined( 'IMAGETYPE_WBMP' ) && define( 'IMAGETYPE_WBMP', 15 );
    ! defined( 'IMAGETYPE_XBM' ) && define( 'IMAGETYPE_XBM', 16 );
    ! defined( 'IMAGETYPE_ICO' ) && define( 'IMAGETYPE_ICO', 17 );
    $define_imagetypes = true;
  }
 
  
  $image_type_num = IMAGETYPE_UNKNOWN;
  if ( $l2 ==  'BM' ) {
    $image_type_num = IMAGETYPE_BMP;
  } elseif ( $l3 ==  "\377\330\377" ) {
    $image_type_num = IMAGETYPE_JPEG;
  } elseif ( $l3 ==  'GIF' ) {
    $image_type_num = IMAGETYPE_GIF;
  } elseif ( $l4 ==  "\000\000\001\000" ) {
    $image_type_num = IMAGETYPE_ICO;
  } elseif ( $l4 ==  "II\052\000" ) {
    $image_type_num = IMAGETYPE_TIFF_II;
  } elseif ( $l4 ==  "MM\000\052" ) {
    $image_type_num = IMAGETYPE_TIFF_MM;
  } elseif ( $l7 == '#define' ) {
    $image_type_num = IMAGETYPE_XBM;
  } elseif ( $l8 ==  "\211\120\116\107\015\012\032\012" ) {
    $image_type_num = IMAGETYPE_PNG;
  }
  
  return $image_type_num;
}

This is well 1000x more efficient than a exec like system('file -i -b --mime-type $f'); could ever be.. (and you should disabled exec functions like that anyway).

And from the source php-5.4.13

// file type markers 
PHPAPI const char php_sig_gif[3] = {'G', 'I', 'F'};
PHPAPI const char php_sig_psd[4] = {'8', 'B', 'P', 'S'};
PHPAPI const char php_sig_bmp[2] = {'B', 'M'};
PHPAPI const char php_sig_swf[3] = {'F', 'W', 'S'};
PHPAPI const char php_sig_swc[3] = {'C', 'W', 'S'};
PHPAPI const char php_sig_jpg[3] = { 0xff,  0xd8,  0xff};
PHPAPI const char php_sig_png[8] = { 0x89,  0x50,  0x4e,  0x47,  0x0d,  0x0a,  0x1a,  0x0a};
PHPAPI const char php_sig_tif_ii[4] = {'I','I',  0x2A,  0x00};
PHPAPI const char php_sig_tif_mm[4] = {'M','M',  0x00,  0x2A};
PHPAPI const char php_sig_jpc[3]  = { 0xff,  0x4f,  0xff};
PHPAPI const char php_sig_jp2[12] = { 0x00,  0x00,  0x00,  0x0c,  0x6a,  0x50,  0x20,  0x20,  0x0d,  0x0a,  0x87,  0x0a};
PHPAPI const char php_sig_iff[4] = {'F','O','R','M'};
PHPAPI const char php_sig_ico[4] = { 0x00,  0x00,  0x01,  0x00};
 
1   IMAGETYPE_GIF
2   IMAGETYPE_JPEG
3   IMAGETYPE_PNG
4   IMAGETYPE_SWF
5   IMAGETYPE_PSD
6   IMAGETYPE_BMP
7   IMAGETYPE_TIFF_II (intel byte order)
8   IMAGETYPE_TIFF_MM (motorola byte order)
9   IMAGETYPE_JPC
10   IMAGETYPE_JP2
11   IMAGETYPE_JPX
12   IMAGETYPE_JB2
13   IMAGETYPE_SWC
14   IMAGETYPE_IFF
15   IMAGETYPE_WBMP
16   IMAGETYPE_XBM
17   IMAGETYPE_ICO

And from imagemagick

static const MagicMapInfo
  MagicMap[] =
  {
    { "8BIMWTEXT", 0, "8\000B\000I\000M\000#" },
    { "8BIMTEXT", 0, "8BIM#" },
    { "8BIM", 0, "8BIM" },
    { "BMP", 0, "BA" },
    { "BMP", 0, "BM" },
    { "BMP", 0, "CI" },
    { "BMP", 0, "CP" },
    { "BMP", 0, "IC" },
    { "PICT", 0, "PICT" },
    { "BMP", 0, "PI" },
    { "CALS", 21, "version: MIL-STD-1840" },
    { "CALS", 0, "srcdocid:" },
    { "CALS", 9, "srcdocid:" },
    { "CALS", 8, "rorient:" },
    { "CGM", 0, "BEGMF" },
    { "CIN", 0, "\200\052\137\327" },
    { "CRW", 0, "II\x1a\x00\x00\x00HEAPCCDR" },
    { "DCM", 128, "DICM" },
    { "DCX", 0, "\261\150\336\72" },
    { "DIB", 0, "\050\000" },
    { "DDS", 0, "DDS " },
    { "DJVU", 0, "AT&TFORM" },
    { "DOT", 0, "digraph" },
    { "DPX", 0, "SDPX" },
    { "DPX", 0, "XPDS" },
    { "EMF", 40, "\040\105\115\106\000\000\001\000" },
    { "EPT", 0, "\305\320\323\306" },
    { "EXR", 0, "\166\057\061\001" },
    { "FAX", 0, "DFAX" },
    { "FIG", 0, "#FIG" },
    { "FITS", 0, "IT0" },
    { "FITS", 0, "SIMPLE" },
    { "FPX", 0, "\320\317\021\340" },
    { "GIF", 0, "GIF8" },
    { "GPLT", 0, "#!/usr/local/bin/gnuplot" },
    { "HDF", 1, "HDF" },
    { "HDR", 0, "#?RADIANCE" },
    { "HDR", 0, "#?RGBE" },
    { "HPGL", 0, "IN;" },
    { "HTML", 1, "HTML" },
    { "HTML", 1, "html" },
    { "ILBM", 8, "ILBM" },
    { "IPTCWTEXT", 0, "\062\000#\000\060\000=\000\042\000&\000#\000\060\000;\000&\000#\000\062\000;\000\042\000" },
    { "IPTCTEXT", 0, "2#0=\042&#0;&#2;\042" },
    { "IPTC", 0, "\034\002" },
    { "JNG", 0, "\213JNG\r\n\032\n" },
    { "JPEG", 0, "\377\330\377" },
    { "JPC", 0, "\377\117" },
    { "JP2", 4, "\152\120\040\040\015" },
    { "MAT", 0, "MATLAB 5.0 MAT-file," },
    { "MIFF", 0, "Id=ImageMagick" },
    { "MIFF", 0, "id=ImageMagick" },
    { "MNG", 0, "\212MNG\r\n\032\n" },
    { "MPC", 0, "id=MagickCache" },
    { "MPEG", 0, "\000\000\001\263" },
    { "MRW", 0, "\x00MRM" },
    { "MVG", 0, "push graphic-context" },
    { "ORF", 0, "IIRO\x08\x00\x00\x00" },
    { "PCD", 2048, "PCD_" },
    { "PCL", 0, "\033E\033" },
    { "PCX", 0, "\012\002" },
    { "PCX", 0, "\012\005" },
    { "PDB", 60, "vIMGView" },
    { "PDF", 0, "%PDF-" },
    { "PES", 0, "#PES" },
    { "PFA", 0, "%!PS-AdobeFont-1.0" },
    { "PFB", 6, "%!PS-AdobeFont-1.0" },
    { "PGX", 0, "\050\107\020\115\046" },
    { "PICT", 522, "\000\021\002\377\014\000" },
    { "PNG", 0, "\211PNG\r\n\032\n" },
    { "PBM", 0, "P1" },
    { "PGM", 0, "P2" },
    { "PPM", 0, "P3" },
    { "PBM", 0, "P4" },
    { "PGM", 0, "P5" },
    { "PPM", 0, "P6" },
    { "PAM", 0, "P7" },
    { "PFM", 0, "PF" },
    { "PFM", 0, "Pf" },
    { "PS", 0, "%!" },
    { "PS", 0, "\004%!" },
    { "PS", 0, "\305\320\323\306" },
    { "PSB", 0, "8BPB" },
    { "PSD", 0, "8BPS" },
    { "PWP", 0, "SFW95" },
    { "RAF", 0, "FUJIFILMCCD-RAW " },
    { "RLE", 0, "\122\314" },
    { "SCT", 0, "CT" },
    { "SFW", 0, "SFW94" },
    { "SGI", 0, "\001\332" },
    { "SUN", 0, "\131\246\152\225" },
    { "SVG", 1, "?XML" },                       
    { "SVG", 1, "?xml" },
    { "TIFF", 0, "\115\115\000\052" },
    { "TIFF", 0, "\111\111\052\000" },
    { "TIFF64", 0, "\115\115\000\053\000\010\000\000" },
    { "TIFF64", 0, "\111\111\053\000\010\000\000\000" },
    { "TTF", 0, "\000\001\000\000\000" },
    { "TXT", 0, "# ImageMagick pixel enumeration:" },
    { "VICAR", 0, "LBLSIZE" },
    { "VICAR", 0, "NJPL1I" },
    { "VIFF", 0, "\253\001" },
    { "WEBP", 8, "WEBP" },
    { "WMF", 0, "\327\315\306\232" },
    { "WMF", 0, "\001\000\011\000" },
    { "WPG", 0, "\377WPC" },
    { "XBM", 0, "#define" },
    { "XCF", 0, "gimp xcf" },
    { "XEF", 0, "FOVb" },
    { "XPM", 1, "* XPM *" },
    { "XWD", 4, "\007\000\000" },
    { "XWD", 5, "\000\000\007" }
 };

Tags

March 24th, 2013

Comments Welcome

Popular Articles
My Online Tools

Related Articles
Newest Posts
Twitter


  •  t.co/ShKrGdqXuJ 
  • RUN GCC! This is a typical shirt I wear, from the  t.co/46LYbFr4k2  shop. A clerk at the LQ recognized it!  t.co/jjmT0dkCPu 
  • Merlin the Magician  t.co/iMmRbanUi4 
  • ROGUE CODE - Latest novel from @markrussinovich  t.co/apkn0LoPIt 
  • RTFM - surprisingly very helpful and way more comprehensive than it looks! @redteamfieldman #pwnAllTheThings  t.co/xiaJ5g0aC9 
  • Dear Hacker - Letters to the Editor of 2600, from Emmanuel Goldstein  t.co/JCfLab7FAJ 
  • The Mythical Man-Month - Essays on Software Engineering, by Frederick P. Brooks, Jr.  t.co/ilWN5GHElr 
  • "where wizards stay up late" - The Origins of the Internet. Favorite book detailing the birth of the net and IMPs  t.co/gY9VTGJgZz 
  • ZERO DAY - read before Trojan horse  t.co/pPMLGDJv8P 
  • Trojan Horse, a novel!  t.co/Hf8EtYaZVa 
  • The Hacker Playbook - very nice high level overview of attacks  t.co/lHwNVWi61u 
  • Clean Code - A Handbook of Agile Software Craftsmanship  t.co/hnJX0x1qIc 
  • Secrets of the JavaScript Ninja - By my absolute favorite JS hacker John Resig!  t.co/tZ42ljmcCl 
  • Hacking Exposed 7: Network Security Secrets & SolutionsMy all time favorite, basic but thorough and accurate.  t.co/jycW0RDVtZ 

Hacking and Hackers

The use of "hacker" to mean "security breaker" is a confusion on the part of the mass media. We hackers refuse to recognize that meaning, and continue using the word to mean someone who loves to program, someone who enjoys playful cleverness, or the combination of the two. See my article, On Hacking.
-- Richard M. Stallman






[hide]

It's very simple - you read the protocol and write the code. -Bill Joy

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. NCSA HTTPd.
UNIX ® is a registered Trademark of The Open Group. POSIX ® is a registered Trademark of The IEEE.

| Google+ | askapache

Site Map | Contact Webmaster | License and Disclaimer | Terms of Service

↑ TOPMain