Change color of region ImageMagick - image-processing

I want to change color region below but it doesn't work. What I'm doing wrong?
Only with -negate it seems to do something but I want to change the region to color #64F733.
convert input.png -region '444x294+530+85' -negate out.png
convert input.png -region '444x294+530+85' -fill '#64F733' out.png
Thanks

You need to "-colorize" it after setting the "-fill" color.
convert input.png -region '444x294+530+85' -fill '#64F733' -colorize 100 out.png

Related

How to draw a image on top of a shape

Simplified example:
I do create a cirlce like following:
magick convert -size 256x256 xc:none -fill #FFFFFF -draw "circle 128,128 256,128" +profile "icc" out.png
And I do convert a given image like following:
magick convert in.png -background none -gravity center -resize 181x181 +profile "icc" out.png
Question:
In my examples above I do have following "core" functions:
-size 256x256 xc:none -fill #FFFFFF -draw "circle 128,128 256,128" +profile "icc"
in.png -background none -gravity center -extent 181x181 +profile "icc"
How can I combine those images WITHOUT saving the first one to a temporary file? I want to create a 256x256 output image, draw the circle to this image and then draw the converted input image on top of the circle (centered).
My current solution
Create 2 different images and combine them like following:
magick convert -composite -gravity Center out1.png out2.png out.png
EDIT - FULL EXAMPLE
PS Script looks like following:
$in = ".\in.png"
$out1 = ".\tmp1.png"
$out2 = ".\tmp2.png"
$out = ".\out.png"
// 1) create circle image
magick convert -size 256x256 xc:none -fill #FFFFFF -draw "circle 128,128 256,128" +profile "icc" PNG32:$out1
// 2) convert input image
magick convert $in -background none -gravity center -resize 181x181 +profile "icc" -colorspace Gray -fill "#E91FCB" -colorize 50 PNG32:$out2
// 3) combine circle + converted image
magick convert -composite -gravity Center $out1 $out2 PNG32:$out
// 4) delete temp. images
Remove-Item $out1
Remove-Item $out2
Input Image:
Output Image (not visible, but it has the white circle as background + a transparent background otherwise):
You can use parenthesised processing like this:
magick -size 256x256 xc:none -fill white -draw "circle 128,128 256,128" \( in.png -background none -gravity center -resize 181x181 -colorspace Gray -fill "#E91FCB" -colorize 50 \) -composite result.png
On Windows, omit the \ before parentheses.

Convert RGB to Grayscale in ImageMagick (but not the entire image)

I have the following bar chart:
I transformed it to greyscale using the following command:
convert image.tif -set colorspace Gray -separate -average image_greyscale.tif
and my result was
It is greyscale indeed, but the axes and the legend are grey as well. This is obvious now, but I'd like them to be black, like in the original image. Something like this:
How can I do it? Remake the bar charts again, with a greyscale palette, is not possible right now.
I think what you want to do in ImageMagick is simpler than your command. Just do
Input:
convert barchart.png -colorspace gray result.png
Result:
You can select the plum colour and change that to gray20 and then select the lime colour and change it to gray80 like this:
magick chart.png -fuzz 10% \
-fill gray20 -opaque "rgb(68,1,84)" \
-fill gray80 -opaque "rgb(122,209,81)" result.png
Or, as a one-liner:
magick chart.png -fuzz 10% -fill gray20 -opaque "rgb(68,1,84)" -fill gray80 -opaque "rgb(122,209,81)" result.png

combine two commands that swap white for black into one

