12

I'm looking to center crop and image using Imagick PHP apis (not command line version of Imagick).

Essentially I want to do what is possible via command line, using API. Here is an example via command line: http://www.imagemagick.org/Usage/crop/#crop_gravity

Here is what I'm doing (not working). It always crops the upper left corner of the source:

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

Why is the setGravity not applying to the image before the crop? http://www.php.net/manual/en/function.imagick-setgravity.php says it should apply to the object (in this case the single image)...

rynop
  • 50,086
  • 26
  • 101
  • 112

4 Answers4

17

Its too late for the original person who asked the question but for future visitors, correct solution is

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

Sorry for late reply but I too stuck here just 30 mins ago and first google result redirected me here. Hope same will not happen with others.

Kapil Sharma
  • 10,135
  • 8
  • 37
  • 66
  • 2
    does this always center crop? what if I want to change the gravity? – rynop Sep 26 '12 at 15:25
  • 1
    Yes, it always crop with centre gravity. Actually it first scale image to match height or width and then crop from centre to make thumbnail of any image. This is the same logic used by FB, twitter, google and many other sites to create thumbnails. If you need to change the gravity, use `bool Imagick::cropImage ( int $width , int $height , int $x , int $y )` as defined at http://php.net/manual/en/imagick.cropimage.php – Kapil Sharma Sep 27 '12 at 06:41
4

Looks like there is not support, here is how I ended up doing it: https://gist.github.com/1364489

rynop
  • 50,086
  • 26
  • 101
  • 112
0

I have created component to crop and resize images here is the code (yii2)

Component uses imagine/imagine extension, install it before

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

The difference between crop and resize is :

  • crop cant display all image, so borders will be cropped (best for not informative thumbnails)
  • resize displays full image, but borders will be filled with static color (or transperency if needed) (best if all image needed to be shown, as in shop catalog)

Use this component statically, best practice as ServiceLocator

0

The Imagemagick object's cropImage() method's 3rd and 4th argument are defining the upper-left corner of the crop. Either try passing those as null (and use the setGravity() method), or you may actually have to calculate where the crop is supposed to take place and pop those numbers into the cropImage() method (and don't bother with setGravity()).

For what it's worth, I have done a lot of coding around Imagemagick using PHP, and due to the horrible documentation of the Imagemagick extension, I resorted to making lots of nice'd command line calls.

WWW
  • 9,734
  • 1
  • 29
  • 33
  • thanks. null,null does not work. I can do the math, but would prefer to leverage built in if possible. I want to avoid going CLI for a bunch of reasons, one of which is performance (im writing an image manipulation service that will be used fairly heavily). – rynop Nov 04 '11 at 18:30
  • The main service that I wrote that uses the CLI processes a couple thousand images a day without a hiccup, and it runs on Linux on an Intel Core i5 760 with 4GB RAM that also serves a couple web sites. – WWW Nov 04 '11 at 19:00
  • thanks. I decided to just do the math as it only took a few minutes. Gonna leave this question open for a few days to see if anyone knows of a way to use the built-in gravity. – rynop Nov 04 '11 at 19:46