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);
The Simple Solution Using CSSBy setting the width property to 100%, you are telling the image to take up all the horizontal space that is available. With the height property set to auto, your image's height changes proportionally with the width to ensure the aspect ratio is maintained.
Image resizing with the pointer toolBy clicking and dragging on these handles, the object is resized by moving the edge or corner clicked on to adjust the width and/or height of the selected object. If the Shift key is held down whilst moving the handle, then the proportions of the object will be preserved.
How to fit image without stretching and maintain aspect ratio? Answer: If you want to use the image as a CSS background, there is an elegant solution. Simply use cover or contain in the background-size CSS3 property. contain will give you a scaled-down image.
We can resize the image by specifying the width and height of an image. A common solution is to use the max-width: 100%; and height: auto; so that large images do not exceed the width of their container. The max-width and max-height properties of CSS works better, but they are not supported in many browsers.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With