Zenphoto Download W/ Maps, RSS, EXIF, Subalbums & Video

If you are looking for ZenPhoto with ZenVideo, Google Maps Integration and RSS applied to the latest SVN (441) you are in luck! I have prepared the package using the code available on trac and this forum.

Download: Removed (incorporated into SVN)

Note: these functions are available on any theme, but google maps integration and EXIF have only been applied to the 'default' and 'default-dark' themes.

Getting these new functions to work in your themes:

Google Maps Integration (images need to be geotagged) The following line goes in your images.php file:
`<?php printImageMap(); ?>`

EXIF Display - The following line goes in your images.php file:
`<?php printImageEXIFData(); ?>`

RSS Link - Goes wherever you want it to go and requires customfunctions.php and rss.php
`< a href="page/rss">RSS`

ZenVideo discussion: http://www.zenphoto.org/support/topic.php?id=795&replies=82
Google Maps Integration on trac: http://www.zenphoto.org/trac/ticket/78
RSS discussion: http://www.zenphoto.org/support/topic.php?id=764&replies=17#post-7722

This download incorporates fixes for the following tickets: 98, 82, 78, 7

Enjoy!
«1345

Comments

  • You rock! Thanks. Its working for me at www.gnomadic.org (only geo-coded the washington DC pics).

    It is putting the pin in the wrong location for the coordinates contained in the XIF data. Any idea why?
    Example: http://www.gnomadic.org/gallery/washington-dc/willard+3.jpg.php

    How do we set the map type? (street, satellite, hybrid)
  • Ambitious Lemon: I really cant provide support for this since I didnt write it, I just put everything together. I am not sure why your pictures are showing up in incorrect places. I geocoded mine using picasa + google earth and they came out exactly where I tagged them in google earth. But I did check your image out in my google earth and it came out exactly where you said it should.

    Also, you might want to download the zip file again and grab the new template_functions.php it fixes an issue where videos were trying to export exif info.

    Documentation for the mapping file: http://www.systemsevendesigns.com/phoogle
  • Ah thanks for the tip, uploaded the new template_functions.php file. I downloaded some geotagged images from other zenphoto galleries with this hack (ones that were working) and they worked on my gallery as well. So I am just tagging the files incorrectly somehow.

    I've tried a few different apps to geo tag them and it always comes out the same.

    Maybe someone else will have a wise idea.
  • AmbitiousLemon,

    We're not sure why this is happening, but it appears your problem with map pins in the wrong location is related to the encoding method used to store the GPS data in your images.

    Some cameras store EXIF in "Big Endian" format, some use "Little Endian" (top-down or bottom-up byte order). It seems the that geotagging with Google tools can in some cases result in images which are Big-Endian containing GPS data which is Little-Endian. The EXIF parser included in these patches is unable to tell the difference, and parses the data as Big-Endian, rendering scrambled coordinates.

    You should find that images which display correctly on your map are from a different make of camera than the ones that do not. So far, I can report that Canon images work, and Sony ones appear not to in some cases.
  • To confirm dspnorman's statements: As far as we can tell the problem has to do with the original Endian-ness of the EXIF data and the Endian-ness of the GPS data written to into the EXIF data.

    EXIF has a 'flag' of sorts that state if it is Little or Big Endian. If the tool used to encode the GPS data ignores that, you'll end up with your map points in vary strange places. The EXIF library reads the 'flag' and decodes the EXIF data accordingly. If the GPS data isn't written in the same Endian-style, you'll get strange coords. It isn't the parers fault (afaik), it reads the endian-ness of the EXIF correctly.

    I have an example image at:
    http://mu.thenullpointer.net/Silverdale_Brewery_and_Geocaching_200704/IMG_0014.JPG.php.

    View the page and notice that I have a debug statement "Endian as defined in EXIF: Intel". Now download the full image, and geocode it *somewhere*. Put it in your own gallery and notice that it shows up correctly. dspnorman has confirmed that he can geocode my image and it'll work correctly.

    Now take a look at:
    http://mu.thenullpointer.net/Silverdale_Brewery_and_Geocaching_200704/from_smith_tower_coded_1.jpg.php
    (this image is a test from Google Images).
    Notice it says the Endian-ness is Motorola (BigEndian) and notice how the location is *way* off.
    If I tell the Exif library to just decode the GPS stuff as Intel (LittleEndian) it'll showup in Seattle as it should be.

    Someone has posted something about Exif byte-order problems at the following URL:
    http://www.whirljack.net/jeremybrooks/2007/03/01/zooomr-metadata-the-plot-thickens/
  • Another note: Are you using anything *before* geocoding the images to edit EXIF data? IIRC, dspnorman had stripped out his EXIF data before geocoding which may have done something to change the byte-order for the EXIF data.

    I would like some data about the images you are trying to geocode:
    * What is the endian-ness (byte-order) of the EXIF data of an image directly off your camera? I'm sure many EXIF reader programs can give you this information.

    * Are you doing any editing *before* geocoding them? If so, what program? If you know the EXIF byte-order *before* editing, what is the EXIF byte order *after* editing?
  • Well that seems like a possible explanation.

    I don't know how to check the Endian-ness of the files. I tried half a dozen different applications and none of them give that sort of information. Do you have any recommendations on how to check this? (OSX). The files appear to have been converted to JPEG, but I don't know what software was used to do this.

    The EXIF info is:
    File Name willard 3.jpg
    Document Type JPEG Image
    File Size 81056 bytes
    Color Model RGB
    Depth 8
    DPI Height 72
    DPI Width 72
    Pixel Height 480
    Pixel Width 712
    Profile Name sRGB Profile

    Exif Properties

    Aperture Value 4.339844
    Color Space 1
    Compressed Bits Per Pixel 3
    Custom Rendered 0
    Date Time Digitized 2007:02:10 13:22:25
    Date Time Original 2007:02:10 13:22:25
    Exif Version 2.2.1
    Exposure Bias Value 0
    Exposure Mode 0
    Exposure Time 0.008
    Flash 0
    FlashPix Version 1.0
    FNumber 4.5
    Focal Length 28
    Focal Plane Resolution Unit 2
    Focal Plane X Resolution 3443.946
    Focal Plane Y Resolution 3442.017
    ISO Speed Ratings 800
    Max Aperture Value 3.614716
    Metering Mode 5
    Pixel X Dimension 712
    Pixel Y Dimension 480
    Scene Capture Type 0
    Sensing Method 2
    Shutter Speed Value 6.965789
    White Balance 0

    GPS Properties

    Altitude 0
    Altitude Reference 0
    GPS Version 2.2
    Latitude 38.88923
    Latitude Reference N
    Longitude 77.05008
    Longitude Reference W
    Map Datum WGS-84

    IPTC Properties

    Caption / Abstract
    City Washington
    Headline
    Province / State D.C.
    Sub-Location

    JFIF Properties

    Density Unit 1
    JFIF Version 1.1
    X Density 72
    Y Density 72

    TIFF Properties

    Artist Gregg Mendez
    Date Time 2007:02:10 13:22:25
    Make Canon
    Model Canon EOS DIGITAL REBEL
    Resolution Unit 2

    So I also can not find any application that allows me to remove the geocoded EXIF tags. Any ideas on this? I tried setting the tags with a variety of different applications, but they all did the same thing. Are there any applications that can do this properly? - If not its probably best to change the phoogle code to be able to read these files regardless of the Endian formatting (like every application I have tried seems to be able to do).

    The trouble I am in now is that:
    1) I can't undo what I have done.
    2) If I could undo what I have done I can't geocode images without running into this same problem again.

    Ideally I would be able to find an application that can geocode images properly, runs on OSX (Intel and PPC), works for any camera (since my photos will be taken on many different camera), and doesn't matter if it was processed initially with with something like lightroom or aperture first. This is because my photos are taken by many different people with their own cameras and geocoded on their own computers (I don't know anyone who uses windows though so no need for a windows solution).
  • @AmbitiousLemon
    I'm using OS X, and using a command line program called 'jhead' to read and strip Exif data. I've also tried tagging photos with various apps and it always works *unless* the Exif data is BigEndian then the GPS coordinates are completely wrong when parsed by Exifixer. The problem is likely within the Exifixer, the Exif parser. It isn't Phoogle that needs to be changed. Phoogle simply takes gps points and displays it on a map.

    Gallery2 also uses Exifixer. Currently they are looking to move to another Exif parser simply because Exifixer has a lot of problems.

    I think I am going to checkout some of the suggested alternatives (on the Gallery2 wiki) to Exifixer when I get home from work. Perhaps I can work something up with minimal changes to the core Zen Exif code.

    The apps I use on OS X are HoudahGeo and GPSPhotoLinker and they work fine.

    I wouldn't worry about your images for now.
  • @mannkind
    Thanks for the tip about jhead. I stripped the exif data and re-geocoded it and got it working. I don't like having to remove all the original data though.

    It would be great if you could find a more mixed endian friendly exif parser.
  • @AmbitiousLemon

    Last night I spent some time trying other parsers and I'm not all that impressed with any of them. So I turned my eyes back to Exifer. I think I found the problem. I sent the fix to dspnorman and I can send it to you if you'd like to test.

    Let me know
  • I'd be happy to test it. You can email it to me at jbanks@ambitiouslemon.com
  • Just applied mannkind's patch, and my problem images now display correctly on the map.
  • trisweb Administrator
    mannkind - good to hear you fixed the bug in Exifixer - It may be clunky, but it is well written I think and easy to hack/fix. That's part of the reason I adopted it.

    This is a good package. I may just patch it all into SVN after testing...
  • @AmbitiousLemon
    I've uploaded the patch to Zenphoto Trac. #78

    @trisweb
    The library *is* pretty decent. You are right, it does seem pretty easy to hack/fix. It could probably use some improvements, but what couldn't?
    I like it more than the other libraries I toyed with.

    Glad you like the package! I'm also glad it has gained some momentum.
  • gps patch tested and working perfectly here.
    You guys all rock.
  • I've been using Exifier for a couple days but found that Panasonic's MakerNote tag is not parsed.

    Since I created it, I though that anyone might be interested.
    Let me know
  • @jordi-kun

    By all means we'd love to see it. Anything to improve the useability of the EXIF parsing is OK by us.
  • here are the 2 changes.

    - in exif.php/read_entry() add a new "else if" for the panasonic makernote

    `} else if(eregi("PANASONIC",$make)) {

    require_once('makers/panasonic.php');

    parsePanasonic($data,$result,$seek,$globalOffset);

    $result[$ifd_name]['KnownMaker'] = 1;`

    - a new file "panasonic.php" in "makers" folder

    `<?php<br />
    //================================================================================================

    //================================================================================================

    //================================================================================================

    /*

    Exifer

    Extracts EXIF information from digital photos.

    Copyright © 2003 Jake Olefsky

    http://www.offsky.com/software/exif/index.php

    jake@olefsky.com

    Please see exif.php for the complete information about this software.

    ------------

    This program is free software; you can redistribute it and/or modify it under the terms of

    the GNU General Public License as published by the Free Software Foundation; either version 2

    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;

    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    See the GNU General Public License for more details. http://www.gnu.org/copyleft/gpl.html

    */

    //================================================================================================

    //================================================================================================

    //================================================================================================

    //=================

    // Looks up the name of the tag for the MakerNote (Depends on Manufacturer)

    //====================================================================

    function lookup_Panasonic_tag($tag) {

    switch($tag) {

    case "0001": $tag = "Quality";break;

    case "0002": $tag = "FirmwareVersion";break;

    case "0003": $tag = "WhiteBalance";break;

    case "0007": $tag = "FocusMode";break;

    case "000f": $tag = "AFMode";break;

    case "001a": $tag = "ImageStabilizer";break;

    case "001c": $tag = "MacroMode";break;

    case "001f": $tag = "ShootingMode";break;

    case "0020": $tag = "Audio";break;

    case "0021": $tag = "DataDump";break;

    case "0023": $tag = "WhiteBalanceBias";break;

    case "0024": $tag = "FlashBias";break;

    case "0025": $tag = "SerialNumber";break;

    case "0028": $tag = "ColourEffect";break;

    case "002a": $tag = "BurstMode";break;

    case "002b": $tag = "SequenceNumber";break;

    case "002c": $tag = "Contrast";break;

    case "002d": $tag = "NoiseReduction";break;

    case "002e": $tag = "SelfTimer";break;

    case "0030": $tag = "Rotation";break;

    case "0032": $tag = "ColorMode";break;

    case "0036": $tag = "TravelDay";break;

    default: $tag = "unknown:".$tag;break;

    }

    return $tag;

    }

    //=================

    // Formats Data for the data type

    //====================================================================

    function formatPanasonicData($type,$tag,$intel,$data) {

    if($type=="ASCII") {

    } else if($type=="URATIONAL" || $type=="SRATIONAL") {

    $data = bin2hex($data);

    if($intel==1) $data = intel2Moto($data);

    $top = hexdec(substr($data,8,8));

    $bottom = hexdec(substr($data,0,8));

    if($bottom!=0) $data=$top/$bottom;

    else if($top==0) $data = 0;

    else $data=$top."/".$bottom;

    if($tag=="0023") { //White Balance Adjust

    $data=$data." EV";

    }

    } else if($type=="USHORT" || $type=="SSHORT" || $type=="ULONG" || $type=="SLONG" || $type=="FLOAT" || $type=="DOUBLE") {

    $data = bin2hex($data);

    if($intel==1) $data = intel2Moto($data);

    $data=hexdec($data);

    if($tag=="0001") { //Image Quality

    if($data == 2) $data = "High";

    else if($data == 3) $data = "Standard";

    else if($data == 6) $data = "Very High";

    else if($data == 7) $data = "RAW";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="0003") { //White Balance

    if($data == 1) $data = "Auto";

    else if($data == 2) $data = "Daylight";

    else if($data == 3) $data = "Cloudy";

    else if($data == 4) $data = "Halogen";

    else if($data == 5) $data = "Manual";

    else if($data == 8) $data = "Flash";

    else if($data == 10) $data = "Black and White";

    else if($data == 11) $data = "Manual";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="0007") { //Focus Mode

    if($data == 1) $data = "Auto";

    else if($data == 2) $data = "Manual";

    else if($data == 4) $data = "Auto, Focus button";

    else if($data == 5) $data = "Auto, Continuous";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="000f") { //AFMode

    $data = "Unknown (".$data.")";

    }

    if($tag=="001a") { //Image Stabilizer

    if($data == 2) $data = "Mode 1";

    else if($data == 3) $data = "Off";

    else if($data == 4) $data = "Mode 2";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="001c") { //Macro mode

    if($data == 1) $data = "On";

    else if($data == 2) $data = "Off";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="001f") { //Shooting Mode

    if($data == 1) $data = "Normal";

    else if($data == 2) $data = "Portrait";

    else if($data == 3) $data = "Scenery";

    else if($data == 4) $data = "Sports";

    else if($data == 5) $data = "Night Portrait";

    else if($data == 6) $data = "Program";

    else if($data == 7) $data = "Aperture Priority";

    else if($data == 8) $data = "Shutter Priority";

    else if($data == 9) $data = "Macro";

    else if($data == 11) $data = "Manual";

    else if($data == 13) $data = "Panning";

    else if($data == 18) $data = "Fireworks";

    else if($data == 19) $data = "Party";

    else if($data == 20) $data = "Snow";

    else if($data == 21) $data = "Night Scenery";

    else if($data == 22) $data = "Food";

    else if($data == 23) $data = "Baby";

    else if($data == 27) $data = "High Sensitivity";

    else if($data == 29) $data = "Underwater";

    else if($data == 33) $data = "Pet";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="0020") { //Audio

    if($data == 1) $data = "Yes";

    else if($data == 2) $data = "No";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="0023") { //White Balance Bias

    $data=$data." EV";

    }

    if($tag=="0024") { //Flash Bias

    $data = $data;

    }

    if($tag=="0028") { //Colour Effect

    if($data == 1) $data = "Off";

    else if($data == 2) $data = "Warm";

    else if($data == 3) $data = "Cool";

    else if($data == 4) $data = "Black and White";

    else if($data == 5) $data = "Sepia";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="002a") { //Burst Mode

    if($data == 0) $data = "Off";

    else if($data == 1) $data = "Low/High Quality";

    else if($data == 2) $data = "Infinite";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="002c") { //Contrast

    if($data == 0) $data = "Standard";

    else if($data == 1) $data = "Low";

    else if($data == 2) $data = "High";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="002d") { //Noise Reduction

    if($data == 0) $data = "Standard";

    else if($data == 1) $data = "Low";

    else if($data == 2) $data = "High";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="002e") { //Self Timer

    if($data == 1) $data = "Off";

    else if($data == 2) $data = "10s";

    else if($data == 3) $data = "2s";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="0030") { //Rotation

    if($data == 1) $data = "Horizontal (normal)";

    else if($data == 6) $data = "Rotate 90 CW";

    else if($data == 8) $data = "Rotate 270 CW";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="0032") { //Color Mode

    if($data == 0) $data = "Normal";

    else if($data == 1) $data = "Natural";

    else $data = "Unknown (".$data.")";

    }

    if($tag=="0036") { //Travel Day

    $data=$data;

    }

    } else if($type=="UNDEFINED") {

    } else {

    $data = bin2hex($data);

    if($intel==1) $data = intel2Moto($data);

    }

    return $data;

    }

    //=================

    // Panasonic Special data section

    //====================================================================

    function parsePanasonic($block,&$result) {

    //if($result['Endien']=="Intel") $intel=1;

    //else $intel=0;

    $intel=1;

    $model = $result['IFD0']['Model'];

    $place=8; //current place

    $offset=8;

    $num = bin2hex(substr($block,$place,4));$place+=4;

    if($intel==1) $num = intel2Moto($num);

    $result['SubIFD']['MakerNote']['Offset'] = hexdec($num);

    //Get number of tags (2 bytes)

    $num = bin2hex(substr($block,$place,2));$place+=2;

    if($intel==1) $num = intel2Moto($num);

    $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);

    //loop thru all tags Each field is 12 bytes

    for($i=0;$i
    //2 byte tag

    $tag = bin2hex(substr($block,$place,2));$place+=2;

    if($intel==1) $tag = intel2Moto($tag);

    $tag_name = lookup_Panasonic_tag($tag);

    //2 byte type

    $type = bin2hex(substr($block,$place,2));$place+=2;

    if($intel==1) $type = intel2Moto($type);

    lookup_type($type,$size);

    //4 byte count of number of data units

    $count = bin2hex(substr($block,$place,4));$place+=4;

    if($intel==1) $count = intel2Moto($count);

    $bytesofdata = $size*hexdec($count);

    //4 byte value of data or pointer to data

    $value = substr($block,$place,4);$place+=4;

    if($bytesofdata<=4) {<br />
    $data = $value;

    } else {

    $value = bin2hex($value);

    if($intel==1) $value = intel2Moto($value);

    $data = substr($block,hexdec($value)-$offset,$bytesofdata*2);

    }

    $formated_data = formatPanasonicData($type,$tag,$intel,$data);

    if($result['VerboseOutput']==1) {

    $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;

    if($type=="URATIONAL" || $type=="SRATIONAL" || $type=="USHORT" || $type=="SSHORT" || $type=="ULONG" || $type=="SLONG" || $type=="FLOAT" || $type=="DOUBLE") {

    $data = bin2hex($data);

    if($intel==1) $data = intel2Moto($data);

    }

    $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['RawData'] = $data;

    $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['Type'] = $type;

    $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['Bytes'] = $bytesofdata;

    } else {

    $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;

    }

    }

    }

    ?>`
  • jordi-kun, can you diff your changes against the current SVN version of exif.php, and post a patch on Trac? If you could include the panasonic.php maker file, too, that would be helpful.
  • Attached the panasonic.php in ticket #4.
    Unfortunately, i don't know how to make a patch. The only change in exif.php is the extra "else if" added between line 622 and 623 to consider the panasonic makernote.
  • @jordi-kun
    If you're on Linux (or the like) something like `diff -rupN [file1] [file2]` should do the trick :)
  • not running linux, so attached the patch of the gnuwin32 version of diff (ticket 4)
  • I just wanted to note that I have applied a few updates to the package above.
  • The package has been updated again, mainly because mankind is churning out fixes like crazy. The additional patches/diffs in this update are from tickets #'s: 83, 74, 32, 4, 2
  • Hi, just installed it, very nice :)

    How can one use it in a post? All I see is a link to a zenphoto page
  • Just installed this, but i get the following error;

    Warning: require_once(exif/iptc.php) [function.require-once]: failed to open stream: No such file or directory in C:\xampp\htdocs\zen\functions.php on line 4

    Fatal error: require_once() [function.require]: Failed opening required 'exif/iptc.php' (include_path='.;C:\xampp\php\pear\') in C:\xampp\htdocs\zen\functions.php on line 4

    As you can see im using XAMPP on w2k3, I've looked in the exif folder and there is only a file called exif.php no iptc.php.

    HELP! PLEASE!

    Many thanks!
  • nabberuk, I have updated the package with iptc.php included in the exif folder. You should be able to simply grab the file and drop it in your install.
  • edit
  • Many thanks o kind one, worked a treat!
  • I've just re-read my post and I think it's not very clear :$

    How can I embed the video in a post?
Sign In or Register to comment.