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 ?

有帮助吗?

解决方案 2

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;
    }

其他提示

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
}

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top