/** * Parces IPTC data and returns those tags zenphoto is interested in * folds multiple tags into single zp data items based on precedence. * * @param string $imageName the name of the image * @return array */ function getImageMetadata($imageName) { require_once dirname(__FILE__) . '/exif/exif.php'; global $iptc; $result = array(); getimagesize($imageName, $imageInfo); if (is_array($imageInfo)) { $exifraw = read_exif_data_protected($imageName); if (isset($exifraw['SubIFD'])) { $subIFD = $exifraw['SubIFD']; } else { $subIFD = array(); } /* EXIF date */ if (isset($subIFD['DateTime'])) { $date = $subIFD['DateTime']; } else { $date = ''; } if (empty($date) && isset($subIFD['DateTimeOriginal'])) { $date = $subIFD['DateTimeOriginal']; } if (empty($date) && isset($subIFD['DateTimeDigitized'])) { $date = $subIFD['DateTimeDigitized']; } if (!empty($date)) { $result['date'] = $date; } /* check IPTC data */ if (isset($imageInfo["APP13"])) { $iptc = iptcparse($imageInfo["APP13"]); if ($iptc) { $characterset = getIPTCTag('1#090'); if (!$characterset) { $characterset = getOption('IPTC_encoding'); } else { if (substr($characterset, 0, 1) == chr(27)) { // IPTC escape encoding $characterset = substr($characterset, 1); if ($characterset == '%G') { $characterset = 'UTF-8'; } else { // we don't know, need to understand the IPTC standard here. In the mean time, default it. $characterset = getOption('IPTC_encoding'); } } else { if ($characterset == 'UTF8') { $characterset = 'UTF-8'; } } } /* iptc date */ $date = getIPTCTag('2#055'); if (!empty($date)) { $result['date'] = substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2); } /* iptc title */ $title = getIPTCTag('2#005'); /* Option Name */ if (empty($title)) { $title = getIPTCTag('2#105'); /* Headline */ } if (!empty($title)) { $result['title'] = prepIPTCString($title, $characterset); } /* iptc description */ $caption = getIPTCTag('2#120'); if (!empty($caption)) { $result['desc'] = prepIPTCString($caption, $characterset); } /* iptc location, state, country */ $location = getIPTCTag('2#092'); if (!empty($location)) { $result['location'] = prepIPTCString($location, $characterset); } $city = getIPTCTag('2#090'); if (!empty($city)) { $result['city'] = prepIPTCString($city, $characterset); } $state = getIPTCTag('2#095'); if (!empty($state)) { $result['state'] = prepIPTCString($state, $characterset); } $country = getIPTCTag('2#101'); if (!empty($country)) { $result['country'] = prepIPTCString($country, $characterset); } /* iptc credit */ $credit = getIPTCTag('2#080'); /* by-line */ if (empty($credit)) { $credit = getIPTCTag('2#110'); /* credit */ } if (empty($credit)) { $credit = getIPTCTag('2#115'); /* source */ } if (!empty($credit)) { $result['credit'] = prepIPTCString($credit, $characterset); } /* iptc copyright */ $copyright = getIPTCTag('2#116'); if (!empty($copyright)) { $result['copyright'] = prepIPTCString($copyright, $characterset); } /* iptc keywords (tags) */ $keywords = getIPTCTagArray('2#025'); if (is_array($keywords)) { $taglist = array(); foreach ($keywords as $keyword) { $taglist[] = prepIPTCString($keyword, $characterset); } $result['tags'] = $taglist; } } } } return $result; }
/** * Parses Exif/IPTC data * */ function updateMetaData() { require_once dirname(__FILE__) . '/exif/exif.php'; global $_zp_exifvars; $IPTCtags = array('SKIP' => '2#000', 'ObjectType' => '2#003', 'ObjectAttr' => '2#004', 'ObjectName' => '2#005', 'EditStatus' => '2#007', 'EditorialUpdate' => '2#008', 'Urgency' => '2#010', 'SubRef' => '2#012', 'Category' => '2#015', 'SuppCategory' => '2#020', 'FixtureID' => '2#022', 'Keywords' => '2#025', 'ContentLocCode' => '2#026', 'ContentLocName' => '2#027', 'ReleaseDate' => '2#030', 'ReleaseTime' => '2#035', 'ExpireDate' => '2#037', 'ExpireTime' => '2#038', 'SpecialInstru' => '2#040', 'ActionAdvised' => '2#042', 'RefService' => '2#045', 'RefDate' => '2#047', 'RefNumber' => '2#050', 'DateCreated' => '2#055', 'TimeCreated' => '2#060', 'DigitizeDate' => '2#062', 'DigitizeTime' => '2#063', 'OriginatingProgram' => '2#065', 'ProgramVersion' => '2#070', 'ObjectCycle' => '2#075', 'ByLine' => '2#080', 'ByLineTitle' => '2#085', 'City' => '2#090', 'SubLocation' => '2#092', 'State' => '2#095', 'LocationCode' => '2#100', 'LocationName' => '2#101', 'TransmissionRef' => '2#103', 'ImageHeadline' => '2#105', 'ImageCredit' => '2#110', 'Source' => '2#115', 'Copyright' => '2#116', 'Contact' => '2#118', 'ImageCaption' => '2#120', 'ImageCaptionWriter' => '2#122', 'ImageType' => '2#130', 'Orientation' => '2#131', 'LangID' => '2#135', 'Subfile' => '8#010'); $this->set('hasMetadata', 0); $result = array(); if (get_class($this) == '_Image') { $localpath = $this->localpath; } else { $localpath = $this->getThumbImageFile(); } $xdate = $this->getDateTime(); if (!empty($localpath)) { // there is some kind of image to get metadata from $exifraw = read_exif_data_protected($localpath); if (isset($exifraw['ValidEXIFData'])) { $this->set('hasMetadata', 1); foreach ($_zp_exifvars as $field => $exifvar) { if (isset($exifraw[$exifvar[0]][$exifvar[1]])) { $exif = trim(sanitize($exifraw[$exifvar[0]][$exifvar[1]], 1)); $this->set($field, $exif); } else { if (isset($exifraw[$exifvar[0]]['MakerNote'][$exifvar[1]])) { $exif = trim(sanitize($exifraw[$exifvar[0]]['MakerNote'][$exifvar[1]], 1)); $this->set($field, $exif); } } } } /* check IPTC data */ $iptcdata = zp_imageIPTC($localpath); if (!empty($iptcdata)) { $iptc = iptcparse($iptcdata); if ($iptc) { $this->set('hasMetadata', 1); $characterset = $this->getIPTCTag('1#090', $iptc); if (!$characterset) { $characterset = getOption('IPTC_encoding'); } else { if (substr($characterset, 0, 1) == chr(27)) { // IPTC escape encoding $characterset = substr($characterset, 1); if ($characterset == '%G') { $characterset = 'UTF-8'; } else { // we don't know, need to understand the IPTC standard here. In the mean time, default it. $characterset = getOption('IPTC_encoding'); } } else { if ($characterset == 'UTF8') { $characterset = 'UTF-8'; } } } // Extract IPTC fields of interest foreach ($_zp_exifvars as $field => $exifvar) { if ($exifvar[0] == 'IPTC') { $datum = $this->getIPTCTag($IPTCtags[$exifvar[1]], $iptc); $this->set($field, $this->prepIPTCString($datum, $characterset)); } } /* iptc keywords (tags) */ $datum = $this->getIPTCTagArray('2#025', $iptc); if (is_array($datum)) { $tags = array(); $result['tags'] = array(); foreach ($datum as $item) { $tags[] = $this->prepIPTCString(sanitize($item, 3), $characterset); } $this->setTags($tags); } } } } /* "import" metadata into Zenphoto fields as makes sense */ zp_apply_filter('image_metadata', $this); /* iptc date */ $date = $this->get('IPTCDateCreated'); if (!empty($date)) { if (strlen($date) > 8) { $time = substr($date, 8); } else { /* got date from IPTC, now must get time */ $time = $this->get('IPTCTimeCreated'); } $date = substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2); if (!empty($time)) { $date = $date . ' ' . substr($time, 0, 2) . ':' . substr($time, 2, 2) . ':' . substr($time, 4, 2); } } /* EXIF date */ if (empty($date)) { $date = $this->get('EXIFDateTime'); } if (empty($date)) { $date = $this->get('EXIFDateTimeOriginal'); } if (empty($date)) { $date = $this->get('EXIFDateTimeDigitized'); } if (!empty($date)) { $xdate = $date; $this->setDateTime($date); } /* iptc title */ $title = $this->get('IPTCObjectName'); if (empty($title)) { $title = $this->get('IPTCImageHeadline'); } //EXIF title [sic] if (empty($title)) { $title = $this->get('EXIFDescription'); } if (!empty($title)) { $this->setTitle($title); } /* iptc description */ $desc = $this->get('IPTCImageCaption'); if (!empty($desc)) { $this->setDesc($desc); } /* iptc location, state, country */ $loc = $this->get('IPTCSubLocation'); if (!empty($loc)) { $this->setLocation($loc); } $city = $this->get('IPTCCity'); if (!empty($city)) { $this->setCity($city); } $state = $this->get('IPTCState'); if (!empty($state)) { $this->setState($state); } $country = $this->get('IPTCLocationName'); if (!empty($country)) { $this->setCountry($country); } /* iptc credit */ $credit = $this->get('IPTCByLine'); if (empty($credit)) { $credit = $this->get('IPTCImageCredit'); } if (empty($credit)) { $credit = $this->get('IPTCSource'); } if (!empty($credit)) { $this->setCredit($credit); } /* iptc copyright */ $this->setCopyright($this->get('IPTCCopyright')); $x = $this->getTitle(); if (empty($x)) { $this->set('title', $this->getDefaultTitle()); } if (empty($xdate)) { $this->set('date', strftime('%Y-%m-%d %H:%M:%S', $this->get('mtime'))); } $alb = $this->album; if (!is_null($alb)) { $save = false; if (strtotime($alb->getUpdatedDate()) < strtotime($this->getDateTime())) { $alb->setUpdatedDate($this->getDateTime()); $save = true; } if (is_null($albdate = $alb->getDateTime()) || $this->album->gallery->getAlbumUseImagedate() && strtotime($albdate) < strtotime($this->getDateTime())) { $this->album->setDateTime($this->getDateTime()); // not necessarily the right one, but will do. Can be changed in Admin $save = true; } if ($save) { $this->album->save(); } } }
/** * Returns an array of EXIF data * * @return array */ function getExifData() { require_once dirname(__FILE__) . '/exif/exif.php'; global $_zp_exifvars; $exif = array(); if (is_null($v = $this->get('EXIFValid')) || $v != 1 || $this->fileChanged()) { $exifraw = read_exif_data_protected($this->localpath); if (isset($exifraw['ValidEXIFData'])) { foreach ($_zp_exifvars as $field => $exifvar) { if (isset($exifraw[$exifvar[0]][$exifvar[1]])) { $exif[$field] = sanitize($exifraw[$exifvar[0]][$exifvar[1]], 3); $this->set($field, $exif[$field]); } } $this->set('EXIFValid', 1); } else { $this->set('EXIFValid', 0); } $this->set('mtime', $this->filemtime); $this->save(); } else { // Put together an array of EXIF data to return if ($this->get('EXIFValid') == 1) { foreach ($_zp_exifvars as $field => $exifvar) { $exif[$field] = $this->get($field); } } else { return false; } } return $exif; }
/** * Parses Exif/IPTC data * */ function updateMetaData() { global $_zp_exifvars, $_zp_gallery; if ($_zp_exifvars) { require_once dirname(__FILE__) . '/exif/exif.php'; $IPTCtags = array('SKIP' => '2#000', 'ObjectType' => '2#003', 'ObjectAttr' => '2#004', 'ObjectName' => '2#005', 'EditStatus' => '2#007', 'EditorialUpdate' => '2#008', 'Urgency' => '2#010', 'SubRef' => '2#012', 'Category' => '2#015', 'SuppCategory' => '2#020', 'FixtureID' => '2#022', 'Keywords' => '2#025', 'ContentLocationCode' => '2#026', 'ContentLocationName' => '2#027', 'ReleaseDate' => '2#030', 'ReleaseTime' => '2#035', 'ExpireDate' => '2#037', 'ExpireTime' => '2#038', 'SpecialInstru' => '2#040', 'ActionAdvised' => '2#042', 'RefService' => '2#045', 'RefDate' => '2#047', 'RefNumber' => '2#050', 'DateCreated' => '2#055', 'TimeCreated' => '2#060', 'DigitizeDate' => '2#062', 'DigitizeTime' => '2#063', 'OriginatingProgram' => '2#065', 'ProgramVersion' => '2#070', 'ObjectCycle' => '2#075', 'ByLine' => '2#080', 'ByLineTitle' => '2#085', 'City' => '2#090', 'SubLocation' => '2#092', 'State' => '2#095', 'LocationCode' => '2#100', 'LocationName' => '2#101', 'TransmissionRef' => '2#103', 'ImageHeadline' => '2#105', 'ImageCredit' => '2#110', 'Source' => '2#115', 'Copyright' => '2#116', 'Contact' => '2#118', 'ImageCaption' => '2#120', 'ImageCaptionWriter' => '2#122', 'ImageType' => '2#130', 'Orientation' => '2#131', 'LangID' => '2#135', 'Subfile' => '8#010'); $this->set('hasMetadata', 0); foreach ($_zp_exifvars as $field => $exifvar) { $this->set($field, NULL); } $result = array(); if (get_class($this) == 'Image') { $localpath = $this->localpath; } else { $localpath = $this->getThumbImageFile(); } if (!empty($localpath)) { // there is some kind of image to get metadata from $exifraw = read_exif_data_protected($localpath); if (isset($exifraw['ValidEXIFData'])) { $this->set('hasMetadata', 1); foreach ($_zp_exifvars as $field => $exifvar) { $exif = NULL; if (isset($exifraw[$exifvar[0]][$exifvar[1]])) { $exif = trim(sanitize($exifraw[$exifvar[0]][$exifvar[1]], 1)); } else { if (isset($exifraw[$exifvar[0]]['MakerNote'][$exifvar[1]])) { $exif = trim(sanitize($exifraw[$exifvar[0]]['MakerNote'][$exifvar[1]], 1)); } } $this->set($field, $exif); } } /* check IPTC data */ $iptcdata = zp_imageIPTC($localpath); if (!empty($iptcdata)) { $iptc = iptcparse($iptcdata); if ($iptc) { $this->set('hasMetadata', 1); $characterset = self::getIPTCTag('1#090', $iptc); if (!$characterset) { $characterset = getOption('IPTC_encoding'); } else { if (substr($characterset, 0, 1) == chr(27)) { // IPTC escape encoding $characterset = substr($characterset, 1); if ($characterset == '%G') { $characterset = 'UTF-8'; } else { // we don't know, need to understand the IPTC standard here. In the mean time, default it. $characterset = getOption('IPTC_encoding'); } } else { if ($characterset == 'UTF8') { $characterset = 'UTF-8'; } } } // Extract IPTC fields of interest foreach ($_zp_exifvars as $field => $exifvar) { if ($exifvar[0] == 'IPTC') { $datum = self::getIPTCTag($IPTCtags[$exifvar[1]], $iptc); $this->set($field, $this->prepIPTCString($datum, $characterset)); } } /* iptc keywords (tags) */ if ($_zp_exifvars['IPTCKeywords'][5]) { $datum = self::getIPTCTagArray($IPTCtags['Keywords'], $iptc); if (is_array($datum)) { $tags = array(); $result['tags'] = array(); foreach ($datum as $item) { $tags[] = $this->prepIPTCString(sanitize($item, 3), $characterset); } $this->setTags($tags); } } } } } /* "import" metadata into database fields as makes sense */ /* ZenPhoto20 Image Rotation */ $this->set('rotation', substr(trim(self::fetchMetadata('EXIFOrientation'), '!'), 0, 1)); /* ZenPhoto20 "date" field population */ if ($date = self::fetchMetadata('IPTCDateCreated')) { if (strlen($date) > 8) { $time = substr($date, 8); } else { /* got date from IPTC, now must get time */ $time = $this->get('IPTCTimeCreated'); } $date = substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2); if (!empty($time)) { $date = $date . ' ' . substr($time, 0, 2) . ':' . substr($time, 2, 2) . ':' . substr($time, 4, 2); } } if (empty($date)) { $date = self::fetchMetadata('EXIFDateTime'); } if (empty($date)) { $date = self::fetchMetadata('EXIFDateTimeOriginal'); } if (empty($date)) { $date = self::fetchMetadata('EXIFDateTimeDigitized'); } if (empty($date)) { $this->setDateTime(strftime('%Y-%m-%d %H:%M:%S', $this->filemtime)); } else { $this->setDateTime($date); } /* ZenPhoto20 "title" field population */ $title = self::fetchMetadata('IPTCObjectName'); if (empty($title)) { $title = self::fetchMetadata('IPTCImageHeadline'); } if (empty($title)) { $title = self::fetchMetadata('EXIFDescription'); //EXIF title [sic] } if (!empty($title)) { if (getoption('transform_newlines')) { $title = nl2br($title); } $this->setTitle($title); } /* ZenPhoto20 "description" field population */ $desc = self::fetchMetadata('IPTCImageCaption'); if (!empty($desc)) { if (getoption('transform_newlines')) { $desc = nl2br($desc); } $this->setDesc($desc); } // ZenPhoyo20 GPS data foreach (array('EXIFGPSLatitude', 'EXIFGPSLongitude') as $source) { $data = self::fetchMetadata($source); if (!empty($data)) { $ref = strtoupper($this->get($source . 'Ref')); $this->set($source, self::toDMS($data, $ref)); if (in_array($ref, array('S', 'W'))) { $data = '-' . $data; } $this->set(substr($source, 4), $data); } } $alt = self::fetchMetadata('EXIFGPSAltitude'); if (!empty($alt)) { if (self::fetchMetadata('EXIFGPSAltitudeRef') == '-') { $alt = -$alt; } $this->set('GPSAltitude', $alt); } // simple field imports $import = array('location' => 'IPTCSubLocation', 'city' => 'IPTCCity', 'state' => 'IPTCState', 'country' => 'IPTCLocationName', 'copyright' => 'IPTCCopyright'); foreach ($import as $key => $source) { $data = self::fetchMetadata($source); $this->set($key, $data); } /* ZenPhoto20 "credit" field population */ $credit = self::fetchMetadata('IPTCByLine'); if (empty($credit)) { $credit = self::fetchMetadata('IPTCImageCredit'); } if (empty($credit)) { $credit = self::fetchMetadata('IPTCSource'); } if (!empty($credit)) { $this->setCredit($credit); } zp_apply_filter('image_metadata', $this); $alb = $this->album; if (is_object($alb)) { if (!$this->get('owner')) { $this->setOwner($alb->getOwner()); } $save = false; if (strtotime($alb->getUpdatedDate()) < strtotime($this->getDateTime())) { $alb->setUpdatedDate($this->getDateTime()); $save = true; } if (is_null($albdate = $alb->getDateTime()) || $_zp_gallery->getAlbumUseImagedate() && strtotime($albdate) < strtotime($this->getDateTime())) { $alb->setDateTime($this->getDateTime()); // not necessarily the right one, but will do. Can be changed in Admin $save = true; } if ($save) { $alb->save(); } } } }