2007-08-02 20:19:02 +00:00
< ? php
/**
* @ file
* GD2 toolkit for image manipulation within Drupal .
*/
/**
2012-05-17 12:58:49 +00:00
* @ addtogroup image
2007-08-02 20:19:02 +00:00
* @ {
*/
/**
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Returns GD - specific image toolkit settings .
*
* This function verifies that the GD PHP extension is installed . If it is not ,
* a form error message is set , informing the user about the missing extension .
*
* The form elements returned by this function are integrated into the form
* built by system_image_toolkit_settings () .
*
* @ return
* An array of Form API elements to be added to the form .
*
* @ see hook_image_toolkits ()
* @ see system_image_toolkit_settings ()
2007-08-02 20:19:02 +00:00
*/
function image_gd_settings () {
if ( image_gd_check_settings ()) {
$form [ 'status' ] = array (
2008-07-16 21:59:29 +00:00
'#markup' => t ( 'The GD toolkit is installed and working properly.' )
2007-08-02 20:19:02 +00:00
);
$form [ 'image_jpeg_quality' ] = array (
2012-04-19 11:31:47 +00:00
'#type' => 'number' ,
2007-08-02 20:19:02 +00:00
'#title' => t ( 'JPEG quality' ),
'#description' => t ( 'Define the image quality for JPEG manipulations. Ranges from 0 to 100. Higher values mean better image quality but bigger files.' ),
2012-04-19 11:31:47 +00:00
'#min' => 0 ,
'#max' => 100 ,
2007-08-02 20:19:02 +00:00
'#default_value' => variable_get ( 'image_jpeg_quality' , 75 ),
'#field_suffix' => t ( '%' ),
);
2008-02-06 19:38:28 +00:00
2007-08-02 20:19:02 +00:00
return $form ;
}
else {
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' )));
return FALSE ;
}
}
/**
2012-10-04 15:28:39 +00:00
* Verifies GD2 settings ( that the right version is actually installed ) .
2007-08-02 20:19:02 +00:00
*
* @ return
2012-10-04 15:28:39 +00:00
* A Boolean indicating whether the correct version of the GD toolkit is
* available on this machine .
*
* @ see image_gd_settings ()
* @ see system_image_toolkits ()
2007-08-02 20:19:02 +00:00
*/
function image_gd_check_settings () {
if ( $check = get_extension_funcs ( 'gd' )) {
if ( in_array ( 'imagegd2' , $check )) {
// GD2 support is available.
return TRUE ;
}
}
return FALSE ;
}
/**
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Scales an image to the specified size using GD .
2009-03-09 11:44:54 +00:00
*
* @ param $image
* An image object . The $image -> resource , $image -> info [ 'width' ], and
* $image -> info [ 'height' ] values will be modified by this call .
* @ param $width
* The new width of the resized image , in pixels .
* @ param $height
* The new height of the resized image , in pixels .
2012-10-04 15:28:39 +00:00
*
2009-03-09 11:44:54 +00:00
* @ return
* TRUE or FALSE , based on success .
*
2012-10-04 15:28:39 +00:00
* @ see hook_image_toolkits ()
2009-03-09 11:44:54 +00:00
* @ see image_resize ()
2007-08-02 20:19:02 +00:00
*/
2009-03-09 11:44:54 +00:00
function image_gd_resize ( stdClass $image , $width , $height ) {
$res = image_gd_create_tmp ( $image , $width , $height );
2007-08-02 20:19:02 +00:00
2009-03-09 11:44:54 +00:00
if ( ! imagecopyresampled ( $res , $image -> resource , 0 , 0 , 0 , 0 , $width , $height , $image -> info [ 'width' ], $image -> info [ 'height' ])) {
2007-08-02 20:19:02 +00:00
return FALSE ;
}
2009-03-09 11:44:54 +00:00
imagedestroy ( $image -> resource );
// Update image object.
$image -> resource = $res ;
$image -> info [ 'width' ] = $width ;
$image -> info [ 'height' ] = $height ;
return TRUE ;
2007-08-02 20:19:02 +00:00
}
2009-03-10 09:43:01 +00:00
/**
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Rotates an image a specified number of degrees .
2009-03-10 09:43:01 +00:00
*
* @ param $image
* An image object . The $image -> resource , $image -> info [ 'width' ], and
* $image -> info [ 'height' ] values will be modified by this call .
* @ param $degrees
* The number of ( clockwise ) degrees to rotate the image .
* @ param $background
2012-10-04 15:28:39 +00:00
* ( optional ) A 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 . For images that
* support transparency , this will default to transparent . Otherwise it will
2009-03-10 09:43:01 +00:00
* be white .
2012-10-04 15:28:39 +00:00
*
2009-03-10 09:43:01 +00:00
* @ return
* TRUE or FALSE , based on success .
*
* @ see image_rotate ()
*/
function image_gd_rotate ( stdClass $image , $degrees , $background = NULL ) {
// PHP installations using non-bundled GD do not have imagerotate.
2009-08-24 00:14:23 +00:00
if ( ! function_exists ( 'imagerotate' )) {
2009-03-10 09:43:01 +00:00
watchdog ( 'image' , 'The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.' , array ( '%file' => $image -> source ));
return FALSE ;
}
$width = $image -> info [ 'width' ];
$height = $image -> info [ 'height' ];
// Convert the hexadecimal background value to a color index value.
if ( isset ( $background )) {
$rgb = array ();
for ( $i = 16 ; $i >= 0 ; $i -= 8 ) {
$rgb [] = (( $background >> $i ) & 0xFF );
}
$background = imagecolorallocatealpha ( $image -> resource , $rgb [ 0 ], $rgb [ 1 ], $rgb [ 2 ], 0 );
}
// Set the background color as transparent if $background is NULL.
else {
// Get the current transparent color.
$background = imagecolortransparent ( $image -> resource );
// If no transparent colors, use white.
if ( $background == 0 ) {
$background = imagecolorallocatealpha ( $image -> resource , 255 , 255 , 255 , 0 );
}
}
2010-01-25 10:38:35 +00:00
// Images are assigned a new color palette when rotating, removing any
2009-03-10 09:43:01 +00:00
// transparency flags. For GIF images, keep a record of the transparent color.
if ( $image -> info [ 'extension' ] == 'gif' ) {
$transparent_index = imagecolortransparent ( $image -> resource );
if ( $transparent_index != 0 ) {
$transparent_gif_color = imagecolorsforindex ( $image -> resource , $transparent_index );
}
}
$image -> resource = imagerotate ( $image -> resource , 360 - $degrees , $background );
// GIFs need to reassign the transparent color after performing the rotate.
if ( isset ( $transparent_gif_color )) {
$background = imagecolorexactalpha ( $image -> resource , $transparent_gif_color [ 'red' ], $transparent_gif_color [ 'green' ], $transparent_gif_color [ 'blue' ], $transparent_gif_color [ 'alpha' ]);
imagecolortransparent ( $image -> resource , $background );
}
$image -> info [ 'width' ] = imagesx ( $image -> resource );
$image -> info [ 'height' ] = imagesy ( $image -> resource );
return TRUE ;
}
2007-08-02 20:19:02 +00:00
/**
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Crops an image using the GD toolkit .
2009-03-09 11:44:54 +00:00
*
* @ param $image
* An image object . The $image -> resource , $image -> info [ 'width' ], and
* $image -> info [ 'height' ] values will be modified by this call .
* @ param $x
* The starting x offset at which to start the crop , in pixels .
* @ param $y
* The starting y offset at which to start the crop , in pixels .
* @ param $width
* The width of the cropped area , in pixels .
* @ param $height
* The height of the cropped area , in pixels .
2012-10-04 15:28:39 +00:00
*
2009-03-09 11:44:54 +00:00
* @ return
* TRUE or FALSE , based on success .
*
2012-10-04 15:28:39 +00:00
* @ see hook_image_toolkits ()
2009-03-09 11:44:54 +00:00
* @ see image_crop ()
2007-08-02 20:19:02 +00:00
*/
2009-03-09 11:44:54 +00:00
function image_gd_crop ( stdClass $image , $x , $y , $width , $height ) {
$res = image_gd_create_tmp ( $image , $width , $height );
2007-08-02 20:19:02 +00:00
2009-03-09 11:44:54 +00:00
if ( ! imagecopyresampled ( $res , $image -> resource , 0 , 0 , $x , $y , $width , $height , $width , $height )) {
2007-08-02 20:19:02 +00:00
return FALSE ;
}
2009-03-09 11:44:54 +00:00
// Destroy the original image and return the modified image.
imagedestroy ( $image -> resource );
$image -> resource = $res ;
$image -> info [ 'width' ] = $width ;
$image -> info [ 'height' ] = $height ;
return TRUE ;
2007-08-02 20:19:02 +00:00
}
/**
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Converts an image to grayscale using the GD toolkit .
2009-03-09 11:44:54 +00:00
*
* Note that transparent GIFs loose transparency when desaturated .
*
* @ param $image
* An image object . The $image -> resource value will be modified by this call .
2012-10-04 15:28:39 +00:00
*
2009-03-09 11:44:54 +00:00
* @ return
* TRUE or FALSE , based on success .
*
2012-10-04 15:28:39 +00:00
* @ see hook_image_toolkits ()
2009-03-09 11:44:54 +00:00
* @ see image_desaturate ()
2007-08-02 20:19:02 +00:00
*/
2009-03-09 11:44:54 +00:00
function image_gd_desaturate ( stdClass $image ) {
2009-03-10 09:43:01 +00:00
// PHP installations using non-bundled GD do not have imagefilter.
2009-08-24 00:14:23 +00:00
if ( ! function_exists ( 'imagefilter' )) {
2009-07-21 00:07:41 +00:00
watchdog ( 'image' , 'The image %file could not be desaturated because the imagefilter() function is not available in this PHP installation.' , array ( '%file' => $image -> source ));
2009-03-10 09:43:01 +00:00
return FALSE ;
}
2009-03-09 11:44:54 +00:00
return imagefilter ( $image -> resource , IMG_FILTER_GRAYSCALE );
2007-08-02 20:19:02 +00:00
}
/**
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Creates a GD image resource from a file .
2007-08-02 20:19:02 +00:00
*
2009-03-09 11:44:54 +00:00
* @ param $image
* An image object . The $image -> resource value will populated by this call .
2012-10-04 15:28:39 +00:00
*
2007-08-02 20:19:02 +00:00
* @ return
2009-03-09 11:44:54 +00:00
* TRUE or FALSE , based on success .
*
2012-10-04 15:28:39 +00:00
* @ see hook_image_toolkits ()
2009-03-09 11:44:54 +00:00
* @ see image_load ()
2007-08-02 20:19:02 +00:00
*/
2009-03-09 11:44:54 +00:00
function image_gd_load ( stdClass $image ) {
$extension = str_replace ( 'jpg' , 'jpeg' , $image -> info [ 'extension' ]);
2009-05-24 17:39:35 +00:00
$function = 'imagecreatefrom' . $extension ;
2012-06-05 05:48:01 +00:00
if ( function_exists ( $function ) && $image -> resource = $function ( $image -> source )) {
if ( ! imageistruecolor ( $image -> resource )) {
// Convert indexed images to true color, so that filters work
// correctly and don't result in unnecessary dither.
$new_image = image_gd_create_tmp ( $image , $image -> info [ 'width' ], $image -> info [ 'height' ]);
imagecopy ( $new_image , $image -> resource , 0 , 0 , 0 , 0 , $image -> info [ 'width' ], $image -> info [ 'height' ]);
imagedestroy ( $image -> resource );
$image -> resource = $new_image ;
}
return ( bool ) $image -> resource ;
}
return FALSE ;
2007-08-02 20:19:02 +00:00
}
/**
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Writes an image resource to a destination file .
2007-08-02 20:19:02 +00:00
*
2009-03-09 11:44:54 +00:00
* @ param $image
* An image object .
2007-08-02 20:19:02 +00:00
* @ param $destination
2010-09-21 15:28:11 +00:00
* A string file URI or path where the image should be saved .
2012-10-04 15:28:39 +00:00
*
2007-08-02 20:19:02 +00:00
* @ return
2009-03-09 11:44:54 +00:00
* TRUE or FALSE , based on success .
*
2012-10-04 15:28:39 +00:00
* @ see hook_image_toolkits ()
2009-03-09 11:44:54 +00:00
* @ see image_save ()
2007-08-02 20:19:02 +00:00
*/
2009-03-09 11:44:54 +00:00
function image_gd_save ( stdClass $image , $destination ) {
2010-09-21 15:28:11 +00:00
$scheme = file_uri_scheme ( $destination );
// Work around lack of stream wrapper support in imagejpeg() and imagepng().
if ( $scheme && file_stream_wrapper_valid_scheme ( $scheme )) {
// If destination is not local, save image to temporary local file.
$local_wrappers = file_get_stream_wrappers ( STREAM_WRAPPERS_LOCAL );
if ( ! isset ( $local_wrappers [ $scheme ])) {
$permanent_destination = $destination ;
$destination = drupal_tempnam ( 'temporary://' , 'gd_' );
}
// Convert stream wrapper URI to normal path.
$destination = drupal_realpath ( $destination );
2009-08-17 19:14:42 +00:00
}
2010-01-30 07:59:26 +00:00
2009-03-09 11:44:54 +00:00
$extension = str_replace ( 'jpg' , 'jpeg' , $image -> info [ 'extension' ]);
2009-05-24 17:39:35 +00:00
$function = 'image' . $extension ;
2009-03-09 11:44:54 +00:00
if ( ! function_exists ( $function )) {
2007-08-02 20:19:02 +00:00
return FALSE ;
}
if ( $extension == 'jpeg' ) {
2010-09-21 15:28:11 +00:00
$success = $function ( $image -> resource , $destination , variable_get ( 'image_jpeg_quality' , 75 ));
2007-08-02 20:19:02 +00:00
}
else {
2009-03-09 11:44:54 +00:00
// Always save PNG images with full transparency.
if ( $extension == 'png' ) {
imagealphablending ( $image -> resource , FALSE );
imagesavealpha ( $image -> resource , TRUE );
}
2010-09-21 15:28:11 +00:00
$success = $function ( $image -> resource , $destination );
}
// Move temporary local file to remote destination.
if ( isset ( $permanent_destination ) && $success ) {
return ( bool ) file_unmanaged_move ( $destination , $permanent_destination , FILE_EXISTS_REPLACE );
2007-08-02 20:19:02 +00:00
}
2010-09-21 15:28:11 +00:00
return $success ;
2007-08-02 20:19:02 +00:00
}
2009-03-09 11:44:54 +00:00
/**
2012-10-04 15:28:39 +00:00
* Creates a truecolor image preserving transparency from a provided image .
2009-03-09 11:44:54 +00:00
*
* @ param $image
* An image object .
* @ param $width
* The new width of the new image , in pixels .
* @ param $height
* The new height of the new image , in pixels .
2012-10-04 15:28:39 +00:00
*
2009-03-09 11:44:54 +00:00
* @ return
* A GD image handle .
*/
function image_gd_create_tmp ( stdClass $image , $width , $height ) {
$res = imagecreatetruecolor ( $width , $height );
if ( $image -> info [ 'extension' ] == 'gif' ) {
// Grab transparent color index from image resource.
$transparent = imagecolortransparent ( $image -> resource );
if ( $transparent >= 0 ) {
// The original must have a transparent color, allocate to the new image.
$transparent_color = imagecolorsforindex ( $image -> resource , $transparent );
$transparent = imagecolorallocate ( $res , $transparent_color [ 'red' ], $transparent_color [ 'green' ], $transparent_color [ 'blue' ]);
// Flood with our new transparent color.
imagefill ( $res , 0 , 0 , $transparent );
imagecolortransparent ( $res , $transparent );
}
}
elseif ( $image -> info [ 'extension' ] == 'png' ) {
imagealphablending ( $res , FALSE );
$transparency = imagecolorallocatealpha ( $res , 0 , 0 , 0 , 127 );
imagefill ( $res , 0 , 0 , $transparency );
imagealphablending ( $res , TRUE );
imagesavealpha ( $res , TRUE );
}
else {
imagefill ( $res , 0 , 0 , imagecolorallocate ( $res , 255 , 255 , 255 ));
}
return $res ;
}
2009-09-01 17:49:11 +00:00
/**
* Get details about an image .
2012-10-04 15:28:39 +00:00
* Image toolkit callback : Retrieves details about an image .
2009-09-01 17:49:11 +00:00
*
* @ param $image
* An image object .
2012-10-04 15:28:39 +00:00
*
2009-09-01 17:49:11 +00:00
* @ 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 .
* - " extension " : Commonly used file extension for the image .
* - " mime_type " : MIME type ( 'image/jpeg' , 'image/gif' , 'image/png' ) .
*
2012-10-04 15:28:39 +00:00
* @ see hook_image_toolkits ()
2009-09-01 17:49:11 +00:00
* @ see image_get_info ()
*/
function image_gd_get_info ( stdClass $image ) {
$details = FALSE ;
2011-06-30 05:31:12 +00:00
$data = getimagesize ( $image -> source );
2009-09-01 17:49:11 +00:00
if ( isset ( $data ) && is_array ( $data )) {
$extensions = array ( '1' => 'gif' , '2' => 'jpg' , '3' => 'png' );
2010-10-28 02:27:09 +00:00
$extension = isset ( $extensions [ $data [ 2 ]]) ? $extensions [ $data [ 2 ]] : '' ;
2009-09-01 17:49:11 +00:00
$details = array (
'width' => $data [ 0 ],
'height' => $data [ 1 ],
'extension' => $extension ,
'mime_type' => $data [ 'mime' ],
);
}
return $details ;
}
2007-08-02 20:19:02 +00:00
/**
2012-05-17 12:58:49 +00:00
* @ } End of " addtogroup image " .
2007-08-02 20:19:02 +00:00
*/