ImageMagick - Resize to max width - php

I want to resize an image to a max width. So I don't care about the height of the image, but I just want to always resize it to a specific width.
I'm certain I've done this before I just can't remember how I did it now.

Seems this is the way it is done, noting that width is the first parameter.
convert -resize '100' image.png
For anyone else wondering about height, then you would do this:
convert -resize 'x100' image.png
Source: http://www.imagemagick.org/script/command-line-processing.php
Edit (Nov 2014): Note that in the latest versions of ImageMagick you can no longer use quotes around the values as per Kevin Labécot's comment.

Your question is ambiguous. Your titles asks to resize an image to a max width, but then you seem to say you want to resize the image to a specific width.
If you want to resize something to a max width of 600px (ie, any image with a width of less than 600px will be unaffected), use:
convert original_image.jpg -resize 600x\> result_image.jpg
Or, to directly modify the original image:
mogrify -resize 600x\> original_image.jpg
If you'd like max height rather than max width:
convert original_image.jpg -resize x600\> result_image.jpg

Are you just chasing the math to work out the correct aspect ratio?
$new_width = 400; // config
$image_width = 480; // loaded from image
$image_height = 786; // loaded from image
$new_height = $new_width * ($image_height / $image_width);
echo "$image_width x $image_height becomes $new_width x $new_height";

The way to resize to a given width in ImageMagick is:
convert image -resize Wx result
or just
convert image -resize W result
where W=width and is provided, but H=height is not included
See https://imagemagick.org/script/command-line-processing.php#geometry

Related

How to find out image auto height if the desired width is 1024 in PHP from any sized image?

I have an image with an example dimension of 1600x1200, i would like to resize it down to width: 1024 using PHP.
How do i calculate the height if i only know the desired width?
I know this works on the command line but it calculates the height for me:
mogrify -resize 1024 someimage.jpg
I am looking to calculate the height in code since php doesn't have any functions that do it for you and they all require the height to be specified.
Thanks

Imagemagick Crop command not giving perfect result

I am using Imagemagick for resizing and cropping image.
Test Image :
I need to re-size it for 300 x 320 frame for this first I am resizing the image and then cropping it and i am using the following commands:
exec("convert /uploadImagePath -thumbnail 300 /newImagePath");
exec("convert /newImagePath -gravity Center -crop 290x310+0+0 /newImagePath");
But it gives me following image
As you can see image is not complete. Where am I mistaken?
(Answer is updated, providing an illustrated example for -liquid-rescale further below now)
Your original image's dimensions are:
489 x 640 pixels
Your desired dimensions seem to be:
290 x 310 pixels
This cannot scale to these dimensions without either:
cropping (do not keep all areas of the intial image)
keeping desired width (give up desired height)
keeping desired height (give up desired width)
distortion (do not keep the aspect ratio when scaling)
padding (add more pixels to one or more edges)
removing pixels where it's not obvious ("liquid rescale" or "seam carving" -- see Wikipedia)
Your result shows '1.' (cropping), which you don't like. So you have options '2.' (keeping width), '3.' (keeping height), '4.' (distortion), '5.' (padding) and '6.' (seam carving) left to test.
'2.': Keeping desired Height
convert WPTgp.jpg -resize x310 keep-height.jpg
Resulting Image has dimensions of 237 x 310 pixels.
Keep Height....
(determine width automatically)
'3.': Keeping desired Width
convert WPTgp.jpg -resize 290x keep-width.jpg
Resulting Image has dimensions of 290 x 380 pixels.
Keep Width.....
(determine height automatically)
'4.': Distortion
convert WPTgp.jpg -resize 290x310\! distorted.jpg
Resulting Image has dimensions of 290 x 310 pixels.
Distorted......
(ignore aspect ratio -- distort image if required to fit dimensions)
'5.': Padding
convert WPTgp.jpg \
-resize 290x310 \
-gravity center \
-background orange \
-extent 290x310 \
padded.jpg
Resulting Image has dimensions of 290 x 310 pixels. (Orange background was added only to demonstrate that the 'extention' of the image did work.)
Padded.........
(keep aspect ratio -- extend image for desired dimensions)
'6.': Seam Carving
convert WPTgp.jpg -liquid-rescale 290x310\! liquid.jpg
The above would be the command you'd spontaneously derive from quick-reading the ImageMagick command options reference. However, it doesn't work well, and instead I used:
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 290x310 liquid.jpg
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 48.4% liquid.jpg
Further below is an explanation why I needed to modify it....
Liquid-rescaled
Sorry -- I cannot provide example picture right now; this requires the additional ImageMagick delegate liblqr (liquid rescaling library) to be installed, which I don't have at this moment) I've now had the opportunity to create a 'liquidly rescaled' version of the original image.
Caveats about Seam Carving / '-liquid-rescale':
As stated above, the last image is not the result of my originally proposed command, but of one of these two modified versions:
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 290x310 liquid.jpg
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 48.4% liquid.jpg
Remember, we have an original image of 489x610 pixels, which we are expected to scale to 290x310 pixels. But -liquid-rescale isn't good at rescaling in two dimensions at once -- it's designed to scale into one direction only (horizontal or vertical). If you try to do both at once, results may not be what you'd expect. Here is the result for the originally proposed command:
convert WPTgp.jpg -liquid-rescale 290x310\! liquid.jpg
LQR gone wrong
That's why I came up with the two modified commands which work in two steps:
First, apply liquid rescaling to the horizontal dimension only, expanding the original's width from 489 pixels to 599 pixels.
Second, apply 'normal' aspect-ratio-keeping scaling to the intermediate result to produce the final image.
Try:
$inputFile = "WPTgp.jpg";
exec("convert {$inputFile} -resize 290x310^ -gravity Center -crop 290x310+0+0 picCropped.png");

