ImageMagick: Can I control which instance is used from a multi-resolution .ico file? - imagemagick-convert

We have an in-house tool that does some operations on windows icon files. Turns out that it only really supports the type of .ico files that are generated by ImageMagick. Should be no big deal because we currently use ImageMagick anyway to generate sizes not supplied in the original image. My plan was to always use ImageMagick to generate images, even when the original .ico file contained an image with the correct resolution, to ensure the image was of the correct format.
So far, so good. However in practice this does not seem to work the way I expect it to. Specifically I'm after a 256x256 icon. The original file contains (I believe) a 256x256 version as it looks high res when viewed from the browser. However, the output file from ImageMagick is obviously a low-resolution one scaled up.
The command line I'm using is:
convert.exe orig.ico -background #FFFFFFFFFFFF0101 -compose Copy \
-gravity Center -scale 256x256! -depth 8 temp2.ico
Question: is there some better set of commands to use, which might start from the 256x256 icon?

Your orig.ico file probably contains multiple dimensions. They will also be stored in the output file. This means a dimension of 16x16 will be upscaled to 256x256 and that produces an ugly image. The 256x256 resolution is most likely the first dimension. You can see all the dimensions with the following command:
identify.exe orig.ico
With the command below you can get a specific dimension/image by specifying the index (starts at zero):
convert.exe orig.ico[0] -background #FFFFFFFFFFFF0101 -compose Copy ^
-gravity Center -scale 256x256! -depth 8 temp2.ico
If the 256x256 dimension is the last image you should set the index to -1:
convert.exe orig.ico[-1] -background #FFFFFFFFFFFF0101 -compose Copy ^
-gravity Center -scale 256x256! -depth 8 temp2.ico

Related

Batch convert white background to transparent

Seeking to set a folder of PNG line drawings to background transparent and getting lost in examples and options recommended for other cases. Essentially when I find a line of command that seems to fit I don't know how to apply it to an entire folder. Also getting lost in options like fuzz and anti-alias which I'm not even sure would benefit my images, below. I'm on a Mac running v7 of Magick and really appreciate your kind help.
Simplest Sample
Most Complex Sample
This should do what you want in Imagemagick 7. You should use magick mogrify to process a whole folder of images. To convert white to transparent in an image you can use -fuzz XX% -transparent white, where XX is a percent tolerance for nearby colors. For JPG, typically about 15% seems to work due to jpg compression change of flat colors. So I put your images into a folder called drawings and create a new empty folder called drawings2 to hold the output image, which need to be PNG (or TIFF) so use transparency.
cd
cd desktop/drawings
magick mogrify -path ../drawings2 -format png -fuzz 15% -transparent white *.jpg
Results:
See https://imagemagick.org/Usage/basics/#mogrify

Batch Resize Photos While Maintaining the Aspect Ratio AND Fitting to a specific pixel size

I am looking to batch resize pictures to a specific pixel size while maintaining the aspect ratio. Is their a way that the picture aspect can be preserved and the rest of the space can be filled in with white? For example, I resize an image to 200 x 200 and due to preserving the aspect ratio it is changed to 200 x 194. I would like the actual image to remain 200 x 194 and white space to fill in the remaining area to create an image that is 200 x 200 px. Thank you in advance!
You can do that with ImageMagick which is included in most Linux distros and is available for macOS and Windows.
Just in Terminal, or Command Prompt on Windows:
magick input.jpg -background white -resize 200x200 -gravity center -extent 200x200 result.jpg
If you have many files to do, you may be better using ImageMagick's mogrify command, which will do them all in one go for you! So make a new directory called processed for the output files and then use this to process all PNG files in the current directory:
magick mogrify -path processed -background white -resize 200x200 -gravity center -extent 200x200 '*.png'
I don't know if you are on Windows or not, so you may or may not need the single quotes around the filenames at the end of that command. Basically, it determines whether the expansion of the filename list is done by the shell (which has limitations on the number of files), or internally by ImageMagick (which does not).
If you are running anything older than v7, the commands become:
convert input.jpg ...
or
mogrify ...

AutoMerge two images files to one

I am using Montage command-line tool to merge the two jpg images. The output jpg contains the common strip present in the input jpgs. Below is the command to merge two jpgs:
montage -geometry 500 input1.jpg input2.jpg output.jpg
How can I avoid the common area in the output file?
Is there any other tool available to auto-merge the two images?
In ImageMagick, you can simply append the two images side by side or top/bottom.
convert image1.jpg image2.jpg -append result.jpg
will do top/bottom
convert image1.jpg image2.jpg +append result.jpg
will do left/right.
You can append as many images as you want of different sizes. You can use the -gravity setting to align them as desired. If different sizes, then you will have background regions, which you can control the color by using -background somecolor. If desired, you can resize the images by adding -resize 500 after reading the inputs and before the append.
See http://www.imagemagick.org/Usage/layers/#append
I suspect you are trying to make a panoramic by stitching two images with an area of common overlap.
So, if we start with left.png:
and right.png:
You probably want this:
convert left.png -page +200 right.png -mosaic result.png
Just so you can see what happens if I change the x-offset and also how to add a y-offset:
convert left.png -page +280+30 right.png -mosaic result.png
If you want to do what Mark Setchell is suggesting, then using -page is probably the best method, if you have more than one image to merge and the offsets are different. If you only have on pair of image, you can overlap them using +smush in ImageMagick. It is like +append, but allows either overlap or a gap according to the sign of the argument. Unlike -page, it only shifts in one direction according to +/- smush. Using Mark's images,
convert left.jpg right.jpg +smush -400 result.jpg