I have a large number of images that are white with transparent backgrounds, and I would like to make them black with transparent backgrounds. It's simple enough to do with GIMP or BIMP, but with thousands of images, command-line seems a better way to go.
In ImageMagick, I've found that the following two commands do what I want:
mogrify -alpha set -channel RGBA -background black -flatten +repage -negate *.png
mogrify -alpha set -channel RGBA -transparent white *.png
However, I'd rather not make two passes. I've tried to combine them a number of different ways:
mogrify -alpha set -channel RGBA -background black -flatten +repage -negate +repage -transparent white *.png
mogrify -alpha set -channel RGBA -background black -flatten +repage -negate -alpha set -channel RGBA -transparent white *.png
mogrify -alpha set -channel RGBA -background black -flatten +repage -negate +repage -alpha set -channel RGBA -transparent white *.png
as well as a couple other permutations of the same ideas. All of them result in a purely black image. What am I missing?
Is there an easier way to invert black and white or at least convert white to black, but leaving the alpha layer untouched?
mogrify -negate *.png
converts white to transparent and transparent to white, and
mogrify -fill black -opaque white *.png
leaves behind messy white edges.
In ImageMagick you can do:
mogrify -format png -fill "rgba(0,0,0,1)" -opaque "rgba(255,255,255,1)" *.png
If your white is not perfectly white, then add -fuzz XX%
mogrify -format png -fuzz 5% -fill "rgba(0,0,0,1)" -opaque "rgba(255,255,255,1)" *.png
The issue is that you need to specify alpha values in your colors, since your image has transparency. Thus use rgba(r,g,b,a) values (note the a) or use hex values with #RRGGBBAA
If using IM 7, then mogrify is replace with magick mogrify
Here is an example using convert. I created a white image with transparency elsewhere from the logo: image.
http://www.fmwconcepts.com/misc_tests/transparency_invert/logot.png
Then ran
convert logot.png -fill "rgba(0,0,0,1)" -opaque "rgba(255,255,255,1)" logot_invert.png
Which returns black where the input was white and keeps the transparency unchanged.
http://www.fmwconcepts.com/misc_tests/transparency_invert/logot_invert.png
Is this not what you want?
Perhaps what you want is the following in ImageMagick. Just a guess until I can see your actual input files.
mogrify -format png -alpha off -negate -alpha on *.png
In ImageMagick, try
mogrify -alpha off -negate -alpha on *.png
This turns off the alpha channel inverts the black and white and then turns on the original alpha channel.
As a test, I did
convert aircon.png -alpha off -negate -alpha on aircon_fred.png
The equivalent of your two mogrify command is
mogrify -background black -alpha background -alpha off -negate -transparent white *.png
I had to replace your -flatten with the equivalent since one needs to reset the compose method to over afterwards for the -transparent to work. But mogrify does not accept -compose over.
As a simple test, I did
convert aircon.png -background black -flatten -negate -transparent white aircon_fred2.png
Another method similar to the first is just to make the whole underlying image black and keep the alpha channel.
mogrify -alpha off -fill black -opaque white -alpha on *.png
Again as a test, I did
convert aircon.png -alpha off -fill black -opaque white -alpha on aircon_fred3.png
However, my first method should give better antialiasing, since it keeps your original alpha channel. Your method will recreate the alpha via -transparent white and will have more stair-stepped aliasing.

Replace only background color of PNG

Here is my code:
#! /usr/bin/env sh
# Generate test image.
convert -size 100x60 xc:blue -fill blue -stroke black -draw "circle 50,30 55,55" in.png
# Make background transparent.
convert in.png -fill none -draw 'matte 0,0 floodfill' -flop -draw 'matte 0,0 floodfill' -flop out.png
# Replace transparent background with green.
mogrify -background green -flatten out.png
# The wrong way.
convert in.png -transparent blue oops.png
mogrify -background green -flatten oops.png
It is based on this snippet: https://snippets.aktagon.com/snippets/558-how-to-remove-a-background-with-imagemagick
Starting with this:
I want to get this:
Not this:
Can I achieve this with a single convert command instead of a convert followed by a mogrify?
I am using ImageMagick 6.8.9-9.
Essentially, you are seeking a "floodfill", like this:
convert in.png -fill green -draw 'color 0,0 floodfill' result.png
That will look at the top-left pixel (0,0) and fill all similarly coloured pixels which are connected to it with green. If your background has slight variations in it, e.g. it's a JPEG, add some fuzz factor
convert in.jpg -fuzz 25% ...
Note that if your circle had touched the top and bottom edges, it would prevent the fill from flooding around to the right side of the diagram. So, let's say you had created your circle like this:
convert -size 100x60 xc:blue -fill blue -stroke black -draw "circle 50,30 50,0" in.png
And then you run the above command, you will get:
If that happens, you can add a single pixel wide border all the way around for the colour to "flow" through first, then flood-fill, and finally remove it later:
convert in.png -bordercolor blue -border 1 -fill green -draw 'color 0,0 floodfill' -shave 1x1 result.png

Replace Colors in Image with Transparency

How do I replace a color in an image which contains transparency with ImageMagick, but afterwards retain the transparency of the original image.
This is very useful for batch-changing of colors in icons.
Updated Answer
Option 1
A simpler option might be like this:
convert start.png -alpha deactivate -fill blue -opaque red -alpha activate result.png
which changes this:
to this:
Option 2
Another option, which uses an in-memory copy of the image, can also avoid the need to create 2 processes and write an intermediate file to disk:
convert start.png -write MPR:orig \
-alpha off -fill blue -opaque red \
MPR:orig -compose CopyOpacity -composite result.png
Option 3
Yet another method, that uses clone instead of MPR:
convert start.png \
\( +clone -alpha off -fill blue -opaque red \) \
+swap -compose CopyOpacity -composite result.png
Original Answer
If I create an image that contains transparency like this:
convert -size 400x400 xc:none -fill red -draw "rectangle 10,10 100,100" -fill blue -draw "rectangle 200,200 300,300" -bordercolor black -border 5 start.png
I'll get this (I am showing it overlaid on a checkerboard just to visualise the transparency):
If I now run this
convert start.png -fill yellow -opaque red result.png
I'll get this (again overlaid on a checkerboard):
Not sure why you need a more complicated, 2-stage process - or have I misunderstood your question?
convert file-in.png -alpha off -fill REPLACEMENT -opaque COLOR file-out.png
then
convert file-out.png file-in.png -compose CopyOpacity -composite PNG32:file-final.png

Resources