центр кадрирования с гравитацией с использованием Imagick и PHP

Я хочу центрировать обрезку и изображение с помощью API-интерфейса Imagick PHP (а не версии 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 говорит, что он должен применяться к объекту (в данном случае к одному изображению)...


person rynop    schedule 04.11.2011    source источник


Ответы (4)


Слишком поздно для первоначального человека, который задал вопрос, но для будущих посетителей правильное решение

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

Извините за поздний ответ, но я тоже застрял здесь всего 30 минут назад, и первый результат Google перенаправил меня сюда. Надеюсь, с другими такого не будет.

person Kapil Sharma    schedule 26.09.2012
comment
всегда ли это центр кадрирования? что, если я хочу изменить гравитацию? - person rynop; 26.09.2012
comment
Да, он всегда кадрирует с центром тяжести. На самом деле он сначала масштабирует изображение, чтобы соответствовать высоте или ширине, а затем обрезает от центра, чтобы сделать миниатюру любого изображения. Это та же логика, которую используют FB, Twitter, Google и многие другие сайты для создания миниатюр. Если вам нужно изменить гравитацию, используйте bool Imagick::cropImage ( int $width , int $height , int $x , int $y ), как определено на php.net/manual/en /imagick.cropiimage.php - person Kapil Sharma; 27.09.2012

Похоже, поддержки нет, вот как я это сделал: https://gist.github.com/1364489

person rynop    schedule 14.11.2011
comment
Как вы определяете эти вычисления? - person j0k; 05.12.2012

3-й и 4-й аргумент метода cropImage() объекта Imagemagick определяют верхний левый угол обрезки. Либо попробуйте передать их как null (и используйте метод setGravity()), либо вам, возможно, придется рассчитать, где должен происходить урожай, и вставить эти числа в метод cropImage() (и не беспокойтесь о setGravity()).

Что бы это ни стоило, я сделал много кода вокруг Imagemagick с использованием PHP, и из-за ужасной документации расширения Imagemagick я прибегал к множеству приятных вызовов командной строки.

person Crontab    schedule 04.11.2011
comment
Благодарю. нуль, нуль не работает. Я могу сделать математику, но предпочел бы использовать встроенный, если это возможно. Я хочу избежать CLI по целому ряду причин, одной из которых является производительность (я пишу сервис обработки изображений, который будет использоваться довольно интенсивно). - person rynop; 04.11.2011
comment
Основной сервис, который я написал, который использует CLI, обрабатывает пару тысяч изображений в день без сбоев и работает в Linux на процессоре Intel Core i5 760 с 4 ГБ ОЗУ, который также обслуживает пару веб-сайтов. - person Crontab; 04.11.2011
comment
Благодарю. Я решил просто посчитать, так как это заняло всего несколько минут. Я оставлю этот вопрос открытым на несколько дней, чтобы узнать, знает ли кто-нибудь, как использовать встроенную гравитацию. - person rynop; 04.11.2011

Я создал компонент для обрезки и изменения размера изображений, вот код (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

person Ivan Derkach    schedule 27.11.2018