Using ImageMagick to add whitespace to images in bulk

I have a bunch of images that are rectangular and I need them to be square, i.e. 1000x1000, so I've decided to use ImageMagick to pad the sides of the image with the amount of whitespace necessary to make the image square.
I've found the code from the following link useful (see next paragraph). But this requires me to process each image individually, to set the filename and then the -thumbnail dimensions. How can I use this same process to process an entire folder?
Here's the code and the link to it:
http://imagemagick.org/Usage/thumbnails/#pad
convert -define jpeg:size=200x200 hatching_orig.jpg -thumbnail '100x100>' \
-background white -gravity center -extent 100x100 pad_extent.gif
It is not very clear from your question what you actually have (i.e. how big your images are? what format are they?), nor what you actually want (you only provide an example that doesn't do what you want. But I'll take your question at the face-vale of the title and hope you can work out anything missing from there.
If you want to do ImageMagick in bulk, you either need to use a loop in bash, like this:
#!/bin/bash
for f in *.jpg; do
convert "%f" ...
done
or use IM's mogrify command. That is quite a powerful command, so make a backup of your images before you even think of trying to use it.
Let's assume you want to place all JPEG images in the current directory onto a white 1000x1000 pixel background. You would do this:
mogrify -background white -gravity center -extent 1000x1000 *.jpg
Updated Answer
It should be possible to do the resizing and the white padding in a single ImageMagick command without needing to use SIPS as well, like this if you now want 1200x1200 square images padded with white:
mogrify -background white -gravity center -resize 1200x1200\> -extent 1200x1200 *.jpg

“Diff” an image using ImageMagick

How can I get the difference between two images? I have the original image. Someone has written on an exact duplicate of the original image. Now, I need to compare the original to the written on image and extract just the writing in image format.
Example: I have a picture of a house. Someone took a copy and wrote “Hello!” on the copy. I want to somehow compare the two pictures, remove the house, and be left with an image of the words “Hello!”.
Is this possible with ImageMagick? I know there are ways to get the statistical difference between images, but that is not what I am looking for.
My own favorites are these two:
compare image1 image2 -compose src diff.png
compare image1 image2 -compose src diff.pdf
The only difference between the 2 commands above: the first one shows the visual difference between the two images as a PNG file, the second one as a PDF.
The resulting diff file displays all pixels which are different in red color. The ones which are unchanged appear white.
Short and sweet.
Note, your images need not be the same type. You can even mix JPEG, TIFF, PNG -- under one condition: the images should be of the same size (image dimension in pixels). The output format is determined by the output filename's extension.
Should you, for some reason, need a higher resolution than the default one (72 dpi) -- then just add an appropriate -density parameter:
compare -density 300 image1 image2 -compose src diff.jpeg
Illustrated examples
Here are a few illustrations of results for variations of the above command. Note: the two files compared were even PDF files, so it works with these too (as long as they are 1-pagers)!
Left: Image with text Center: Original image Right: Differences (=text) in red pixels.
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-compose src \
diff-compose-default.pdf
This is the same command I suggested earlier above.
Left: Image with text Center: Original image Right: Differences in 'seagreen' pixels.
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-compose src \
-highlight-color seagreen \
diff-compose-default.pdf
This command adds a parameter to make the difference pixels 'seagreen' instead of the default red.
Left: Image with text Center: Original image Right: Blue diffs (but w. some context background)
l
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-highlight-color blue \
diff-compose-default.pdf
This command removes the -compose src part -- the result is the default behavior of compare which keeps as a lightened background the first one of the 2 diffed images. (This time with added parameter to make the diff pixels appear in blue.)
While compare does a good job for many applications, I found that sometimes I prefer a different approach, particularly when comparing images which are mostly grayscale:
convert '(' file1.png -flatten -grayscale Rec709Luminance ')' \
'(' file2.png -flatten -grayscale Rec709Luminance ')' \
'(' -clone 0-1 -compose darken -composite ')' \
-channel RGB -combine diff.png
The idea is follows: convert both file1.png and file2.png to grayscale. Then trat the first as the red channel of the resulting image, the second as the green channel. The blue channel is formed from these two using the darken compose operator, which essentially means taking the minimum.
So things which are white in both images stay white. Things which are black in both images stay black. Things which are white in the first image but black in the second turn red, and things which are white in the second but black in the first turn green.
The result gives you a nicely color-coded image where you can easily associate green with the first input and red with the second. Here is an example where I'm using this to compare the output from LaTeX against that from KaTeX (before I fixed some bug to make this better):
You can combine the approaches, using compare to see where something changed and then using the above to see in more detail how it changed.
From ImageMagick 6.3.4, you can use -compose ChangeMask (see also "Removing a Known Background" and following sections).
For example, using IM7 and these images stone.png, diamond_ore.png, and netherrack.png:
magick diamond_ore.png stone.png -fuzz 15% -compose ChangeMask -composite diamond_ore_overlay.png gives:
magick netherrack.png \( diamond_ore.png stone.png -fuzz 15% -compose ChangeMask -composite +compose \) -composite nether_diamond_ore.png gives:

Resources