Reputation: 500
I am trying to create an image gallery. I want to try this time with PHP Image Magick.
When a file is uploaded I want it to be resized to 1024x724. If the image is vertical (width < height ) I want it to be fitted in the center of the image and transparent background ( or white if not possible ) at both sides where should be blank, so the image can be always 1024x724 and the aspect radio to be kept.
Same applies if the image is horizontal ( width > height ).
Here is my code so far:
$img = new Imagick($targetFile);
$img->scaleImage(1024,724);
$img->setGravity(imagick::GRAVITY_CENTER);
$img->setImageBackgroundColor('white');
$img->extentImage(1024,724,0,0);
$img->writeImage($targetFile);
$img = new Imagick($targetFile);
$img->scaleImage(150,150);
$img->setGravity(imagick::GRAVITY_CENTER);
$img->setImageBackgroundColor('white');
$img->extentImage(150,150,0,0);
$img->writeImage($targetThumb);
Upvotes: 6
Views: 8375
Reputation: 4029
If I am understanding what you want correctly, you are already part way there. Right now if you try to use a transparent PNG (source and destination), instead of a jpeg, it'll flatten the image and make the background solid white, and you do not want this correct?
What you'll need to do is determine if the image has, or might have, transparency and then set the background color to None. -extent
flattens images, so to preserve the transparency the background will need to be None
in those cases. (And, as mentioned, you will of course need to use png or gif output rather than jpg as jpeg can't handle transparency.) Normally I would do simple extension checking as it's good enough most of the time, but there are more detailed checks.
$background = preg_match('/\.gif$|\.png$/', $thumbnailFilename) == 1 ? 'None' : 'white';
$edge = shell_exec("convert $imgFile -resize 1024x724 -background $background -gravity center -extent 1024x724 -quality 90 $thumbnailFilename");
I check the output thumbnail here because if you are outputting to a jpeg, regardless of the source, it's going to be stripped of transparency. With this, if you provide $imgFile
as test-transparent1.png and $thumbnailFilename
as test-transparent1.sized.png, test-transparent1.sized.png should come out being sized to fit 1024x724 and padded with transparent pixels so the original image is centered.
==Edit for ImageMagick PHP class:==
First, in order to do a proportional scale, you'll need to set the bestfit parameter of scaleImage to true. Additionally, it appears that extentImage doesn't use the gravity option at all when you use the API, so we have to use negative X or Y offsets to properly center the image on the new canvas. Here's what my test script looked like once I got it working:
<?php
$targetFile = 'mizu.png';
$targetThumb = 'mizu.thumb.png';
$background = preg_match('/\.gif$|\.png$/', $targetThumb) == 1 ? 'None' : 'white';
$img = new Imagick($targetFile);
$img->scaleImage(150,150,true);
$img->setImageBackgroundColor($background);
$w = $img->getImageWidth();
$h = $img->getImageHeight();
$img->extentImage(150,150,($w-150)/2,($h-150)/2);
$img->writeImage($targetThumb);
== Update per comments: ==
For those who come to this answer and are using imagemagick after 6.5.7-8, this answer needs to be adjusted so that the extentImage x and y values are negative. you can see the caution note at php.net/manual/en/imagick.extentimage.php - courtesy of Jeff Richards
Upvotes: 13