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
Related
It is straightforward to draw a filled rounded rectangle in ImageMagick v6:
convert -size 800x600 xc:transparent -fill white -stroke black -strokewidth 20 -draw "roundRectangle 50,100,600,500 32,33" output.png
But how do you draw a rounded rectangle with transparent fill over an existing image? (Only drawing the outside borders, no filling of the insides.)
Input image:
Desired output image:
Here is how to draw round rectangle on transparency in Imagemagick 6. The draw command has 3 arguments: top-left corner, bottom-right corner, corner radii.
convert -size 500x500 xc:transparent -fill transparent -stroke black -strokewidth 10 -draw "roundrectangle 100,100 399,399 30,30" roundrectangle.png
See https://imagemagick.org/Usage/draw/#primitives
Use imagemagick and differentiate between inner and outer corners:
magick input.png +write mpr:input ( +clone -alpha off -fill black -colorize 100 -fill white -draw "roundRectangle 64,71 663,504 28,28" -fill black -draw "roundRectangle 83,92 641,484 8,8" ) -alpha off -compose copy_opacity -composite mpr:input -compose over -composite output.png
Update in July 5 2022 AM:
magick input.png +write mpr:input( mpr:input -alpha off -threshold 101% -fill white -draw "roundRectangle 64,72 660,502 26,26" -fill black -draw "roundRectangle 84,92 640,482 6,6" ) -channel-fx "| gray=>alpha" mpr:input -compose over -composite output.png
I am trying to add a border to the 100x100 blue square only, without adding it to the 200x200 background red frame. How would I achieve this? I've experimented with many configurations including parentheses ().
exec("convert -size 200x200 xc:red -size 100x100 -draw rectangle -bordercolor yellow -border 2 xc:blue -geometry +5+5 -composite temp_bg.png ")
Try starting with the blue box, adding a border and then extending like this:
magick -size 100x100 xc:blue -bordercolor lime -border 10 -gravity northwest -background red -extent 400x400 -bordercolor yellow -border 10 result.png
Sorry, no time, gotta dash - add in a -page ... or -geometry ... before extent to set the position of the blue box.
I am using imagemagick to draw a border on the top of an image.
THIS IS MY CODE:
convert source.jpg -stroke red -strokewidth 2 -fill transparent -draw \"roundrectangle 10,10 628,151 10,10\" source.jpg
This works fine but i need to be able to position the -draw where i want.
I tried to position the border like using -geometry like so:
convert source.jpg -stroke red -strokewidth 2 -fill transparent -geometry +5+15 -draw \"roundrectangle 10,10 628,151 10,10\" source.jpg
But this does not position it where i want. I also tried using -gravity and that doesn't work either!
Could someone please advise on this?
Thanks in advance.
Bonzo is correct, you cannot use -geometry with -draw.
In ImageMagick with -draw you can also translate to where you want the center to be and then specify +- distances to the corners from the center placement.
Suppose you have a 100x100 size box you want draw and you want it centered at 250,250, then
convert input.jpg -stroke red -strokewidth 2 -fill transparent -draw "translate 250,250 roundrectangle -50,-50 50,50 10,10" output.png
That makes it easier to draw the same size boxes at different locations.
see
http://www.imagemagick.org/Usage/draw/
http://www.imagemagick.org/script/magick-vector-graphics.php
I wrote this script and it's working fine, but I would like to do all of it in one step on the fly, without the extra temp image.
explanation: i have a lot of broken image files and i want to draw a circle underneath each image. for this i have to create a temporary image circle.png and then use "image DstOver" to place it below each of the images:
convert -size 200x200 xc:transparent -fill red -draw 'translate 100,100 circle 0,0 100,0' circle.png
mogrify -draw "image DstOver 0,0 0,0 'circle.png'" images/*.png
Something along the lines of:
mogrify -fill red -draw "DstOver translate 100,100 circle 0,0 100,0" images/*.png
But this is always giving me an error, no matter where i place the DstOver:
mogrify: non-conforming drawing primitive definition `DstOver' # error/draw.c/DrawImage/3169.
Composition operators like "DstOver" are only used with the "image" primitive of "-draw". Just omit it. See the "-draw" entry in the ImageMagick commandline documentation.
You can have multiple "-draw " options, some drawing figures such as "circle ..." and others such as "image DstOver ...".
I am not sure what you are trying to do, but in general, mogrify will have trouble doing anything with multi-image operators or stack operators. The only exception I know of is the -draw image operator, so you need to create your image up-front and then use that:
# Blue rectangle with transparent centre
convert -size 200x200 xc:none -bordercolor blue -border 50 start.png
# Your circle
convert -size 200x200 xc:white -fill red -draw 'translate 100,100 circle 0,0 100,0' circle.png
# Now underlay
mogrify -draw "image DstOver 0,0 0,0 'circle.png'" start.png
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