Image file size differences between Imagemagick and GD library

I have been doing some tests and found out that Imagemagick creates larger file sized images compared to GD library.
I have tried using thumbnailImage method and also resizeImage method (with different filters) of Imagemagick for creating an image of max dimension 1024x680 jpeg with JPEG compression and quality 80 and at 72 pixels per inch resolution and am also using stripImage method to remove unneeded meta data. The file size created by Imagemagick is always in the range of 700KB to 800KB depending upon various filters. On the other hand GD library produces an image of size 1024x680 which is only 41KB in size.
Can anyone please explain the difference in file sizes. I opened up the 2 files in Photo shop and checked to see any differences but could not find any (DPI, color profile, 8 bit channel etc), but still cant explain the difference in file sizes.
$srgbPath = "pathTosrgbColorProfile";
$srgb = file_get_contents($srgbPath);
$image->profileImage('icc', $srgb);
$image->stripImage();
$image->setImageResolution(72,72);
$image->setImageUnits(1);
$image->setInterlaceScheme(Imagick::INTERLACE_JPEG);
$image->setImageCompression(imagick::COMPRESSION_JPEG);
$image->setImageCompressionQuality(80);
$image->setColorspace(imagick::COLORSPACE_SRGB);
$image->resizeImage($thumb_width,$thumb_nheight,imagick::FILTER_CATROM,1);
$image->writeImage($destination);
The size went down by 40KB giving an output of 711KB which is still pretty big. The Hi-res original file I am testing on is a jpeg of size 3008x2000 (4.2MB).
Edit:
I think I figured it out, the method setCompression() does it for the Object and not the image, instead I used setImageCompression() and setImageCompressionQuality() and now the size has reduced to 100KB.. All good now!
Maybe the Quality settings of GD and ImageMagick aren't easily comparable, 80% in one does not mean the same as 80% in the other. I found the following note in an article form Smashing Magazine:
It turns out that JPEG quality scales are not defined in a specification or standard, and they are not uniform across encoders. A quality of 60 in Photoshop might be the same as a quality of 40 in one program, quality B+ in another and quality fantastico in a third. In my tests, I found that Photoshop’s 60 is closest to -quality 82 in ImageMagick.
So you may pay more attention on quality when comparing the different result files. Maybe the colors differ or the gd image has more artifacts.
The differnce seems rather large; when I did some tests a couple of years ago the file size of IM was about 5x the size of GD.
It would be interesting to see your actual code used.
I am at work at the moment but have a photo resized to 592 x 592 and the filesize is 50.3KB I know it is not the same size as yours but it was saved at quality 100
You can run this and see what IM says about the output files:
convert image -verbose -identify
EDIT:
You must be doing something wrong I have just run a test and the results are below - For some reason the thumbnail size is the same as the resize size! Maybe a bug.
Original file size: 4700 x 3178 2.31MB
-resize dimensions = 1021 x 680 186kb
-thumbnail dimensions = 1021 x 680 186kb
GD dimensions = 1024 x 682 100kb
$original = 'IMG_4979_1.CR2';
// Convert to jpg as GD will not work with CR2 files
exec("convert $original image.jpg");
$image = "image.jpg";
exec("convert $image -resize 1024x680 output1.jpg");
exec("convert $image -thumbnail 1024x680 -strip output2.jpg");
// Set the path to the image to resize
$input_image = 'image.jpg';
// Get the size of the original image into an array
$size = getimagesize( $input_image );
// Set the new width of the image
$thumb_width = "1024";
// Calculate the height of the new image to keep the aspect ratio
$thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
// Create a new true color image in the memory
$thumbnail = ImageCreateTrueColor( $thumb_width, $thumb_height );
// Create a new image from file
$src_img = ImageCreateFromJPEG( $input_image );
// Create the resized image
ImageCopyResampled( $thumbnail, $src_img, 0, 0, 0, 0, $thumb_width, $thumb_height, $size[0], $size[1] );
// Save the image as resized.jpg
ImageJPEG( $thumbnail, "output3.jpg" );
// Clear the memory of the tempory image
ImageDestroy( $thumbnail );

