image.inc

  1. 7.x drupal-7.x/includes/image.inc
  2. 6.x drupal-6.x/includes/image.inc

API for manipulating images.

File

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