Appending a label of variable width to one with a fixed size - imagemagick

I am trying to use an Imagemagick command to create a single-letter text label, give it a shadow, place it on the left side of a fixed-size canvas area, and then append this it another label of fixed height but unknown width. So, the desired result is a single letter on the left side of the final transparent PNG, and another label set about 100px to the right of the origin, e.g. this mockup:
I have all of this working in the following command, except that the shadowed text label is not in a fixed size box (should be 100px by 25px). Here's the result:
I think that what I need to do is to turn off the -trim option somehow, but I'm not sure how to do that. +trim is not a valid option, and +repage doesn't do it.
convert \
\( -background transparent \
\( -gravity west -fill lavender -font Constantia.ttf \
-pointsize 12 label:'x' -trim \
\( +clone -background black -shadow 100x3+0+0 -channel A -level 0,50% \
+channel \) \
+swap +repage -gravity center -composite \) \
-size 100x25 -gravity west \) \
\( -size x25 -fill black -background transparent -font MyriadPro-Semibold.otf \
-pointsize 15 label:'Long legend for x' -gravity west \) \
+append -strip legend_test.png
(The trim option is needed to get the height down to 25px--the shadow operation generates too large a vertical extension otherwise. EDIT: And I guess I was wrong above--even w/o the -trim anywhere in the command, the fixed-size image I'm hoping for doesn't work out.)

Hm, looks like there isn't much of a community for ImageMagick left here. I posted to the ImageMagick phpBB board and was able to put together an answer. Briefly:
The -trim option is not an option that affects every image after it is invoked. Instead, it is essentially a command that executes immediately.
The -extent option can be used to increase or decrease an image to a desired size. Apparently the -size command, which I used in my original code, can only be used to set the initial size of an image, not to change the size of an image that already exists.
Here is the final working command:
convert \
\( -background transparent -extent 100x25 -gravity west \
\( -fill lavender -font Constantia.ttf \
-pointsize 12 label:'x' -trim -extent 100x25 -gravity west \
\( +clone -background black -shadow 100x3+0+0 -channel A -level 0,50% \
+channel \) \
+swap +repage -gravity center -composite \) \
-background transparent -extent x25 \) \
\( -size x25 -fill black -background transparent -font MyriadPro- Semibold.otf \
-pointsize 15 label:'Long legend for x' -gravity west \) \
+append -strip legend_test.png

Related

How to colorize an image with multiply to add transparency to the colour with Image Magick

I would like to colorize an image with two colours, red on the left half and green on the right half but the colorize function just adds a coloured overlay to the image rather than multiplying it on. So I would like my image to look like this but it is currently looking like this. Here is the original image
My code at the moment is this:
convert normal.png \
\( -clone 0 -crop 50x100% -fill red -colorize 60% \) \
\( -clone 0 -crop 50x100%+64 -fill green -colorize 60% \) \
-delete 0 -background none -flatten result.png
I have tried adding -compose multiply -composite to the code but I just get this which has the right effect but I cannot get it to the position that I want, heres the code for that:
convert normal.png \
\( -clone 0 -crop 50x100% -fill red -colorize 70% \) \
\( -clone 0 -crop 50x100%+64 -fill green -colorize 70% \) \
-background none -compose multiply -composite result.png
One simple approach would be to assemble the red-green overlay inside parentheses, then do a multiply composite over the input image.
magick lena_circ.png -size %wx%h \
\( xc:red xc:green +append -scale 50x100% \) \
-compose multiply -channel rgb -composite result.png
That command give me this result...

How to handle multiple elements with imagemagick cli?

We need to put 'information bar's to thousands of image files. For like a week or so i'm trying to learn imagemagick but i just couldn't figure this many elements out so i wanted to ask for a help here.
I get the idea of '-/+append'ing elements and swapping between them but when it comes to 3x3 matrix cells and text/image mixings, i just can't do it. As an example, i can get the 3 rows appended and a column next to it but i can't get to the next step of 'appending 2 more rows together then put them as a column block again' because when i try, all those append gets right or bottom as a whole image.. Well, you will get the idea when you see my brief image below..
magick.exe -size 150x100 -gravity center caption:"txt2" caption:"txt3" caption:"txt4" \
-append -size 94x294 xc:white -border 3 -swap 0,1 \
+append outoutout.jpg
FYI, height/width of rows/columns are there just for example not important.. And here comes MSPaint skills:
You have to create each section separately using parenthesis processing. Then if you want append them appropriately. Alternately, you can create a background image and compose ... -composite each image into its correct location.
Here is an example in ImageMagick using the second method.
Unix Syntax:
magick -size 400x400 xc:white \
\( barn.jpg -crop 400x200+0+0 +repage \) \
-geometry +0+0 -compose over -composite \
\( -size 100x200 xc:white -shave 5x5 -bordercolor black -border 5 \) \
-gravity northwest -geometry +0+200 -compose over -composite \
\( -size 100x200 -background white -gravity center -fill black \
-font Candice label:"Text1\n\nText2\n\nText3" \) \
-gravity northwest -geometry +100+200 -compose over -composite \
\( -size 100x200 -background skyblue -gravity center -fill red \
-font Arial label:"First_line\n\n\nSecond_line" \) \
-gravity northwest -geometry +300+200 -compose over -composite \
result.png
See for example:
parenthesis processing
appending
convert ... -composite

ImageMagick, set relative size in chain of convert operators

