1<?php 2// +----------------------------------------------------------------------+ 3// | PHP Version 4 | 4// +----------------------------------------------------------------------+ 5// | Copyright (c) 1997-2003 The PHP Group | 6// +----------------------------------------------------------------------+ 7// | This source file is subject to version 2.02 of the PHP license, | 8// | that is bundled with this package in the file LICENSE, and is | 9// | available at through the world-wide-web at | 10// | http://www.php.net/license/2_02.txt. | 11// | If you did not receive a copy of the PHP license and are unable to | 12// | obtain it through the world-wide-web, please send a note to | 13// | license@php.net so we can mail you a copy immediately. | 14// +----------------------------------------------------------------------+ 15// | Authors: Jason Rust <jrust@rustyparts.com> | 16// +----------------------------------------------------------------------+ 17// $Id: Imlib.php 258825 2008-04-30 23:00:13Z cweiske $ 18// {{{ requires 19 20require_once 'Image/Transform.php'; 21 22// }}} 23// {{{ example usage 24 25// $img = new Image_Transform::factory('Imlib'); 26// $angle = -90; 27// $img->load('test.png'); 28// $img->rotate($angle); 29// $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'arial.ttf','color'=>'#ffffff')); 30// $img->display(); 31 32// }}} 33// {{{ class Image_Transform_Driver_Imlib 34 35/** 36 * Performs image manipulation with the imlib library. 37 * 38 * @see http://mmcc.cx/php_imlib/index.php 39 * @version Revision: 1.0 40 * @author Jason Rust <jrust@rustyparts.com> 41 * @package Image_Transform 42 */ 43 44// }}} 45class Image_Transform_Driver_Imlib extends Image_Transform { 46 // {{{ properties 47 48 /** 49 * Holds the image file for manipulation 50 */ 51 var $imageHandle = ''; 52 53 /** 54 * Holds the original image file 55 */ 56 var $oldHandle = ''; 57 58 // }}} 59 // {{{ constructor 60 61 /** 62 * Check settings 63 * 64 * @see __construct() 65 */ 66 function Image_Transform_Imlib() 67 { 68 $this->__construct(); 69 } 70 71 /** 72 * Check settings 73 * 74 * @return mixed true or or a PEAR error object on error 75 * 76 * @see PEAR::isError() 77 */ 78 function __construct() 79 { 80 if (!PEAR::loadExtension('imlib')) { 81 $this->isError( 82 PEAR::raiseError( 83 'Couldn\'t find the imlib extension.', 84 IMAGE_TRANSFORM_ERROR_UNSUPPORTED 85 ) 86 ); 87 } 88 } 89 90 // }}} 91 // {{{ load() 92 93 /** 94 * Load image 95 * 96 * @param string filename 97 * 98 * @return mixed TRUE or a PEAR error object on error 99 * @see PEAR::isError() 100 */ 101 function load($image) 102 { 103 $this->image = $image; 104 $this->imageHandle = imlib_load_image($this->image); 105 $result =& $this->_get_image_details($image); 106 if (PEAR::isError($result)) { 107 return $result; 108 } 109 110 return true; 111 } 112 113 // }}} 114 // {{{ addText() 115 116 /** 117 * Adds text to the image. Note that the angle should be one of the following 118 * constants: IMLIB_TEXT_TO_RIGHT, IMLIB_TEXT_TO_LEFT, IMLIB_TEXT_TO_DOWN, 119 * IMLIB_TEXT_TO_UP, IMLIB_TEXT_TO_ANGLE 120 * 121 * @param array options Array contains options 122 * array( 123 * 'text' The string to draw 124 * 'x' Horizontal position 125 * 'y' Vertical Position 126 * 'color' Font color 127 * 'font' Font to be used 128 * 'size' Size of the fonts in pixel 129 * 'angle' A imlib direction constant 130 * ) 131 * 132 * @return TRUE or PEAR Error object on error 133 * @see PEAR::isError() 134 */ 135 function addText($params) 136 { 137 $default_params = array( 138 'text' => 'This is Text', 139 'x' => 10, 140 'y' => 20, 141 'color' => array(255,0,0), 142 'font' => 'Arial.ttf', 143 'size' => '12', 144 'angle' => IMLIB_TEXT_TO_RIGHT, 145 ); 146 $params = array_merge($default_params, $params); 147 extract($params); 148 149 if (!is_array($color)){ 150 if ($color[0] == '#'){ 151 $color = $this->colorhex2colorarray($color); 152 } else { 153 include_once 'Image/Transform/Driver/ColorsDefs.php'; 154 $color = isset($colornames[$color]) ? $colornames[$color] : false; 155 } 156 } 157 158 $fontResource = imlib_load_font($font . '/' . $size); 159 imlib_text_draw($this->imageHandle, $fontResource, $x, $y, $text, $angle, $color[0], $color[1], $color[2], 255); 160 return true; 161 } 162 163 // }}} 164 // {{{ rotate() 165 166 /** 167 * Rotate image by the given angle 168 * 169 * @param int $angle Rotation angle 170 * 171 * @return TRUE or PEAR Error object on error 172 */ 173 function rotate($angle) 174 { 175 $this->oldHandle = $this->imageHandle; 176 $this->imageHandle = imlib_create_rotated_image($this->imageHandle, $angle); 177 $new_x = imlib_image_get_width($this->imageHandle); 178 $new_y = imlib_image_get_height($this->imageHandle); 179 // when rotating it creates a bigger picture than before so that it can rotate at any angle 180 // so for right angles we crop it back to the original size 181 if ($angle % 90 == 0) { 182 if (abs($angle) == 90 || $angle == 270) { 183 $y_pos = ($new_x - $this->img_x) / 2; 184 $x_pos = ($new_y - $this->img_y) / 2; 185 $y_pos++; 186 $x_pos++; 187 $this->crop($this->img_y, $this->img_x, $x_pos, $y_pos); 188 } else { 189 $x_pos = ($new_x - $this->img_x) / 2; 190 $y_pos = ($new_y - $this->img_y) / 2; 191 $this->crop($this->img_x, $this->img_y, $x_pos, $y_pos); 192 } 193 } else { 194 $this->img_x = $new_x; 195 $this->img_y = $new_y; 196 } 197 198 return true; 199 } 200 201 // }}} 202 // {{{ crop() 203 204 /** 205 * Crops the current image to a specified height and width 206 * 207 * @param int $in_cropWidth The width of the new image 208 * @param int $in_cropHeight The height of the new image 209 * @param int $in_cropX The X coordinate on the image to start the crop 210 * @param int $in_cropY The Y coordinate on the image to start the crop 211 * 212 * @access public 213 * @return TRUE or PEAR Error object on error 214 */ 215 function crop($in_cropWidth, $in_cropHeight, $in_cropX, $in_cropY) 216 { 217 // Sanity check 218 if (!$this->_intersects($in_cropWidth, $in_cropHeight, $in_cropX, $in_cropY)) { 219 return PEAR::raiseError('Nothing to crop', IMAGE_TRANSFORM_ERROR_OUTOFBOUND); 220 } 221 $this->oldHandle = $this->imageHandle; 222 $this->imageHandle = imlib_create_cropped_image($this->imageHandle, $in_cropX, $in_cropY, $in_cropWidth, $in_cropHeight); 223 $this->img_x = $in_cropWidth; 224 $this->img_y = $in_cropHeight; 225 return true; 226 } 227 228 // }}} 229 // {{{ save() 230 231 /** 232 * Save the image file. Determines what type of image to save based on extension. 233 * 234 * @param $filename string the name of the file to write to 235 * @param $type string (optional) define the output format, default 236 * is the current used format 237 * @param $quality int (optional) output DPI, default is 75 238 * 239 * @return TRUE on success or PEAR Error object on error 240 */ 241 function save($filename, $type = '', $quality = 75) 242 { 243 if (!is_resource($this->imageHandle)) { 244 return PEAR::raiseError('Invalid image', true); 245 } 246 247 $err = 0; 248 $type = ($type == '') ? $this->type : $type; 249 $quality = (is_null($quality)) ? $this->_options['quality'] : $quality; 250 imlib_image_set_format($this->imageHandle, $type); 251 $return = imlib_save_image($this->imageHandle, $filename, $err, $quality); 252 $this->imageHandle = $this->oldHandle; 253 $this->resized = false; 254 if (!$return) { 255 return PEAR::raiseError('Couldn\'t save image. Reason: ' . $err, true); 256 } 257 return true; 258 } 259 260 // }}} 261 // {{{ display() 262 263 /** 264 * Display image without saving and lose changes 265 * 266 * This method adds the Content-type HTTP header 267 * 268 * @param string $type (optional) (JPG,PNG...); 269 * @param int $quality (optional) 75 270 * 271 * @return TRUE on success or PEAR Error object on error 272 */ 273 function display($type = '', $quality = null) 274 { 275 if (!is_resource($this->imageHandle)) { 276 return PEAR::raiseError('Invalid image', true); 277 } 278 279 $type = ($type == '') ? $this->type : $type; 280 $quality = (is_null($quality)) ? $this->_options['quality'] : $quality; 281 imlib_image_set_format($this->imageHandle, $type); 282 $err = 0; 283 header('Content-type: ' . $this->getMimeType($type)); 284 $return = imlib_dump_image($this->imageHandle, $err, $quality); 285 $this->imageHandle = $this->oldHandle; 286 $this->resized = false; 287 imlib_free_image($this->oldHandle); 288 if (!$return) { 289 return PEAR::raiseError('Couldn\'t output image. Reason: ' . $err, true); 290 } 291 return true; 292 } 293 294 // }}} 295 // {{{ free() 296 297 /** 298 * Destroy image handle 299 * 300 * @return void 301 */ 302 function free() 303 { 304 if (is_resource($this->imageHandle)) { 305 imlib_free_image($this->imageHandle); 306 } 307 } 308 309 // }}} 310 // {{{ _resize() 311 312 /** 313 * Resize the image. 314 * 315 * @access private 316 * 317 * @param int $new_x New width 318 * @param int $new_y New height 319 * @param mixed $options Optional parameters 320 * 321 * @return TRUE on success or PEAR Error object on error 322 * @see PEAR::isError() 323 */ 324 function _resize($new_x, $new_y, $options = null) 325 { 326 if ($this->resized === true) { 327 return PEAR::raiseError('You have already resized the image without saving it. Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE); 328 } 329 330 $this->oldHandle = $this->imageHandle; 331 $this->imageHandle = imlib_create_scaled_image($this->imageHandle, $new_x, $new_y); 332 $this->img_x = $new_x; 333 $this->img_y = $new_y; 334 $this->resized = true; 335 return true; 336 } 337 338 // }}} 339 // {{{ _get_image_details() 340 341 /** 342 * Gets the image details 343 * 344 * @access private 345 * @return TRUE on success or PEAR Error object on error 346 */ 347 function _get_image_details() 348 { 349 $this->img_x = imlib_image_get_width($this->imageHandle); 350 $this->img_y = imlib_image_get_height($this->imageHandle); 351 $this->type = imlib_image_format($this->imageHandle); 352 $this->type = ($this->type == '') ? 'png' : $this->type; 353 return true; 354 } 355 356 // }}} 357 358 /** 359 * Horizontal mirroring 360 * 361 * @return TRUE on success, PEAR Error object on error 362 */ 363 function mirror() 364 { 365 imlib_image_flip_horizontal($this->imageHandle); 366 return true; 367 } 368 369 /** 370 * Vertical mirroring 371 * 372 * @return TRUE on success, PEAR Error object on error 373 */ 374 function flip() 375 { 376 imlib_image_flip_vertical($this->imageHandle); 377 return true; 378 } 379}