'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 = "";
}
/** -------------------------------------
/* 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
Tag Pair:
{exp:imgsizer:size src="/images/news/moped.jpg" width="100"}