webmaster@1
|
1 <?php |
webmaster@1
|
2 // $Id: image.inc,v 1.24 2008/01/28 16:05:17 goba Exp $ |
webmaster@1
|
3 |
webmaster@1
|
4 /** |
webmaster@1
|
5 * @file |
webmaster@1
|
6 * API for manipulating images. |
webmaster@1
|
7 */ |
webmaster@1
|
8 |
webmaster@1
|
9 /** |
webmaster@1
|
10 * @defgroup image Image toolkits |
webmaster@1
|
11 * @{ |
webmaster@1
|
12 * Drupal's image toolkits provide an abstraction layer for common image file |
webmaster@1
|
13 * manipulations like scaling, cropping, and rotating. The abstraction frees |
webmaster@1
|
14 * module authors from the need to support multiple image libraries, and it |
webmaster@1
|
15 * allows site administrators to choose the library that's best for them. |
webmaster@1
|
16 * |
webmaster@1
|
17 * PHP includes the GD library by default so a GD toolkit is installed with |
webmaster@1
|
18 * Drupal. Other toolkits like ImageMagic are available from contrib modules. |
webmaster@1
|
19 * GD works well for small images, but using it with larger files may cause PHP |
webmaster@1
|
20 * to run out of memory. In contrast the ImageMagick library does not suffer |
webmaster@1
|
21 * from this problem, but it requires the ISP to have installed additional |
webmaster@1
|
22 * software. |
webmaster@1
|
23 * |
webmaster@1
|
24 * Image toolkits are installed by copying the image.ToolkitName.inc file into |
webmaster@1
|
25 * Drupal's includes directory. The toolkit must then be enabled using the |
webmaster@1
|
26 * admin/settings/image-toolkit form. |
webmaster@1
|
27 * |
webmaster@1
|
28 * Only one toolkit maybe selected at a time. If a module author wishes to call |
webmaster@1
|
29 * a specific toolkit they can check that it is installed by calling |
webmaster@1
|
30 * image_get_available_toolkits(), and then calling its functions directly. |
webmaster@1
|
31 */ |
webmaster@1
|
32 |
webmaster@1
|
33 /** |
webmaster@1
|
34 * Return a list of available toolkits. |
webmaster@1
|
35 * |
webmaster@1
|
36 * @return |
webmaster@1
|
37 * An array of toolkit name => descriptive title. |
webmaster@1
|
38 */ |
webmaster@1
|
39 function image_get_available_toolkits() { |
webmaster@1
|
40 $toolkits = file_scan_directory('includes', 'image\..*\.inc$'); |
webmaster@1
|
41 |
webmaster@1
|
42 $output = array(); |
webmaster@1
|
43 foreach ($toolkits as $file => $toolkit) { |
webmaster@1
|
44 include_once "./$file"; |
webmaster@1
|
45 $function = str_replace('.', '_', $toolkit->name) .'_info'; |
webmaster@1
|
46 if (function_exists($function)) { |
webmaster@1
|
47 $info = $function(); |
webmaster@1
|
48 $output[$info['name']] = $info['title']; |
webmaster@1
|
49 } |
webmaster@1
|
50 } |
webmaster@1
|
51 |
webmaster@1
|
52 return $output; |
webmaster@1
|
53 } |
webmaster@1
|
54 |
webmaster@1
|
55 /** |
webmaster@1
|
56 * Retrieve the name of the currently used toolkit. |
webmaster@1
|
57 * |
webmaster@1
|
58 * @return |
webmaster@1
|
59 * String containing the name of the selected toolkit, or FALSE on error. |
webmaster@1
|
60 */ |
webmaster@1
|
61 function image_get_toolkit() { |
webmaster@1
|
62 static $toolkit; |
webmaster@1
|
63 |
webmaster@1
|
64 if (!$toolkit) { |
webmaster@1
|
65 $toolkit = variable_get('image_toolkit', 'gd'); |
webmaster@1
|
66 $toolkit_file = './includes/image.'. $toolkit .'.inc'; |
webmaster@1
|
67 if (isset($toolkit) && file_exists($toolkit_file)) { |
webmaster@1
|
68 include_once $toolkit_file; |
webmaster@1
|
69 } |
webmaster@1
|
70 elseif (!image_gd_check_settings()) { |
webmaster@1
|
71 $toolkit = FALSE; |
webmaster@1
|
72 } |
webmaster@1
|
73 } |
webmaster@1
|
74 |
webmaster@1
|
75 return $toolkit; |
webmaster@1
|
76 } |
webmaster@1
|
77 |
webmaster@1
|
78 /** |
webmaster@1
|
79 * Invokes the given method using the currently selected toolkit. |
webmaster@1
|
80 * |
webmaster@1
|
81 * @param $method |
webmaster@1
|
82 * A string containing the method to invoke. |
webmaster@1
|
83 * @param $params |
webmaster@1
|
84 * An optional array of parameters to pass to the toolkit method. |
webmaster@1
|
85 * @return |
webmaster@1
|
86 * Mixed values (typically Boolean indicating successful operation). |
webmaster@1
|
87 */ |
webmaster@1
|
88 function image_toolkit_invoke($method, $params = array()) { |
webmaster@1
|
89 if ($toolkit = image_get_toolkit()) { |
webmaster@1
|
90 $function = 'image_'. $toolkit .'_'. $method; |
webmaster@1
|
91 if (function_exists($function)) { |
webmaster@1
|
92 return call_user_func_array($function, $params); |
webmaster@1
|
93 } |
webmaster@1
|
94 else { |
webmaster@1
|
95 watchdog('php', 'The selected image handling toolkit %toolkit can not correctly process %function.', array('%toolkit' => $toolkit, '%function' => $function), WATCHDOG_ERROR); |
webmaster@1
|
96 return FALSE; |
webmaster@1
|
97 } |
webmaster@1
|
98 } |
webmaster@1
|
99 } |
webmaster@1
|
100 |
webmaster@1
|
101 |
webmaster@1
|
102 /** |
webmaster@1
|
103 * Get details about an image. |
webmaster@1
|
104 * |
webmaster@1
|
105 * Drupal only supports GIF, JPG and PNG file formats. |
webmaster@1
|
106 * |
webmaster@1
|
107 * @return |
webmaster@1
|
108 * FALSE, if the file could not be found or is not an image. Otherwise, a |
webmaster@1
|
109 * keyed array containing information about the image: |
webmaster@1
|
110 * 'width' - Width in pixels. |
webmaster@1
|
111 * 'height' - Height in pixels. |
webmaster@1
|
112 * 'extension' - Commonly used file extension for the image. |
webmaster@1
|
113 * 'mime_type' - MIME type ('image/jpeg', 'image/gif', 'image/png'). |
webmaster@1
|
114 * 'file_size' - File size in bytes. |
webmaster@1
|
115 */ |
webmaster@1
|
116 function image_get_info($file) { |
webmaster@1
|
117 if (!is_file($file)) { |
webmaster@1
|
118 return FALSE; |
webmaster@1
|
119 } |
webmaster@1
|
120 |
webmaster@1
|
121 $details = FALSE; |
webmaster@1
|
122 $data = @getimagesize($file); |
webmaster@1
|
123 $file_size = @filesize($file); |
webmaster@1
|
124 |
webmaster@1
|
125 if (isset($data) && is_array($data)) { |
webmaster@1
|
126 $extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png'); |
webmaster@1
|
127 $extension = array_key_exists($data[2], $extensions) ? $extensions[$data[2]] : ''; |
webmaster@1
|
128 $details = array('width' => $data[0], |
webmaster@1
|
129 'height' => $data[1], |
webmaster@1
|
130 'extension' => $extension, |
webmaster@1
|
131 'file_size' => $file_size, |
webmaster@1
|
132 'mime_type' => $data['mime']); |
webmaster@1
|
133 } |
webmaster@1
|
134 |
webmaster@1
|
135 return $details; |
webmaster@1
|
136 } |
webmaster@1
|
137 |
webmaster@1
|
138 /** |
webmaster@1
|
139 * Scales an image to the exact width and height given. Achieves the |
webmaster@1
|
140 * target aspect ratio by cropping the original image equally on both |
webmaster@1
|
141 * sides, or equally on the top and bottom. This function is, for |
webmaster@1
|
142 * example, useful to create uniform sized avatars from larger images. |
webmaster@1
|
143 * |
webmaster@1
|
144 * The resulting image always has the exact target dimensions. |
webmaster@1
|
145 * |
webmaster@1
|
146 * @param $source |
webmaster@1
|
147 * The file path of the source image. |
webmaster@1
|
148 * @param $destination |
webmaster@1
|
149 * The file path of the destination image. |
webmaster@1
|
150 * @param $width |
webmaster@1
|
151 * The target width, in pixels. |
webmaster@1
|
152 * @param $height |
webmaster@1
|
153 * The target height, in pixels. |
webmaster@1
|
154 * @return |
webmaster@1
|
155 * TRUE or FALSE, based on success. |
webmaster@1
|
156 */ |
webmaster@1
|
157 function image_scale_and_crop($source, $destination, $width, $height) { |
webmaster@1
|
158 $info = image_get_info($source); |
webmaster@1
|
159 |
webmaster@1
|
160 $scale = max($width / $info['width'], $height / $info['height']); |
webmaster@1
|
161 $x = round(($info['width'] * $scale - $width) / 2); |
webmaster@1
|
162 $y = round(($info['height'] * $scale - $height) / 2); |
webmaster@1
|
163 |
webmaster@1
|
164 if (image_toolkit_invoke('resize', array($source, $destination, $info['width'] * $scale, $info['height'] * $scale))) { |
webmaster@1
|
165 return image_toolkit_invoke('crop', array($destination, $destination, $x, $y, $width, $height)); |
webmaster@1
|
166 } |
webmaster@1
|
167 return FALSE; |
webmaster@1
|
168 } |
webmaster@1
|
169 |
webmaster@1
|
170 /** |
webmaster@1
|
171 * Scales an image to the given width and height while maintaining aspect |
webmaster@1
|
172 * ratio. |
webmaster@1
|
173 * |
webmaster@1
|
174 * The resulting image can be smaller for one or both target dimensions. |
webmaster@1
|
175 * |
webmaster@1
|
176 * @param $source |
webmaster@1
|
177 * The file path of the source image. |
webmaster@1
|
178 * @param $destination |
webmaster@1
|
179 * The file path of the destination image. |
webmaster@1
|
180 * @param $width |
webmaster@1
|
181 * The target width, in pixels. |
webmaster@1
|
182 * @param $height |
webmaster@1
|
183 * The target height, in pixels. |
webmaster@1
|
184 * @return |
webmaster@1
|
185 * TRUE or FALSE, based on success. |
webmaster@1
|
186 */ |
webmaster@1
|
187 function image_scale($source, $destination, $width, $height) { |
webmaster@1
|
188 $info = image_get_info($source); |
webmaster@1
|
189 |
webmaster@1
|
190 // Don't scale up. |
webmaster@1
|
191 if ($width >= $info['width'] && $height >= $info['height']) { |
webmaster@1
|
192 return FALSE; |
webmaster@1
|
193 } |
webmaster@1
|
194 |
webmaster@1
|
195 $aspect = $info['height'] / $info['width']; |
webmaster@1
|
196 if ($aspect < $height / $width) { |
webmaster@1
|
197 $width = (int)min($width, $info['width']); |
webmaster@1
|
198 $height = (int)round($width * $aspect); |
webmaster@1
|
199 } |
webmaster@1
|
200 else { |
webmaster@1
|
201 $height = (int)min($height, $info['height']); |
webmaster@1
|
202 $width = (int)round($height / $aspect); |
webmaster@1
|
203 } |
webmaster@1
|
204 |
webmaster@1
|
205 return image_toolkit_invoke('resize', array($source, $destination, $width, $height)); |
webmaster@1
|
206 } |
webmaster@1
|
207 |
webmaster@1
|
208 /** |
webmaster@1
|
209 * Resize an image to the given dimensions (ignoring aspect ratio). |
webmaster@1
|
210 * |
webmaster@1
|
211 * @param $source |
webmaster@1
|
212 * The file path of the source image. |
webmaster@1
|
213 * @param $destination |
webmaster@1
|
214 * The file path of the destination image. |
webmaster@1
|
215 * @param $width |
webmaster@1
|
216 * The target width, in pixels. |
webmaster@1
|
217 * @param $height |
webmaster@1
|
218 * The target height, in pixels. |
webmaster@1
|
219 * @return |
webmaster@1
|
220 * TRUE or FALSE, based on success. |
webmaster@1
|
221 */ |
webmaster@1
|
222 function image_resize($source, $destination, $width, $height) { |
webmaster@1
|
223 return image_toolkit_invoke('resize', array($source, $destination, $width, $height)); |
webmaster@1
|
224 } |
webmaster@1
|
225 |
webmaster@1
|
226 /** |
webmaster@1
|
227 * Rotate an image by the given number of degrees. |
webmaster@1
|
228 * |
webmaster@1
|
229 * @param $source |
webmaster@1
|
230 * The file path of the source image. |
webmaster@1
|
231 * @param $destination |
webmaster@1
|
232 * The file path of the destination image. |
webmaster@1
|
233 * @param $degrees |
webmaster@1
|
234 * The number of (clockwise) degrees to rotate the image. |
webmaster@1
|
235 * @param $background |
webmaster@1
|
236 * An hexidecimal integer specifying the background color to use for the |
webmaster@1
|
237 * uncovered area of the image after the rotation. E.g. 0x000000 for black, |
webmaster@1
|
238 * 0xff00ff for magenta, and 0xffffff for white. |
webmaster@1
|
239 * @return |
webmaster@1
|
240 * TRUE or FALSE, based on success. |
webmaster@1
|
241 */ |
webmaster@1
|
242 function image_rotate($source, $destination, $degrees, $background = 0x000000) { |
webmaster@1
|
243 return image_toolkit_invoke('rotate', array($source, $destination, $degrees, $background)); |
webmaster@1
|
244 } |
webmaster@1
|
245 |
webmaster@1
|
246 /** |
webmaster@1
|
247 * Crop an image to the rectangle specified by the given rectangle. |
webmaster@1
|
248 * |
webmaster@1
|
249 * @param $source |
webmaster@1
|
250 * The file path of the source image. |
webmaster@1
|
251 * @param $destination |
webmaster@1
|
252 * The file path of the destination image. |
webmaster@1
|
253 * @param $x |
webmaster@1
|
254 * The top left co-ordinate, in pixels, of the crop area (x axis value). |
webmaster@1
|
255 * @param $y |
webmaster@1
|
256 * The top left co-ordinate, in pixels, of the crop area (y axis value). |
webmaster@1
|
257 * @param $width |
webmaster@1
|
258 * The target width, in pixels. |
webmaster@1
|
259 * @param $height |
webmaster@1
|
260 * The target height, in pixels. |
webmaster@1
|
261 * @return |
webmaster@1
|
262 * TRUE or FALSE, based on success. |
webmaster@1
|
263 */ |
webmaster@1
|
264 function image_crop($source, $destination, $x, $y, $width, $height) { |
webmaster@1
|
265 return image_toolkit_invoke('crop', array($source, $destination, $x, $y, $width, $height)); |
webmaster@1
|
266 } |
webmaster@1
|
267 |
webmaster@1
|
268 /** |
webmaster@1
|
269 * @} End of "defgroup image". |
webmaster@1
|
270 */ |