Exif support

I'm trying to get Exif support going, where can I send my contributions? It works so far but it's not pretty... if anybody is interested look at http://www.zareff.it/zenphoto/

Comments

  • I've been working on some exif stuff myself. I'll let you know as soon as I get it online and we can compare notes.
  • great, I have to admin that mine is kind of a hack, I had to use an external class because my ISP didn't compile exif support in php.

    This is the lib I used: http://www.sanisoft.com/phpexifrw
  • I used the following code in the image.php file of the template to show (and hide) the EXIF information:

    BTW: I copied the code from another webside/forum and changed it to fit in here and to be able to turn it off and on without AJAX.

    `


    <?php<br />
    $showexif = $HTTP_GET_VARS['showexif'];

    if (($showexif == "1")){

    $image = "albums/".getAlbumTitle()."/".getImageTitle();

    /* In my gallery code all my images are under the gallery folder, under a specific gallery, the path below can be changed to where you images are located. */

    /*$imagepath = $_SERVER['DOCUMENT_ROOT']."/gallery/".$gallery."/".$filename.".jpg";*/

    $imagepath = $image;

    /* next line obtains the exif data from the images the second parameter can be changed to 'EXIF' but seems 'IFD0' works fine for the list of information I need */

    @$exif = exif_read_data($imagepath, 'IFD0');

    /* Because manufacture vary , the exif information provided isnt always in the same name, I check to see if at least two of the exif information is not blank, if they are then I assume no valid exif information is present. */

    if (($exif['FNumber'] == "") || ($exif['FocalLength'] == ""))

    return "No EXIF Data";

    else

    {

    @$exif = exif_read_data($imagepath, 'IFD0', true);

    //uncomment the next code block, if you wish to see ALL values inside of the exif information, useful for finding the exact keys you want beforehand/*

    foreach ($exif as $key => $section) {

    foreach ($section as $name => $val) {

    echo "n";

    }

    }

    */

    //convert the raw values to understandible values

    $Fnumber = explode("/", $exif['EXIF']['FNumber']);

    $Fnumber = $Fnumber[0] / $Fnumber[1];

    $Focal = explode("/", $exif['EXIF']['FocalLength']);

    $Focal = $Focal[0] / $Focal[1];

    //prepare the text for return

    $exif_text = "Model: ".$exif['IFD0']['Model']."
    ";

    $exif_text = $exif_text."Shutter: ".$exif['EXIF']['ExposureTime']."
    ";

    $exif_text = $exif_text."Aperture: f/".$Fnumber."
    ";

    $exif_text = $exif_text."ISO Speed: ".$exif['EXIF']['ISOSpeedRatings']."
    ";

    $exif_text = $exif_text."Focal Length: ".round($Focal)."mm
    ";

    echo "

    Hide EXIF information<?php echo $showexif;?>
    ".$exif_text;

    }

    }

    else

    {

    echo "
    Show EXIF information<?php echo $showexif;?>
    ";

    }

    ?>

    `
  • Maybe it's an idea to be able to use the EXIF value of "ImageDescription" as automatic title of the image in the upload mode.
  • I added the following in the template_functions.php:

    require_once("exif.inc");

    function getImageEXIFData() {
    $er = new phpExifRW("../" . getFullImageURL());
    $er->processFile();
    $er->showImageInfo();
    }

    and then called the getImageEXIFData() from the template's image.php.

    the exif.inc can be found on http://www.sanisoft.com/phpexifrw

    on a side note, exif.inc has data caching on by default, I had to turn it off to get it to work on my website.
  • trisweb Administrator
    Great, I'll add this into the codebase for the next release. Thanks for doing it yourself! :)

    Eventually I'll give you the ability to select which EXIF tags to display and all that.
  • thanx, that would ideed be great. Also think of the "ImageDescription" as automatic title.
    Keep on doing the good work!

    PS: also tried gallery2 yesterday, but that wasn't that intuitive
  • trisweb Administrator
    Sadly, I laugh at gallery2. They spent three years and did XP (extreme programming) and forgot why they were doing it.

    It has its place though. If you want your users to upload pics, or if you want some of the more sophisticated modules, then it's a good thing to have.
  • i got a fairly simple list of exif data working for my gallery. it shows the camera i used, aperture, iso, shutter speed, focal length and date/time taken. i added this function to template-functions.php:
    `

    function printExifData() {

    global $_zp_current_image;

    $crntimg = $_zp_current_image->getFullImage();

    $HTTP_HOST = getenv('HTTP_HOST'); /* domain name */

    $current_image = "http://$HTTP_HOST$crntimg";

    $exif = read_exif_data($current_image);

    while(list($k,$v)=each($exif)) {

    if($k=="DateTimeTaken") { echo "Taken: $v
    n"; }

    if($k=="Make") { echo "Camera: "; if($v!="Canon") { echo "$v ";} }

    if($k=="Model") { echo "$v
    n"; }

    if($k=="ExposureTime") { $exposure = $v;

    if($exposure != "")

    {

    $exposure2 = split("/",$exposure);

    if(count($exposure2) == 2)

    {

    $exposure = round($exposure2[0]/$exposure2[1],2);

    if($exposure < 1) $exposure = '1/'.round($exposure2[1]/$exposure2[0],0);

    }

    $exposure = "$lang_exposure $exposure";

    }

    echo "Shutter Speed: $exposure sec
    n"; }

    if($k=="FNumber") { $fstop = $v;

    if($fstop != "")

    {

    $fstop = split("/",$fstop);

    if(count($fstop) == 2) $fstop = round($fstop[0]/$fstop[1],2);

    $focal = "$lang_focal $fstop";

    }

    echo "Aperture: f/$fstop
    n"; }

    if($k=="ISOSpeedRatings") { echo "ISO Speed: $v
    n"; }

    if($k=="FocalLength") { $focal = $v;

    if($focal != "")

    {

    $focal = split("/",$focal);

    if(count($focal) == 2) $focal = round($focal[0]/$focal[1],2);

    $focal = "$lang_focal $focal mm";

    }

    echo "Focal Length: $focal
    n"; }

    }

    }

    `

    then i can call `<?php printExifData(); ?>` in my templates to display it. hope this helps out.

  • sorry to repost so soon. i change the code a bit to clean up the date formatting.

    `function printExifData() {

    global $_zp_current_image;

    $crntimg = $_zp_current_image->getFullImage();

    $HTTP_HOST = getenv('HTTP_HOST'); /* domain name */

    $current_image = "http://$HTTP_HOST$crntimg";

    $exif = read_exif_data($current_image);

    while(list($k,$v)=each($exif)) {

    if($k=="DateTimeOriginal") { $datetime = $v;

    list($fulldate, $fulltime) = explode(' ', $datetime, 2);

    list($year, $monthnum, $day) = explode(':', $fulldate, 3);

    list($hour, $minute, $second) = explode(':', $fulltime, 3);

    $num[0] = "/01/";

    $num[1] = "/02/";

    $num[2] = "/03/";

    $num[3] = "/04/";

    $num[4] = "/05/";

    $num[5] = "/06/";

    $num[6] = "/07/";

    $num[7] = "/08/";

    $num[8] = "/09/";

    $num[9] = "/10/";

    $num[10] = "/11/";

    $num[11] = "/12/";

    $alpha[0] = "January";

    $alpha[1] = "February";

    $alpha[2] = "March";

    $alpha[3] = "April";

    $alpha[4] = "May";

    $alpha[5] = "June";

    $alpha[6] = "July";

    $alpha[7] = "August";

    $alpha[8] = "September";

    $alpha[9] = "October";

    $alpha[10] = "November";

    $alpha[11] = "December";

    $month = preg_replace($num, $alpha, $monthnum);

    if ($hour >=13) {

    $cleanhour = $hour -12; }

    echo "Taken: $day $month $year at $cleanhour:$minute "; if ($hour >=13) { echo "PM"; } else { echo "AM"; } echo "
    \n"; }

    if($k=="Make") { echo "Camera: "; if($v!="Canon") { echo "$v ";} }

    if($k=="Model") { echo "$v
    \n"; }

    if($k=="ExposureTime") { $exposure = $v;

    if($exposure != "")

    {

    $exposure2 = split("/",$exposure);

    if(count($exposure2) == 2)

    {

    $exposure = round($exposure2[0]/$exposure2[1],2);

    if($exposure < 1) $exposure = '1/'.round($exposure2[1]/$exposure2[0],0);

    }

    $exposure = "$lang_exposure $exposure";

    }

    echo "Shutter Speed: $exposure sec
    \n"; }

    if($k=="FNumber") { $fstop = $v;

    if($fstop != "")

    {

    $fstop = split("/",$fstop);

    if(count($fstop) == 2) $fstop = round($fstop[0]/$fstop[1],2);

    $focal = "$lang_focal $fstop";

    }

    echo "Aperture: f/$fstop
    \n"; }

    if($k=="ISOSpeedRatings") { echo "ISO Speed: $v
    \n"; }

    if($k=="FocalLength") { $focal = $v;

    if($focal != "")

    {

    $focal = split("/",$focal);

    if(count($focal) == 2) $focal = round($focal[0]/$focal[1],2);

    $focal = "$lang_focal $focal mm";

    }

    echo "Focal Length: $focal
    \n"; }

    }

    }`

  • So when will the exif stuff be part of the release? I'm looking forward to that...
  • Are you guys able to put the exif stuff into the database, so sorting by picture date can be applied?
  • Dryan, thanks a lot for the EXIF functions. For some reason all of the times in the AM do not contain an hour value. All those in the PM work fine. For example it will show 4:25 p.m. but 10:23 a.m. will display as :23 a.m.

    Any ideas? Thank you.
  • Just solved my own problem. In the GET EXIF function listed above (the most recent cleaned up version) there is a slight problem with the $hour to $cleanhour conversion.

    To fix
    Go down to line 44 and look for

    `if ($hour >=13) {

    $cleanhour = $hour -12; }`

    after this statement you need to tack on the phrase

    `else {

    $cleanhour = $hour;

    }`

    Hence, the final phrase should read

    `if ($hour >=13) {

    $cleanhour = $hour -12;

    } else {

    $cleanhour = $hour;

    }`

    Overall though, great work dryan. This is a really useful function. Thanks.
  • thnx for the posts on this topic, as my IIS host does not allow the php exif dll to be activated (ggrr) I found that the solution with the exif.inc works however this seems to terribly slow down the load preformance. So I found the next solution that works for me under apache and IIS which reads the xmp data from photoshop within the image and since I edit every image for me this is not a problem now it runs fast ! it might work for you too..

    http://www.photography-on-the.net/ee/beta/cs_xmp_to_exif.php

    only one problem that is it does show f.i. the F number as F 40/10 instead of F4.0 ;(

    for the url path part I used
    $xmp_parsed = ee_extract_exif_from_pscs_xmp ("../" . getFullImageURL() . "",1);
  • well I got it to work (divide the F num) thnx to dryan's code mentioned above and a php function from php.net which strips the tags from the xmp data output ;
    `$strvalue = preg_replace ("@&lt;/?[^>]*>*@, ", $value);`

    so the full code for getting the xmp date is as follow;

    `

    <?php</p>

    $xmp_parsed = ee_extract_exif_from_pscs_xmp ("../" . getFullImageURL() . "",1);

    function ee_extract_exif_from_pscs_xmp ($filename,$printout=0) {

    ob_start();

    readfile($filename);

    $source = ob_get_contents();

    ob_end_clean();

    $xmpdata_start = strpos($source,"
    $xmpdata_end = strpos($source,"");

    $xmplenght = $xmpdata_end-$xmpdata_start;

    $xmpdata = substr($source,$xmpdata_start,$xmplenght+12);

    $xmp_parsed = array();

    $regexps = array(

    //array("name" => "maker", "regexp" => "/.+/"),

    array("name" => "model", "regexp" => "/.+/"),

    array("name" => "exp", "regexp" => "/.+/"),

    array("name" => "f", "regexp" => "/.+/"),

    array("name" => "mm", "regexp" => "/.+/"),

    array("name" => "iso", "regexp" => "/s*s*.+s*s*/"),

    );

    foreach ($regexps as $key => $k) {

    $name = $k["name"];

    $regexp = $k["regexp"];

    unset($r);

    preg_match ($regexp, $xmpdata, $r);

    $xmp_item = "";

    $xmp_item = @$r[0];

    array_push($xmp_parsed,array("item" => $name, "value" => $xmp_item));

    }

    echo "

    ";

    if ($printout == 1) {

    foreach ($xmp_parsed as $key => $k) {

    $item = $k["item"];

    $value = $k["value"];

    $strvalue = preg_replace ("@&lt;/?[^>]*>*@, ", $value);

    if($item=="model"){

    print "
    " . $strvalue . "
    ";

    } else if ($item=="exp") {

    $exposure = split("/",$strvalue);

    if(count($exposure) == 2){

    $strvalue = round($exposure[0]/$exposure[1],2);

    if($strvalue < 1) $strvalue = '1/'.round($exposure[1]/$exposure[0],0);}

    print "
    " . $strvalue . " sec.
    ";

    } else if ($item=="f") {

    $strvalue = split("/",$strvalue);

    if(count($strvalue) == 2) $strvalue = round($strvalue[0]/$strvalue[1],2);

    print "
    f/ " . $strvalue . "
    ";

    } else if ($item=="mm") {

    $strvalue = split("/",$strvalue);

    if(count($strvalue) == 2) $strvalue = round($strvalue[0]/$strvalue[1],2);

    print "
    " . $strvalue . "" . $item . "
    ";

    } else {

    print "
    " . $item . "" . $strvalue . "
    ";

    }

    }

    }

    echo "
    ";

    return ($xmp_parsed);

    }

    ?>

    `

    I hope this will help ppl who are stuck on IIS ;)
  • thankyou to dryan, i used parts of your example code to get the date and cam model on my image pages. http://austinandteresa.co.uk/gallery

    Just a thought if exif data is going to be inserted into the db so that we can sort etc on it. If this will be on upload then a function should be added to the admin section to do this for a) existing images and b) ftp'd images
Sign In or Register to comment.