GraphicsMagick :: -alpha and -annotate equivalent of ImageMagick - imagemagick-convert

ImageMagick convert have -alpha option that :
-alpha option activate, deactivate, reset, or set the alpha channel
is there an equivalent option in GraphicsMagick convert?
Similarly, is there an -annotate option?
Thank you!

I was trying to convert a transparent PNG to JPG but the result wasn't satisfying (as per attached). I managed to add a white background using the following command line script
magick convert image1.png -background white -alpha remove -alpha off image2.jpg
The nodejs's gm utility code I used to get the same result:
gm('PATH/TO/IMAGE')
.setFormat('jpg')
.fill('white')
.opaque('none')
.write('PATH/TO/OUTPUT', function(err, image) {
if (err) return cb(err);
return cb(null, image);
});

Related

How to batch-resize PNG files?

I have a number of PNG image files that I'd like to increase in size. I do not want to rescale the image. I just want to extend the white background further down and to the right. In GIMP terms what I want is to increase the Canvas Size, and cover the increased area with white pixels, in a batch context. The input images may be different sizes, but the output images should all be a fixed size (e.g.: 1280 x 720 pixels).
I've tried this with various online tools, with GIMP, and with a very old version of Photoshop. Most of the tools I've tried to date do one of the following which I don't want:
Rescale the existing image to cover the new canvas size, or
Center the starting image and extend the canvas in all directions, or
Fail to perform this in a batch mode.
I just want to extend existing PNG images with additional white pixels down and to the right. What's the easiest way to do this to a large number of files?
imagemagick is a common tool for this. the -crop operation combined with -gravity can probably do what you want.
magick input.jpg -crop 1000x1000+0+0\! -background white -flatten output.png
source for the magick spell: https://legacy.imagemagick.org/Usage/crop/
In ImageMagick, you process a whole folder of images using mogrify. You can extend them using -extent. With mogrify, it is wise to first create a new empty directory to hold the results. So
cd image_directory
mogrify -format png -path path/to/new_directory -background white -gravity northwest -extent WxH *.png
Where WxH, is your desired final width and height after padding with the white. This assumes that all images will be padded to the same width and height
Expand By Size
cd test1
mogrify -format png -path ../test2 -background white -gravity northwest -extent 500x500 *.jpg
Expand By Percent
cd test1
mogrify -format png -path ../test2 -background white -gravity northwest -extent 150x150% *.jpg
For ImageMagick 7, add magick before mogrify. So "magick mogrify ..."
The ImageMagick command that did what I needed used "convert" with the -geometry and -composite arguments. In a Windows batch file context:
for %%a in (img*.png) do (
magick convert -size 1280x720 xc:white "%%a" -geometry 512x384+40+40 -composite "work-%%~na.pdf"
)

ImageMagick to compare 2 images, marked with 2 different color on the output image

I want make 2 different colors on the output image when using Imagemagick. I have an original image with "Hello World" in it. And a modified image with "Hello Warcraft" in the same area. The default compare command will give me a image and mark all the differences with red.
Now I want to use 2 different colors like "orld" marked as red, and "arcraft" marked as another color, maybe blue. Is ImageMagick able to do this?
If not, how to use ImageMagick to transfer a specified color to another one?
Below are the sample.
Image A
Image B
Then I use the compare like: compare imageA.png imageB.png imageC.png
then the Image C will be:
Image C
But now I just know there are some differences between Image A and Image B. so I want to make some color-code on the Image C, it could be like below Image D:
Image D
from this I can know which parts are the same, and Green means what the difference on Image A and Red means what's the difference on Image B.
You can do this in ImageMagick 6 (Unix Syntax).
ImageA:
ImageB:
convert img1.png img2b.png \
-define compose:args="0,1,-1,0.5" \
-compose mathematics -composite -auto-level \
\( xc:red xc:blue +append \) -clut diff.png
This is a biased difference. Anything above 0.5 or mid gray (in normalized values) will be one color corresponding to one image and anything below 0.5 will be the other color corresponding to the other image.
See clut and compose mathematics
For ImageMagick 7, change convert to magick.
ADDITION:
Given your new input images. Here is how to do that:
imageA:
imageB:
convert imageA.png imageB.png -write mpr:img +delete -fill white -colorize 80% \
\( mpr:img -compose minus -composite -threshold 0 -background red -alpha shape \) \
\( mpr:img +swap -compose minus -composite -threshold 0 -background blue -alpha shape \) \
-background none -compose over -flatten result.png
Sorry, I used blue in stead of green. But you can change that if you want.

mix single channel images into color image

