Setting opacity of each image drawn on canvas with imagemagick - imagemagick

I have the command below which takes multiple image sources and draw it onto 1 output.png file.
Convert img1.jpg -resize 1000x1000!
-draw "image over 169,555 875,109 'img1.png'"
-draw "image over 29,55 375,209 'img2.png'"
-draw "image over 129,525 15,29 'img3.png'"
png24:output.png
Is there a way to set the opacity of each of the images being drawn? where some might have opacity of 60% , while others have 100%
I tried this but doesn't work:
Convert img1.jpg -resize 1000x1000!
\( -alpha set -channel A -evaluate set 60% \) -draw "image over 169,555 875,109 'img1.png'"
\( -alpha set -channel A -evaluate set 100% \) -draw "image over 29,55 375,209 'img2.png'"
\( -alpha set -channel A -evaluate set 90% \) -draw "image over 129,525 15,29 'img3.png'"
png24:output.png
Thanks in advance

I think you want something like this...
convert img1.jpg -resize 1000x1000! \
\( img1.png -alpha set -channel A -evaluate set 60% -resize 707x447 \) -geometry +169+109 -composite \
\( img2.png -alpha set -channel A -evaluate set 100% -resize 347x155 \) -geometry +29+55 -composite \
\( img3.png -alpha set -channel A -evaluate set 90% -resize 115x497 \) -geometry +15+29 -composite \
png24:output.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...

Treasure hunt for edges

I want to make a children's treasure hunt where the next location is given by a picture e.g.
To make a more suitable printable picture, I can use -canny like this:
convert hut.jpg -canny 0x1+10%+30% -negate hutCanny.jpg
To make it more interesting, I was thinking that I want to make two images -one with horizontal lines and one with vertical lines:
convert hut.jpg -colorspace gray -morphology Convolve Sobel -negate hutH.jpg
convert hut.jpg -colorspace gray -morphology Convolve Sobel:90 -negate hutV.jpg
I would like the location to be only guessable when both picture are found and can be combined using a light source. The problem is that Sobel not only detects vertical lines but also angled lines. As can be seen, the location is far too easy to recognise with just one picture. I have been trying with different kernels and trying to erode the pictures. -nothing woks.
How do I make two images that by themselves are not 'guessable' but can be combined to one. e.g. by making one image with only near horizontal lines and an other with only near vertical lines?
You could do something like the following in ImageMagick. Make a random mask and apply it to the image. Then invert the mask and do the same. The two images, when added together, will make the input.
Input:
convert \( hut.png -write mpr:img +delete \) \
\( mpr:img +noise random -channel g -separate +channel -blur 0x5 -threshold 50% +write mpr:mask +delete \) \
\( mpr:img mpr:mask -compose multiply -composite +write hut_out1.png \) \
\( mpr:img \( mpr:mask -negate \) -compose multiply -composite +write hut_out2.png \) \
null:
Output 1:
Output 2:
ADDITION
If it has to be grayscale, then you can do the above and make each output gray.
convert \( hut.png -write mpr:img +delete \) \
\( mpr:img +noise random -channel g -separate +channel -blur 0x5 -threshold 50% +write mpr:mask +delete \) \
\( mpr:img mpr:mask -compose multiply -composite -colorspace gray +write hut_out1.png \) \
\( mpr:img \( mpr:mask -negate \) -compose multiply -composite -colorspace gray +write hut_out2.png \) \
null:
Output 1:
Output 2:
Now add them together to reconstitute:
convert hut_out1.png hut_out2.png -evaluate-sequence add hut_out12.png

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...

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.

Create drop shadow effects in Imagemagick

The border shadow effects used in the images of this blog post seem to be embeded in the images themselves (not css3). How can it be created in imagemagick?
Edit 1:
The solution which I found quite accidentlly is posted below as an answer.
Somehow I found the command which does what I wanted exactly:
For images which are already scaled and compressed:
convert input.jpeg -bordercolor white -border 13 \( +clone -background black -shadow 80x3+2+2 \) +swap -background white -layers merge +repage output.jpg
For creating thumbnails:
convert input.jpeg -thumbnail 200x200 -bordercolor white -border 6 \( +clone -background black -shadow 80x3+2+2 \) +swap -background white -layers merge +repage output.jpg
For raw images:
convert input.jpeg -scale 600x400 -quality 86 -strip -bordercolor white -border 13 \( +clone -background black -shadow 80x3+2+2 \) +swap -background white -layers merge +repage output.jpg
There is a -shadow argument on convert that has options to do this.
http://web.archive.org/web/20120607055659/http://blog.bemoko.com/2009/07/01/add-shadow-and-border-to-images-with-imagemagick/
Shutter uses the following command https://github.com/shutter-project/shutter/blob/master/share/shutter/resources/system/plugins/perl/spshadow/spshadow#L375
convert in.png -gravity 'northwest' -background 'rgba(255,255,255,0)' -splice '10x10' \( +clone -background '#005f005f005f0000' -shadow "80x3-1-1" \) +swap -background none -mosaic +repage \( +clone -background '#005f005f005f0000' -shadow "80x3+5+5" \) +swap -background none -mosaic +repage out.png

Resources