Last active
June 29, 2023 18:13
-
-
Save pqina/7a42bf0833d988dd81d3c9438009da21 to your computer and use it in GitHub Desktop.
Create thumbnails with PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
// 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'] | |
); | |
} |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example from effcore CMS/CMF (/system/module_core/backend/core.php):
Usage: