| Drupal | PHP Cross Reference | Content Management Systems |
1 <?php 2 3 /** 4 * @file 5 * GD2 toolkit for image manipulation within Drupal. 6 */ 7 8 /** 9 * @addtogroup image 10 * @{ 11 */ 12 13 /** 14 * Retrieve settings for the GD2 toolkit. 15 */ 16 function image_gd_settings() { 17 if (image_gd_check_settings()) { 18 $form['status'] = array( 19 '#markup' => t('The GD toolkit is installed and working properly.') 20 ); 21 22 $form['image_jpeg_quality'] = array( 23 '#type' => 'textfield', 24 '#title' => t('JPEG quality'), 25 '#description' => t('Define the image quality for JPEG manipulations. Ranges from 0 to 100. Higher values mean better image quality but bigger files.'), 26 '#size' => 10, 27 '#maxlength' => 3, 28 '#default_value' => variable_get('image_jpeg_quality', 75), 29 '#field_suffix' => t('%'), 30 ); 31 $form['#element_validate'] = array('image_gd_settings_validate'); 32 33 return $form; 34 } 35 else { 36 form_set_error('image_toolkit', t('The GD image toolkit requires that the GD module for PHP be installed and configured properly. For more information see <a href="@url">PHP\'s image documentation</a>.', array('@url' => 'http://php.net/image'))); 37 return FALSE; 38 } 39 } 40 41 /** 42 * Validate the submitted GD settings. 43 */ 44 function image_gd_settings_validate($form, &$form_state) { 45 // Validate image quality range. 46 $value = $form_state['values']['image_jpeg_quality']; 47 if (!is_numeric($value) || $value < 0 || $value > 100) { 48 form_set_error('image_jpeg_quality', t('JPEG quality must be a number between 0 and 100.')); 49 } 50 } 51 52 /** 53 * Verify GD2 settings (that the right version is actually installed). 54 * 55 * @return 56 * A boolean indicating if the GD toolkit is available on this machine. 57 */ 58 function image_gd_check_settings() { 59 if ($check = get_extension_funcs('gd')) { 60 if (in_array('imagegd2', $check)) { 61 // GD2 support is available. 62 return TRUE; 63 } 64 } 65 return FALSE; 66 } 67 68 /** 69 * Scale an image to the specified size using GD. 70 * 71 * @param $image 72 * An image object. The $image->resource, $image->info['width'], and 73 * $image->info['height'] values will be modified by this call. 74 * @param $width 75 * The new width of the resized image, in pixels. 76 * @param $height 77 * The new height of the resized image, in pixels. 78 * @return 79 * TRUE or FALSE, based on success. 80 * 81 * @see image_resize() 82 */ 83 function image_gd_resize(stdClass $image, $width, $height) { 84 $res = image_gd_create_tmp($image, $width, $height); 85 86 if (!imagecopyresampled($res, $image->resource, 0, 0, 0, 0, $width, $height, $image->info['width'], $image->info['height'])) { 87 return FALSE; 88 } 89 90 imagedestroy($image->resource); 91 // Update image object. 92 $image->resource = $res; 93 $image->info['width'] = $width; 94 $image->info['height'] = $height; 95 return TRUE; 96 } 97 98 /** 99 * Rotate an image the given number of degrees. 100 * 101 * @param $image 102 * An image object. The $image->resource, $image->info['width'], and 103 * $image->info['height'] values will be modified by this call. 104 * @param $degrees 105 * The number of (clockwise) degrees to rotate the image. 106 * @param $background 107 * An hexadecimal integer specifying the background color to use for the 108 * uncovered area of the image after the rotation. E.g. 0x000000 for black, 109 * 0xff00ff for magenta, and 0xffffff for white. For images that support 110 * transparency, this will default to transparent. Otherwise it will 111 * be white. 112 * @return 113 * TRUE or FALSE, based on success. 114 * 115 * @see image_rotate() 116 */ 117 function image_gd_rotate(stdClass $image, $degrees, $background = NULL) { 118 // PHP installations using non-bundled GD do not have imagerotate. 119 if (!function_exists('imagerotate')) { 120 watchdog('image', 'The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', array('%file' => $image->source)); 121 return FALSE; 122 } 123 124 $width = $image->info['width']; 125 $height = $image->info['height']; 126 127 // Convert the hexadecimal background value to a color index value. 128 if (isset($background)) { 129 $rgb = array(); 130 for ($i = 16; $i >= 0; $i -= 8) { 131 $rgb[] = (($background >> $i) & 0xFF); 132 } 133 $background = imagecolorallocatealpha($image->resource, $rgb[0], $rgb[1], $rgb[2], 0); 134 } 135 // Set the background color as transparent if $background is NULL. 136 else { 137 // Get the current transparent color. 138 $background = imagecolortransparent($image->resource); 139 140 // If no transparent colors, use white. 141 if ($background == 0) { 142 $background = imagecolorallocatealpha($image->resource, 255, 255, 255, 0); 143 } 144 } 145 146 // Images are assigned a new color palette when rotating, removing any 147 // transparency flags. For GIF images, keep a record of the transparent color. 148 if ($image->info['extension'] == 'gif') { 149 $transparent_index = imagecolortransparent($image->resource); 150 if ($transparent_index != 0) { 151 $transparent_gif_color = imagecolorsforindex($image->resource, $transparent_index); 152 } 153 } 154 155 $image->resource = imagerotate($image->resource, 360 - $degrees, $background); 156 157 // GIFs need to reassign the transparent color after performing the rotate. 158 if (isset($transparent_gif_color)) { 159 $background = imagecolorexactalpha($image->resource, $transparent_gif_color['red'], $transparent_gif_color['green'], $transparent_gif_color['blue'], $transparent_gif_color['alpha']); 160 imagecolortransparent($image->resource, $background); 161 } 162 163 $image->info['width'] = imagesx($image->resource); 164 $image->info['height'] = imagesy($image->resource); 165 return TRUE; 166 } 167 168 /** 169 * Crop an image using the GD toolkit. 170 * 171 * @param $image 172 * An image object. The $image->resource, $image->info['width'], and 173 * $image->info['height'] values will be modified by this call. 174 * @param $x 175 * The starting x offset at which to start the crop, in pixels. 176 * @param $y 177 * The starting y offset at which to start the crop, in pixels. 178 * @param $width 179 * The width of the cropped area, in pixels. 180 * @param $height 181 * The height of the cropped area, in pixels. 182 * @return 183 * TRUE or FALSE, based on success. 184 * 185 * @see image_crop() 186 */ 187 function image_gd_crop(stdClass $image, $x, $y, $width, $height) { 188 $res = image_gd_create_tmp($image, $width, $height); 189 190 if (!imagecopyresampled($res, $image->resource, 0, 0, $x, $y, $width, $height, $width, $height)) { 191 return FALSE; 192 } 193 194 // Destroy the original image and return the modified image. 195 imagedestroy($image->resource); 196 $image->resource = $res; 197 $image->info['width'] = $width; 198 $image->info['height'] = $height; 199 return TRUE; 200 } 201 202 /** 203 * Convert an image resource to grayscale. 204 * 205 * Note that transparent GIFs loose transparency when desaturated. 206 * 207 * @param $image 208 * An image object. The $image->resource value will be modified by this call. 209 * @return 210 * TRUE or FALSE, based on success. 211 * 212 * @see image_desaturate() 213 */ 214 function image_gd_desaturate(stdClass $image) { 215 // PHP installations using non-bundled GD do not have imagefilter. 216 if (!function_exists('imagefilter')) { 217 watchdog('image', 'The image %file could not be desaturated because the imagefilter() function is not available in this PHP installation.', array('%file' => $image->source)); 218 return FALSE; 219 } 220 221 return imagefilter($image->resource, IMG_FILTER_GRAYSCALE); 222 } 223 224 /** 225 * GD helper function to create an image resource from a file. 226 * 227 * @param $image 228 * An image object. The $image->resource value will populated by this call. 229 * @return 230 * TRUE or FALSE, based on success. 231 * 232 * @see image_load() 233 */ 234 function image_gd_load(stdClass $image) { 235 $extension = str_replace('jpg', 'jpeg', $image->info['extension']); 236 $function = 'imagecreatefrom' . $extension; 237 return (function_exists($function) && $image->resource = $function($image->source)); 238 } 239 240 /** 241 * GD helper to write an image resource to a destination file. 242 * 243 * @param $image 244 * An image object. 245 * @param $destination 246 * A string file URI or path where the image should be saved. 247 * @return 248 * TRUE or FALSE, based on success. 249 * 250 * @see image_save() 251 */ 252 function image_gd_save(stdClass $image, $destination) { 253 $scheme = file_uri_scheme($destination); 254 // Work around lack of stream wrapper support in imagejpeg() and imagepng(). 255 if ($scheme && file_stream_wrapper_valid_scheme($scheme)) { 256 // If destination is not local, save image to temporary local file. 257 $local_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL); 258 if (!isset($local_wrappers[$scheme])) { 259 $permanent_destination = $destination; 260 $destination = drupal_tempnam('temporary://', 'gd_'); 261 } 262 // Convert stream wrapper URI to normal path. 263 $destination = drupal_realpath($destination); 264 } 265 266 $extension = str_replace('jpg', 'jpeg', $image->info['extension']); 267 $function = 'image' . $extension; 268 if (!function_exists($function)) { 269 return FALSE; 270 } 271 if ($extension == 'jpeg') { 272 $success = $function($image->resource, $destination, variable_get('image_jpeg_quality', 75)); 273 } 274 else { 275 // Always save PNG images with full transparency. 276 if ($extension == 'png') { 277 imagealphablending($image->resource, FALSE); 278 imagesavealpha($image->resource, TRUE); 279 } 280 $success = $function($image->resource, $destination); 281 } 282 // Move temporary local file to remote destination. 283 if (isset($permanent_destination) && $success) { 284 return (bool) file_unmanaged_move($destination, $permanent_destination, FILE_EXISTS_REPLACE); 285 } 286 return $success; 287 } 288 289 /** 290 * Create a truecolor image preserving transparency from a provided image. 291 * 292 * @param $image 293 * An image object. 294 * @param $width 295 * The new width of the new image, in pixels. 296 * @param $height 297 * The new height of the new image, in pixels. 298 * @return 299 * A GD image handle. 300 */ 301 function image_gd_create_tmp(stdClass $image, $width, $height) { 302 $res = imagecreatetruecolor($width, $height); 303 304 if ($image->info['extension'] == 'gif') { 305 // Grab transparent color index from image resource. 306 $transparent = imagecolortransparent($image->resource); 307 308 if ($transparent >= 0) { 309 // The original must have a transparent color, allocate to the new image. 310 $transparent_color = imagecolorsforindex($image->resource, $transparent); 311 $transparent = imagecolorallocate($res, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); 312 313 // Flood with our new transparent color. 314 imagefill($res, 0, 0, $transparent); 315 imagecolortransparent($res, $transparent); 316 } 317 } 318 elseif ($image->info['extension'] == 'png') { 319 imagealphablending($res, FALSE); 320 $transparency = imagecolorallocatealpha($res, 0, 0, 0, 127); 321 imagefill($res, 0, 0, $transparency); 322 imagealphablending($res, TRUE); 323 imagesavealpha($res, TRUE); 324 } 325 else { 326 imagefill($res, 0, 0, imagecolorallocate($res, 255, 255, 255)); 327 } 328 329 return $res; 330 } 331 332 /** 333 * Get details about an image. 334 * 335 * @param $image 336 * An image object. 337 * @return 338 * FALSE, if the file could not be found or is not an image. Otherwise, a 339 * keyed array containing information about the image: 340 * - "width": Width, in pixels. 341 * - "height": Height, in pixels. 342 * - "extension": Commonly used file extension for the image. 343 * - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png'). 344 * 345 * @see image_get_info() 346 */ 347 function image_gd_get_info(stdClass $image) { 348 $details = FALSE; 349 $data = getimagesize($image->source); 350 351 if (isset($data) && is_array($data)) { 352 $extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png'); 353 $extension = isset($extensions[$data[2]]) ? $extensions[$data[2]] : ''; 354 $details = array( 355 'width' => $data[0], 356 'height' => $data[1], 357 'extension' => $extension, 358 'mime_type' => $data['mime'], 359 ); 360 } 361 362 return $details; 363 } 364 365 /** 366 * @} End of "addtogroup image". 367 */
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title