/[drupal]/drupal/modules/system/image.gd.inc
ViewVC logotype

Contents of /drupal/modules/system/image.gd.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


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

  ViewVC Help
Powered by ViewVC 1.1.2