summaryrefslogtreecommitdiff
path: root/includes/image.inc
diff options
context:
space:
mode:
Diffstat (limited to 'includes/image.inc')
-rw-r--r--includes/image.inc279
1 files changed, 184 insertions, 95 deletions
diff --git a/includes/image.inc b/includes/image.inc
index a38e23419..6f94810e0 100644
--- a/includes/image.inc
+++ b/includes/image.inc
@@ -36,20 +36,20 @@
* Return a list of available toolkits.
*
* @return
- * An array of toolkit name => descriptive title.
+ * An array with the toolkit names as keys and the descriptions as values.
*/
function image_get_available_toolkits() {
// hook_image_toolkits returns an array of toolkit names.
$toolkits = module_invoke_all('image_toolkits');
$output = array();
- foreach ($toolkits as $name) {
- $function = 'image_' . $name . '_info';
- if (drupal_function_exists($function)) {
- $info = $function();
- $output[$info['name']] = $info['title'];
+ foreach ($toolkits as $name => $info) {
+ // Only allow modules that aren't marked as unavailable.
+ if ($info['available']) {
+ $output[$name] = $info['title'];
}
}
+
return $output;
}
@@ -62,14 +62,13 @@ function image_get_available_toolkits() {
function image_get_toolkit() {
static $toolkit;
- if (!$toolkit) {
+ if (!isset($toolkit)) {
+ $toolkits = image_get_available_toolkits();
$toolkit = variable_get('image_toolkit', 'gd');
- if (isset($toolkit) &&
- drupal_function_exists("image_" . $toolkit . "_resize")) {
- }
- elseif (!drupal_function_exists("image_gd_check_settings") ||
- !image_gd_check_settings()) {
- $toolkit = FALSE;
+ if (!isset($toolkits[$toolkit]) || !drupal_function_exists('image_' . $toolkit . '_load')) {
+ // The selected toolkit isn't available so return the first one found. If
+ // none are available this will return FALSE.
+ $toolkit = reset($toolkits);
}
}
@@ -81,25 +80,23 @@ function image_get_toolkit() {
*
* @param $method
* A string containing the method to invoke.
+ * @param $image
+ * An image object returned by image_load().
* @param $params
* An optional array of parameters to pass to the toolkit method.
* @return
* Mixed values (typically Boolean indicating successful operation).
*/
-function image_toolkit_invoke($method, $params = array()) {
- if ($toolkit = image_get_toolkit()) {
- $function = 'image_' . $toolkit . '_' . $method;
- if (drupal_function_exists($function)) {
- return call_user_func_array($function, $params);
- }
- else {
- watchdog('php', 'The selected image handling toolkit %toolkit can not correctly process %function.', array('%toolkit' => $toolkit, '%function' => $function), WATCHDOG_ERROR);
- return FALSE;
- }
+function image_toolkit_invoke($method, stdClass $image, array $params = array()) {
+ $function = 'image_' . $image->toolkit . '_' . $method;
+ if (drupal_function_exists($function)) {
+ array_unshift($params, $image);
+ return call_user_func_array($function, $params);
}
+ watchdog('image', 'The selected image handling toolkit %toolkit can not correctly process %function.', array('%toolkit' => $image->toolkit, '%function' => $function), WATCHDOG_ERROR);
+ return FALSE;
}
-
/**
* Get details about an image.
*
@@ -108,8 +105,8 @@ function image_toolkit_invoke($method, $params = array()) {
* @return
* FALSE, if the file could not be found or is not an image. Otherwise, a
* keyed array containing information about the image:
- * 'width' - Width in pixels.
- * 'height' - Height in pixels.
+ * 'width' - Width, in pixels.
+ * 'height' - Height, in pixels.
* 'extension' - Commonly used file extension for the image.
* 'mime_type' - MIME type ('image/jpeg', 'image/gif', 'image/png').
* 'file_size' - File size in bytes.
@@ -137,133 +134,225 @@ function image_get_info($file) {
}
/**
- * Scales an image to the exact width and height given. Achieves the
- * target aspect ratio by cropping the original image equally on both
- * sides, or equally on the top and bottom. This function is, for
- * example, useful to create uniform sized avatars from larger images.
+ * Scales an image to the exact width and height given.
+ *
+ * This function achieves the target aspect ratio by cropping the original image
+ * equally on both sides, or equally on the top and bottom. This function is
+ * useful to create uniform sized avatars from larger images.
*
* The resulting image always has the exact target dimensions.
*
- * @param $source
- * The file path of the source image.
- * @param $destination
- * The file path of the destination image.
+ * @param $image
+ * An image object returned by image_load().
* @param $width
* The target width, in pixels.
* @param $height
* The target height, in pixels.
* @return
* TRUE or FALSE, based on success.
+ *
+ * @see image_load()
+ * @see image_resize()
+ * @see image_crop()
*/
-function image_scale_and_crop($source, $destination, $width, $height) {
- $info = image_get_info($source);
-
- $scale = max($width / $info['width'], $height / $info['height']);
- $x = round(($info['width'] * $scale - $width) / 2);
- $y = round(($info['height'] * $scale - $height) / 2);
+function image_scale_and_crop(stdClass $image, $width, $height) {
+ $scale = max($width / $image->info['width'], $height / $image->info['height']);
+ $x = ($image->info['width'] * $scale - $width) / 2;
+ $y = ($image->info['height'] * $scale - $height) / 2;
- if (image_toolkit_invoke('resize', array($source, $destination, $info['width'] * $scale, $info['height'] * $scale))) {
- return image_toolkit_invoke('crop', array($destination, $destination, $x, $y, $width, $height));
+ if (image_resize($image, $image->info['width'] * $scale, $image->info['height'] * $scale)) {
+ return image_crop($image, $x, $y, $width, $height);
}
return FALSE;
}
/**
- * Scales an image to the given width and height while maintaining aspect
- * ratio.
+ * Scales an image to the given width and height while maintaining aspect ratio.
*
* The resulting image can be smaller for one or both target dimensions.
*
- * @param $source
- * The file path of the source image.
- * @param $destination
- * The file path of the destination image.
+ * @param $image
+ * An image object returned by image_load().
* @param $width
- * The target width, in pixels.
+ * The target width, in pixels. This value is omitted then the scaling will
+ * based only on the height value.
* @param $height
- * The target height, in pixels.
+ * The target height, in pixels. This value is omitted then the scaling will
+ * based only on the width value.
+ * @param $upscale
+ * Boolean indicating that files smaller than the dimensions will be scalled
+ * up. This generally results in a low quality image.
* @return
* TRUE or FALSE, based on success.
+ *
+ * @see image_load()
+ * @see image_scale_and_crop()
*/
-function image_scale($source, $destination, $width, $height) {
- $info = image_get_info($source);
+function image_scale(stdClass $image, $width = NULL, $height = NULL, $upscale = FALSE) {
+ $aspect = $image->info['height'] / $image->info['width'];
- // Don't scale up.
- if ($width >= $info['width'] && $height >= $info['height']) {
- return FALSE;
+ if ($upscale) {
+ // Set width/height according to aspect ratio if either is empty.
+ $width = !empty($width) ? $width : $height / $aspect;
+ $height = !empty($height) ? $height : $width / $aspect;
+ }
+ else {
+ // Set impossibly large values if the width and height aren't set.
+ $width = !empty($width) ? $width : 9999999;
+ $height = !empty($height) ? $height : 9999999;
+
+ // Don't scale up.
+ if (round($width) >= $image->info['width'] && round($height) >= $image->info['height']) {
+ return TRUE;
+ }
}
- $aspect = $info['height'] / $info['width'];
if ($aspect < $height / $width) {
- $width = (int)min($width, $info['width']);
- $height = (int)round($width * $aspect);
+ $height = $width * $aspect;
}
else {
- $height = (int)min($height, $info['height']);
- $width = (int)round($height / $aspect);
+ $width = $height / $aspect;
}
- return image_toolkit_invoke('resize', array($source, $destination, $width, $height));
+ return image_resize($image, $width, $height);
}
/**
* Resize an image to the given dimensions (ignoring aspect ratio).
*
- * @param $source
- * The file path of the source image.
- * @param $destination
- * The file path of the destination image.
+ * @param $image
+ * An image object returned by image_load().
* @param $width
* The target width, in pixels.
* @param $height
* The target height, in pixels.
- * @return
- * TRUE or FALSE, based on success.
- */
-function image_resize($source, $destination, $width, $height) {
- return image_toolkit_invoke('resize', array($source, $destination, $width, $height));
-}
-
-/**
- * Rotate an image by the given number of degrees.
- *
- * @param $source
- * The file path of the source image.
- * @param $destination
- * The file path of the destination image.
- * @param $degrees
- * The number of (clockwise) degrees to rotate the image.
- * @param $background
- * An hexadecimal integer specifying the background color to use for the
- * uncovered area of the image after the rotation. E.g. 0x000000 for black,
- * 0xff00ff for magenta, and 0xffffff for white.
+ * @param $toolkit
+ * An optional override of the default image toolkit.
* @return
* TRUE or FALSE, based on success.
+ *
+ * @see image_load()
*/
-function image_rotate($source, $destination, $degrees, $background = 0x000000) {
- return image_toolkit_invoke('rotate', array($source, $destination, $degrees, $background));
+function image_resize(stdClass $image, $width, $height) {
+ $width = (int) round($width);
+ $height = (int) round($height);
+
+ return image_toolkit_invoke('resize', $image, array($width, $height));
}
/**
* Crop an image to the rectangle specified by the given rectangle.
*
- * @param $source
- * The file path of the source image.
- * @param $destination
- * The file path of the destination image.
+ * @param $image
+ * An image object returned by image_load().
* @param $x
- * The top left co-ordinate, in pixels, of the crop area (x axis value).
+ * The top left coordinate, in pixels, of the crop area (x axis value).
* @param $y
- * The top left co-ordinate, in pixels, of the crop area (y axis value).
+ * The top left coordinate, in pixels, of the crop area (y axis value).
* @param $width
* The target width, in pixels.
* @param $height
* The target height, in pixels.
* @return
* TRUE or FALSE, based on success.
+ *
+ * @see image_load()
+ * @see image_scale_and_crop()
+ */
+function image_crop(stdClass $image, $x, $y, $width, $height) {
+ $aspect = $image->info['height'] / $image->info['width'];
+ if (empty($height)) $height = $width / $aspect;
+ if (empty($width)) $width = $height * $aspect;
+
+ $width = (int) round($width);
+ $height = (int) round($height);
+
+ return image_toolkit_invoke('crop', $image, array($x, $y, $width, $height));
+}
+
+/**
+ * Convert an image to grayscale.
+ *
+ * @param $image
+ * An image object returned by image_load().
+ * @return
+ * TRUE or FALSE, based on success.
+ *
+ * @see image_load()
+ */
+function image_desaturate(stdClass $image) {
+ return image_toolkit_invoke('desaturate', $image);
+}
+
+
+/**
+ * Load an image file and return an image object.
+ *
+ * Any changes to the file are not saved until image_save() is called.
+ *
+ * @param $file
+ * Path to an image file.
+ * @param $toolkit
+ * An optional, image toolkit name to override the default.
+ * @return
+ * An image object or FALSE if there was a problem loading the file. The
+ * image object has the following properties:
+ * - 'source' - The original file path.
+ * - 'info' - The array of information returned by image_get_info()
+ * - 'toolkit' - The name of the image toolkit requested when the image was
+ * loaded.
+ * Image tookits may add additional properties. The caller is advised not to
+ * monkey about with them.
+ *
+ * @see image_save()
+ * @see image_get_info()
+ * @see image_get_available_toolkits()
*/
-function image_crop($source, $destination, $x, $y, $width, $height) {
- return image_toolkit_invoke('crop', array($source, $destination, $x, $y, $width, $height));
+function image_load($file, $toolkit = FALSE) {
+ if (!$toolkit) {
+ $toolkit = image_get_toolkit();
+ }
+ if ($toolkit) {
+ $image = new stdClass();
+ $image->source = $file;
+ $image->info = image_get_info($file);
+ $image->toolkit = $toolkit;
+ if (image_toolkit_invoke('load', $image)) {
+ return $image;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Close the image and save the changes to a file.
+ *
+ * @param $image
+ * An image object returned by image_load(). The object's 'info' property
+ * will be updated if the file is saved successfully.
+ * @param $destination
+ * Destination path where the image should be saved. If it is empty the
+ * original image file will be overwritten.
+ * @return
+ * TRUE or FALSE, based on success.
+ *
+ * @see image_load()
+ */
+function image_save(stdClass $image, $destination = NULL) {
+ if (empty($destination)) {
+ $destination = $image->source;
+ }
+ if ($return = image_toolkit_invoke('save', $image, array($destination))) {
+ // Clear the cached file size and refresh the image information.
+ clearstatcache();
+ $image->info = image_get_info($destination);
+
+ if (@chmod($destination, 0664)) {
+ return $return;
+ }
+ watchdog('image', 'Could not set permissions on destination file: %file', array('%file' => $destination));
+ }
+ return FALSE;
}
/**