Recommendation for compressing JPG files with ImageMagick - image-processing

I want to compress a JPG image file with ImageMagick but can't get much difference in size. By default the output size is bigger than the input. I don't know why, but after adding some +profile options and setting down the quality I can get an smaller size but still similar to original.
The input image is 255kb, the processed image is 264kb (using +profile to remove profiles and setting quality to 70%). Is there any way to compress that image to 150kb at least? Is that possible? What ImageMagick options can I use?

I use always:
quality in 85
progressive (comprobed compression)
a very tiny gausssian blur to optimize the size (0.05 or 0.5 of radius) depends on the quality and size of the picture, this notably optimizes the size of the jpeg.
Strip any comment or EXIF metadata
in imagemagick should be
convert -strip -interlace Plane -gaussian-blur 0.05 -quality 85% source.jpg result.jpg
or in the newer version:
magick source.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85% result.jpg
Source.
From #Fordi in the comments (Don't forget to upvote him if you like this):
If you dislike blurring, use -sampling-factor 4:2:0 instead. What this does is reduce the chroma channel's resolution to half, without messing with the luminance resolution that your eyes latch onto. If you want better fidelity in the conversion, you can get a slight improvement without an increase in filesize by specifying -define jpeg:dct-method=float - that is, use the more accurate floating point discrete cosine transform, rather than the default fast integer version.

I'm using the Google Pagespeed Insights image optimization guidelines, and for ImageMagick they recommend the following:
-sampling-factor 4:2:0
-strip
-quality 85 [it can vary, I use range 60-80, lower number here means smaller file]
-interlace
-colorspace RGB
Command in ImageMagick:
convert image.jpg -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG -colorspace RGB image_converted.jpg
With these options I get up to 40% savings in JPEG size without much visible loss.

Just saying for those who using Imagick class in PHP:
$im -> gaussianBlurImage(0.8, 10); //blur
$im -> setImageCompressionQuality(85); //set compress quality to 85

Once I needed to resize photos from camera for developing:
Original filesize: 2800 kB
Resolution: 3264x2448
Command:
mogrify -quality "97%" -resize 2048x2048 -filter Lanczos -interlace Plane -gaussian-blur 0.05
Result filesize 753 kB
Resolution 2048x2048
and I can't see any changes in full screen with my 1920x1080 resolution monitor. 2048 resolution is the best for developing 10 cm photos at maximum quality of 360 dpi. I don't want to strip it.
edit: I noticed that I even get much better results without blurring. Without blurring filesize is 50% of original, but quality is better (when zooming).

#JavisPerez -- Is there any way to compress that image to 150kb at least? Is that
possible? What ImageMagick options can I use?
See the following links where there is an option in ImageMagick to specify the desired output file size for writing to JPG files.
http://www.imagemagick.org/Usage/formats/#jpg_write
http://www.imagemagick.org/script/command-line-options.php#define
-define jpeg:extent={size}
As of IM v6.5.8-2 you can specify a maximum output filesize for the JPEG image. The size is specified with a suffix. For example "400kb".
convert image.jpg -define jpeg:extent=150kb result.jpg
You will lose some quality by decompressing and recompressing in addition to any loss due to lowering -quality value from the input.

I would add an useful side note and a general suggestion to minimize JPG and PNG.
First of all, ImageMagick reads (or better "guess"...) the input jpeg compression level and so if you don't add -quality NN at all, the output should use the same level as input. Sometimes could be an important feature. Otherwise the default level is -quality 92 (see www.imagemagick.org)
The suggestion is about a really awesome free tool ImageOptim, also for batch process.
You can get smaller jpgs (and pngs as well, especially after the use of the free ImageAlpha [not batch process] or the free Pngyu if you need batch process).
Not only, these tools are for Mac and Win and as Command Line (I suggest installing using Brew and then searching in Brew formulas).

I added -adaptive-resize 60% to the suggested command, but with -quality 60%.
convert -strip -interlace Plane -gaussian-blur 0.05 -quality 60% -adaptive-resize 60% img_original.jpg img_resize.jpg
These were my results
img_original.jpg = 13,913KB
img_resized.jpg = 845KB
I'm not sure if that conversion destroys my image too much, but I honestly didn't think my conversion looked like crap. It was a wide angle panorama and I didn't care for meticulous obstruction.

Here's a complete solution for those using Imagick in PHP:
$im = new \Imagick($filePath);
$im->setImageCompression(\Imagick::COMPRESSION_JPEG);
$im->setImageCompressionQuality(85);
$im->stripImage();
$im->setInterlaceScheme(\Imagick::INTERLACE_PLANE);
// Try between 0 or 5 radius. If you find radius of 5
// produces too blurry pictures decrease to 0 until you
// find a good balance between size and quality.
$im->gaussianBlurImage(0.05, 5);
// Include this part if you also want to specify a maximum size for the images
$size = $im->getImageGeometry();
$maxWidth = 1920;
$maxHeight = 1080;
// ----------
// | |
// ----------
if($size['width'] >= $size['height']){
if($size['width'] > $maxWidth){
$im->resizeImage($maxWidth, 0, \Imagick::FILTER_LANCZOS, 1);
}
}
// ------
// | |
// | |
// | |
// | |
// ------
else{
if($size['height'] > $maxHeight){
$im->resizeImage(0, $maxHeight, \Imagick::FILTER_LANCZOS, 1);
}
}

