In my application I need to resize and make the quality on PNG files poorer.
In full size the PNGs are 3100x4400px using 2,20MB disk space.
When running the following command:
convert -resize 1400 -quality 10 input.png output.png
the images are resized to 1400x2000 using 5,33MB disk space.
So my question is: How can I reduce the file size?
You can further reduce quality of PNG by using posterization:
https://github.com/pornel/mediancut-posterizer (Mac GUI)
This is a lossy operation that allows zlib to compress better.
Convert image to PNG8 using pngquant.
It reduces images to 256 colors, so quality depends on the type of image, but pngquant makes very good palettes, so you might be surprised how often it works.
Use Zopfli-png or AdvPNG to re-compress images better.
This is lossless and recommended for all images if you have CPU cycles to spare.
After using imagemagick to resize, you can compress the image using pngquant.
On mac (with homebrew) brew install pngquant then:
pngquant <filename.png>
This will create a new image filename-fs8.png that is normally much smaller in size.
Help page says, that -quality option used with PNG sets the compression level for zlib, where (roughly) 0 is the worst compression, 100 - is the best (default is 75). So try to set -quality to 100 or even remove the option.
Another method is to specify PNG:compression-level=N, PNG:compression-strategy=N and PNG:compression-filter=N to achieve even better results.
http://www.imagemagick.org/script/command-line-options.php#quality
For lazy people that arrived here wanting to paste in a one liner:
mogrify -resize 50% -quality 50 *.png && pngquant *.png --ext .png --force
This modifies all of the pngs in the current directory in place, so make sure you have a backup. Modify your resize and quality parameters as suits your needs. I did a quick experiment and mogrify first, then pngquant, resulted in significantly smaller image size.
The ubuntu package for pngquant is called "pngquant" but I had it installed already on 20.04LTS so seems like it may be there by default.
I found that the best way was to use the
- density [value]
parameter.
Related
I have a bunch of shots from a Raspberry Pi webcam, that I want to combine into a gif. They're 640x480 pixel jpg files, about 200 kB each. I have 200 of them I'd like to combine.
Right now, if I do convert -loop 0 *.jpg out.gif, it ends up being like 45 MB, which is crazy.
I can do a few tricks, like adding the options: -layers optimizeframe, -colors 40, -dither None, and -fuzz 20%, which gets it down to 13 MB, which is still pretty horrendous.
I know I can use the -resize option; doing resize 50% gets it down to ~5 MB, but that's still kind of large and it's now a 320x240 image of fairly low quality (due to the fuzz/colors arguments).
I'm pretty sure I've seen gifs on the internet before that weren't this huge in file size, but were large images and pretty good quality. Is there something else to try? are they actually getting a lot more compression from using .gifv's or something? Or are they usually not 200 frames? (I feel like I've seen ones that were long enough and must have been a high enough frame rate that they were.)
To be honest, I don't specifically need them to be gif's, but I want something that just auto plays in a browser, without any special plugins. The other thing is, I want it to be playing automatically and loop like a gif. I'm looking at just making an mp4 with ffmpeg, but I don't see how to make it get treated as a gifv or whatever and play/loop automatically.
To make GIF in Linux, you need to install ImageMagick. If you use any Debian based distro like Linux Mint, Ubuntu or elementary OS, run this command:
sudo apt-get install imagemagick
If you use any other distro, find this app in your package manager. After that, place all the images you want to create a GIF from in one folder. I put these images in the gif-icons folder.
I'm trying to batch convert PDF's to PNG's. Previously, this was always done manually through GIMP by importing a PDF, then converting it to PNG.
With the script that I wrote, this should all be done automatically. But for some reason, the image quality I get from using
convert \
-density 300 \
-adaptive-resize 2048 \
-define png:compression-level=9 \
"File1"
"File2"
Doesn't have the same "quality" compared to doing it via GIMP. See the image below for the difference in image quality.
In GIMP, I don't change much to the image. When I import the PDF, I change the resolution to 2048 pixels. When I convert and export it to PNG, I use all the default values GIMP offers, nothing fancy.
Changing the density to a higher or lower value doesn't do anything to the image. Also changing adaptive-resizing to normal resizing doesn't do much.
In the example image, both pictures are 2048 pixels wide. As you can see the lower image has a lot thicker/blurrier lines.
Example image comparison:
So, I have found a way around my problem.
Increasing the PPI kind of helped but still not as much as I would have liked it to.
Eventually I added this:
-channel A -fx "p*(p>0.2?22:0)"
Just some simple piece of code I found somewhere around here. It checks for the Alpha levels in the picture and if it's below a certain threshold it will just remove or "make the pixel" transparent. If it's over the threshold it will just boost the pixel to maximum visibility. Combined with the high PPI I dont get any "half pixels" anymore.
I searched everywhere but couldn't find an answer to this.
I would like to output all images of a folder in 50Kb exactly and maintain the original aspect ratio.
I tried ImageMagick and resizing to 250x250 e.g but it is not working for me, what it does is change the first dimension and adapt the other, so output images have not the same size.
for image in `ls $#*.jpg`; do
mogrify "${image}" -resize 250x250 "${image}"
done
How do it? Thanks
Updated Answer
If you want the file size of the images to be limited to 50kB, use:
convert input.jpg -define jpeg:extent=50KB output.jpg
Original Answer
Use mogrify, but be careful it will overwrite all your images:
mogrify -resize 250x250! *.jpg
In general, when using mogrify I like to use the -path option to specify an output directory for results, like this to avoid originals getting overwritten:
mkdir results
mogrify -path results ...
Your script will work if you add the ! after the resize which forces the resize even if it distorts the shape of the picture.
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.
I need to do the same operations for more than 60 files:
scale image
unsharpen mask
Is it possible to execute this from a script possibly passing the scale value ? I'm on Ubuntu if this could influence the answer.
edit:
What I need to do is to resize some Android icons from 64x64 to 96x96 (as far, maybe other resolutions too).
But these icons have already been blurred so, just increasing the size, I don't get a nice result.
I've seen that if I resize to 96x96 and apply the "Unsharp Mask" filter with the default values (Radius: 5,0 - Amount: 0,50 - Threshold: 0),
I get an acceptable result.
As you are on Ubuntu, you likely already have ImageMagick installed - convert, identify and mogrify commands, amongst others.
So, make a copy of your data and try something like this on a copy:
mogrify -resize 640x480 -unsharp 6x3+1+0 *.jpg
or maybe this
mogrify -resize 1024x768 -sharpen 0x1.0 *.tif
to resize all JPEGs to 640x480 max and sharpen them, and in the second case to resize and sharpen a bunch of TIFFs.
If you specify your GIMP parameters I can probably make closer suggestions.
I compared ImageMagick with other tools. In my example I just want to resize and compress images. The goal is an acceptable file size with good quality.
Original file size: 127 Kb
Comparison between ImageMagick and Caesium
Unscaled, quality set to 80%
ImageMagick: convert image.jpg -strip -quality 80 optImage.jpg
=> 123 Kb
Casesium: 101 Kb
Scaled to 640x359, quality set to 80%
ImageMagick: convert image.jpg -strip -resize 640x359! -quality 80 optImage.jpg
=> 48 Kb
Caesium: 33.6 Kb
So what is wrong with that? Is there any ImageMagick-option I should include? Or is the quality parameter different between these tools?
EDIT: is there any Linux shell tool which is able to resize (maybe crop) and compress as good as Caesium?
I found out that these quality-parameters are not the same; 80% quality on ImageMagick corresponds to 87% (not exact) in Caesium; to get a acceptable file size the ImageMagick quality-parameter should set to 80 (not losless). But I think it's not bad to use an extra losless compression for ImageMagick-resized images like jpegtran for JPGs and optiPNG for PNGs. They can reduce the file size a bit more.
If you have an acceptable file size in mind, you can tell ImageMagick what it is and it will do its best to honour it.
Like this:
convert image.jpg -strip -define jpeg:extent=88kb optImage.jpg
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.