You have to crop your image if you don't want to "scale" thumbnails to fit. For cropping, you have to find exact starting points and it requires a little bit effort.
Writing a custom method to find exact cropping point, resize and return the new image is good idea. Imagine is really good library, it provides all methods we need.
Steps to follow:
- Get the original image's dimensions using getSize()
- Detect orientation of the image by comparing width and height.
- Then find the exact crop point by orientation which you need to fit your new thumbnail without "scaling":
- If it's landscape, find target width by using target box's width
- Otherwise by using height.
- Resize image using THUMBNAIL_OUTBOUND and create a "little big thumbnail".
- Crop resized image using the cropping points which you find before.
- Return the image instance.
Pseudo code:
function resizeToFit( $targetWidth, $targetHeight, $sourceFilename )
{
// Box is Imagine Box instance
// Point is Imagine Point instance
$target = new Box($targetWidth, $targetHeight );
$originalImage = imagine->open( $sourceFilename );
$orgSize = $originalImage->getSize();
if ($orgSize->width > $orgSize->height) {
// Landscaped.. We need to crop image by horizontally
$w = $orgSize->width * ( $target->height / $orgSize->height );
$h = $target->height;
$cropBy = new Point( ( max ( $w - $target->width, 0 ) ) / 2, 0);
} else {
// Portrait..
$w = $target->width; // Use target box's width and crop vertically
$h = $orgSize->height * ( $target->width / $orgSize->width );
$cropBy = new Point( 0, ( max( $h - $target->height , 0 ) ) / 2);
}
$tempBox = Box($w, $h);
$img = $originalImage->thumbnail($tempBox, ImageInterface::THUMBNAIL_OUTBOUND);
// Here is the magic..
return $img->crop($cropBy, $target); // Return "ready to save" final image instance
}