Better error handling for GD code

This commit is contained in:
Matthew Barbour 2019-06-12 17:40:43 -05:00
parent f9f4c3bd37
commit 97f60b3ea5
2 changed files with 113 additions and 72 deletions

View File

@ -345,12 +345,14 @@ function image_resize_gd(String $image_filename, array $info, int $new_width, in
} }
$image = imagecreatefromstring(file_get_contents($image_filename)); $image = imagecreatefromstring(file_get_contents($image_filename));
$image_resized = imagecreatetruecolor($new_width, $new_height);
if($image==false) { try {
if($image===false) {
throw new ImageResizeException("Could not load image: ".$image_filename); throw new ImageResizeException("Could not load image: ".$image_filename);
} }
if($image_resized===false) {
$image_resized = imagecreatetruecolor($new_width, $new_height); throw new ImageResizeException("Could not create output image with dimensions $new_width c $new_height ");
}
// Handle transparent images // Handle transparent images
switch($info[2]) { switch($info[2]) {
@ -365,9 +367,14 @@ function image_resize_gd(String $image_filename, array $info, int $new_width, in
// Allocate the same color in the new image resource // Allocate the same color in the new image resource
$transparency = imagecolorallocate($image_resized, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); $transparency = imagecolorallocate($image_resized, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
if($transparency===false) {
throw new ImageResizeException("Unable to allocate transparent color");
}
// Completely fill the background of the new image with allocated color. // Completely fill the background of the new image with allocated color.
imagefill($image_resized, 0, 0, $transparency); if(imagefill($image_resized, 0, 0, $transparency)===false) {
throw new ImageResizeException("Unable to fill new image with transparent color");
}
// Set the background color for new image to transparent // Set the background color for new image to transparent
imagecolortransparent($image_resized, $transparency); imagecolortransparent($image_resized, $transparency);
@ -378,15 +385,24 @@ function image_resize_gd(String $image_filename, array $info, int $new_width, in
// //
// More info here: http://stackoverflow.com/questions/279236/how-do-i-resize-pngs-with-transparency-in-php // More info here: http://stackoverflow.com/questions/279236/how-do-i-resize-pngs-with-transparency-in-php
// //
imagealphablending($image_resized, false); if(imagealphablending($image_resized, false)===false) {
imagesavealpha($image_resized, true); throw new ImageResizeException("Unable to disable image alpha blending");
}
if(imagesavealpha($image_resized, true)===false) {
throw new ImageResizeException("Unable to enable image save alpha");
}
$transparent_color = imagecolorallocatealpha($image_resized, 255, 255, 255, 127); $transparent_color = imagecolorallocatealpha($image_resized, 255, 255, 255, 127);
imagefilledrectangle($image_resized, 0, 0, $new_width, $new_height, $transparent_color); if($transparent_color===false) {
throw new ImageResizeException("Unable to allocate transparent color");
}
if(imagefilledrectangle($image_resized, 0, 0, $new_width, $new_height, $transparent_color)===false) {
throw new ImageResizeException("Unable to fill new image with transparent color");
}
break; break;
} }
// Actually resize the image. // Actually resize the image.
imagecopyresampled( if(imagecopyresampled(
$image_resized, $image_resized,
$image, $image,
0, 0,
@ -397,8 +413,11 @@ function image_resize_gd(String $image_filename, array $info, int $new_width, in
$new_height, $new_height,
$width, $width,
$height $height
); )===false) {
throw new ImageResizeException("Unable to copy resized image data to new image");
}
$result = false;
switch($output_type) { switch($output_type) {
case "bmp": case "bmp":
$result = imagebmp($image_resized, $output_filename, true); $result = imagebmp($image_resized, $output_filename, true);
@ -422,5 +441,20 @@ function image_resize_gd(String $image_filename, array $info, int $new_width, in
if($result==false) { if($result==false) {
throw new ImageResizeException("Failed to save the new image, function returned false when saving type: $output_type"); throw new ImageResizeException("Failed to save the new image, function returned false when saving type: $output_type");
} }
} finally {
imagedestroy($image);
imagedestroy($image_resized); imagedestroy($image_resized);
}
}
function is_animated_gif(String $image_filename) {
$isanigif = 0;
if (($fh = @fopen($image_filename, 'rb'))) {
//check if gif is animated (via http://www.php.net/manual/en/function.imagecreatefromgif.php#104473)
while (!feof($fh) && $isanigif < 2) {
$chunk = fread($fh, 1024 * 100);
$isanigif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
}
}
return ($isanigif == 0);
} }

View File

@ -171,8 +171,14 @@ class RotateImage extends Extension
$background_color = imagecolorallocatealpha($image, 0, 0, 0, 127); $background_color = imagecolorallocatealpha($image, 0, 0, 0, 127);
break; break;
} }
if($background_color===false) {
throw new ImageRotateException("Unable to allocate transparent color");
}
$image_rotated = imagerotate($image, $deg, $background_color); $image_rotated = imagerotate($image, $deg, $background_color);
if($image_rotated===false) {
throw new ImageRotateException("Image rotate failed");
}
/* Temp storage while we rotate */ /* Temp storage while we rotate */
$tmp_filename = tempnam(ini_get('upload_tmp_dir'), 'shimmie_rotate'); $tmp_filename = tempnam(ini_get('upload_tmp_dir'), 'shimmie_rotate');
@ -181,6 +187,7 @@ class RotateImage extends Extension
} }
/* Output to the same format as the original image */ /* Output to the same format as the original image */
$result = false;
switch ($info[2]) { switch ($info[2]) {
case IMAGETYPE_GIF: $result = imagegif($image_rotated, $tmp_filename); break; case IMAGETYPE_GIF: $result = imagegif($image_rotated, $tmp_filename); break;
case IMAGETYPE_JPEG: $result = imagejpeg($image_rotated, $tmp_filename); break; case IMAGETYPE_JPEG: $result = imagejpeg($image_rotated, $tmp_filename); break;
@ -191,7 +198,7 @@ class RotateImage extends Extension
throw new ImageRotateException("Unsupported image type."); throw new ImageRotateException("Unsupported image type.");
} }
if($result==false) { if($result===false) {
throw new ImageRotateException("Could not save image: ".$tmp_filename); throw new ImageRotateException("Could not save image: ".$tmp_filename);
} }