I'd need to set the size relative to the size already set. I'd need it because my flow involves defining primitives inside other ones. Eg
convert -size 200x100 xc:black \( -size 30x40% xc:red \) -gravity West -composite out.png
That 30x40% is not working this way, it becomes pixels 30x40. I can achieve this specific goal in the first example by using resize
convert -size 200x100 xc:black \( xc:red -resize 30x40% \) -gravity West -composite out.png
In this second version, xc:red inherits the size 200x100, so -resize works as expected. Though the size of further/inner primitives are not reduced to 60x40, it remains 200x100, so in the third example, the green rectangle has orientation landscape and not portrait
convert -size 200x150 xc:blue \
\( xc:red -resize 50x100% \
\( xc:green -resize 40% \) \
-gravity Center \
-composite \
\) \
-gravity West \
-composite \
out.png
So green area is 80x60 pixels, 40% of 200x150. I'd like to somehow reset the size to the size of xc:red after resize by the time I'm introducing xc:green.
I think you are trying to create canvases whereby each one is a percentage of the the size of the previous one. There may be an easier way, but you could save each canvas (and implicitly its size) in a MPR "Magick Persistent Register" (named lump of RAM) as you create it, then recall the latest one and overwrite it each time you want to do something relative to that:
convert -gravity west -size 200x100 xc:black -write MPR:S \
\( MPR:S -resize 30x40% -fill red -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill blue -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill lime -colorize 100 \) -composite result.png
Alternatively, you could let your bash/POSIX shell do it for you inside an "arithmetic expression":
W=200
H=100
convert -gravity west -size ${W}x${H} xc:black \
\( -size $((W=W*30/100))x$((H=H*40/100)) xc:red \) -composite \
\( -size $((W=W*50/100))x$((H=H*50/100)) xc:blue \) -composite \
result.png
Be aware that the shell only deals with integer maths, so it's not going to end well if you aim for 50% of 25 pixels...

ImageMagick draw rectangle with special corners

Hi I would like to create a mask image with "special corners" I am calling them special because I don't really know how to call them in english here is what I would like to achieve:
what I am using now is
convert xc:black -size 300x300 -fill white -draw "roundrectangle 3,3,296,296,5,5"
but this gives me rounded corners. Thank you in advance for any suggestions.
Here's one way of doing it.
convert -size 300x300 xc:none \
-shave 10 -bordercolor black -border 10 \
-fill black -draw "polyline 0,0 30,0 0,30" \
\( +clone -flip \) -gravity north -composite \
\( +clone -flop \) -gravity south -composite -background white -flatten result.png
That says... "Draw a rectangle your full size and transparent, shave 10 pixels off all round and add a 10 pixel black border (easier than doing the maths and making a 280x280 and adding 10 on each side). Draw a triangle in the top-left. Copy the whole shape and flip it and draw it on top of the original. Copy the whole shape and flop it and draw it again on the original. Now make all the transparent areas white."
Here is another way - maybe a little easier. Draw the original square, then copy it, enlarge it by square-root(2) (i.e. 141%), thicken the borders, rotate 45 degrees and composite it onto itself. Kinda depends how your brain works!
magick -size 300x300 xc:none -shave 10 -bordercolor black -border 10 \
\( +clone -scale 142% -shave 30 -border 30 -rotate 45 \) \
-gravity center -composite -background white -flatten result.png
Here is a link to a page showing how to do what you want along with other effects https://www.imagemagick.org/Usage/thumbnails/#rounded
This is the code from the page:
convert thumbnail.gif -alpha set -compose DstOut \
\( -size 20x15 xc:none -draw "polygon 0,0 0,14 19,0" \
-write mpr:triangle +delete \) \
\( mpr:triangle \) -gravity northwest -composite \
\( mpr:triangle -flip \) -gravity southwest -composite \
\( mpr:triangle -flop \) -gravity northeast -composite \
\( mpr:triangle -rotate 180 \) -gravity southeast -composite \
corner_cutoff.png
You should check out the examples as there is another method you could use for smaller images.

Create an image with text over filling space

I want to create a flare image using imagemagick and then add text on top of it. I was thinking that it was going to be quite easy, but I am having issues adding the text on top of the generated image.
This is so far what I have (keep in mind that the text as well as the dimension are dynamic):
FLARE:
\(
-fill transparent -size 300x1 xc: +noise Random -channel G -separate +channel \
-scale 300x300\! \
\( -size 300x300 gradient: -evaluate cos .5 \) \
-compose hardlight -composite \
-virtual-pixel HorizontalTileEdge -distort Polar -1
\)
TEXT
-fill red \
-gravity center \
-font Arial \
annotate:"Logo 12345678"
EDIT:
The text is showing, but I can't figure out how to overimpress the text on top of the image in a way that it will fill the image for the full width (from left to right, with some padding if possible)
Figured out:
convert \
\( -background transparent -size 300x1 xc: +noise Random -channel G -separate +channel -scale 300x300\! \( -size 300x300 gradient: -evaluate cos .5 \) -compose hardlight -composite -virtual-pixel HorizontalTileEdge -distort Polar -1 \) \
\( -background transparent -size 300x300 -fill blue -gravity center -font Arial caption:"Logo \\n13474899" \) \
-gravity center -composite /tmp/flare_2_final.png
Now I need to figure out how to change the background color of the flare from black to gray and I am done.

Resources