Mash
Mash

Reputation: 420

Compress image quality (from 4MB to 2MB) without losing its dimension

I am trying to compress the quality of an image using ImageMagick. I mean that I have an image which dimension is 1600X800 and size is 4MB. Now I am trying to compress the quality of this image into 2MB without resizing its dimensions, means the newly generated image also have the same dimension as actual image (i.e. 1600X800) but the quality of this image should be compress into 2MB (half of the actual image). For this, now I am using the below code, but this is not compress the size of the newly created image:

$src_img = "src.png";
$dest_img = "dest.png";
exec("convert $src_img -quality 90 $dest_img");

So can anyone please tell me what can I do to compress the size of the image without losing its actual dimension using ImageMagick?

Upvotes: 2

Views: 1641

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207375

Try using ImageMagick and defining the maximum output size (in kB) that you want and letting it reduce the quality until that size is achieved:

convert input.jpg -define jpeg:extent=2000k output.jpg

For example, if I create a 2000x2000 image of noise, like this

convert -size 2000x2000 xc:gray +noise gaussian input.jpg

I get this 4MB file.

-rw-r--r--@  1 mark  staff    4175639 12 May 15:40 input.jpg

If I use the command above to reduce the file size

convert input.jpg -define jpeg:extent=2000k output.jpg

I get this 1.9MB file

-rw-r--r--   1 mark  staff    1933708 12 May 15:41 output.jpg

but its pixel dimensions remain unaltered at 2000x2000

identify output.jpg

output.jpg JPEG 2000x2000 2000x2000+0+0 8-bit sRGB 1.934MB 0.000u 0:00.000

Just for fun, you can see how setting different file sizes changes the quality setting:

convert input.jpg -define jpeg:extent=2000k output.jpg <--- 2MB file => 82 quality
identify -verbose output.jpg | grep -i quality
Quality: 82

convert input.jpg -define jpeg:extent=1000k output.jpg <--- 1MB file => 65 quality
identify -verbose output.jpg | grep -i quality
Quality: 65

convert input.jpg -define jpeg:extent=500k output.jpg <--- 500kB file => 38 quality
identify -verbose output.jpg | grep -i quality
Quality: 38

If you want a way to do something similar with Python, I wrote an answer that works pretty well here. It does a binary search for a JPEG quality that satisfies a maximum size requirement.

Upvotes: 5

Ruslanas Balčiūnas
Ruslanas Balčiūnas

Reputation: 7418

You can change image quality using GD library functions. It is more secure than using exec().

$im = imagecreatefrompng("src.png");

imagepng($im, 'dest.png', $quality);
imagedestroy($im);

Upvotes: 0

Related Questions