PHP: Automatically Creating a Photo Gallery from Digital Camera Files (Exif Data)

Monday, March 23, 2009

Digital cameras actually store a Pandora's box of additional information in any JPEG or TIFF that they create. Information about the camera itself and the specifications of the image (such as ISO speed used) will be saved. Also, most cameras actually save a small thumbnail version of the image as wellthat's how they implement the preview function on the camera itself.

PHP has a library, the Exif library that can read this data. (The data is in a standard format known as the Exif specification.) This library, like many others, is actually included in the PHP distribution but is not compiled in by default. You will need to specify that you want to compile or include it into your version of PHP. For more information on this, visit the PHP documentation: http://php.net/exif.

This information can be great to use when building photo albums of your pictures. Listing 18.5.1 is a quick example that scans a provided directory for any .JPG images and, for each one, reads the thumbnail and other Exif data, displaying it to the user with a link to the full image.

<style>
div {
    text-align: center;
    border: 2px solid black;
    padding: 5px;
    margin: 10px;
}
ul {
    font-size: 9px;
    text-align: left;
}
</style>
<?php
// Define a path - We are assuming that this will be a relative path working
//  both in the filesystem, and through the web for links:
$path = "photos/";

// Open the directory
$do = dir($path);

// Loop through it, looking for any/all JPG files:
while (($file = $do->read()) !== false) {
    // Parse this for the extension
    $info = pathinfo($path . $file);

    // Continue only if this is a Jpeg
    if (strtolower($info['extension']) == 'jpg') {
        // We found one!  Start a DIV to display & link to this:
        echo "<div><a href=\"{$path}{$file}\">";

        // Let's try to grab the graphic, and if so, display it.
           if ($thumb = exif_thumbnail($path . $file, $width,
                   $height, $type)) {
            // We got one.  Therefore first figure out the mime type of it
            $mime = image_type_to_mime_type($type);

            // Now we are going to use an HTML trick, and embed the graphic
            // directly into the webpage as base64 encoded data
            $encoded = base64_encode($thumb);
            echo "<img src=\"data:{$mime};base64,{$encoded}\" /><br />";
        }

        // In either case, place the name of the file as part of the link:
        echo $file, "</a>\n";

        // Now let's read in all the Exif data:
        if ($exif = exif_read_data($path . $file)) {
            // We got it.  So start an unordered list to display it all
            echo "<ul>\n";

            // We need to loop through each 'section' of this data
            foreach ($exif as $section => $sectiondata) {
                // If sectiondata is an array, start a new list:
                if (is_array($sectiondata)) {
                    // Output the section name, and start a new list
                    echo "<li>{$section}<ul>\n";

                    // Loop through this section now
                    foreach ($sectiondata as $name => $data) {
                        // Output this line of data
                        echo "<li>{$name} = ", htmlspecialchars($data),
                            "</li>\n";
                    }

                    // Close our section off
                    echo "</ul></li>\n";
                } else {
                    // It's not really a section, its got data.  Echo it
                    echo "<li>{$section} = ",
                        htmlspecialchars($sectiondata), "</li>\n";
                }
            }

            // Close the entire list off
            echo "</ul>\n";
        }

        // Close the div tag
        echo "</div>\n";
    }
}
?>


As written, this ends up generating some potentially ugly pages (as well as large). The biggest problem is that what Exif data exists depends completely on the manufacturer, and even the model of the camera. Some may only include a few fields; however, most include far more than you would expect. If you were going to truly be writing some form of photo gallery software based on this code, you would certainly need to pick a subset of the fields that you would want to display.

Hope it helps.

0 comments: