Using PHP to Extract Image Exif Data

Those of us fluent in digital photography have come across the term “Exif data” numerous times when it comes to software we use to digitally manipulate photographs. Exif (Exchangeable image file format) data is generally used to identify the properties of the camera that snapped a picture, and usually the software that altered it afterwards. It can tell you when a picture was taken, what kind of camera took it, as well as the camera’s model, shutter speed, focal length, and even provide a thumbnail of the image on the camera’s LCD screen.

Why would you need to extract this information?  If you’re ever uploaded images to stock photography sites and wonder how they know so much about your pictures, it’s because they extract the Exif data from your pictures to provide more information on how they were taken. This quick tutorial will demonstrate how to extract Exif data from an image using PHP.

Enabling the Exif Extension

The Exif functions for PHP may not be native to your installation, so you can check by viewing your phpinfo file or running “php -m” via command line to see a list of modules compiled in. If you don’t see Exif listed, there are three ways you can enable it depending on how you installed PHP:

  • If you compiled PHP manually, you can re-compile while adding –enable-exif to the configure line
  • If PHP is installed via package (rpm/deb), it should already have Exif enabled. If not, you can install an RPM for the extension manually
  • If you use cPanel, run EasyApache and select the Exif extension from the PHP module list, and recompile

Determining the Image Type

The exif_imagetype function identifies the format of an image, but returns the result as a code.  The PHP function reference provides a full list of these return codes, but 1-8 are the most common out of the 16:

1: GIF
3: PNG
4: SWF
5: PSD
6: BMP
7/8: TIFF

Here’s a code example that lists all the desired valid image types in an array and detects the type of image from the specified file, returning the result in “human readable” format:

$image = "/path/to/myimage";

