/** * Creates the cache folder version of the image, including watermarking * * @param string $newfilename the name of the file when it is in the cache * @param string $imgfile the image name * @param array $args the cropping arguments * @param bool $allow_watermark set to true if image may be watermarked * @param string $theme the current theme * @param string $album the album containing the image */ function cacheImage($newfilename, $imgfile, $args, $allow_watermark = false, $theme, $album) { @(list($size, $width, $height, $cw, $ch, $cx, $cy, $quality, $thumb, $crop, $thumbstandin, $passedWM, $adminrequest, $effects) = $args); // Set the config variables for convenience. $image_use_side = getOption('image_use_side'); $upscale = getOption('image_allow_upscale'); $allowscale = true; $sharpenthumbs = getOption('thumb_sharpen'); $sharpenimages = getOption('image_sharpen'); $id = NULL; $watermark_use_image = getAlbumInherited($album, 'watermark', $id); if (empty($watermark_use_image)) { $watermark_use_image = IMAGE_WATERMARK; } if (!$effects) { if ($thumb && getOption('thumb_gray')) { $effects = 'gray'; } else { if (getOption('image_gray')) { $effects = 'gray'; } } } $newfile = SERVERCACHE . $newfilename; if (DEBUG_IMAGE) { debugLog("cacheImage(\$imgfile=" . basename($imgfile) . ", \$newfilename={$newfilename}, \$allow_watermark={$allow_watermark}, \$theme={$theme}) \$size={$size}, \$width={$width}, \$height={$height}, \$cw={$cw}, \$ch={$ch}, \$cx=" . (is_null($cx) ? 'NULL' : $cx) . ", \$cy=" . (is_null($cy) ? 'NULL' : $cy) . ", \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop} \$image_use_side={$image_use_side}; \$upscale={$upscale};"); } // Check for the source image. if (!file_exists($imgfile) || !is_readable($imgfile)) { imageError(gettext('Image not found or is unreadable.'), 'err-imagenotfound.png'); } $rotate = false; if (zp_imageCanRotate() && getOption('auto_rotate')) { $rotate = getImageRotation($imgfile); } if ($im = zp_imageGet($imgfile)) { if ($rotate) { $im = zp_rotateImage($im, $rotate); } $w = zp_imageWidth($im); $h = zp_imageHeight($im); // Give the sizing dimension to $dim $ratio_in = ''; $ratio_out = ''; $crop = $crop || $cw != 0 || $ch != 0; if (!empty($size)) { $dim = $size; $width = $height = false; if ($crop) { $dim = $size; if (!$ch) { $ch = $size; } if (!$cw) { $cw = $size; } } } else { if (!empty($width) && !empty($height)) { $ratio_in = $h / $w; $ratio_out = $height / $width; if ($ratio_in > $ratio_out) { // image is taller than desired, $height is the determining factor $thumb = true; $dim = $width; if (!$ch) { $ch = $height; } } else { // image is wider than desired, $width is the determining factor $dim = $height; if (!$cw) { $cw = $width; } } } else { if (!empty($width)) { $dim = $width; $size = $height = false; } else { if (!empty($height)) { $dim = $height; $size = $width = false; } else { // There's a problem up there somewhere... imageError(gettext("Unknown error! Please report to the developers at <a href=\"http://www.zenphoto.org/\">www.zenphoto.org</a>"), 'err-imagegeneral.png'); } } } } $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim); list($neww, $newh) = $sizes; if (DEBUG_IMAGE) { debugLog("cacheImage:" . basename($imgfile) . ": \$size={$size}, \$width={$width}, \$height={$height}, \$w={$w}; \$h={$h}; \$cw={$cw}, " . "\$ch={$ch}, \$cx={$cx}, \$cy={$cy}, \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$newh={$newh}, \$neww={$neww}, \$dim={$dim}, " . "\$ratio_in={$ratio_in}, \$ratio_out={$ratio_out} \$upscale={$upscale} \$rotate={$rotate} \$effects={$effects}"); } if (!$upscale && $newh >= $h && $neww >= $w) { // image is the same size or smaller than the request $neww = $w; $newh = $h; $allowscale = false; if ($crop) { if ($width > $neww) { $width = $neww; } if ($height > $newh) { $height = $newh; } } if (DEBUG_IMAGE) { debugLog("cacheImage:no upscale " . basename($imgfile) . ": \$newh={$newh}, \$neww={$neww}, \$crop={$crop}, \$thumb={$thumb}, \$rotate={$rotate}, watermark=" . $watermark_use_image); } } // Crop the image if requested. if ($crop) { if ($cw > $ch) { $ir = $ch / $cw; } else { $ir = $cw / $ch; } if ($size) { $neww = $size; $newh = $ir * $size; } else { $neww = $width; $newh = $height; if ($neww > $newh) { if ($newh === false) { $newh = $ir * $neww; } } else { if ($neww === false) { $neww = $ir * $newh; } } } if (is_null($cx) && is_null($cy)) { // scale crop to max of image // set crop scale factor $cf = 1; if ($cw) { $cf = min($cf, $cw / $neww); } if ($ch) { $cf = min($cf, $ch / $newh); } // set the image area of the crop (use the most image possible, rule of thirds positioning) if (!$cw || $w / $cw * $ch > $h) { $cw = round($h / $ch * $cw * $cf); $ch = round($h * $cf); $cx = round(($w - $cw) / 3); } else { $ch = round($w / $cw * $ch * $cf); $cw = round($w * $cf); $cy = round(($h - $ch) / 3); } } else { // custom crop if (!$cw || $cw > $w) { $cw = $w; } if (!$ch || $ch > $h) { $ch = $h; } } // force the crop to be within the image if ($cw + $cx > $w) { $cx = $w - $cw; } if ($cx < 0) { $cw = $cw + $cx; $cx = 0; } if ($ch + $cy > $h) { $cy = $h - $ch; } if ($cy < 0) { $ch = $ch + $cy; $cy = 0; } if (DEBUG_IMAGE) { debugLog("cacheImage:crop " . basename($imgfile) . ":\$size={$size}, \$width={$width}, \$height={$height}, \$cw={$cw}, \$ch={$ch}, \$cx={$cx}, \$cy={$cy}, \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$rotate={$rotate}"); } $newim = zp_createImage($neww, $newh); zp_resampleImage($newim, $im, 0, 0, $cx, $cy, $neww, $newh, $cw, $ch); } else { if ($allowscale) { $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim); list($neww, $newh) = $sizes; } if (DEBUG_IMAGE) { debugLog("cacheImage:no crop " . basename($imgfile) . ":\$size={$size}, \$width={$width}, \$height={$height}, \$dim={$dim}, \$neww={$neww}; \$newh={$newh}; \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$rotate={$rotate}; \$allowscale={$allowscale};"); } $newim = zp_createImage($neww, $newh); zp_resampleImage($newim, $im, 0, 0, 0, 0, $neww, $newh, $w, $h); } $imgEffects = explode(',', $effects); if (in_array('gray', $imgEffects)) { zp_imageGray($newim); } if ($thumb && $sharpenthumbs || !$thumb && $sharpenimages) { zp_imageUnsharpMask($newim, getOption('sharpen_amount'), getOption('sharpen_radius'), getOption('sharpen_threshold')); } $watermark_image = false; if ($passedWM) { if ($passedWM != NO_WATERMARK) { $watermark_image = getWatermarkPath($passedWM); if (!file_exists($watermark_image)) { $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png'; } } } else { if ($allow_watermark) { $watermark_image = $watermark_use_image; if ($watermark_image) { if ($watermark_image != NO_WATERMARK) { $watermark_image = getWatermarkPath($watermark_image); if (!file_exists($watermark_image)) { $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png'; } } } } } if ($watermark_image) { $offset_h = getOption('watermark_h_offset') / 100; $offset_w = getOption('watermark_w_offset') / 100; $watermark = zp_imageGet($watermark_image); $watermark_width = zp_imageWidth($watermark); $watermark_height = zp_imageHeight($watermark); $imw = zp_imageWidth($newim); $imh = zp_imageHeight($newim); $nw = sqrt($imw * $imh * $percent * ($watermark_width / $watermark_height)); $nh = $nw * ($watermark_height / $watermark_width); $percent = getOption('watermark_scale') / 100; $r = sqrt($imw * $imh * $percent / ($watermark_width * $watermark_height)); if (!getOption('watermark_allow_upscale')) { $r = min(1, $r); } $nw = round($watermark_width * $r); $nh = round($watermark_height * $r); if ($nw != $watermark_width || $nh != $watermark_height) { $watermark = zp_imageResizeAlpha($watermark, $nw, $nh); } // Position Overlay in Bottom Right $dest_x = max(0, floor(($imw - $nw) * $offset_w)); $dest_y = max(0, floor(($imh - $nh) * $offset_h)); if (DEBUG_IMAGE) { debugLog("Watermark:" . basename($imgfile) . ": \$offset_h={$offset_h}, \$offset_w={$offset_w}, \$watermark_height={$watermark_height}, \$watermark_width={$watermark_width}, \$imw={$imw}, \$imh={$imh}, \$percent={$percent}, \$r={$r}, \$nw={$nw}, \$nh={$nh}, \$dest_x={$dest_x}, \$dest_y={$dest_y}"); } zp_copyCanvas($newim, $watermark, $dest_x, $dest_y, 0, 0, $nw, $nh); zp_imageKill($watermark); } // Create the cached file (with lots of compatibility)... mkdir_recursive(dirname($newfile)); if (zp_imageOutput($newim, getSuffix($newfile), $newfile, $quality)) { // successful save of cached image if (getOption('ImbedIPTC') && getSuffix($newfilename) == 'jpg') { // the imbed function works only with JPEG images $iptc_data = zp_imageIPTC($imgfile); if (empty($iptc_data)) { global $_zp_extra_filetypes; // because we are doing the require in a function! if (!$_zp_extra_filetypes) { $_zp_extra_filetypes = array(); } require_once dirname(__FILE__) . '/functions.php'; // it is ok to increase memory footprint now since the image processing is complete $gallery = new Gallery(); $iptc = array('1#090' => chr(0x1b) . chr(0x25) . chr(0x47), '2#115' => $gallery->getTitle()); $imgfile = str_replace(ALBUM_FOLDER_SERVERPATH, '', $imgfile); $imagename = basename($imgfile); $albumname = dirname($imgfile); $image = newImage(new Album(new Gallery(), $albumname), $imagename); $copyright = $image->getCopyright(); if (empty($copyright)) { $copyright = getOption('default_copyright'); } if (!empty($copyright)) { $iptc['2#116'] = $copyright; } $credit = $image->getCredit(); if (!empty($credit)) { $iptc['2#110'] = $credit; } foreach ($iptc as $tag => $string) { $tag_parts = explode('#', $tag); $iptc_data .= iptc_make_tag($tag_parts[0], $tag_parts[1], $string); } } else { if (GRAPHICS_LIBRARY == 'Imagick' && IMAGICK_RETAIN_PROFILES) { // Imageick has preserved the metadata $iptc_data = false; } } if ($iptc_data) { $content = iptcembed($iptc_data, $newfile); $fw = fopen($newfile, 'w'); fwrite($fw, $content); fclose($fw); clearstatcache(); } } if (DEBUG_IMAGE) { debugLog('Finished:' . basename($imgfile)); } } else { if (DEBUG_IMAGE) { debugLog('cacheImage: failed to create ' . $newfile); } } @chmod($newfile, 0666 & CHMOD_VALUE); zp_imageKill($newim); zp_imageKill($im); } }
/** * 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(); } } } }
/** * 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(); } } }
/** * Creates the cache folder version of the image, including watermarking * * @param string $newfilename the name of the file when it is in the cache * @param string $imgfile the image name * @param array $args the cropping arguments * @param bool $allow_watermark set to true if image may be watermarked * @param string $theme the current theme * @param string $album the album containing the image */ function cacheImage($newfilename, $imgfile, $args, $allow_watermark = false, $theme, $album) { global $_zp_gallery; try { @(list($size, $width, $height, $cw, $ch, $cx, $cy, $quality, $thumb, $crop, $thumbstandin, $passedWM, $adminrequest, $effects) = $args); // Set the config variables for convenience. $image_use_side = getOption('image_use_side'); $upscale = getOption('image_allow_upscale'); $allowscale = true; $sharpenthumbs = getOption('thumb_sharpen'); $sharpenimages = getOption('image_sharpen'); $id = $im = NULL; $watermark_use_image = getAlbumInherited($album, 'watermark', $id); if (empty($watermark_use_image)) { $watermark_use_image = IMAGE_WATERMARK; } if (!$effects) { if ($thumb && getOption('thumb_gray')) { $effects = 'gray'; } else { if (getOption('image_gray')) { $effects = 'gray'; } } } $newfile = SERVERCACHE . $newfilename; mkdir_recursive(dirname($newfile), FOLDER_MOD); if (DEBUG_IMAGE) { debugLog("cacheImage(\$imgfile=" . basename($imgfile) . ", \$newfilename={$newfilename}, \$allow_watermark={$allow_watermark}, \$theme={$theme}) \$size={$size}, \$width={$width}, \$height={$height}, \$cw={$cw}, \$ch={$ch}, \$cx=" . (is_null($cx) ? 'NULL' : $cx) . ", \$cy=" . (is_null($cy) ? 'NULL' : $cy) . ", \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop} \$image_use_side={$image_use_side}; \$upscale={$upscale});"); } // Check for the source image. if (!file_exists($imgfile) || !is_readable($imgfile)) { imageError('404 Not Found', sprintf(gettext('Image %s not found or is unreadable.'), filesystemToInternal($imgfile)), 'err-imagenotfound.png'); } $rotate = false; if (zp_imageCanRotate()) { $rotate = getImageRotation($imgfile); } $s = getSuffix($imgfile); if (function_exists('exif_thumbnail') && getOption('use_embedded_thumb') && ($s == 'jpg' || $s == 'jpeg')) { $im = exif_thumbnail($imgfile, $tw, $th, $tt); if ($im) { if ($size) { $big_enough = $tw >= $size && $th >= $size; } else { $big_enough = $tw >= $width && $th >= $height; } if ($big_enough) { $im = zp_imageFromString($im); if (DEBUG_IMAGE && $im) { debugLog(sprintf(gettext('Using %1$ux%2$u %3$s thumbnail image.'), $tw, $th, image_type_to_mime_type($tt))); } } else { $im = false; } } else { $im = false; } } if (!$im) { $im = zp_imageGet($imgfile); } if (!$im) { imageError('404 Not Found', sprintf(gettext('Image %s not renderable (imageGet).'), filesystemToInternal($imgfile)), 'err-failimage.png'); } if ($rotate) { if (DEBUG_IMAGE) { debugLog("cacheImage:rotate->{$rotate}"); } $im = zp_rotateImage($im, $rotate); if (!$im) { imageError('404 Not Found', sprintf(gettext('Image %s not rotatable.'), filesystemToInternal($imgfile)), 'err-failimage.png'); } } $w = zp_imageWidth($im); $h = zp_imageHeight($im); // Give the sizing dimension to $dim $ratio_in = ''; $ratio_out = ''; $crop = $crop || $cw != 0 || $ch != 0; if (!empty($size)) { $dim = $size; if ($crop) { $dim = $size; if (!$ch) { $ch = $size; } if (!$cw) { $cw = $size; } $width = $cw; $height = $ch; $size = false; } else { $width = $height = false; } } else { if (!empty($width) && !empty($height)) { $ratio_in = $h / $w; $ratio_out = $height / $width; if ($ratio_in > $ratio_out) { // image is taller than desired, $height is the determining factor $thumb = true; $dim = $width; if (!$ch) { $ch = $height; } } else { // image is wider than desired, $width is the determining factor $dim = $height; if (!$cw) { $cw = $width; } } } else { if (!empty($width)) { $dim = $width; $size = $height = false; } else { if (!empty($height)) { $dim = $height; $size = $width = false; } else { // There's a problem up there somewhere... imageError('404 Not Found', sprintf(gettext('Unknown error processing %s! Please report to the <a href="' . GITHUB . '/issues">developers</a>'), filesystemToInternal($imgfile)), 'err-imagegeneral.png'); } } } } $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim); list($neww, $newh) = $sizes; if (DEBUG_IMAGE) { debugLog("cacheImage:" . basename($imgfile) . ": \$size={$size}, \$width={$width}, \$height={$height}, \$w={$w}; \$h={$h}; \$cw={$cw}, " . "\$ch={$ch}, \$cx={$cx}, \$cy={$cy}, \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$newh={$newh}, \$neww={$neww}, \$dim={$dim}, " . "\$ratio_in={$ratio_in}, \$ratio_out={$ratio_out} \$upscale={$upscale} \$rotate={$rotate} \$effects={$effects}"); } if (!$upscale && $newh >= $h && $neww >= $w) { // image is the same size or smaller than the request $neww = $w; $newh = $h; $allowscale = false; if ($crop) { if ($width > $neww) { $width = $neww; } if ($height > $newh) { $height = $newh; } } if (DEBUG_IMAGE) { debugLog("cacheImage:no upscale " . basename($imgfile) . ": \$newh={$newh}, \$neww={$neww}, \$crop={$crop}, \$thumb={$thumb}, \$rotate={$rotate}, watermark=" . $watermark_use_image); } } $watermark_image = false; if ($passedWM) { if ($passedWM != NO_WATERMARK) { $watermark_image = getWatermarkPath($passedWM); if (!file_exists($watermark_image)) { $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png'; } } } else { if ($allow_watermark) { $watermark_image = $watermark_use_image; if ($watermark_image) { if ($watermark_image != NO_WATERMARK) { $watermark_image = getWatermarkPath($watermark_image); if (!file_exists($watermark_image)) { $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png'; } } } } } // Crop the image if requested. if ($crop) { if ($cw > $ch) { $ir = $ch / $cw; } else { $ir = $cw / $ch; } if ($size) { $neww = $size; $newh = $ir * $size; } else { $neww = $width; $newh = $height; if ($neww > $newh) { if ($newh === false) { $newh = $ir * $neww; } } else { if ($neww === false) { $neww = $ir * $newh; } } } if (is_null($cx) && is_null($cy)) { // scale crop to max of image // set crop scale factor $cf = 1; if ($cw) { $cf = min($cf, $cw / $neww); } if ($ch) { $cf = min($cf, $ch / $newh); } // set the image area of the crop (use the most image possible, rule of thirds positioning) if (!$cw || $w / $cw * $ch > $h) { $cw = round($h / $ch * $cw * $cf); $ch = round($h * $cf); $cx = round(($w - $cw) / 3); } else { $ch = round($w / $cw * $ch * $cf); $cw = round($w * $cf); $cy = round(($h - $ch) / 3); } } else { // custom crop if (!$cw || $cw > $w) { $cw = $w; } if (!$ch || $ch > $h) { $ch = $h; } } // force the crop to be within the image if ($cw + $cx > $w) { $cx = $w - $cw; } if ($cx < 0) { $cw = $cw + $cx; $cx = 0; } if ($ch + $cy > $h) { $cy = $h - $ch; } if ($cy < 0) { $ch = $ch + $cy; $cy = 0; } if (DEBUG_IMAGE) { debugLog("cacheImage:crop " . basename($imgfile) . ":\$size={$size}, \$width={$width}, \$height={$height}, \$cw={$cw}, \$ch={$ch}, \$cx={$cx}, \$cy={$cy}, \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$rotate={$rotate}"); } $newim = zp_createImage($neww, $newh); if (!zp_resampleImage($newim, $im, 0, 0, $cx, $cy, $neww, $newh, $cw, $ch)) { imageError('404 Not Found', sprintf(gettext('Image %s not renderable (resample).'), filesystemToInternal($imgfile)), 'err-failimage.png'); } } else { if ($newh >= $h && $neww >= $w && !$rotate && !$effects && !$watermark_image && (!$upscale || $newh == $h && $neww == $w)) { // we can just use the original! if (SYMLINK && @symlink($imgfile, $newfile)) { if (DEBUG_IMAGE) { debugLog("cacheImage:symlink original " . basename($imgfile) . ":\$size={$size}, \$width={$width}, \$height={$height}, \$dim={$dim}, \$neww={$neww}; \$newh={$newh}; \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$rotate={$rotate}; \$allowscale={$allowscale};"); } clearstatcache(); return true; } else { if (@copy($imgfile, $newfile)) { if (DEBUG_IMAGE) { debugLog("cacheImage:copy original " . basename($imgfile) . ":\$size={$size}, \$width={$width}, \$height={$height}, \$dim={$dim}, \$neww={$neww}; \$newh={$newh}; \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$rotate={$rotate}; \$allowscale={$allowscale};"); } clearstatcache(); return true; } } } if ($allowscale) { $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim); list($neww, $newh) = $sizes; } if (DEBUG_IMAGE) { debugLog("cacheImage:no crop " . basename($imgfile) . ":\$size={$size}, \$width={$width}, \$height={$height}, \$dim={$dim}, \$neww={$neww}; \$newh={$newh}; \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$rotate={$rotate}; \$allowscale={$allowscale};"); } $newim = zp_createImage($neww, $newh); if (!zp_resampleImage($newim, $im, 0, 0, 0, 0, $neww, $newh, $w, $h)) { imageError('404 Not Found', sprintf(gettext('Image %s not renderable (resample).'), filesystemToInternal($imgfile)), 'err-failimage.png'); } if ($thumb && $sharpenthumbs || !$thumb && $sharpenimages) { if (!zp_imageUnsharpMask($newim, getOption('sharpen_amount'), getOption('sharpen_radius'), getOption('sharpen_threshold'))) { imageError('404 Not Found', sprintf(gettext('Image %s not renderable (unsharp).'), filesystemToInternal($imgfile)), 'err-failimage.png'); } } } $imgEffects = explode(',', $effects); if (in_array('gray', $imgEffects)) { zp_imageGray($newim); } if ($watermark_image) { $offset_h = getOption('watermark_h_offset') / 100; $offset_w = getOption('watermark_w_offset') / 100; $percent = getOption('watermark_scale') / 100; $watermark = zp_imageGet($watermark_image); if (!$watermark) { imageError('404 Not Found', sprintf(gettext('Watermark %s not renderable.'), $watermark_image), 'err-failimage.png'); } $watermark_width = zp_imageWidth($watermark); $watermark_height = zp_imageHeight($watermark); $imw = zp_imageWidth($newim); $imh = zp_imageHeight($newim); $nw = sqrt($imw * $imh * $percent * ($watermark_width / $watermark_height)); $nh = $nw * ($watermark_height / $watermark_width); $r = sqrt($imw * $imh * $percent / ($watermark_width * $watermark_height)); if (!getOption('watermark_allow_upscale')) { $r = min(1, $r); } $nw = round($watermark_width * $r); $nh = round($watermark_height * $r); if ($nw != $watermark_width || $nh != $watermark_height) { $watermark = zp_imageResizeAlpha($watermark, $nw, $nh); if (!$watermark) { imageError('404 Not Found', sprintf(gettext('Watermark %s not resizeable.'), $watermark_image), 'err-failimage.png'); } } // Position Overlay in Bottom Right $dest_x = max(0, floor(($imw - $nw) * $offset_w)); $dest_y = max(0, floor(($imh - $nh) * $offset_h)); if (DEBUG_IMAGE) { debugLog("Watermark:" . basename($imgfile) . ": \$offset_h={$offset_h}, \$offset_w={$offset_w}, \$watermark_height={$watermark_height}, \$watermark_width={$watermark_width}, \$imw={$imw}, \$imh={$imh}, \$percent={$percent}, \$r={$r}, \$nw={$nw}, \$nh={$nh}, \$dest_x={$dest_x}, \$dest_y={$dest_y}"); } if (!zp_copyCanvas($newim, $watermark, $dest_x, $dest_y, 0, 0, $nw, $nh)) { imageError('404 Not Found', sprintf(gettext('Image %s not renderable (copycanvas).'), filesystemToInternal($imgfile)), 'err-failimage.png'); } zp_imageKill($watermark); } // Create the cached file (with lots of compatibility)... @chmod($newfile, 0777); if (zp_imageOutput($newim, getSuffix($newfile), $newfile, $quality)) { // successful save of cached image if (getOption('ImbedIPTC') && getSuffix($newfilename) == 'jpg' && GRAPHICS_LIBRARY != 'Imagick') { // the imbed function works only with JPEG images global $_zp_images_classes; // because we are doing the require in a function! require_once dirname(__FILE__) . '/functions.php'; // it is ok to increase memory footprint now since the image processing is complete $iptc = array('1#090' => chr(0x1b) . chr(0x25) . chr(0x47), '2#115' => $_zp_gallery->getTitle()); $iptc_data = zp_imageIPTC($imgfile); if ($iptc_data) { $iptc_data = iptcparse($iptc_data); if ($iptc_data) { $iptc = array_merge($iptc_data, $iptc); } } $imgfile = str_replace(ALBUM_FOLDER_SERVERPATH, '', $imgfile); $imagename = basename($imgfile); $albumname = dirname($imgfile); $image = newImage(newAlbum($albumname), $imagename); $copyright = $image->getCopyright(); if (empty($copyright)) { $copyright = getOption('default_copyright'); } if (!empty($copyright)) { $iptc['2#116'] = $copyright; } $credit = $image->getCredit(); if (!empty($credit)) { $iptc['2#110'] = $credit; } $iptc_result = ''; foreach ($iptc as $tag => $string) { $tag_parts = explode('#', $tag); if (is_array($string)) { foreach ($string as $element) { $iptc_result .= iptc_make_tag($tag_parts[0], $tag_parts[1], $element); } } else { $iptc_result .= iptc_make_tag($tag_parts[0], $tag_parts[1], $string); } } $content = iptcembed($iptc_result, $newfile); $fw = fopen($newfile, 'w'); fwrite($fw, $content); fclose($fw); clearstatcache(); } @chmod($newfile, FILE_MOD); if (DEBUG_IMAGE) { debugLog('Finished:' . basename($imgfile)); } } else { if (DEBUG_IMAGE) { debugLog('cacheImage: failed to create ' . $newfile); } imageError('404 Not Found', sprintf(gettext('cacheImage: failed to create %s'), $newfile), 'err-failimage.png'); } @chmod($newfile, FILE_MOD); zp_imageKill($newim); zp_imageKill($im); } catch (Exception $e) { debugLog('cacheImage(' . $newfilename . ') exception: ' . $e->getMessage()); imageError('404 Not Found', sprintf(gettext('cacheImage(%1$s) exception: %2$s'), $newfilename, $e->getMessage()), 'err-failimage.png'); return false; } clearstatcache(); return true; }