PHP Classes

File: RImageManipulator.class.php

Recommend this page to a friend!
  Classes of Riccardo Brambilla   RImageManipulator   RImageManipulator.class.php   Download  
File: RImageManipulator.class.php
Role: Class source
Content type: text/plain
Description: Class file
Class: RImageManipulator
Manipulate and apply effects on images
Author: By
Last change: bug if image is cropped and then resized, happened if after the crop operation the resulting image had width = height
Date: 15 years ago
Size: 32,858 bytes
 

Contents

Class file image Download
<?php // ------------------------------------------------------------------------ // // RImageManipulator.class.php,v 1.0 2007/02/15 19:00:00 R.Brambilla // // ------------------------------------------------------------------------ // // RImageManipulator - Image Manipulation Class // // Copyright (C) 2007 Riccardo Brambilla // // <ribrambilla@tiscali.it> // // ------------------------------------------------------------------------ // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation; either version 2 of the License, or // // (at your option) any later version. // // // // You may not change or alter any portion of this comment or credits // // of supporting developers from this source code or any supporting // // source code which is considered copyrighted (c) material of the // // original comment or credit authors. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program; if not, write to the Free Software // // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // ------------------------------------------------------------------------ // /** * Options are detected from a simple config. file * HINT => Change path of the ini file in "parse_ini_file" function to an absolute one * dirname(__FILE__) works well only if conf.ini.php file is saved * in the same folder as the class file's one */ $conf = parse_ini_file( dirname(__FILE__) . "/conf.ini.php"); $lang = $conf['lang']; $er_image_w = $conf['er_image_w']; $er_image_h = $conf['er_image_h']; $debug_mode = $conf['debug_mode']; /** * Including files * [1] Language file * HINT => Change path of the lang file to an absolute one * dirname(__FILE__) works well only if lang file is saved * in the same folder as the class file's one */ if(file_exists( dirname(__FILE__) . "/" . $lang . ".php" )){ include_once( dirname(__FILE__) . "/" . $lang . ".php" ); } else { die("LANGUAGE FILE NOT FOUND!"); } /** * Handles images * Operations supported: resize ANDOR rotate ANDOR apply filters ANDOR interlace AND save the brand new Image * * @author Riccardo Brambilla aka ricketno <riccardobra@gmail.com> * @package RImageManipulator * @version 1.0 Feb 2007 PHP5 * */ class RImageManipulator { /** * Class var :: $image_pathname * * @var string * @access private */ private $image_pathname; /** * Class var :: $image_name * * @var string * @access private */ private $image_name; /** * Class var :: $image_path * * @var string * @access private */ private $image_path; /** * Class var :: $ext * * @var string * @access private */ private $ext; /** * Class var :: $new_w * * @var int * @access private */ private $new_w; /** * Class var :: $new_h * * @var int * @access private */ private $new_h; /** * Class var :: $new_name * * @var string * @access private */ private $new_name; /** * Class var :: $mantain_prop * * @var bool * @access private */ private $constrain_prop = true; /** * Class var :: $allowed_ext * * @var array * @access private */ private $allowed_ext = array( 'jpg', 'jpeg', 'png', 'gif' ); /** * Class var :: image resource * * @var resource * @access private */ private $im_resource; /** * Class var :: $img_info * * @var array * @access private */ private $im_resource_info = array(); /** * Class var :: $error_string * Holds infos about errors occurred * * @var string * @access public */ public $error_string = ""; /** * Class var :: $memory_needed * Memory needed for script to perform actions * * @var int * @access private */ private $memory_needed = 0; /** * CLASS Constants * Defaul Size values * Note: _WIDTH & _HEIGHT are both of type int * */ const _WIDTH = 120; const _HEIGHT = 120; /** * CLASS Constants * Constants used by the alloc(), predictMemoryUsage() functions * */ const _MB = 1048576; // Bytes in a MB const _64K = 65536; // Bytes in 64K const _TFACTOR = 4.8; // This value works for me :: you can change it const _UPPERLIMIT = 83886080; // 80MB ( in Bytes ) Limit :: you can change it /** * Class Constructor * * @param string $image_pathname * @param string $new_name * @return RImageManipulator * * @access public */ public function __construct( $image_pathname, $new_name = "" ) { // :: CHECKING INPUTS if(!is_string($image_pathname) || !ereg(".", $image_pathname)) { $this->setError(_ERR_PATHINVALID, 1); } if(!is_file($image_pathname) || !file_exists($image_pathname)) { $this->setError(_ERR_NOTAFILE, 1); } // :: SETTING CLASS VARS // : Extension manipulation $this->image_pathname = $image_pathname; $path_components = explode("/", $this->image_pathname); $image_name_ext = array_pop($path_components);// returns the last element of the path array ( name.ext ) // : If image is in the same directory of the script then path is dirname(__FILE__) // : else path is the result of the implode function $this->image_path = sizeof($path_components > 0) ? implode("/", $path_components) : dirname(__FILE__); // : Detecting image name and extension $name_components = explode(".", $image_name_ext); $this->ext = strtolower(array_pop($name_components));// extracts last component $this->image_name = implode(".", $name_components); // : Checking if extension is allowed if( empty($this->ext) ) $this->setError(_ERRNOTALLOWED, 1); if( !in_array($this->ext, $this->allowed_ext) ) $this->setError(_ERRNOTALLOWED, 1); // : New name if any ; else original name is used $this->new_name = empty($new_name) ? $this->image_name : $new_name; // : Creates the image resource to work on $this->createImageResource(); }// ef /** * Get class var value using class var name * * @param string $var_name * @return mixed * * @example $extension = $object->getVar('ext'); * @access public */ public function getVar($var_name = "") { return (isset($this->$var_name) && !empty($var_name)) ? $this->$var_name : ""; }// ef /** * Creates an image resource from filesystem * Appropriate function is chose on the base of file's extension * * @access private */ private function createImageResource() { // : Get current image size, extra infos like channels and bits $this->im_resource_info = getimagesize($this->image_pathname); // : We may have to dinamically allocate some extra memory $this->alloc(); // :: Creating an empty image switch($this->ext) { default: case "jpg":// JPG Images case "jpeg": if(!($img = imagecreatefromjpeg($this->image_pathname))) { // : Setting the error string $this->setError(_ERR_IMAGECREATION); $this->showImgError(); } break; case "png":// PNG Images :: Note: Right pronunciation is "ping" NOT "pee en gee" :) if(!($img = @imagecreatefrompng($this->image_pathname))) { // : Setting the error string $this->setError(_ERR_IMAGECREATION); $this->showImgError(); } break; case "gif":// GIF Images :: Note: Right pronunciation is "jif" NOT "GIF" :) // Note: GIF Support is expected to return in a GD library version released after mid 2004 if( function_exists('imagecreatefromgif') && function_exists('imagegif')) { if((!$img = @imagecreatefromgif($this->image_pathname))) { // : Setting the error string $this->setError(_ERR_IMAGECREATION); $this->showImgError(); } } else { // Gif Support disabled $this->setError(_ERR_GIFNOTSUPPORTED); $this->showImgError(); } break; }// ends switch // : Image created is saved as a class var // : Type is 'resource' $this->im_resource = $img; }// ef /** * Resizes the image, constrains proportions if asked * * @param int $new_w * @param int $new_h * @param bool $mantain_prop * * @access private */ public function resize( $new_w = 0, $new_h = 0, $constrain_prop = true) { // : We may have to dinamically allocate some extra memory $this->alloc(); // :: CHECKING INPUTS if(!is_int($new_w) || empty($new_w)) { $new_w = self::_WIDTH; } if(!is_int($new_h) || empty($new_h)) { $new_h = self::_HEIGHT; } if(!is_bool($constrain_prop)) { $constrain_prop = true; } // Check if resource is valid if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } // : New Size $this->new_w = $new_w; $this->new_h = $new_h; // : Proportion must or must not be kept $this->constrain_prop = $constrain_prop; // Image Size $img_width = $this->im_resource_info[0];// W $img_height = $this->im_resource_info[1];// H // :: CONSTRAIN PROPORTION if( $this->constrain_prop ) { // Ratio $size_prop = round( ($img_width/$img_height), 3 ); // W = H square if( $size_prop == 1 ) { if( $img_width === $this->new_w && $img_height === $this->new_h) { $tmp_img = $this->im_resource;// no changes needed } else { // New W-H $new_width = $this->new_w; $new_height = $this->new_h; // Copy ( resample ) $tmp_img = ImageCreateTrueColor( $new_width, $new_height ); imagecopyresampled( $tmp_img, $this->im_resource, 0, 0, 0, 0,$this->new_w, $this->new_h, $img_width, $img_height ); } }// ends square case elseif( $size_prop > 1 )// W > H { // : Ratio must be computed if( $img_width > $this->new_w ) { $ratio = ( $img_width/$this->new_w ); $new_height = floor( $img_height/$ratio ); } else { $ratio = ( $this->new_w/$img_width ); $new_height = floor( $img_height*$ratio ); } $new_width = $this->new_w; // Copy ( resample ) $tmp_img = ImageCreateTrueColor($new_width,$new_height); imagecopyresampled($tmp_img, $this->im_resource, 0, 0, 0, 0,$new_width,$new_height, $img_width, $img_height); }// ends W > H elseif( $size_prop < 1 )// W < H { // : Ratio must be computed if( $img_height > $this->new_h ) { $ratio = ( $img_height/$this->new_h ); $new_width = floor( $img_width/$ratio ); } else { $ratio = ( $this->new_h/$img_height ); $new_width = floor( $img_width*$ratio ); } $new_height = $this->new_h; // Copy ( resample ) $tmp_img = ImageCreateTrueColor($new_width,$new_height); imagecopyresampled( $tmp_img, $this->im_resource, 0, 0, 0, 0, $new_width, $new_height, $img_width, $img_height); }// ends W < H else { $this->setError(_ERR_RESIZE);// Error } // "Refreshing" resource $this->im_resource = $tmp_img; }// ends if costrain proportions else // Note: PROPORTIONS WILL BE LOST { // Copy ( resample ) width are height are taken directly from user input $tmp_img = ImageCreateTrueColor($this->new_w, $this->new_h); imagecopyresampled( $tmp_img, $this->im_resource, 0, 0, 0, 0, $this->new_w, $this->new_h, $img_width, $img_height); // "Refreshing" resource $this->im_resource = $tmp_img; }// ends main else $this->im_resource = $tmp_img; // :: Size infos must be refreshed // :: Now size infos are taken directly from the resource itself $this->im_resource_info[0] = imagesx($this->im_resource); $this->im_resource_info[1] = imagesy($this->im_resource); }// ef /** * Rotates image by $angle degrees * IMPORTANT NOTE: imagerotate function does not preserve infos about transparency * * @param int $angle 0 < angle < 360 * @param int $bgc "background" color :: specifies the color of the uncovered zone after the rotation. * @param bool $clockwise rotation is clockwise ( default ) or counter clockwise * * @access public */ public function rotate($angle, $bgc = 0, $clockwise = true) { // : We may have to dinamically allocate some extra memory $this->alloc(); // :: CHECKING INPUTS if(!is_int($angle) || ($angle % 90) != 0) { $angle = 90;// angle must be a multiple of 90 } if(!is_int($bgc) || $bgc > 360 || $bgc < 0 ) { $bgc = 0; } if( $clockwise == true ) { $angle = abs(360 - $angle); } // Check if resource is valid if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } // : Rotation $this->im_resource = @imagerotate($this->im_resource, $angle, $bgc ) or $this->setError(_ERR_ROTATION); }// ef /** * Applies filters provided by imagefilter function * Filter Constants are numeric; range is between 0 and 10 * Performs checks on optional args number * Filter names are: * * IMG_FILTER_NEGATE => 0 * IMG_FILTER_GRAYSCALE => 1 * IMG_FILTER_BRIGHTNESS => 2 * IMG_FILTER_CONTRAST => 3 * IMG_FILTER_COLORIZE => 4 * IMG_FILTER_EDGEDETECT => 5 * IMG_FILTER_EMBOSS => 6 * IMG_FILTER_GAUSSIAN_BLUR => 7 * IMG_FILTER_SELECTIVE_BLUR => 8 * IMG_FILTER_MEAN_REMOVAL => 9 * IMG_FILTER_SMOOTH => 10 * * @param int $filter_index * @param array $args optional args * * @access public */ public function applyFilter( $filter_index = 0 ) { // : We may have to dinamically allocate some extra memory $this->alloc(); // :: CHECK // Index is not in the range 0 - 10 if($filter_index < 0 || $filter_index > 10) { $this->setError(_ERR_FILTERDOESNOTEXIST); } // Check if resource is valid if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } // : How many args were sent to the function $args_num = func_num_args(); // : Args $args = func_get_args(); // :: Switch between indexes, options have their own number of parameters switch($filter_index) { default: case IMG_FILTER_NEGATE: @imagefilter($this->im_resource, $filter_index); break; case IMG_FILTER_GRAYSCALE: @imagefilter($this->im_resource, $filter_index); break; case IMG_FILTER_BRIGHTNESS: if($args_num != 2) $this->setError(_ERR_FILTERPARAMNUMBER); @imagefilter($this->im_resource, $filter_index, $args[1]); break; case IMG_FILTER_CONTRAST: if($args_num != 2) $this->setError(_ERR_FILTERPARAMNUMBER); @imagefilter($this->im_resource, $filter_index, $args[1]); break; case IMG_FILTER_COLORIZE: if($args_num != 4) $this->setError(_ERR_FILTERPARAMNUMBER); @imagefilter($this->im_resource, $filter_index, $args[1], $args[2], $args[3]); break; case IMG_FILTER_EDGEDETECT: @imagefilter($this->im_resource, $filter_index); break; case IMG_FILTER_EMBOSS: @imagefilter($this->im_resource, $filter_index); break; case IMG_FILTER_GAUSSIAN_BLUR: @imagefilter($this->im_resource, $filter_index); break; case IMG_FILTER_SELECTIVE_BLUR: @imagefilter($this->im_resource, $filter_index); break; case IMG_FILTER_MEAN_REMOVAL: @imagefilter($this->im_resource, $filter_index); break; case IMG_FILTER_SMOOTH: if($args_num != 2) $this->setError(_ERR_FILTERPARAMNUMBER); @imagefilter($this->im_resource, $filter_index, $args[1]); break; }// ends switch }// ef /** * Interlace or deinterlace image * * @param int $interlace_bit_val */ public function interlace( $interlace_bit_val = 0 ) { // :: CHECKING INPUTS if( !in_array($interlace_bit_val, array(1, 0)) ) $interlace_bit_val = 0; // : We may have to dinamically allocate some extra memory $this->alloc(); // Check if resource is valid if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } // : Interlace op @imageinterlace($this->im_resource, $interlace_bit_val); }// ef /** * Crops image * * @param int $crop_width * @param int $crop_height * @param int $d_x * @param int $d_y * @param int $src_x * @param int $src_y * @param array $bgc * * @access public */ public function crop($crop_width, $crop_height, $d_x = 0, $d_y = 0, $src_x = 0, $src_y = 0, $bgc = array()) { // : We may have to dinamically allocate some extra memory $this->alloc(); // :: CHECKING INPUTS // Is resource a valid one if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } if(!is_int($crop_width)) { $crop_width = $this->im_resource_info[0]; } if(!is_int($crop_height)) { $crop_height = $this->im_resource_info[1]; } if(!is_array($bgc) || count($bgc) !== 3) { $bgc = array(255, 255, 255); } // : Fill $tmp_img = ImageCreateTrueColor($crop_width, $crop_height); $bg_color = imagecolorallocate($tmp_img, $bgc[0], $bgc[1], $bgc[2]); imagefill($tmp_img, 0, 0, $bg_color); // Copy ( resample ) @imagecopyresampled( $tmp_img, $this->im_resource, (int)$d_x, (int)$d_y, (int)$src_x, (int)$src_y, $crop_width, $crop_height, $crop_width, $crop_height); // :: Size infos must be refreshed $this->im_resource_info[0] = $crop_width; $this->im_resource_info[1] = $crop_height; $this->im_resource = $tmp_img; }// ef /** * Draw a message on the image * * @param string $msg * @param int $font * @param int $x * @param int $y * @param array $text_color * * @access public */ public function drawString($msg, $font = 2, $x = 0, $y = 0, $text_color = array()) { // : We may have to dinamically allocate some extra memory $this->alloc(); // :: CHECKING INPUTS if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } if(!is_string($msg)) { $this->setError(_ERR_DRAWNOMSG); } if(!is_int($x) || !is_int($y)) { $x = $y = 0; } if($font < 1 || $font > 5) { $font = 2; } if(!is_array($text_color) || count($text_color) !== 3) { $text_color = array(255, 255, 255); } $text_color = imagecolorallocate($this->im_resource, $text_color[0], $text_color[1], $text_color[2]);// a kind of white // : Writing a message on the canvas @imagestring($this->im_resource, $font, $x, $y, $msg, $text_color) or $this->setError(_ERR_DS); }// ef /** * Generate a fog-like effect * It draws an alpha indexed gray rectangle on the image * Note: alpha is 0 to 127, where 0 is opaque * * @param int $alpha * * @access public */ function fog($alpha = 63) { // : We may have to dinamically allocate some extra memory $this->alloc(); if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } if(!is_numeric($alpha) || $alpha < 0 || $alpha >127) { $alpha = 63; } // :: $fog is a light gray, put on the image generate a fog-like effect $fog = imagecolorallocatealpha($this->im_resource, 211, 211, 211, (int)$alpha); @imagefilledrectangle($this->im_resource, 0, 0, $this->im_resource_info[0], $this->im_resource_info[1], $fog) or $this->setError(_ERR_FOG); }// ef /** * Draw a string ( TRUE TYPE FONTS ) on image with a given angle * * @param int $size font size * @param int $angle angolo * @param int $x * @param int $y * @param array $text_color * @param string $font * @param string $msg * * @access public */ public function drawTText($size, $angle, $x, $y, $text_color = array(), $msg, $font = 'arial.ttf') { // : We may have to dinamically allocate some extra memory $this->alloc(); // :: CHECKING INPUTS if (!is_resource($this->im_resource)) { $this->setError(_ERR_NOTAVALIDRESOURCE, 1); } if(!is_numeric($size)) { $size = 10; } if(!is_numeric($angle)) { $angle = 0; } if(!is_int($x) || !is_int($y)) { $x = $y = 0; } if(!is_string($font)) { $font = 'arial.ttf'; } if(!is_array($text_color) || count($text_color) !== 3) { $text_color = array(255, 255, 255); } if(!is_string($msg)) { $this->setError(_ERR_DRAWNOMSG); } // : Allocating text color $text_color = imagecolorallocate($this->im_resource, $text_color[0], $text_color[1], $text_color[2]);// a kind of white // : Draw string @imagettftext($this->im_resource, $size, $angle, $x, $y, $text_color, $font, $msg) or $this->setError(_ERR_TTEXT); }// ef /** * Gives a sepia-like effect * [1] Image is converted in grayscale * [2] Image is converted from RGB to CMYK * [3] CMYK values are changed to obtain a sepia-like effect * [4] CMKY values are converted to RGB * * @access public */ public function sepia() { $this->alloc(); // : First we need to grayscale the image $this->applyFilter(1); // : Let's create an empty image $im = imagecreatetruecolor($this->im_resource_info[0], $this->im_resource_info[1]); // :: Looping image's pixels for ($y = 0; $y < $this->im_resource_info[1]; $y++) { for ($x = 0; $x < $this->im_resource_info[0]; $x++) { /** * THESE LINES FROM PHP MANUAL * FUNCTION: imagecolorat * Returns the index of the color of the pixel at the specified location * Use bitshifting and masking to access the distinct red, green and blue component values */ $rgb = imagecolorat($this->im_resource, $x, $y); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> 8) & 0xFF; $b = $rgb & 0xFF; // : We need CMYK values to obtain our sepia-like effect list($C, $M, $Y, $K) = $this->rgbToCMYK($r, $g, $b); // : These are custom values, they works for me // : You can increase $M ( magenta channel ) to obtain // : a more "purpled" sepia effect $M = $M + 0.14; $Y = $Y + 0.30; // : Reconvert to RGB list($r, $g, $b) = $this->cmykToRGB($C, $M, $Y, $K); // : This is our new sepia-like color $col = imagecolorallocate($im, $r, $g, $b); // : Setting pixel RGB Value imagesetpixel($im, $x, $y, $col); }// end inner for }// ends 2D loop $this->im_resource = $im; }// ef /** * Converts RGB values to CMYK values * Function first converts to CMY and then * performs the convertion between CMY and CMYK * * Algorithm found at easyrgb http://www.easyrgb.com/ ( pseudocode ) * Here's my php implementation * * @param int $r * @param int $g * @param int $b * @return array * * @access private */ private function rgbToCMYK($r, $g, $b) { // RGB to CMY $C = 1 - ( $r / 255 ); $M = 1 - ( $g / 255 ); $Y = 1 - ( $b / 255 ); //Where CMYK and CMY values = 0 1 $var_K = 1; if ( $C < $var_K ) $var_K = $C; if ( $M < $var_K ) $var_K = $M; if ( $Y < $var_K ) $var_K = $Y; if ( $var_K == 1 ) { //Black $C = 0; $M = 0; $Y = 0; } else { $C = ( $C - $var_K ) / ( 1 - $var_K ); $M = ( $M - $var_K ) / ( 1 - $var_K ); $Y = ( $Y - $var_K ) / ( 1 - $var_K ); } // $K ( black value ) $K = $var_K; return array($C, $M, $Y, $K); }// ef /** * Converts CMYK to RGB * First converts from CMYK to CMY * then performs the convertion between CMY and RGB * * Algorithm found at easyrgb http://www.easyrgb.com/ ( pseudocode ) * Here's my php implementation * * @param float $C * @param float $M * @param float $Y * @param float $K * @return array * * @access private */ private function cmykToRGB($C, $M, $Y, $K) { // : CMYK and CMY values are 0 1 // : CMYK to CMY $C = doubleval( $C * ( 1 - $K ) + $K ); $M = doubleval( $M * ( 1 - $K ) + $K ); $Y = doubleval( $Y * ( 1 - $K ) + $K ); // : CMY to RGB $R = ( 1 - $C ) * 255; $G = ( 1 - $M ) * 255; $B = ( 1 - $Y ) * 255; return array($R, $G, $B); }// ef /** * Allows multiple manipulations to take effect with a single function call * Optional args for applyFilter are hardcoded here * For custom behaviours use applyFilter function alone * A funny method isn't it? Enjoy :) * * @param string $combo_code * @param int $angle rotation angle * @access public * * @example $istance->$a->rcombo("introtneg", 90); * @example $istance->$a->rcombo("bluebrig"); */ public function rcombo($combo_code = "", $angle = 0) { // : We may have to dinamically allocate some extra memory $this->alloc(); if(eregi("int", $combo_code)) $this->interlace(1); if(eregi("rot", $combo_code)) $this->rotate($angle); if(eregi("neg", $combo_code)) $this->applyFilter(0); if(eregi("gray", $combo_code)) $this->applyFilter(1); if(eregi("emb", $combo_code)) $this->applyFilter(6); if(eregi("blue", $combo_code)) $this->applyFilter(4, 0, 0, 255); if(eregi("red", $combo_code)) $this->applyFilter(4, 255, 0, 0); if(eregi("green", $combo_code)) $this->applyFilter(4, 0, 255, 0); if(eregi("smo", $combo_code)) $this->applyFilter(10, 50); if(eregi("blur", $combo_code)) $this->applyFilter(7); if(eregi("brig", $combo_code)) $this->applyFilter(2, 50); if(eregi("edge", $combo_code)) $this->applyFilter(5); if(eregi("cont", $combo_code)) $this->applyFilter(3, 50); if(eregi("sketch", $combo_code)) $this->applyFilter(9); if(eregi("sepia", $combo_code)) $this->sepia(); }// ef /** * Saves the brand new image to filesystem * * @param string $suffix string will be appended at the image name * @access public * * @example $this->save('_rotated') => filename will be : imagename_rotated.ext */ public function save( $suffix = "" ) { global $debug_mode; // : Saving image according to extension switch($this->ext) { // imagejpeg has a third parameter ( int quality :: hard coded here value=100) default: case "jpg": case "jpeg": imagejpeg($this->im_resource, $this->new_name . $suffix . "." . $this->ext, 100); break; case "gif": imagegif($this->im_resource, $this->new_name . $suffix . "." . $this->ext); break; case "png": imagepng($this->im_resource, $this->new_name . $suffix . "." . $this->ext); break; }// ends switch // :: Free imagedestroy($this->im_resource); // : Show errors if any echo ( empty($this->error_string) && $debug_mode) ? "Op Successfull<br />" : $this->showError(); }// ef /** * Alloc as much memory as needed to work with the image * * This function inspired by posts appeared on php.net site in the manual page of * imagecreatefromjpeg function * Thanks to yaroukh at gmail dot com, Karolis Tamutis karolis.t_AT_gmail.com, JohnBrook at pobox dot com * * @access private */ private function alloc() { // : How many bytes we'll need to allocate $memory_needed = !empty($this->memory_needed) ? $this->memory_needed : $this->predictMemoryUsage(); // : Retrieving data on current memory limit $current_limit = ceil(ini_get('memory_limit')) * 1024 * 1024; $current_usage = ceil(memory_get_usage()); // : New limit $new_limit = $current_limit + ceil(($current_usage + $memory_needed - $current_limit )); if(($new_limit > $current_limit)) { if(!($new_limit > self::_UPPERLIMIT)) { // : Malloc ini_set( 'memory_limit', ceil($new_limit/self::_MB) . 'M' ); } else { $this->setError( sprintf(_MEM_LIMIT_REACHED, $new_limit), 1); } }// endif }// ef /** * Computes memory needed forn performing operations * * This function inspired by posts appeared on php.net site in the manual page of * imagecreatefromjpeg function * Thanks to yaroukh at gmail dot com, Karolis Tamutis karolis.t_AT_gmail.com, JohnBrook at pobox dot com * * @return int * @access private * */ private function predictMemoryUsage() { // : Computing memory needed $memory_needed = ceil( ( $this->im_resource_info[0] * $this->im_resource_info[1] * $this->im_resource_info['bits'] * $this->im_resource_info['channels'] / 8 + self::_64K ) * self::_TFACTOR ); return $memory_needed; }// ef /** * Appends data ($er_msg) to the $error_string Class var * If code is set to 1 execution is stopped * * @param string $er_msg * @param int $code * * @access private */ private function setError($er_msg = "", $code = 0) { $this->error_string .= $er_msg . " "; // If code is 1 execution must be stopped // Error is fatal if( $code === 1 ) { $this->showError(); exit(); } }// ef /** * Shows Current Error String * * @access public * */ public function showError() { global $debug_mode; if( $debug_mode ) echo $this->error_string; }// ef /** * Shows a PNG image or a string with an error message * if something has gone wrong during the image creation * * @access private */ private function showImgError() { // : Image size is a configuration option global $er_image_w; global $er_image_h; // :: Creating an empty image $im = imagecreate($er_image_w, $er_image_h); // : Color Allocation $bg_color = imagecolorallocate($im, 160, 0, 0);// a kind of red $text_color = imagecolorallocate($im, 240, 240, 240);// a kind of white // : Painting the background rectangle with $bg_color imagefilledrectangle($im, 0, 0, $er_image_w, $er_image_h, $bg_color); // : Writing a message on the canvas imagestring($im, 4, 20, 10, $this->error_string, $text_color); // :: Output, checks if headers are already sent if(!headers_sent()) { header("Content-type: image/png"); if(!@imagepng($im)) { $this->showError(); } } else { echo $this->showError(); } // :: Free imagedestroy($im); }// ef /** * Class Destructor * * @access public */ public function __destruct() { // If save() has not been called let's destroy the image resource if($this->im_resource) { @imagedestroy($this->im_resource); } }// ef }// END OF CLASS ?>