$types = array(
1 => "GIF",
2 => "JPEG",
3 => "PNG",
4 => "SWF",
5 => "PSD",
6 => "BMP",
7 => "TIFF",
8 => "TIFF"

$imagetype = exif_imagetype($image);

if (array_key_exists($imagetype, $types)) {
echo "Image type is: " . $types[$imagetype];
} else {
echo "Not a valid image type";

Reading Exif Header Data

The exif_read_data function can be used to extract header data from JPEG and TIFF files:

$image = "/path/to/myimage";
$exif = exif_read_data($image, 0, true);
foreach ($exif as $key => $section) {
foreach ($section as $name => $val) {
echo "$key.$name: $val\n";

This will return the elements of the array from exif_read_data, which can be very long depending on what information is available for the image. There are seven sections (arrays) of data types:

  • FILE:  Contains the file’s name, size, timestamp, and what other sections were found (as listed below)
  • COMPUTED: Contains the actual attributes of the image
  • ANY_TAG:  Any information that is tagged
  • IFD0:  Mostly contains information about the camera itself, the software used to edit the image, when it was last modified, etc
  • THUMBNAIL: Information about the embedded thumbnail for the image
  • COMMENT: Comment headers for JPEG images
  • EXIF: Contains more information supplementary to what is in IFD0, mostly related to the camera (includes focal length, zoom ratio, etc)

Depending on the information available for the image, you’ll actually see a lot of data in the output. Say, for instance, you want to only output the IFD0 data to see the information of the camera that took the image:

$image = "image.jpg";
$exif = exif_read_data($image, 0, true);

foreach ($exif as $key => $section) {
foreach ($section as $name => $val) {
if($key == "IFD0"){
echo "$key.$name: $val\n";

This will output:

IFD0.ImageWidth: 2592
IFD0.ImageLength: 3872
IFD0.BitsPerSample: Array
IFD0.Compression: 1
IFD0.PhotometricInterpretation: 2
IFD0.Model: NIKON D80
IFD0.Orientation: 1
IFD0.XResolution: 72/10000
IFD0.YResolution: 72/1
IFD0.PlanarConfiguration: 1
IFD0.ResolutionUnit: 2
IFD0.Software: Adobe Photoshop CS4 Windows
IFD0.DateTime: 2010:02:06 22:24:09
IFD0.Exif_IFD_Pointer: 304

Or, you can further narrow down the output by specifying specific values in the $exif multi-dimensional array:

$image = "image.jpg";
$exif = exif_read_data($image, 0, true);
echo "Software: " . $exif['IFD0']['Software'] . "\n";

This will return:

Software: Adobe Photoshop CS4 Windows

Using Exif to generate a thumbnail

As touched on previously, many cameras and image manipulation software will include an embedded thumbnail for an image. You can extract this thumbnail using the exif_thumbnail function:

$image = "image.jpg";
$thumbnail = exif_thumbnail($image, $width, $height, $type);
echo "<img  width='$width' height='$height' src='data:image;base64,".base64_encode($thumbnail)."'>";

Keep in mind that the thumbnail generated here is from the Exif data – there are other ways to create a thumbnails using many of the PHP image functions.

Be Sociable, Share!

27 thoughts on “Using PHP to Extract Image Exif Data

  1. Hi,

    I have to retrieve the following information from the image. is it possible by exif_read_data?
    1) title
    2) tag

    Thanks for helping me :-)

  2. hi nessa,

    thanks for the code.
    i just test it but how come all the image i try dont have the IFD data things?

  3. found out exif is stripped when processed by base64_encode/ base64_decode

    $pic = base64_decode($img_str);
    $im = imagecreatefromstring($pic);
    imagejpeg($im, ‘noexif.jpg’);

    noexif.jpg has exif stripped….wondering how to keep exif intacted?

  4. How about support for EXIF 2.2?
    I’ve tried these samples on a JPEG created by a Canon 5D Mark II, which writes EXIF 2.2.
    The problem is that I couldn’t read most of the EXIF.

    So, is there any PHP code than can retrieve EXIF 2.2 data?

  5. Is there a way to embed “keywords” in a image file using a product like lightroom and then be able to access that info using PHP?

    I would like to be able to create a custom search function for images using keywords and on upload run a PHP program to extract the keywords and add them to the image database table for searching. But I don’t see such keywords in the exif data being extracted. Am I missing it?

  6. I can take a look – you mind sending me an original format of an image from your camera? Email to admin [ @ ] v-nessa [ dot ] net and I’ll see if I can get this to work!

  7. I answered my own question. Its not exit data you want if your looking to pull the keywords off a photo that you have assigned in an application like Lightroom. You want the IPTC data. So here is a little code that loops through a set of images (store the image names in a database for example) and pulls the keywords out and then writes them to a keywords field for each image. This way you can assign all your keywords during image processing, then upload the images and access all the keywords without re-entering them:

    do {

    $theId = $row_photos[‘photoid’]; //photoid stored in DB for each photo entry

    $eachfile = “../images//”.$row_photos[‘name’];// where images are stored on server. name is the name of the image file, stored in the DB

    $size = GetImageSize ($eachfile, &$info);
    $iptc = iptcparse($info[“APP13”]);// get keywords data from image
    $keywords = $iptc[“2#025”][0];// keywords array

    $updateSQL = sprintf(“UPDATE photos SET keywords=’$keywords’ WHERE photoid=’$theId'”);
    $Result1 = mysql_query($updateSQL, $DBConnection) or die(mysql_error());

    while ($row_photos = mysql_fetch_assoc($photos));

  8. On the above post some formatting got stripped out of one line since I used brackets. The $eachfile line looks more like this:
    $eachfile = “../images/..path../”.$row_photos[‘name’];

    Which is the path to the file on the server.

  9. How easy are guys? I do a search for extracting exif data and wind up on a blog with a hot chick telling me how to do something I was expecting from a male geek. Instantly bookmarked.

    You’re pretty hot.

  10. Would I be even easier if I tell you that I’m actually a 43 year old man, and use the hot chick image to attract male visitors? Just kidding :)

  11. Thanks. Is this exif data you’re pulling just for personal reference? Or is there some specific reason to pull it?

    The only reason I’m curious about exif data is because in Adobe Photoshop, sometimes the data will make an image load sideways.

    Now if you can create a code to remove certain exif data, things will be golden. :P

  12. I tried this and the info I need is not showing.
    What I am after is to extract the GPS (Lat/Long) from the image,
    (next step will be to add code to store the info in a in a MYSql database.)

    Any thoughts? (|)

  13. Ha! I found your blog again and the same post! This post helped me solve something.

    I still have a minor problem though…

    When test for type 2 JPG, 3 still passes my test!
    if($check_image_type == 2){
    //$check_image_type == 3 and code will run
    //code if type is 2
    } else {
    //code if type is anything but 2

    PNG’s seem to break that code whether I test for 3 or whether I test for ‘image/jpeg’ or ‘jpeg’ or ‘JPG’. No matter what, it breaks when I test PNG’s and the damn exif_imagetype flat out says 3 and PHP says “2 = 3”.

    But i just know that 2 does not equal 3.

    Any ideas why this is happening? Think it could be codeigniter? or XAMPP or I’m doing something stupid and I just can’t see it.

    Thanks if you can help.

    PS- i’m glad you’re not a 43 yr old man. I do happen to be a 40 yr old man.

  14. somewhat false alarm. I can now verify that 2 does not equal 3 and my problem was between the keyboard and the chair.

    But, I still can get the OR operator to work. Do you know why this doesn’t work ceteris paribus:

    if($check_image_type == (2 or 8)){
    // code runs regardless of type
    } else {
    //code if type is anything but 2

    It’s gotta be the way I’m using OR right? I tried || too and it still doesn’t work. If I leave it just 2 without the OR it works.

    Thanks if you can help.

Leave a Reply

Your email address will not be published. Required fields are marked *