【问题标题】:How to pad thumbnails with imagine library如何使用想象库填充缩略图
【发布时间】:2013-09-17 07:53:46
【问题描述】:

我正在使用想象库为图像创建缩略图。就这么简单。

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

该库提供两种模式:插入和出站。在插入模式下,图像会缩小,但不会填充缩略图大小。所以我需要填充它以填充目标大小。有没有使用库函数的简单方法?

【问题讨论】:

    标签: php php-imagine


    【解决方案1】:

    如果您不想“缩放”缩略图以适应大小,则必须裁剪图像。对于裁剪,你必须找到准确的起点,这需要一点努力。

    编写自定义方法来找到精确的裁剪点、调整大小并返回新图像是个好主意。 Imagine 是一个非常好的库,它提供了我们需要的所有方法。

    要遵循的步骤:

    1. 使用 getSize() 获取原始图像的尺寸
    2. 通过比较宽度和高度来检测图像的方向。
    3. 然后按方向找到准确的裁剪点,您需要在不“缩放”的情况下适应新缩略图:
      • 如果是横向,则使用目标框的宽度找到目标宽度
      • 否则使用高度。
    4. 使用 THUMBNAIL_OUTBOUND 调整图像大小并创建“小大缩略图”。
    5. 使用您之前找到的裁剪点裁剪调整大小的图像。
    6. 返回图片实例。

    伪代码:

    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
    }
    

    【讨论】:

    • 当使用 OUTBOUND 模式时,它已经裁剪了缩略图,所以我没有任何问题。在 INSET 模式下,它会缩小图像的大小,但它不会填满整个缩略图区域,所以我需要填充。感谢您的帮助。
    • 我已将问题编辑为在源代码中使用“插入”模式。这是“出境”。但是在问题中,我解释说问题出在“插入”模式。
    【解决方案2】:

    我已经设法使用以下功能填充缩略图。

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

    【讨论】:

    • 较小的图像仍然存在问题,不会放大,但会在两侧填充。我知道这不是问题的一部分,但是知道如何解决这个问题+应用这个填充吗?
    • 我必须将函数参数 \Imagine\Gd\Imagine $img 更改为 \Imagine\Gd\Image $img 才能使其工作
    【解决方案3】:

    foozy,感谢您的评论,它对我帮助很大! 但对我来说,这样做效果更好:

    $img->resize($tempBox);
    

    而不是这个:

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

    也许它会对某人有所帮助。

    【讨论】:

    • 我认为 resize() 函数不能保持纵横比
    猜你喜欢
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 2021-02-20
    • 1970-01-01
    相关资源
    最近更新 更多