How to resize image size

How to reduce image sizes in Linux. I have used ImageMagick for this. But it is not working well for gif images. I have used it as:
To resize image
exec("convert $original -resize " . $width . 'x' . $height . ' ' . $destination);
To reduce image size
exec("convert $original -quality 80% $new_img");
Please let me know if you have any way to reduce image size. This code works well for jpg, but not works well for gif images.
Appreciate your help.
Quoting from the Imagemagick manual:
-quality value
JPEG/MIFF/PNG compression level.
That means that using the quality level will only work on the aforementioned image types, which do not include GIF.
For GIF's your easiest option is to use the -colors command to reduce the number of colors used in your image. The quality of the result depends very much on what your initial image contains, I have seen cases where a reduction from 256 to 16 colors did not cause significant quality loss, and others where a reduction to 128 colors rendered the image unusable. You'll have to experiment.
A last remark: you could transform your GIF to PNG format and use the -quality command on the resulting image. Quality on PNG's however is a bit of a misnomer:
For the MNG and PNG image formats, the quality value sets the zlib compression
level (quality / 10) and filter-type (quality % 10). The default PNG "quality"
is 75, which means compression level 7 with adaptive PNG filtering, unless the
image has a color map, in which case it means compression level 7 with no PNG
filtering.
So don't be surprised if the size reduction is less on PNG's than on JPG', it only improves compression of the lossless PNG image.
To reduce GIF images in size, you can try converting them to PNG or to reduce the color depth. The color depth is the number of colors used in the image. Less colors means a smaller image size.
So you can use GD
http://ua.php.net/manual/en/function.imagecopyresampled.php
<
?php
// The file
$filename = 'test.jpg';
// Set a maximum height and width
$width = 200;
$height = 200;
// Content type
header('Content-Type: image/jpeg');
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}
// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output
imagejpeg($image_p, null, 100);
?>
The following works well for JPEG images and likely works for other image formats. The given density (300) is pretty high and suitable for keeping text readable, so adjust for your situation.
convert input-file -density 300 -quality 50% output-file

Resize panoramic image to fixed size

I want to resize the images to fixed width and height (i.e. 150px). However, theres a problem, if there is lots of difference in height and width of original photo (for example, panoramic photo), the resized thumbnail looks bad. Is there any any smart solution to resize the photos to a fixed width and height? For example, please have a look at this
image:
Here's my code:
<?php
$params = getimagesize($tempFile);
$width = $params[0];
$height = $params[1];
$newwidth=150;
$newheight= 150;
$tmp=imagecreatetruecolor($newwidth,$newheight);
imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
imagejpeg($tmp,$img_name,80);
imagedestroy($src);
imagedestroy($tmp);
?>
Is there any smart way to resize the images in smart way?
Thanks.
There's a smart solution, it's called Seam Carving, and if your server supports ImageMagick, you do it like this:
<?php
$im = new Imagick( 'image.jpg' );
$im->liquidRescaleImage( 600, 100, 3, 25 );
header( 'Content-Type: image/jpg' );
echo $im;
?>
Or alternatively, if it doesn't support, use exec() (carefully) in order to pass image as an argument to executable which can perform seam carving.
BTW it looks like twitpic just crop's the squared image extract.
In one of my previous projects I used following code:
if ($image->width > $image->height){
//crop image in proportions 4/3, then resize to 500x300 (or proportionally lower resolution),
//sharp it a little and decrease quality.
//I used one of the Yii framework extensions.
$image->crop($image->width, $image->width/4*3)->resize(500, 300, Image::WIDTH)->sharpen(15)->quality(75);
}
It looks like twitpic is finding out how long the short axis is, then takes a square centered on the original image with sides equal to the short axis length, then shrinking that down to 150x150.
Not, resmaple, get only center 150x150 pixels.
You will need to calculate the appropriate coordinates for the original area you want to copy:
imagecopyresampled($tmp,$src,0,0,[THIS VALUE],[THIS VALUE],$newwidth,$newheight, [THIS VALUE],[THIS VALUE]);
As of now, you take the area from 0,0 (x,y) to width,height (x,y) of the original area and try to cramp it into 150x150.
you will need to calculate which of width and height that is the "biggest" and crop that and make sure that the ratio is the same as your resulting image (in your case, ratio is 1.0 because of 150x150).
In your example, where width is 1050 and height is 317 pixels so you want a portion of the original image that is 317x317 (ratio 1.0), you need to:
subtract 317 from 1050 = 733; // this is the excessive area for both sides
divide by 2 =~ 366; // to get the excessive area for one side
Now, use first x coordinate 366, to start 366 pixels from the left.
Use second x coordinate 1050 - 366 start 366 pixels from the right.
So your example should be (just guessing here):
imagecopyresampled($tmp,$src,0,0,366,0,$newwidth,$newheight, $width - 366, 0);
You will of course need some logic in order to calculate this correctly for any other size.

Categories