使用Imagick和PHP进行重心裁剪


center crop with gravity using Imagick and PHP

我正在寻找使用Imagick PHP api(不是Imagick的命令行版本)的中心裁剪和图像。

本质上我想做什么是可能通过命令行,使用API。下面是一个通过命令行的例子:http://www.imagemagick.org/Usage/crop/crop_gravity

这是我正在做的(不工作)。它总是裁剪源代码的左上角:

        $this->imagickObj->setGravity('Imagick::GRAVITY_CENTER);
        $this->imagickObj->cropImage(300,250,0,0);
        $this->imagickObj->setImagePage(0, 0, 0, 0);

为什么setGravity不应用于裁剪前的图像?http://www.php.net/manual/en/function.imagick-setgravity.php表示它应该应用于对象(在本例中为单个图像)…

对于最初提出问题的人来说已经太晚了,但对于未来的访问者来说,正确的解决方案是

bool Imagick::cropThumbnailImage (int $width, int $height)

很抱歉回复晚了,但我也在30分钟前被困在这里,第一个谷歌结果重定向到这里。

看起来不支持,这是我最终的做法:https://gist.github.com/1364489

Imagemagick对象的cropImage()方法的第3和第4个参数定义了裁剪的左上角。要么尝试传递这些作为null(并使用setGravity()方法),或者你可能实际上必须计算作物应该发生的地方,并将这些数字弹出到cropImage()方法(并且不要打扰setGravity())。

为了它的价值,我已经用PHP围绕Imagemagick做了很多编码,并且由于Imagemagick扩展的可怕文档,我诉诸于做了很多漂亮的命令行调用。

我已经创建了裁剪和调整图像大小的组件下面是代码(yii2)

组件使用imagine/imagine扩展,在

之前安装
<?php
namespace common'components;
use Imagine'Gd'Imagine;
use Imagine'Image'Box;
use Imagine'Image'ImageInterface;
use Imagine'Image'Point;
use Imagine'Imagick'Image;
class ResizeComponent
{
    /**
     * Resize image
     * @param  string   $source         source image path
     * @param  string   $destination    destination image path
     * @param  int      $width
     * @param  int      $height
     * @param  int      $quality        Jpeg sampling quality (0-100, 80 is best for seo)
     * @return boolean                  is picture cropped
     */
    public static function resizeImage($source, $destination, $width, $height, $quality = 80)
    {
        if (file_exists($source) && is_file($source)) {
            $imagine   = new Imagine();
            $size      = new Box($width, $height);
            $mode      = ImageInterface::THUMBNAIL_INSET;
            $resizeimg = $imagine->open($source)->thumbnail($size, $mode);
            $sizeR     = $resizeimg->getSize();
            $widthR    = $sizeR->getWidth();
            $heightR   = $sizeR->getHeight();
            $preserve  = $imagine->create($size);
            $startX    = $startY    = 0;
            if ($widthR < $width) {
                $startX = ($width - $widthR) / 2;
            }
            if ($heightR < $height) {
                $startY = ($height - $heightR) / 2;
            }
            $preserve->paste($resizeimg, new Point($startX, $startY))
                ->save($destination, array('jpeg_quality' => $quality));
            return true;
        } else {
            return false;
        }
    }
    /**
     * Crop image
     * @param  string   $source         source image path
     * @param  string   $destination    destination image path
     * @param  int      $width
     * @param  int      $height
     * @param  int      $quality        Jpeg sampling quality (0-100, 80 is best for seo)
     * @return boolean                  is picture cropped
     */
    public static function cropImage($source, $destination, $width, $height, $quality = 80)
    {
        if (file_exists($source) && is_file($source)) {
            $imagine = new Imagine();
            $size    = new Box($width, $height);
            $mode    = ImageInterface::THUMBNAIL_OUTBOUND;
            $image   = $imagine->open($source)->thumbnail($size, $mode);
            $image->thumbnail($size, $mode)->save($destination, array('jpeg_quality' => $quality));
            return true;
        } else {
            return false;
        }
    }
}

裁剪和调整大小的区别是:

  • 裁剪不能显示所有图像,所以边框将被裁剪(最好是没有信息的缩略图)
  • 调整大小显示完整的图像,但边框将填充静态颜色(或透明如果需要)(最好是如果所有的图像需要显示,如在商店目录)

静态使用该组件,最佳实践为ServiceLocator