Recently, I had simple but interesting problem on wordpress where I could not find ready automatic solution: thumbnail generation based on image ratio. I use wordpress as CMS for image-heavy site.
For example, I want that 3 sized images:
- For landscape pictures I need 202×133 thumbnails
- For square (or alike) images I need 156×142 thumbnails
- For portrait images I need 120×162 thumbnails
The exact size of thumbnails matters, as I want to put these images in nice picture frames, with no spacing around. So obviously, I need a cropper that should work automatically.
WordPress itself does not provide that function. Thus I started looking for plugin as basis for such cropper. I have chosen scissors – a very nice wordpress plugin I can recommend for others. It allows user to control resizing and cropping images on upload, also it provides additional options for resizing/cropping images automatically.
However, how to make this plugin crop images depending on ratio automatically? Well, we need to hack into its source.
All modifications done are in scissors.php, scissors_resize_auto($metadata) function. We work with medium image size, as scissors does not work with thumbnails itself (we could implement this as well).
Step 1. Configuration.
We need to configure scissors to use adaptive image resize for medium sized images, or it will not pass through the function. Obviously, we can’t use inputs to define image size for all 3 cases without more serious coding, so we stop configuring there and hack into source.
Step 2. Determining image ratio.
Image ratio can be calculated at this: $ratio = $srcW/$srcH; , where $srcW is width and $srcH is height of original image. If $ratio is bigger than 1, image is landscape, in other case it is portrait. For this case we assume that ratio between 1 and 1.3 means square image, though we could use other steps.
if ($size=='medium') {
if ($ratio>1.3) {
$maxW=202;
$maxH=133;
} else if ($ratio>=1){
$maxW=156;
$maxH=142;
} else {
$maxW=120;
$maxH=162;
}
$dstH=$maxH;
$dstW=$maxW;
…..
So, we now have the image size to use and the image would be resized to exact size required. However, the image would be screwed when original image ratio would not match resized image ratio. We need to crop image as well as resize it.
Step 3. Croping the image to proper ratio.
Luckily, imagecopyresampled that is used to resize image can crop it during same operation as well. For this, we need to calculate area we need to crop in original image. First, let us initialize some variables:
$startx=0;
$starty=0;
$endy=$srcH;
$endx=$srcW;
Then,
if ($dstW/$dstH<$ratio) {
$endx=round($srcH*$dstW/$dstH);
$startx=round(($srcW-$endx)/2);
} else {
$endy=round($srcW*$dstH/$dstW);
$starty=round(($srcH-$endy)/2);
}
The only thing left is changing imagecopyresampled request to
imagecopyresampled($dst, $src, 0, 0, $startx, $starty, $dstW, $dstH, $endx, $endy)
Which crops required area from center of original image and resizes it.
That’s it. The end product is still in development and will be launched this week.
0 Comments