3

I am using imagine library to create thumbnails for images. It is as simple as this.

$size = new \Imagine\Image\Box(240, 180);
$imagine->open($source_path)->thumbnail($size, 'inset')->save($target_path);

the library provides two modes : inset and outbound. in inset mode the image is resized down but it does not fill the thumbnail size. So I need to pad it to fill the target size. Is there an easy way to do this using library functions ?

bkilinc
  • 989
  • 2
  • 13
  • 28

3 Answers3

6

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:

  1. Get the original image's dimensions using getSize()
  2. Detect orientation of the image by comparing width and height.
  3. 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.
  4. Resize image using THUMBNAIL_OUTBOUND and create a "little big thumbnail".
  5. Crop resized image using the cropping points which you find before.
  6. 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
}
edigu
  • 9,878
  • 5
  • 57
  • 80
  • when using OUTBOUND mode it allready crops the thumbnail so I have no problems with it. In INSET mode it resizes the image down , but it does not fill the whole thumbnail area so I need padding. Thanks for your help. – bkilinc Sep 17 '13 at 08:57
  • I have edited my question to have 'inset' mode in the source. It was 'outbound'. However in the question, I explained that the problem was with 'inset' mode. – bkilinc Sep 17 '13 at 09:01
1

I have managed to pad thumbnails with following function.

function pad(\Imagine\Gd\Imagine $img, \Imagine\Image\Box $size, $fcolor='#000', $ftransparency = 100)
    {
        $tsize = $img->getSize();
        $x = $y = 0;
        if ($size->getWidth() > $tsize->getWidth()) {
            $x =  round(($size->getWidth() - $tsize->getWidth()) / 2);
        } elseif ($size->getHeight() > $tsize->getHeight()) {
            $y = round(($size->getHeight() - $tsize->getHeight()) / 2);
        }
        $pasteto = new \Imagine\Image\Point($x, $y);
        $imagine = new \Imagine\Gd\Imagine();
        $color = new \Imagine\Image\Color($fcolor, $ftransparency);
        $image = $imagine->create($size, $color);

        $image->paste($img, $pasteto);

        return $image;
    }
bkilinc
  • 989
  • 2
  • 13
  • 28
  • there is still a problem with smaller images what will not be upscaled, but will be padded on both sides. i know this was not part of the question, but any idea how to solve that + apply this padding? – gondo Nov 27 '14 at 17:33
  • I had to change function parameter \Imagine\Gd\Imagine $img to \Imagine\Gd\Image $img to make it work – Axi May 21 '15 at 10:12
0

foozy, thanks for your comment, it helped me a lot! But for me better worked this:

$img->resize($tempBox);

Instead of this:

 $img = $originalImage->thumbnail($tempBox, ImageInterface::THUMBNAIL_OUTBOUND);

Maybe it will help somebody.

Shimmy
  • 35
  • 1
  • 5