/** * Handles the saving of image meta data * * @author Andreas Gohr <*****@*****.**> */ function media_metasave($id, $auth, $data) { if ($auth < AUTH_UPLOAD) { return false; } if (!checkSecurityToken()) { return false; } global $lang; global $conf; $src = mediaFN($id); $meta = new JpegMeta($src); $meta->_parseAll(); foreach ($data as $key => $val) { $val = trim($val); if (empty($val)) { $meta->deleteField($key); } else { $meta->setField($key, $val); } } if ($meta->save()) { if ($conf['fperm']) { chmod($src, $conf['fperm']); } msg($lang['metasaveok'], 1); return $id; } else { msg($lang['metasaveerr'], -1); return false; } }
/** * Renders internal and external media * * @author Andreas Gohr <*****@*****.**> * @param string $src media ID * @param string $title descriptive text * @param string $align left|center|right * @param int $width width of media in pixel * @param int $height height of media in pixel * @param string $cache cache|recache|nocache * @param bool $render should the media be embedded inline or just linked * @return string */ function _media($src, $title = null, $align = null, $width = null, $height = null, $cache = null, $render = true) { $ret = ''; list($ext, $mime) = mimetype($src); if (substr($mime, 0, 5) == 'image') { // first get the $title if (!is_null($title)) { $title = $this->_xmlEntities($title); } elseif ($ext == 'jpg' || $ext == 'jpeg') { //try to use the caption from IPTC/EXIF require_once DOKU_INC . 'inc/JpegMeta.php'; $jpeg = new JpegMeta(mediaFN($src)); if ($jpeg !== false) { $cap = $jpeg->getTitle(); } if (!empty($cap)) { $title = $this->_xmlEntities($cap); } } if (!$render) { // if the picture is not supposed to be rendered // return the title of the picture if (!$title) { // just show the sourcename $title = $this->_xmlEntities(utf8_basename(noNS($src))); } return $title; } //add image tag $ret .= '<img src="' . ml($src, array('w' => $width, 'h' => $height, 'cache' => $cache, 'rev' => $this->_getLastMediaRevisionAt($src))) . '"'; $ret .= ' class="media' . $align . '"'; if ($title) { $ret .= ' title="' . $title . '"'; $ret .= ' alt="' . $title . '"'; } else { $ret .= ' alt=""'; } if (!is_null($width)) { $ret .= ' width="' . $this->_xmlEntities($width) . '"'; } if (!is_null($height)) { $ret .= ' height="' . $this->_xmlEntities($height) . '"'; } $ret .= ' />'; } elseif (media_supportedav($mime, 'video') || media_supportedav($mime, 'audio')) { // first get the $title $title = !is_null($title) ? $this->_xmlEntities($title) : false; if (!$render) { // if the file is not supposed to be rendered // return the title of the file (just the sourcename if there is no title) return $title ? $title : $this->_xmlEntities(utf8_basename(noNS($src))); } $att = array(); $att['class'] = "media{$align}"; if ($title) { $att['title'] = $title; } if (media_supportedav($mime, 'video')) { //add video $ret .= $this->_video($src, $width, $height, $att); } if (media_supportedav($mime, 'audio')) { //add audio $ret .= $this->_audio($src, $att); } } elseif ($mime == 'application/x-shockwave-flash') { if (!$render) { // if the flash is not supposed to be rendered // return the title of the flash if (!$title) { // just show the sourcename $title = utf8_basename(noNS($src)); } return $this->_xmlEntities($title); } $att = array(); $att['class'] = "media{$align}"; if ($align == 'right') { $att['align'] = 'right'; } if ($align == 'left') { $att['align'] = 'left'; } $ret .= html_flashobject(ml($src, array('cache' => $cache), true, '&'), $width, $height, array('quality' => 'high'), null, $att, $this->_xmlEntities($title)); } elseif ($title) { // well at least we have a title to display $ret .= $this->_xmlEntities($title); } else { // just show the sourcename $ret .= $this->_xmlEntities(utf8_basename(noNS($src))); } return $ret; }
/** * Returns the requested EXIF/IPTC tag from the current image * * If $tags is an array all given tags are tried until a * value is found. If no value is found $alt is returned. * * Which texts are known is defined in the functions _exifTagNames * and _iptcTagNames() in inc/jpeg.php (You need to prepend IPTC * to the names of the latter one) * * Only allowed in: detail.php * * @author Andreas Gohr <*****@*****.**> * @param array $tags tags to try * @param string $alt alternative output if no data was found * @param null $src the image src, uses global $SRC if not given * @return string */ function tpl_img_getTag($tags, $alt = '', $src = null) { // Init Exif Reader global $SRC; if (is_null($src)) { $src = $SRC; } static $meta = null; if (is_null($meta)) { $meta = new JpegMeta($src); } if ($meta === false) { return $alt; } $info = $meta->getField($tags); if ($info == false) { return $alt; } return $info; }
/** * Renders internal and external media * * @author Andreas Gohr <*****@*****.**> */ function _media($src, $title = NULL, $align = NULL, $width = NULL, $height = NULL, $cache = NULL, $render = true) { $ret = ''; list($ext, $mime, $dl) = mimetype($src); if (substr($mime, 0, 5) == 'image') { // first get the $title if (!is_null($title)) { $title = $this->_xmlEntities($title); } elseif ($ext == 'jpg' || $ext == 'jpeg') { //try to use the caption from IPTC/EXIF require_once DOKU_INC . 'inc/JpegMeta.php'; $jpeg = new JpegMeta(mediaFN($src)); if ($jpeg !== false) { $cap = $jpeg->getTitle(); } if ($cap) { $title = $this->_xmlEntities($cap); } } if (!$render) { // if the picture is not supposed to be rendered // return the title of the picture if (!$title) { // just show the sourcename $title = $this->_xmlEntities(basename(noNS($src))); } return $title; } //add image tag $ret .= '<img src="' . ml($src, array('w' => $width, 'h' => $height, 'cache' => $cache)) . '"'; $ret .= ' class="media' . $align . '"'; // make left/right alignment for no-CSS view work (feeds) if ($align == 'right') { $ret .= ' align="right"'; } if ($align == 'left') { $ret .= ' align="left"'; } if ($title) { $ret .= ' title="' . $title . '"'; $ret .= ' alt="' . $title . '"'; } else { $ret .= ' alt=""'; } if (!is_null($width)) { $ret .= ' width="' . $this->_xmlEntities($width) . '"'; } if (!is_null($height)) { $ret .= ' height="' . $this->_xmlEntities($height) . '"'; } $ret .= ' />'; } elseif ($mime == 'application/x-shockwave-flash') { if (!$render) { // if the flash is not supposed to be rendered // return the title of the flash if (!$title) { // just show the sourcename $title = basename(noNS($src)); } return $this->_xmlEntities($title); } $att = array(); $att['class'] = "media{$align}"; if ($align == 'right') { $att['align'] = 'right'; } if ($align == 'left') { $att['align'] = 'left'; } $ret .= html_flashobject(ml($src, array('cache' => $cache), true, '&'), $width, $height, array('quality' => 'high'), null, $att, $this->_xmlEntities($title)); } elseif ($title) { // well at least we have a title to display $ret .= $this->_xmlEntities($title); } else { // just show the sourcename $ret .= $this->_xmlEntities(basename(noNS($src))); } return $ret; }
/** * Returns the requested EXIF/IPTC tag from the image meta * * @author Kate Arzamastseva <*****@*****.**> * @param array $tags * @param JpegMeta $meta * @param string $alt * @return string */ function media_getTag($tags, $meta, $alt = '') { if ($meta === false) { return $alt; } $info = $meta->getField($tags); if ($info == false) { return $alt; } return $info; }
/** * Renders internal and external media * * @author Andreas Gohr <*****@*****.**> */ function _media($src, $title = NULL, $align = NULL, $width = NULL, $height = NULL, $cache = NULL) { $ret = ''; list($ext, $mime) = mimetype($src); if (substr($mime, 0, 5) == 'image') { //add image tag $ret .= '<img src="' . ml($src, array('w' => $width, 'h' => $height, 'cache' => $cache)) . '"'; $ret .= ' class="media' . $align . '"'; if (!is_null($title)) { $ret .= ' title="' . $this->_xmlEntities($title) . '"'; $ret .= ' alt="' . $this->_xmlEntities($title) . '"'; } elseif ($ext == 'jpg' || $ext == 'jpeg') { //try to use the caption from IPTC/EXIF require_once DOKU_INC . 'inc/JpegMeta.php'; $jpeg = new JpegMeta(mediaFN($src)); if ($jpeg !== false) { $cap = $jpeg->getTitle(); } if ($cap) { $ret .= ' title="' . $this->_xmlEntities($cap) . '"'; $ret .= ' alt="' . $this->_xmlEntities($cap) . '"'; } } else { $ret .= ' alt=""'; } if (!is_null($width)) { $ret .= ' width="' . $this->_xmlEntities($width) . '"'; } if (!is_null($height)) { $ret .= ' height="' . $this->_xmlEntities($height) . '"'; } $ret .= ' />'; } elseif ($mime == 'application/x-shockwave-flash') { $ret .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' . ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"'; if (!is_null($width)) { $ret .= ' width="' . $this->_xmlEntities($width) . '"'; } if (!is_null($height)) { $ret .= ' height="' . $this->_xmlEntities($height) . '"'; } $ret .= '>' . DOKU_LF; $ret .= '<param name="movie" value="' . ml($src) . '" />' . DOKU_LF; $ret .= '<param name="quality" value="high" />' . DOKU_LF; $ret .= '<embed src="' . ml($src) . '"' . ' quality="high"'; if (!is_null($width)) { $ret .= ' width="' . $this->_xmlEntities($width) . '"'; } if (!is_null($height)) { $ret .= ' height="' . $this->_xmlEntities($height) . '"'; } $ret .= ' type="application/x-shockwave-flash"' . ' pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>' . DOKU_LF; $ret .= '</object>' . DOKU_LF; } elseif (!is_null($title)) { // well at least we have a title to display $ret .= $this->_xmlEntities($title); } else { // just show the sourcename $ret .= $this->_xmlEntities(noNS($src)); } return $ret; }
/** * Replaces titles of non-labeled internal media links with their original filenames */ function _replaceLinkTitle(&$event) { global $ID; global $conf; require_once DOKU_INC . 'inc/JpegMeta.php'; $ns = getNS($ID); // get the instructions list from the handler $calls =& $event->data->calls; // array index numbers for readability list($handler_name, $instructions, $source, $title, $linking) = array(0, 1, 0, 1, 6); // scan media link and mark it with its original filename $last = count($calls) - 1; for ($i = 0; $i <= $last; $i++) { // NOTE: 'externalmedia' is processed here because there is a // basename() bug in fetching its auto-filled linktext. // For more details please see common->_correctBasename(). if (!preg_match('/^(?:in|ex)ternalmedia$/', $calls[$i][$handler_name])) { continue; } $inst =& $calls[$i][$instructions]; $filename = false; $linktext = $inst[$title]; $linkonly = $inst[$linking] === 'linkonly'; list($src, $hash) = explode('#', $inst[$source], 2); // get original filename if ($calls[$i][$handler_name] === 'internalmedia') { resolve_mediaid($ns, $src, $exists); list($ext, $mime, $dl) = mimetype($src); $filename = $this->_getOriginalFileName($src); } else { list($ext, $mime, $dl) = mimetype($src); } // prefetch auto-filled linktext if (!$linktext) { if (substr($mime, 0, 5) === 'image' && ($ext === 'jpg' || $ext === 'jpeg') && ($jpeg = new JpegMeta(mediaFN($src))) && ($caption = $jpeg->getTitle())) { $linktext = $caption; } else { $linktext = $this->common->_correctBasename(noNS($src)); } } // add a marker (normally you cannot put '}}' in a media link title // and cannot put ':' in a filename) if ($filename === false) { $inst[$title] = $linktext; } elseif ($inst[$title] !== $linktext) { $inst[$title] = $linktext . '}}preservefilenames:autofilled:' . $filename; } else { $inst[$title] = $linktext . '}}preservefilenames::' . $filename; } } }
/** * resize or crop images using PHP's libGD support * * @author Andreas Gohr <*****@*****.**> * @author Sebastian Wienecke <*****@*****.**> */ function media_resize_imageGD($ext, $from, $from_w, $from_h, $to, $to_w, $to_h, $ofs_x = 0, $ofs_y = 0) { global $conf; if ($conf['gdlib'] < 1) { return false; } //no GDlib available or wanted // check available memory if (!is_mem_available($from_w * $from_h * 4 + $to_w * $to_h * 4)) { return false; } // create an image of the given filetype if ($ext == 'jpg' || $ext == 'jpeg') { if (!function_exists("imagecreatefromjpeg")) { return false; } $image = @imagecreatefromjpeg($from); // rotate the image according to exif orientation tag if ($image) { $meta = new JpegMeta($from); $orientation = $meta->getField("Orientation"); switch ($orientation) { case 3: // rotate 180 degrees clockwise if ($conf['syslog']) { syslog(LOG_WARNING, '[media.php] media_resize_imageGD:orientation: ' . $orientation . ' rotate 180 degrees clockwise'); } $image = imagerotate($image, 180, 0); break; case 6: // only rotate to vertical if width is larger than height if (intval($from_w) > intval($from_h)) { // rotage image 90 degrees clockwise if ($conf['syslog']) { syslog(LOG_WARNING, '[media.php] media_resize_imageGD:orientation: ' . $orientation . ' rotate 90 degrees clockwise'); } $image = imagerotate($image, -90, 0); if ($conf['syslog']) { syslog(LOG_WARNING, '[media.php] media_resize_imageGD: swap width and height as we have just rotated the image vertically'); } $from_w_old = $from_w; $to_w_old = $to_w; $from_w = $from_h; $to_w = $to_h; $from_h = $from_w_old; $to_h = $to_w_old; } break; case 8: // only rotate to vertical if width is larger than height if (intval($from_w) > intval($from_h)) { if ($conf['syslog']) { syslog(LOG_WARNING, '[media.php] media_resize_imageGD:orientation: ' . $orientation . ' rotate 90 degrees anti-clockwise'); } // rotage image 90 degrees anti-clockwise $image = imagerotate($image, 90, 0); if ($conf['syslog']) { syslog(LOG_WARNING, '[media.php] media_resize_imageGD: swap width and height as we have just rotated the image vertically'); } $from_w_old = $from_w; $to_w_old = $to_w; $from_w = $from_h; $to_w = $to_h; $from_h = $from_w_old; $to_h = $to_w_old; } break; } } } elseif ($ext == 'png') { if (!function_exists("imagecreatefrompng")) { return false; } $image = @imagecreatefrompng($from); } elseif ($ext == 'gif') { if (!function_exists("imagecreatefromgif")) { return false; } $image = @imagecreatefromgif($from); } if (!$image) { return false; } if ($conf['gdlib'] > 1 && function_exists("imagecreatetruecolor") && $ext != 'gif') { $newimg = @imagecreatetruecolor($to_w, $to_h); } if (!$newimg) { $newimg = @imagecreate($to_w, $to_h); } if (!$newimg) { imagedestroy($image); return false; } //keep png alpha channel if possible if ($ext == 'png' && $conf['gdlib'] > 1 && function_exists('imagesavealpha')) { imagealphablending($newimg, false); imagesavealpha($newimg, true); } //keep gif transparent color if possible if ($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { if (function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { $transcolorindex = @imagecolortransparent($image); if ($transcolorindex >= 0) { //transparent color exists $transcolor = @imagecolorsforindex($image, $transcolorindex); $transcolorindex = @imagecolorallocate($newimg, $transcolor['red'], $transcolor['green'], $transcolor['blue']); @imagefill($newimg, 0, 0, $transcolorindex); @imagecolortransparent($newimg, $transcolorindex); } else { //filling with white $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); @imagefill($newimg, 0, 0, $whitecolorindex); } } else { //filling with white $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); @imagefill($newimg, 0, 0, $whitecolorindex); } } //try resampling first if (function_exists("imagecopyresampled")) { if (!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); } } else { imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); } $okay = false; if ($ext == 'jpg' || $ext == 'jpeg') { if (!function_exists('imagejpeg')) { $okay = false; } else { $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); } } elseif ($ext == 'png') { if (!function_exists('imagepng')) { $okay = false; } else { // add compress png image if png_qulaity is set if ($conf['png_quality']) { $okay = imagepng($newimg, $to, $conf['png_quality']); } else { $okay = imagepng($newimg, $to); } } } elseif ($ext == 'gif') { if (!function_exists('imagegif')) { $okay = false; } else { $okay = imagegif($newimg, $to); } } // destroy GD image ressources if ($image) { imagedestroy($image); } if ($newimg) { imagedestroy($newimg); } return $okay; }
/** * Defines how a thumbnail should look like */ function _image($data, &$renderer = null, $mode = 'xhtml') { global $ID; if (is_null($renderer) || empty($data['src'])) { return false; } if (!is_array($data['params'])) { $data['params'] = array(); } //prepare link attributes // can use reflected images $reflect = array(); if ($reflection = plugin_load('syntax', 'reflect')) { $reflect = array('reflect' => $this->getConf('reflect') ? 1 : 0, 'bgc' => $this->getConf('reflectBackground')); } // Start Section if ($mode != 'metadata') { $renderer->doc .= '<div class="imageflow_image">' . NL; } // Display $data['params']['tok'] = media_get_token($data['src'], $data['params']['w'], $data['params']['h']); $href = ml($data['src'], array_merge($data['params'], $reflect), true, '&'); if ($mode != 'metadata' && empty($data['alternate_desc'])) { $renderer->doc .= '<img src="' . $href . '" alt="" class="imageflow__noscript__image media"/>'; } // Set Data $fn = mediaFN($data['src']); $data['src'] = ml($data['src']); $data['params'] = array_merge($data['params'], $reflect); // Remove everything except the params. $data['desc'] = trim($data['desc']); $data['title'] = trim($data['title']); if (empty($data['desc']) && ($meta = new JpegMeta($fn))) { $data['title'] = $meta->getField('Iptc.Headline'); $data['desc'] = $meta->getField('Iptc.Caption'); } if ($mode != 'metadata') { if (!empty($data['alternate_desc'])) { $renderer->doc .= $data['alternate_desc']; } else { $renderer->doc .= '<div class="imageflow_caption">' . NL; if (!empty($data['title'])) { $renderer->doc .= "<h3 class=\"imageflow__title\">{$data['title']}</h3>" . NL; } if (!empty($data['desc'])) { $renderer->doc .= "<p class=\"imageflow__text\">{$data['desc']}</p>" . NL; } // End Caption $renderer->doc .= '</div>' . NL; } // End Section $renderer->doc .= '<div class="clearer"></div>' . NL . '</div>' . NL; } else { // Add Metadata unset($data['alternate_desc']); if (!$data['isImage'] && !empty($data['linkto'])) { $data['id'] = $data['linkto']; unset($data['linkto']); } $renderer->meta['relation']['imageflow'][$this->sectionID[sizeof($this->sectionID) - 1]][] = $data; } return $data; }