Get info of applied image manipulation - imagemagick

I am using gm for node. I would like know the equivalent Javascript of the ImageMagick CLI command:
convert /path/to/source.png -format "%#" info:-
This will output the trim data, resulting in something like:
2672x3579+1115+725
I initially assumed the gm equivalent would be:
gm('/path/to/source.png').identify('%#', (err, result) => {
console.log(result)
})
But this just returns the source file size without trimming whitespace.
5000x5000+0+0

Try it this way:
gm convert a.png -format "%#" info:-
Or this way:
gm convert a.png -trim -format "%w %h" info:-

I figured it out.
gm('/path/to/source.png')
.in('-format', '%#')
.write('info:-', (err, result) => {
console.log(result)
})
The writing to info:- was the aha moment.

Related

Can ImageMagick be prevented from overwriting an existing image?

When converting an image, ImageMagick's default behavior seems to be to overwrite any existing file. Is it possible to prevent this? I'm looking for something similar to Wget's --no-clobber download option. I've gone through ImageMagick's list of command-line options, and the closest option I could find was -update, but this can only detect if an input file is changed.
Here's an example of what I'd like to accomplish: On the first run, convert input.jpg output.png produces an output.png that does not already exist, and then on the second run, convert input.jpg output.png detects that output.png already exists and does not overwrite it.
Just test if it exists first, assuming bash:
[ ! -f output.png ] && convert input.png output.png
Or slightly less intuitively, but shorter:
[ -f output.png ] || convert input.png output.png
Does something like this solve your problem?
It will write to output.png but if the file already exists a new file will be created with a random 5 character suffix (eg. output-CKYnY.png then output-hSYZC.png, etc.).
convert input.jpg -resize 50% $(if test -f output.png; then echo "output-$(head -c5 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c5).png"; else echo "output.png"; fi)

Avoid double optimization of image

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:
Is there a way to check if image has been optimized?
Will I lose quality if image has been optimized with -quality 85% few times?
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 ...

mogrify -resize and append new filesize to filename

I would like to mogrify -resize 500 my files and append the new filesize to the filename ie: image-500*500.png
Can someone help me out please.
I don't think you can do that with mogrify because it overwrites the original filename rather than creating a new one. So, I think you will need to do it with convert.
So, for one file called input.png:
convert input.png -resize 400x500\! -set filename:f "%[t]-%[w]x%[h]" "%[filename:f].png"
and your output file will be input-400x500.png
If you wanted to do a whole directory full of PNG files on a Mac, you would make a backup and, then on a spare copy do:
for f in *.png; do
convert "$f" -resize 400x500\! -set filename:f "%[t]-%[w]x%[h]" "%[filename:f].png"
done

Problems converting PDF to BMP using ImageMagick?

I would like to convert a PDF to BMP. The PDF I am talking about is available here.
I use ImageMagick with the following command :
convert -verbose -resize 256x256 phantom-brain-ellipse.pdf phantom.bmp
But the result is a phantom.bmp file corrupted or empty file with pixel dimensions 0x0.
The error message is :
"/opt/local/bin/gsx" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" "-sOutputFile=/var/tmp/magick-1199-UNts2yPB9u2%d" "-f/var/tmp/magick-1199rG26g03biUuT" "-f/var/tmp/magick-1199-sNgqMmlD53M"
/var/tmp/magick-1199-UNts2yPB9u21 PNG 263x263 263x263+0+0 8-bit sRGB 54.6KB 0.010u 0:00.009
phantom-brain-ellipse.pdf PDF 263x263 263x263+0+0 16-bit sRGB 54.6KB 0.000u 0:00.000
phantom-brain-ellipse.pdf=>phantom.bmp PDF 263x263=>256x256 256x256+0+0 16-bit sRGB 262KB 0.020u 0:00.019
When I convert to PNG everything works fine with the same command :
convert -verbose -resize 256x256 phantom-brain-ellipse.pdf phantom.png
Any idea how to fix that ?
Partial Solution
This command allowed me to get the right BMP :
convert phantom.png BMP3:phantom.bmp
But I don't get why it works !
Try:
convert -verbose -resize 256x256 phantom-brain-ellipse.pdf[0] BMP3:phantom.bmp
Update/Explanation
PDF is a multipage format. Potentially, the input PDF has more than one page.
ImageMagick commands can select a specific page with the naming convention filename[i], where i is the index of the page. Indexing is zero-based, so some.pdf[0] means: "Use page 1 of this PDF."
The SOMEFORMAT:filename convention determines the file format for output files and overrides any file format which may be indicated by the filename suffix. So an output filename of GIF:some.png will create a GIF file with the (wrong) suffix .png.
The BMP3: is a specific version of the general BMP format. By default, BMP:filename or filename.bmp will produce version 4 of BMP. To get version 3 use BMP3:filename.bmp. To get version 2 use BMP2:filename.bmp.
I used BMP3: because you reported that it worked...

How do I find out which quantum depth image magick is using?

Is there a flag I can pass at the command line to view the quantum depth that image magick was compiled with.
You just need to pass -version to convert and it will show you the quantum depth behind the version number:
Version: ImageMagick 6.8.8-6 Q16 x86 2014-01-29 http://www.imagemagick.org
Just for reference as Dirk's answer is already correct and accepted, there are other ways of getting at the quantum depth and quantum range:
Get Quantum Depth, e.g. Q8, Q16
convert xc: -format "%q" info:
16
Get Quantum Depth in a variable called "Q"
Q=$(convert xc: -format "%q" info:)
Get Quantum Range, i.e. 255 for 8-bit IM builds, 65535 for 16-bit IM builds
convert xc: -format "%[fx:quantumrange]" info:
65535
Get Quantum Range in a variable called "qrange"
qrange=$(convert xc: -format "%[fx:quantumrange]" info:)
Get Quantum Depth and Quantum Range in variables both in one go (bash only)
read Q qrange < <(convert xc: -format "%q %[fx:quantumrange]" info:)

Resources