annotate modules/system/image.gd.inc @ 13:134d4b2e75f6

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