Did some experimenting myself here and boy does that Gaussian blur make a nice different. The final command I used was:
mogrify * -sampling-factor 4:2:0 -strip -quality 88 -interlace Plane -define jpeg:dct-method=float -colorspace RGB -gaussian-blur 0.05
Without the Gaussian blur at 0.05 it was around 261kb, with it it was around 171KB for the image I was testing on. The visual difference on a 1440p monitor with a large complex image is not noticeable until you zoom way way in.

An very old but helpful answer.
I need to say, to serious large photography, -gaussian-blur is not acceptable, rather than compress ratio.
Comparing below, %95 with -gaussian-blur 0.05 vs. %85 without blurring. Original 17.5MB (8MP with much defail), %95 without blurring 5MB, %85 without blurring 3036KB, %95 with blurring 3365KB.
Comparing between blurring and compress ratio
Maybe lower blurring like 0.02 will work better.

If the image has big dimenssions is hard to get good results without resizing, below is a 60 percent resizing which for most of the purposes doesn't destroys too much of the image.
I use this with good result for gray-scale images (I convert from PNG):
ls ./*.png | xargs -L1 -I {} convert {} -strip -interlace JPEG -sampling-factor 4:2:0 -adaptive-resize 60% -gaussian-blur 0.05 -colorspace Gray -quality 20 {}.jpg
I use this for scanned B&W pages get them to gray-scale images (the extra arguments cleans shadows from previous pages):
ls ./*.png | xargs -L1 -I {} convert {} -strip -interlace JPEG -sampling-factor 4:2:0 -adaptive-resize 60% -gaussian-blur 0.05 -colorspace Gray -quality 20 -density 300 -fill white -fuzz 40% +opaque "#000000" -density 300 {}.jpg
I use this for color images:
ls ./*.png | xargs -L1 -I {} convert {} -strip -interlace JPEG -sampling-factor 4:2:0 -adaptive-resize 60% -gaussian-blur 0.05 -colorspace RGB -quality 20 {}.jpg

Related

Convert images and show result using Image Magick

I am manipulating images using Image Magick. Here is the command that I use:
convert source.png -resize 1200 -quality 75 result.jpg
It works as expected. I am no wondering whether there is a way to report a conversion result showing how much compression has been done (in percentage or kilobyte or just by showing the sizes of original and converted images)?
I have tried -monitor switch, but it only shows a progress kind of report during conversion.
(I am using Linux)
The quality setting you use tells ImageMagick how much to compress the image. Alternately, you can compute the ratio of the output file size by the input size. Or the ratio of the output file size with -quality 75 to that when using -quality 100, even though -quality 100 still compresses some.
You can get the size of the image by
convert image -precision 16 -format "%b\n" info:
Setting a large precision will forces the result to be in Bytes, but you will have to remove the B character from the end. So you can do the following to get the percent of output/input file sizes:
outsize=$(convert output -precision 16 -format "%b\n" info: | sed 's/B//g')
insize=$(convert input -precision 16 -format "%b\n" info: | sed 's/B//g')
percent_size=$(convert xc: -format "%[fx:100*$outsize/$insize]\n" info:)

Image Magick - trim and repage - loss of quality

When I use this command to trim a PDF file:
convert -fuzz 1% -trim +repage multi0.pdf multi0new.pdf
The result is very disappointing and the trimmed image size becomes more than 10 times lower than the source.
Is there any way to make a clean image trimming without loss of quality?
(here it is, before and after)
You probably have to use the -density option with a higher value than the default of 72 dpi. Try 300 for a start:
convert -density 300 -fuzz 1% -trim +repage multi0.pdf multi0new.pdf
Note that higher density values will increase the output file size.

ImageMagick changes colors when converting PDF to images

I am converting various PDFs uploaded by end users into images using following command
-density 140 -limit memory 64MB -limit map 128MB [pdffile] page.png
Here is the result. On the right we have original PDF and on the left output image. As you can see the colors are quite noticeably different.
What could be causing this and how fix it?
try following command:
-density 140 -limit memory 64MB -limit map 128MB -colorspace RGB [pdffile] page.png
Edit: I later discovered that ImageMagick can do it fine, I just needed to use -colorspace sRGB
My final command was:
convert -density 560 -limit memory 64MB -limit map 128MB \
-colorspace sRGB [pdffile] -scale 25% page.png
The oversampling and scaling down was to counter the poor anti-aliasing mentioned below.
Before I discovered that, here was my earlier solution...
In my case the colors produced by ImageMagick's convert were oversaturated, quite like those in the question. I was trying to convert this file using IM 6.7.7.10-6ubuntu3.
-resample 100 made no difference.
-colorspace RGB seemed to produce more accurate saturations, but the entire image was darker than it should have been.
Curiously, this suggestion to use GhostScript instead of ImageMagick for the conversion, produced very close to the correct colors:
gs -q -sDEVICE=png16m -dSubsetFonts=true -dEmbedAllFonts=true \
-sOutputFile=page.png -r200 -dBATCH -dNOPAUSE [pdffile]
(The original suggestion passed the -dUseCIEColor option, but in my case this appeared to reduce the gamma: light pixels were fine, but the dark pixels were too dark, so I removed it.)
After that, the only thing that bothered me was that the anti-aliasing/edges were a little off in places (especially visible on curves passing 45 degrees). To improve that, I created the output at four times the required resolution, and then scaled down afterwards, rendering those errors almost imperceptible. Note that I had to use ImageMagick's -scale for this, and not -geometry or -resize, in order to avoid bicubic ringing effects.
Use the -resample option:
-density 140 -resample 100 -limit memory 64MB -limit map 128MB [pdffile] page.png
Open Source MuPDF util mutool retains color and size using default parameters below
you need though to list the pages separated by a comma at the end of the command.
mutool draw -o draw%d.png abook.pdf 1,2
Otherwise if using Linux try Windows for better colorspace RGB interpretation when using imagemagick's convert.
The following images show how anti-aliasing improves if you sample at a higher resolution and then scale down.
Although 1120 was slightly better quality than 560, it took a long time to convert, so I would probably choose 560 for a good time:quality trade-off.
-colorspace sRGB -density 140
-colorspace sRGB -density 280 -scale 50%
-colorspace sRGB -density 420 -scale 33.3333%
-colorspace sRGB -density 560 -scale 25%
-colorspace sRGB -density 1120 -scale 12.5%
(It is easier to see the difference if you download the last two images and flip between them in your favourite image viewer. Or scroll up this list of images, instead of down. You should seem them becoming progressively uglier.)

How can I reduce the dimensions of gif images with ImageMagick?

What flag in magick.exe convert <flags> will reduce the dimensions of my image?
This is the command I'm using: magick.exe input.png[0] -depth 8 -type Grayscale -dresize 400x300.
The [0] after the source-image filename is meant to strip the first frame of any animated gifs.
How can I do reduce my output gif sizes? My file sizes are too large: my outputs need to be less than 100k. Any methods other than reducing the dimensions are also welcome.
convert test.gif -fuzz 10% -layers Optimize result.gif
Adding a -fuzz 2% produced a better optimization, but still not very good. At -fuzz 15% It isolated the differences for frame optimization to just the visible color band changes I noted before.
At 25% the differences were almost to just the text changes.
Finally at a massive 30% fuzz factor (ignore color changes below that figure, did it optimize to just the text changes.
You can try gifsicle:
gifsicle -O3 old.gif -o new.gif
If it's an animation, you could try skipping frames (see how it works).
magick.exe convert -resize 100x100 .\step1.jpg .\step2.jpg -delay 100 -loop 0 animation.gif
Thanks to Nate.
//IMPORTANT: -resize should come first.
//BY DEFAULT: the aspect ratio will be locked with the longest dimension being set to 100px.
//GENERALIZATION: this order `magick convert 1st<input_file(s)> 2nd<switch(es)> 3rd<output_file>`.
//IMPORTANT-RELATED: `-delay` will not work on second brush! Use `-set delay` for existing files.
Please, also be sure to refresh your folder view to ensure that you're not viewing old output files: Windows Explorer (F5).
Try to use the option:
-type Palette
It might help to reduce your gif file sizes smaller, oh and I believe -depth 8 can only be used for png images.

How to convert a .eps file to a high quality 1024x1024 .jpg?

I have a .eps file that I can look at in Photoshop, and it has a very high resolution, sharp edges, etc. at even larger than 1024x1024.
With ImageMagick I want to convert this .eps to a 1024x1024 .jpg with very high resolution.
However, with the following command, the image is very blurry:
convert -resize "1024x1024" -colorspace RGB -flatten test.eps test.jpg
What ImageMagick parameters do I have to use so that the resulting .jpg is 1024x1024 and a high quality, sharp image?
here's some XMP data we found, perhaps what is causing it to not be resized with -size:
For vector graphics, ImageMagick has both a render resolution and an output size that are independent of each other.
Try something like
convert -density 300 image.eps -resize 1024x1024 image.jpg
Which will render your eps at 300dpi. If 300 * width > 1024, then it will be sharp. If you render it too high though, you waste a lot of memory drawing a really high-res graphic only to down sample it again. I don't currently know of a good way to render it at the "right" resolution in one IM command.
The order of the arguments matters! The -density X argument needs to go before image.eps because you want to affect the resolution that the input file is rendered at.
This is not super obvious in the manpage for convert, but is hinted at:
SYNOPSIS
convert [input-option] input-file [output-option] output-file
Maybe you should try it with -quality 100 -size "1024x1024", because resize often gives results that are ugly to view.

Resources