'Image Sizer', 'pi_version' => '1.6.6', 'pi_author' => 'David Rencher', 'pi_author_url' => 'http://www.lumis.com/', 'pi_description' => 'Image Resizer - resizes and caches images', 'pi_usage' => imgsizer::usage() ); class imgsizer { function size() { global $TMPL, $FNS, $PREFS; /** ------------------------------------- /* include the EE image library /** -------------------------------------*/ require_once PATH_CORE.'core.image_lib'.EXT; $SIZER = new Image_lib(); /** ------------------------------------- /* set a few vars /** -------------------------------------*/ $tagdata = ""; $cachPath = "cache/"; $okmime = array("image/png","image/gif","image/jpeg"); $sofar = ""; /** ------------------------------------- /* collect passed vars from the tag /** -------------------------------------*/ $debug = ( ! $TMPL->fetch_param('debug')) ? '' : $TMPL->fetch_param('debug'); $justurl = ( ! $TMPL->fetch_param('justurl')) ? '' : $TMPL->fetch_param('justurl'); $justcheck = ( ! $TMPL->fetch_param('justcheck')) ? '' : $TMPL->fetch_param('justcheck'); $alt = ( ! $TMPL->fetch_param('alt')) ? '' : $TMPL->fetch_param('alt'); $style = ( ! $TMPL->fetch_param('style')) ? '' : $TMPL->fetch_param('style'); $class = ( ! $TMPL->fetch_param('class')) ? '' : $TMPL->fetch_param('class'); $title = ( ! $TMPL->fetch_param('title')) ? '' : $TMPL->fetch_param('title'); $id = ( ! $TMPL->fetch_param('id')) ? '' : $TMPL->fetch_param('id'); $auto = ( ! $TMPL->fetch_param('auto')) ? '' : $TMPL->fetch_param('auto'); $oversize = ( ! $TMPL->fetch_param('oversize')) ? '' : $TMPL->fetch_param('oversize'); $max_width = ( ! $TMPL->fetch_param('width')) ? '1000' : $TMPL->fetch_param('width'); $max_height = ( ! $TMPL->fetch_param('height')) ? '1000' : $TMPL->fetch_param('height'); $mask = ( ! $TMPL->fetch_param('mask')) ? '' : $TMPL->fetch_param('mask'); $mask_radius = ( ! $TMPL->fetch_param('mask_radius')) ? '0.5' : $TMPL->fetch_param('mask_radius'); $mask_threshold = ( ! $TMPL->fetch_param('mask_threshold')) ? '3' : $TMPL->fetch_param('mask_threshold'); $cache = ( ! $TMPL->fetch_param('cache')) ? '' : $TMPL->fetch_param('cache'); $src = ( ! $TMPL->fetch_param('image')) ? ( !$TMPL->fetch_param('src') ? '' : $TMPL->fetch_param('src') ) : $TMPL->fetch_param('image'); // if no src thers not much we can do... go ahead and stop here if(!$src) { if ($debug) { return "no src= param given"; } else { return; } } $src = str_replace(SLASH, "/", $src); // clean up passed src param // make sure the full html img code is not being passed if (stristr($src, 'filename_security($img_filename); // checks if server supports $ENV DOCUMENT_ROOT use $_SERVER otherwise if (array_key_exists('DOCUMENT_ROOT',$_ENV)) { $img_rootstep = $_ENV['DOCUMENT_ROOT']."/".$img_base; } else { $img_rootstep = $_SERVER['DOCUMENT_ROOT']."/".$img_base; } if ($debug) {print_r($img_rootstep);} // checks the path and removes // if the src path was entered as relitive $img_rootpath = realpath($img_rootstep); if ($debug) {echo "
out_url=".$img_rootpath."
";} $img_fromroot = $img_rootpath."/".$img_filename.".".$img_extension; if ($debug) {echo "
out_url=".$img_fromroot."
";} // can we actually read this file? if(!is_readable($img_fromroot)) { if ($debug) { return " you dont have permissions to read the file: {$img_fromroot}"; } else { return; } } // end everything if the image is not there if (!is_file($img_fromroot)) { if ($debug) { return "{$img_fromroot} could not be found"; } else { return; } } /** ------------------------------------- /* this just checks if the src image is there /* intentions of this are for use with in-template php /** -------------------------------------*/ if ($justcheck) { if(is_file($img_fromroot)){ return "1"; } } /** ------------------------------------- /* Check if cache Dir is there if not attempt to create it /** -------------------------------------*/ if(!is_dir($img_rootpath."/".$cachPath."")) { // make the directory if we can if (!mkdir($img_rootpath."/".$cachPath."", 0777)) { if ($debug) { return "cache Directory could not be created at {$img_rootpath}/{$cachPath}/"; } else { return; } } // check if we can put files in the new directory if (!is_writable($img_rootpath."/".$cachPath."")) { if ($debug) { return "you dont have permissions to write to {$img_rootpath}/{$cachPath}/"; } else { return; } } } /** ------------------------------------- /* get src img sizes and mime type /** -------------------------------------*/ $size = getimagesize($img_fromroot); if ($debug) {print_r($size);} $width = $size[0]; $height = $size[1]; $mime = $size['mime']; /** ------------------------------------- /* lets stop this if the image is not in the ok mime types /* eavun if the file extension says it is the correct format /* prevents proessing if people try to rename a .bmp to .jpg etc. /* dont laugh it happens at my work all the time /** -------------------------------------*/ if (!in_array($mime, $okmime)) { if ($debug) { return "mime type {$mime} not supported"; } else { return; } } /** ------------------------------------- /* do the Cropping if we need to /** -------------------------------------*/ $did_crop = ""; if($width >= $max_width AND $height >= $max_height AND $width != $height){ if($max_width == $max_height AND !$auto){ // do the cropping $img_crop = $this->img_crop($img_rootpath, $cachPath, $img_filename, $img_extension, $width, $height, $cache); // reset vars based on returned cropped values $width = $img_crop['img_width']; $height = $img_crop['img_height']; $img_filename = $img_crop['img_filename']; $img_rootpath = $img_rootpath."/".$cachPath; $did_crop = "1"; // if filename is blank something died inside EE core if($img_filename == ""){ if ($debug) { return "The EE Image Core did not return a filename on croping nothing more we can do"; } else { return; } } } } /** ------------------------------------- /* Set image sizing Ratio /* Auto size Added By Erin Dalzell /** -------------------------------------*/ if ($auto) { if ($width > $height) { $max_width = $auto; } else { $max_height = $auto; } } /** ------------------------------------- /* Resize the image and prep the output /** -------------------------------------*/ $img_size = $this->img_size($img_rootpath, $cachPath, $img_filename, $img_extension, $width, $height, $max_width, $max_height, $did_crop, $mime, $mask, $mask_radius, $mask_threshold, $cache); $sized_file = $img_size['img_filename']; $tn_width = $img_size['img_width']; $tn_height = $img_size['img_height']; // if filename is blank something died inside EE core if($sized_file == ""){ if ($debug) { return "The EE Image Core did not return a filename in Resizing nothing more we can do"; } else { return; } } // allow oversizing? will act bad on cropped images if($oversize == "yes") { if($max_width > $width) { $tn_width = $max_width; } if($max_height > $height) { //$tn_height = $max_height; } } // build output URL $out_url= "/".$img_base."/".$cachPath."".$sized_file; if ($debug) {echo "
out_url=".$out_url;} $out_url= $FNS->remove_double_slashes($out_url); if ($debug) {echo "
remove_double_slashes=".$out_url;} /** ------------------------------------- /* is the tag in a pair if so do that /** -------------------------------------*/ $tagdata = $TMPL->tagdata; if ($tagdata) { foreach ($TMPL->var_single as $key => $val) { if ($val == "url") { $tagdata = $TMPL->swap_var_single($val, $out_url, $tagdata); } if ($val == "sized") { $tagdata = $TMPL->swap_var_single($val, $out_url, $tagdata); } if ($val == "width") { $tagdata = $TMPL->swap_var_single($val, $tn_width, $tagdata); } if ($val == "height") { $tagdata = $TMPL->swap_var_single($val, $tn_height, $tagdata); } } return $tagdata; } /** ------------------------------------- /* sometimes we may just want the path to the image e.g. RSS feeds /** -------------------------------------*/ if ($justurl) { return $out_url; } /** ------------------------------------- /* this is the default output just a simpe img tag /** -------------------------------------*/ $out_tag = "\"$alt\"""; } /** ------------------------------------- /* Resizes image Function /** -------------------------------------*/ function img_size($img_rootpath, $cachPath, $img_filename, $img_extension, $width, $height, $max_width, $max_height, $did_crop, $mime, $mask, $mask_radius, $mask_threshold, $cache){ global $PREFS; /** ------------------------------------- /* include the EE image library /** -------------------------------------*/ require_once PATH_CORE.'core.image_lib'.EXT; $SIZER = new Image_lib(); /** ------------------------------------- /* clear the cache basepath if we did cropping /** -------------------------------------*/ if($did_crop){ $cachPath = ""; } /** ------------------------------------- /* set image ratios /** -------------------------------------*/ $x_ratio = $max_width / $width; $y_ratio = $max_height / $height; if (($width <= $max_width) && ($height <= $max_height) ) { $tn_width = $width; $tn_height = $height; } else if (($x_ratio * $height) < $max_height) { $tn_height = ceil($x_ratio * $height); $tn_width = $max_width; } else { $tn_width = ceil($y_ratio * $width); $tn_height = $max_height; } /** ------------------------------------- /* do we need to update this image or is it already chached /** -------------------------------------*/ $imageModified = @filemtime($img_rootpath); $thumbModified = @filemtime($img_rootpath."/".$cachPath."".$img_filename."_".$tn_width."x".$tn_height.".".$img_extension); /** ------------------------------------- /* EE image Lib resize /** -------------------------------------*/ if ($imageModified > $thumbModified || $cache == "no") { //echo $imageModified." = ".$thumbModified; $res = $SIZER->set_properties( array ( 'resize_protocol' => $PREFS->ini('image_resize_protocol'), 'libpath' => $PREFS->ini('image_library_path'), 'maintain_ratio' => TRUE, 'dynamic_output' => FALSE, 'thumb_prefix' => $tn_width."x".$tn_height, 'file_path' => $img_rootpath, 'file_name' => $img_filename.".".$img_extension, 'new_file_name' => "/".$cachPath."".$img_filename.".".$img_extension, 'quality' => 90, 'dst_width' => $tn_width, 'dst_height' => $tn_height ) ); $didSize = $SIZER->image_resize($res); // did EE image_resize work ? if not return blank array if ($didSize != "1") { $out_sized = array ( 'img_filename' => "", 'img_width' => "", 'img_height' => "" ); return $out_sized; } /** ------------------------------------- /* Apply unsharpen Mask /** -------------------------------------*/ if($mime == "image/jpeg" && $PREFS->core_ini['image_resize_protocol'] == "gd2" && $mask){ $this->UnsharpMask($img_rootpath."".$cachPath."".$img_filename."_".$tn_width."x".$tn_height.".".$img_extension, $mask, $mask_radius, $mask_threshold); } } /** ------------------------------------- /* all good output array /** -------------------------------------*/ $out_sized = array ( 'img_filename' => $img_filename."_".$tn_width."x".$tn_height.".".$img_extension, 'img_width' => $tn_width, 'img_height' => $tn_height ); return $out_sized; } /** ------------------------------------- /* Creates a square image from the original /** -------------------------------------*/ function img_crop($img_rootpath, $cachPath, $img_filename, $img_extension, $width, $height, $cache){ global $PREFS; $x = ""; $y = ""; /** ------------------------------------- /* include the EE image library /** -------------------------------------*/ require_once PATH_CORE.'core.image_lib'.EXT; $SIZER = new Image_lib(); /** ------------------------------------- /* sets the center of the image and how much we need to chop /** -------------------------------------*/ if($width > $height) { $x = ceil(($width - $height) / 2 ); $width = $height; } elseif($height> $width) { $y = ceil(($height - $width) / 2); $height = $width; } /** ------------------------------------- /* do we need to update this image or is it already chached /** -------------------------------------*/ $imageModified = @filemtime($img_rootpath); $thumbModified = @filemtime($img_rootpath."/".$cachPath."".$img_filename."_".$width."x".$height.".".$img_extension); /** ------------------------------------- /* EE image Lib Crop /** -------------------------------------*/ if ($imageModified > $thumbModified || $cache == "no") { $crp = $SIZER->set_properties( array ( 'resize_protocol' => $PREFS->ini('image_resize_protocol'), 'libpath' => $PREFS->ini('image_library_path'), 'dynamic_output' => FALSE, 'thumb_prefix' => $width."x".$height, 'file_path' => $img_rootpath, 'file_name' => $img_filename.".".$img_extension, 'new_file_name' => "/".$cachPath."".$img_filename.".".$img_extension, 'quality' => 90, 'x_axis' => $x, 'y_axis' => $y, 'dst_width' => $width, 'dst_height' => $height, 'maintain_ratio' => FALSE ) ); $didCrop = $SIZER->image_crop($crp); //echo "/".$cachPath."".$img_filename.".".$img_extension; // did EE image_crop work ? if not return blank array if ($didCrop != "1") { $out_cropped = array ( 'img_filename' => '', 'thumb_prefix' => '', 'img_extension' => '', 'img_width' => '', 'img_height' => '' ); return $out_cropped; } } /** ------------------------------------- /* array to output /** -------------------------------------*/ $out_cropped = array ( 'img_filename' => $img_filename."_".$width."x".$height, 'thumb_prefix' => $width."x".$height, 'img_extension' => $img_extension, 'img_width' => $width, 'img_height' => $height ); return $out_cropped; } function UnsharpMask($src, $amount, $radius, $threshold) { //////////////////////////////////////////////////////////////////////////////////////////////// //// //// Unsharp Mask for PHP - version 2.1.1 //// //// Unsharp mask algorithm by Torstein Hønsi 2003-07. //// thoensi_at_netcom_dot_no. //// Please leave this notice. //// /////////////////////////////////////////////////////////////////////////////////////////////// $img = @imagecreatefromjpeg($src); if(!$img){ return ''; } // Attempt to calibrate the parameters to Photoshop: if ($amount > 500) $amount = 500; $amount = $amount * 0.016; if ($radius > 50) $radius = 50; $radius = $radius * 2; if ($threshold > 255) $threshold = 255; $radius = abs(round($radius)); // Only integers make sense. if ($radius == 0) { return $img; imagedestroy($img); break; } //echo imagesx($img); $w = imagesx($img); $h = imagesy($img); $imgCanvas = imagecreatetruecolor($w, $h); $imgBlur = imagecreatetruecolor($w, $h); imageantialias ($img, true); // Gaussian blur matrix: // // 1 2 1 // 2 4 2 // 1 2 1 // ////////////////////////////////////////////////// if (function_exists('imageconvolution')) { // PHP >= 5.1 $matrix = array( array( 1, 2, 1 ), array( 2, 4, 2 ), array( 1, 2, 1 ) ); imagecopy ($imgBlur, $img, 0, 0, 0, 0, $w, $h); imageconvolution($imgBlur, $matrix, 16, 0); } else { // Move copies of the image around one pixel at the time and merge them with weight // according to the matrix. The same matrix is simply repeated for higher radii. for ($i = 0; $i < $radius; $i++) { imagecopy ($imgBlur, $img, 0, 0, 1, 0, $w - 1, $h); // left imagecopymerge ($imgBlur, $img, 1, 0, 0, 0, $w, $h, 50); // right imagecopymerge ($imgBlur, $img, 0, 0, 0, 0, $w, $h, 50); // center imagecopy ($imgCanvas, $imgBlur, 0, 0, 0, 0, $w, $h); imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 33.33333 ); // up imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 25); // down } } if($threshold>0){ // Calculate the difference between the blurred pixels and the original // and set the pixels for ($x = 0; $x < $w-1; $x++) { // each row for ($y = 0; $y < $h; $y++) { // each pixel $rgbOrig = ImageColorAt($img, $x, $y); $rOrig = (($rgbOrig >> 16) & 0xFF); $gOrig = (($rgbOrig >> 8) & 0xFF); $bOrig = ($rgbOrig & 0xFF); $rgbBlur = ImageColorAt($imgBlur, $x, $y); $rBlur = (($rgbBlur >> 16) & 0xFF); $gBlur = (($rgbBlur >> 8) & 0xFF); $bBlur = ($rgbBlur & 0xFF); // When the masked pixels differ less from the original // than the threshold specifies, they are set to their original value. $rNew = (abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig; $gNew = (abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig; $bNew = (abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig; if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) { $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew); ImageSetPixel($img, $x, $y, $pixCol); } } } } else{ for ($x = 0; $x < $w; $x++) { // each row for ($y = 0; $y < $h; $y++) { // each pixel $rgbOrig = ImageColorAt($img, $x, $y); $rOrig = (($rgbOrig >> 16) & 0xFF); $gOrig = (($rgbOrig >> 8) & 0xFF); $bOrig = ($rgbOrig & 0xFF); $rgbBlur = ImageColorAt($imgBlur, $x, $y); $rBlur = (($rgbBlur >> 16) & 0xFF); $gBlur = (($rgbBlur >> 8) & 0xFF); $bBlur = ($rgbBlur & 0xFF); $rNew = ($amount * ($rOrig - $rBlur)) + $rOrig; if($rNew>255){$rNew=255;} elseif($rNew<0){$rNew=0;} $gNew = ($amount * ($gOrig - $gBlur)) + $gOrig; if($gNew>255){$gNew=255;} elseif($gNew<0){$gNew=0;} $bNew = ($amount * ($bOrig - $bBlur)) + $bOrig; if($bNew>255){$bNew=255;} elseif($bNew<0){$bNew=0;} $rgbNew = ($rNew << 16) + ($gNew <<8) + $bNew; ImageSetPixel($img, $x, $y, $rgbNew); } } } imagedestroy($imgCanvas); imagedestroy($imgBlur); imagejpeg($img, $src, 100); return ''; } /** ---------------------------------------- /* Plugin Usage /* This function describes how the plugin is used. /** ----------------------------------------*/ function usage() { ob_start(); ?> This plugin will resize any JPG, GIF or PNG image to the size specified in your EE tag and cache the resized image to the cache folder. If you update the original image a new resized version will be created. NOTE: all resizing is done only done from the original image size Thanks to: Erin Dalzell for the Auto size feature Setup ===================================================== Create a cache folder in the folder that you upload your images to and make sure it is writable The Tag ===================================================== Single Tag: {exp:imgsizer:size src="/images/news/moped.jpg" width="200" alt="My Title" id="img_5334" class="entry_img"} will output My Title Tag Pair: {exp:imgsizer:size src="/images/news/moped.jpg" width="100"}
{/exp:imgsizer:size} Parameters: src= (required) the path from "webroot" to the image or the URL to the image. /images/news/moped.jpg or http://www.lumis.com/images/news/moped.jpg width= the width you wish the image resized to. The height is resized proportionately. or height= the height you wish the image resized to. The width is resized proportionately. or auto= the size of the longest side. If the image is landscape, then this sets the width, else it sets the height. NOTE: - if you use both width and height, width will take precedence - if you use auto, the width and height parameters are ignored. - if "width" is = to "height" the image will be cropped from image center to make a square sized image. mask="90" Applys a Unsharp mask if the image is a jpg (only numerical Values) mask_radius="0.5" (optional) defaults to 0.5 if not provided mask_threshold="3" (optional) defaults to 3 if not provided justcheck= (Single Tag only) if 'yes' the tag will return '1' if the image exists. justurl= (Single Tag only) if 'yes' the tag will only return the path to the image. alt= (Single Tag only) the alt tag of the image. id= (Single Tag only) the id of the image. class= (Single Tag only) the class of the image. cache="no" allows you to turn off image caching (not a good idea) setting this to "no" means your images will be reprocessed everytime the page is loaded (this param defaults to yes)