-
-
Save pqina/7a42bf0833d988dd81d3c9438009da21 to your computer and use it in GitHub Desktop.
<? | |
// Link image type to correct image loader and saver | |
// - makes it easier to add additional types later on | |
// - makes the function easier to read | |
const IMAGE_HANDLERS = [ | |
IMAGETYPE_JPEG => [ | |
'load' => 'imagecreatefromjpeg', | |
'save' => 'imagejpeg', | |
'quality' => 100 | |
], | |
IMAGETYPE_PNG => [ | |
'load' => 'imagecreatefrompng', | |
'save' => 'imagepng', | |
'quality' => 0 | |
], | |
IMAGETYPE_GIF => [ | |
'load' => 'imagecreatefromgif', | |
'save' => 'imagegif' | |
] | |
]; | |
/** | |
* @param $src - a valid file location | |
* @param $dest - a valid file target | |
* @param $targetWidth - desired output width | |
* @param $targetHeight - desired output height or null | |
*/ | |
function createThumbnail($src, $dest, $targetWidth, $targetHeight = null) { | |
// 1. Load the image from the given $src | |
// - see if the file actually exists | |
// - check if it's of a valid image type | |
// - load the image resource | |
// get the type of the image | |
// we need the type to determine the correct loader | |
$type = exif_imagetype($src); | |
// if no valid type or no handler found -> exit | |
if (!$type || !IMAGE_HANDLERS[$type]) { | |
return null; | |
} | |
// load the image with the correct loader | |
$image = call_user_func(IMAGE_HANDLERS[$type]['load'], $src); | |
// no image found at supplied location -> exit | |
if (!$image) { | |
return null; | |
} | |
// 2. Create a thumbnail and resize the loaded $image | |
// - get the image dimensions | |
// - define the output size appropriately | |
// - create a thumbnail based on that size | |
// - set alpha transparency for GIFs and PNGs | |
// - draw the final thumbnail | |
// get original image width and height | |
$width = imagesx($image); | |
$height = imagesy($image); | |
// maintain aspect ratio when no height set | |
if ($targetHeight == null) { | |
// get width to height ratio | |
$ratio = $width / $height; | |
// if is portrait | |
// use ratio to scale height to fit in square | |
if ($width > $height) { | |
$targetHeight = floor($targetWidth / $ratio); | |
} | |
// if is landscape | |
// use ratio to scale width to fit in square | |
else { | |
$targetHeight = $targetWidth; | |
$targetWidth = floor($targetWidth * $ratio); | |
} | |
} | |
// create duplicate image based on calculated target size | |
$thumbnail = imagecreatetruecolor($targetWidth, $targetHeight); | |
// set transparency options for GIFs and PNGs | |
if ($type == IMAGETYPE_GIF || $type == IMAGETYPE_PNG) { | |
// make image transparent | |
imagecolortransparent( | |
$thumbnail, | |
imagecolorallocate($thumbnail, 0, 0, 0) | |
); | |
// additional settings for PNGs | |
if ($type == IMAGETYPE_PNG) { | |
imagealphablending($thumbnail, false); | |
imagesavealpha($thumbnail, true); | |
} | |
} | |
// copy entire source image to duplicate image and resize | |
imagecopyresampled( | |
$thumbnail, | |
$image, | |
0, 0, 0, 0, | |
$targetWidth, $targetHeight, | |
$width, $height | |
); | |
// 3. Save the $thumbnail to disk | |
// - call the correct save method | |
// - set the correct quality level | |
// save the duplicate version of the image to disk | |
return call_user_func( | |
IMAGE_HANDLERS[$type]['save'], | |
$thumbnail, | |
$dest, | |
IMAGE_HANDLERS[$type]['quality'] | |
); | |
} |
After reducing the image, its size in bytes only grows.
it works !! awesome .
If you are trying to make a thumbnail of "gif" image and you are getting invalid index "quality", then go to line 17 and replace
IMAGETYPE_GIF => [ 'load' => 'imagecreatefromgif', 'save' => 'imagegif' ]
with
IMAGETYPE_GIF => [ 'load' => 'imagecreatefromgif', 'save' => 'imagegif', 'quality' => 0 ]
Example from effcore CMS/CMF (/system/module_core/backend/core.php):
namespace effcore {
abstract class core {
static function thumbnail_create($src_path, $dst_path, $dst_w = 100, $result_format = null) {
$type = @exif_imagetype($src_path);
if ($type !== false) {
if ($type == IMAGETYPE_GIF && function_exists('imagecreatefromgif' )) $src_resource = @imagecreatefromgif ($src_path);
if ($type == IMAGETYPE_JPEG && function_exists('imagecreatefromjpeg')) $src_resource = @imagecreatefromjpeg($src_path);
if ($type == IMAGETYPE_PNG && function_exists('imagecreatefrompng' )) $src_resource = @imagecreatefrompng ($src_path);
if (isset($src_resource) &&
$src_resource) {
$src_w = imagesx($src_resource);
$src_h = imagesy($src_resource);
$dst_h = (int)($src_h / ($src_w / $dst_w));
$dst_resource = @imagecreatetruecolor($dst_w, $dst_h);
@imagecolortransparent($dst_resource, imagecolorallocate($dst_resource, 0, 0, 0));
@imagealphablending ($dst_resource, $type == IMAGETYPE_GIF);
@imagesavealpha ($dst_resource, true);
if ($dst_resource) {
@imagecopyresampled($dst_resource, $src_resource, 0, 0, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
if ((($type == IMAGETYPE_PNG && $result_format == null) || $result_format == 'png' ) && function_exists('imagepng' )) $result = @imagepng ($dst_resource, $dst_path.'.png' );
if ((($type == IMAGETYPE_JPEG && $result_format == null) || $result_format == 'jpeg') && function_exists('imagejpeg')) $result = @imagejpeg($dst_resource, $dst_path.'.jpeg');
if ((($type == IMAGETYPE_GIF && $result_format == null) || $result_format == 'gif' ) && function_exists('imagegif' )) $result = @imagegif ($dst_resource, $dst_path.'.gif' );
@imagedestroy($dst_resource);
return $result ?? null;
}
}
}
}
}}
Usage:
core::thumbnail_create('/some_file.gif', '/some_file-thumb');
core::thumbnail_create('/some_file.png', '/some_file-thumb');
core::thumbnail_create('/some_file.jpg', '/some_file-thumb');
Thanks a lot for this!
On my page (https://www.pollisoft.se), is use the same thumbnail size for all image size and aspect ratios. With the following change/addition (the else statement) to your script, I avoided thumbnail image distortion when sourceRatio doesn't equal targetRatio. Feel free to include if you want.
`// maintain aspect ratio when no height set
if ($targetHeight == null) {
$startX = 0;
$startY = 0;
$src_w = width;
$src_h = height;
// get width to height ratio
$ratio = $width / $height;
// if is portrait
// use ratio to scale height to fit in square
if ($width > $height) {
$targetHeight = floor($targetWidth / $ratio);
}
// if is landscape
// use ratio to scale width to fit in square
else {
$targetHeight = $targetWidth;
$targetWidth = floor($targetWidth * $ratio);
}
} else {
// Calculate starting positions and copy area
// to not distort the thumbnail image ratio.
// get width to height ratio
$ratio = $width / $height;
$targetRatio = $targetWidth / $targetHeight;
$combinedRatio = $ratio / $targetRatio;
// Cut X wise in source to avoid thumb image distortion
if ($combinedRatio >= 1) {
$thumbRatio = $height / $targetHeight;
$startX = ($width - ($thumbRatio * $targetWidth)) / 2;
$src_w = ($thumbRatio * $targetWidth);
$startY = 0;
$src_h = $height;
}
// Cut Y wise in source to avoid thumb image distortion
else {
$thumbRatio = $width / $targetWidth;
$startY = ($height - ($thumbRatio * $targetHeight)) / 2;
$src_h = ($thumbRatio * $targetHeight);
$startX = 0;
$src_w = $width;
}
}`
Hi
I am getting error for gif images : imagegif() expects at most 2 arguments, 3 given
Thanks
the
imagegif()
function does not have third parameter so after callingcall_user_func()
on a gif img an error occurs invalid index "quality"