Search code examples
phpimagick

You cannot crop in Imagick twice - you have to use setImagePage otherwise you will see odd Behaviour


I am writing a function to parse SVG's into 300 dpi PNG's and JPG's for print. It has been a painful process but I am at the end of it but I am hitting the wall on a very simple step.

I have my print ready file on a square canvas which I am going to crop to give me the final print file cropped to size. But when I load the file, and crop it the output file is the correct width of 2238px but it is only 213px in height instead of 1019px.

Here is my code:

$crop_me = new \Imagick($canvas_file);

$log .= "---------------------------------------<br/>";
$log .= "CHECK WIDTH: " . $crop_me->getImageWidth() . "<br/>";
$log .= "CHECK HEIGHT: " . $crop_me->getImageHeight() . "<br/>";
$log .= "---------------------------------------<br/>";

$log .= "------------  CROPPED     -------------<br/>";
$log .= "CROP WIDTH: " . $area_width . "<br/>";
$log .= "CROP HEIGHT: " . $area_height . "<br/>";
$log .= "CROP X: " . $area_x . "<br/>";
$log .= "CROP Y: " . $area_y . "<br/>";
$log .= "---------------------------------------<br/>";

$crop_me->cropImage($area_width,$area_height,$area_x,$area_y);
$croparea_filePath = $printfile_folder.str_replace(".xml",".".$position->fileoutput."","AREA_CROP_".$filename);
$crop_me->writeImage($croparea_filePath);

$crop_me = new \Imagick($croparea_filePath);

$log .= "---------------------------------------<br/>";
$log .= "CHECK WIDTH: " . $crop_me->getImageWidth() . "<br/>";
$log .= "CHECK HEIGHT: " . $crop_me->getImageHeight() . "<br/>";
$log .= "---------------------------------------<br/>";

Here is the output:

---------------------------------------
CHECK WIDTH: 2858
CHECK HEIGHT: 1134
---------------------------------------
------------ CROPPED -------------
CROP WIDTH: 2238
CROP HEIGHT: 1019
CROP X: 311
CROP Y: 56
---------------------------------------
---------------------------------------
CHECK WIDTH: 2238
CHECK HEIGHT: 213
---------------------------------------

This is the image I am attempting to crop:

enter image description here

But this is what I get:

enter image description here

Nothing else in my code is giving me the impression there are issues with Imagick etc. I've been able to create that image using the SVG data and rotate position the images successfully and composite and crop from the square image but this step is failing...

Am I missing something would someone be able to try this for me?

I don't think memory is a problem? But I'm not getting errors. I'm running this in Laravel, I've tried moving it out and doing a raw test but it gives the same outcome.

Below is that code with hardcoded crop dimensions - if anyone was willing to test this for me on their systems?

<?php

$masklayerbg_filePath ='/var/www/MATRIX_FINAL_CROPPED_CLIPPATH_11_SVG_6_12.png';

$crop_me = new Imagick($masklayerbg_filePath);

$area_width = 2238;
$area_height = 1019;
$area_x = 311;
$area_y = 56;

$log .= "---------------------------------------<br/>";
$log .= "CHECK WIDTH: " . $crop_me->getImageWidth() . "<br/>";
$log .= "CHECK HEIGHT: " . $crop_me->getImageHeight() . "<br/>";
$log .= "---------------------------------------<br/>";

$log .= "------------  CROPPED     -------------<br/>";
$log .= "CROP WIDTH: " . $area_width . "<br/>";
$log .= "CROP HEIGHT: " . $area_height . "<br/>";
$log .= "CROP X: " . $area_x . "<br/>";
$log .= "CROP Y: " . $area_y . "<br/>";
$log .= "---------------------------------------<br/>";

$crop_me->cropImage($area_width,$area_height,$area_x,$area_y);
$croparea_filePath = '/var/www/AREA_CROP_SVG_6_12.jpg';
$crop_me->writeImage($croparea_filePath);

$crop_me = new Imagick($croparea_filePath);

$log .= "---------------------------------------<br/>";
$log .= "CHECK WIDTH: " . $crop_me->getImageWidth() . "<br/>";
$log .= "CHECK HEIGHT: " . $crop_me->getImageHeight() . "<br/>";
$log .= "---------------------------------------<br/>";

echo $log;

?>

UPDATE 1

Whilst writing the question I decided to try a different file and it works, in looking at the image that isn't working I think the 213px corresponds to the start of the rotated images in the file - but as it turns out that is incorrect.

I solved the problem I will post an answer now.


Solution

  • Right - I went back in my code and when I removed the original crop to convert the base image to the correct size it then worked - but why was it causing the issue?

    When cropping an image, it leaves the image with an 'image page' set to it, which is a way of offsetting the image that needs to be displayed from the full size of the image.

    To fix this you can call setImage($width,$height,$x,$y which resets the 'image page' to be the size you just cropped it to. This needs to be called each time you crop the image so that the next crop is being carried out on the correct dimensions.