We have a storage of images where some images are optimized and some are not.
I'm working on 'script' that will go via every image in the storage and run optimize process.
I'm wondering:
I have tried to run -quality 85% few times on same image and I could not see any lose in quality (after 3-th run the image's size was not changed). However I did not find a proof on official documentation.
Thanks!
You can check if the quality setting is already 75 before optimising:
identify -format %Q fred.jpg
92
Then optimise and check again:
convert fred.jpg -quality 75 optimised.jpg
identify -format %Q optimised.jpg
75
If you are using bash
, this is easy:
q=$(identify -format %Q fred.jpg)
[ $q -ne 75 ] && mogrify -quality 75 fred.jpg
Another way to mark images as optimised might be to set a comment in the file to the word "optimised", like this:
# Set comment
mogrify -set comment "optimised" fred.jpg
# Get comment
identify -format %c fred.jpg
optimised
So, you would test if an image comment contains the word "optimised", and if not, optimise the image and change the comment to show as much:
[[ $(identify -format %c fred.jpg) != *optimised* ]] && { echo Optimising fred.jpg; mogrify -set comment "optimised" -quality 75 fred.jpg; }
Another possibility might be to use Extended File Attributes to tag files (with setfattr
) as you reduce their quality and then use getfattr
to check their quality rather than doing them again.
If you had hundreds or thousands of images to process, I would suggest GNU Parallel. Please try the example below on a small copy of a few files in a directory:
parallel '[[ $(identify -format "%c" {}) != *optimised* ]] && { echo Optimising {}; mogrify -set comment "optimised" -quality 75 {}; }' ::: *jpg
You will find it will process them all in parallel the first pass, and then do nothing on the second pass.
If you have too many images, and get "ERROR: Too many args", you can pass the filenames in on stdin
like this, instead of globbing after the :::
:
find /some/where -iname \*.jpg -print0 | parallel -0 ...