each representing a channel and I want to merge them into a single one, like RGB image. The images are RAW, so no file header. I have managed to mix them with
cat imgPl0.raw imgPl1.raw imgPl2.raw >> img.rgb
but this is mixing the planes one after the other, but is there a way to do an interlaced mix ?
Maybe using imagemagick there is another way ?
Well, what I need at the output is a rgb image (not a png, sadly imagemagick is creating a png as output) containing the data interlaced. To be more explicit, cat-ing the images is going to make a rgb image plane-interlaced (that is rrrrrr...ggggggg...bbbbbbb). What I want is an operation that is creating a rgb image line-interlaced (that is rrr...ggg...bbb...rrr...ggg...bbb...rrr...ggg...bbb...). Sorry for not being explicit from the beginning.
About the data, it seems it is 12 bpp or 14 bpp little endian
ImageMagick offers a few techniques, but you'll need to be responsible for defining all the information missing from the headers. Stuff like image size, quantum depth, and colorspace.
One approach.
convert -size 70x46 -depth 8 \
r:imgPl0.raw g:imgPl1.raw b:imgPl2.raw \
-set colorspace RGB -combine -colorspace sRGB \
output.rgb
Another option is to create a blank canvas, and copy the data from the raw files over to the correct canvas channels.
convert -size 70x46 xc: -depth 8 \
r:imgPl0.raw -compose CopyRed -composite \
g:imgPl1.raw -compose CopyGreen -composite \
b:imgPl2.raw -compose CopyBlue -composite \
-colorspace sRGB output.rgb
Other examples can be found here.
Also note: I'm assuming that these .raw data files only contain single channel samples, are unsigned character color sizes, and have a 70x46 image size. YMMV
Update
Well, what I need at the output is a rgb image (not a png, sadly imagemagick is creating a png as output)
Sorry about that. Just switch output.png to output.rgb. ImageMagick will do the rest.
About the data, it seems it is 12 bpp or 14 bpp little endian
Adjust -depth from 8 to 12, or 14 bits-per-part.
There's also a -endian LSB option, but I don't think that's needed.
What I want is an operation that is creating a rgb image line-interlaced
Easy. Set the -interlace Line options.
So... My previous answer is still helpful, but just needs some additional options.
convert -size 70x46 -depth 12 \
r:imgPl0.raw g:imgPl1.raw b:imgPl2.raw \
-set colorspace RGB -combine -colorspace sRGB \
-interlace Line output.rgb
or
convert -size 70x46 xc: -depth 12 \
r:imgPl0.raw -compose CopyRed -composite \
g:imgPl1.raw -compose CopyGreen -composite \
b:imgPl2.raw -compose CopyBlue -composite \
-colorspace sRGB -interlace Line output.rgb
Hope that get's you close.
If your data is 8 bits per sample, you can do it like this which whilst not very efficient, doesn't require any code writing or compiling or anything:
#!/bin/bash
# Bytes per row
bpr=100
row=0
# Loop through all rows of file
while :; do
# Read a row from each channel and output on stdout redirected to result.rgb
for ((chan=0;chan<3;chan++)); do
dd if=imgPl${chan}.raw bs=$bpr count=1 skip=$row > row.tmp 2> /dev/null
[ ! -s row.tmp ] && exit
cat row.tmp
done
((row+=1))
done > result.rgb

How can I interlace two images using ImageMagick?

I have 2 images of the same size, called image1.png and image2.png. In ImageMagick, is there any way to merge the two images by taking the odd lines from image1.png and merge with the even line from image2.png ?
Sure, make alternate rows transparent:
# Make red test image
convert -size 300x200 xc:red red.png
# Make blue test image
convert -size 300x200 xc:blue blue.png
# Merge with alternate lines made transparent
convert red.png \( blue.png -alpha on -channel A -fx 'j%2' \) -composite result.png
Or, an alternative way of thinking about it is to load both images and then choose pixels from either the first (u) or the second (v) depending on the row:
convert red.png blue.png -fx 'j%2 ? u : v' result.png
On Windows, these two come out as:
REM Do Windows style commands
convert red.png ^( blue.png -alpha on -channel A -fx "j%2" ^) -composite result.png
and
REM Windows style
convert red.png blue.png -fx "j%2 ? u:v" result.png

color pixel count with GraphicsMagick

I need to count pixels in an image that are not background color.
I am calling this from PHP (it's from ImageMagick):
gm convert test.png -fill black +opaque "rgb(255,255,255)" -fill white -opaque "rgb(255,255,255)" -print "pixels = %[fx:w*h*mean]\n"
But it does not give any result, nothing.
I tried using histogram instead:
gm convert test.png -define histogram:unique-colors=true -format %c histogram:info.txt
That works, but gives values for every color and more details, I just need a single number please.
You have got a couple of issues here. You seem to be trying to mix GraphicsMagick with ImageMagick when they are not the same thing.
Firstly, GraphicsMagick does not have the +opaque operator that ImageMagick has.
Secondly, it doesn't have the -fx operator that ImageMagick has for doing maths.
I would suggest you move to, the more powerful, ImageMagick. Then it will work as you expect:
# Create a test image
convert -size 200x200 xc:black xc:white xc:red +append image.png
# Count the white pixels
convert image.png -fill black +opaque "rgb(255,255,255)" -print "pixels = %[fx:w*h*mean]\n" nul:
pixels = 40000
If you really, really must do it with GraphicsMagick, I can only suggest the following - which is heavily based on #GlennRanders-Pehrson answer here:
gm convert image.png +matte -matte -transparent white -operator matte negate 1 result.png
gm identify -verbose result.png | grep -EA5 "Opacity:|Geometry:" | grep -E "Mean|Geometry"
Geometry: 600x200
Mean: 43690.00 (0.6667)
Mean: 43690.00 (0.6667)
And your answer will be:
600 * 200 * (1 - 0.667)

Resources