Page 1 of 1

Apply shadow to rectangle with alpha

Posted: 2019-02-16T05:36:56-07:00
by jawbreaker
Version: ImageMagick 7.0.8-27 Q16 x86_64 2019-02-10
Platform: Linux
API: Shell\Bash

I'm working on a script that draws a rectangle over a wallpaper image so that I can overlay some text with another utility. The fill color is supplied by a variable, so it could be any color with or without alpha. That's pretty easy:

Code: Select all

convert infile.png -draw "fill #000000E6 rectangle 25,1050 325,970" outfile.png
I would also like to add a shadow to the rectangle. The end result should look something like this:

Image
(this is only a demonstration with a transparent terminal over solid color on left and actual wallpaper on right)

After looking through the examples, I'm unsure if I can actually do this the way I'm expecting to. Since the rectangle may have alpha, layering the first rectangle over a blurred rectangle would affect the overall color\transparency of the rectangle, right?

And, of course, I want to do this in one shot without intermediate files if possible. Any suggestions?

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-16T07:42:55-07:00
by snibgo
jawbreaker wrote:Since the rectangle may have alpha, layering the first rectangle over a blurred rectangle would affect the overall color\transparency of the rectangle, right?
Yes.

You are making an image from three components. From front to back, these are: (1) a semi-transparent rectangle, (2) a semi-transparent shadow of that rectangle and (3) a wallpaper image.

As the rectangle is semi-transparent, you will be able to "see through" it to both the shadow and the wallpaper.

If you wanted, you could make the shadow transparent where the rectangle is. Then the shadow wouldn't be visible through the rectangle.

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-16T09:34:54-07:00
by jawbreaker
I still don't understand how to even get the shadow to\under\around the rectangle in the first place. Every attempt ends up with the first rectangle being drawn on the wallpaper, and then the entire image gets shadowed.

Code: Select all

convert infile.png \
    \( -draw "fill #000000E6 rectangle 25,1050 325,970" \) \
    \( +clone -background black -shadow 80x3 \) +swap \
    -layers merge +repage outfile.png
How do I tell IM what to apply the shadow to?

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-16T10:13:50-07:00
by snibgo
You are directly drawing a rectangle on infile.png, and then making a shadow of the result.

Instead, you need to make an image that is the rectangle. Then make a shadow of that, then merge those two images, then composite that over infile.png.

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-17T14:12:13-07:00
by jawbreaker
I was finally able to piece this together.

Code: Select all

convert -size 300x80 xc:\#000000e6 -fill none rectangle.png
convert rectangle.png \
    \( -clone 0 -background \#000000e6 -shadow 100x5+0+0 \) +swap \
    -background none -layers merge +repage shadow.png
composite -compose Dst_Out -gravity center \
    rectangle.png shadow.png -alpha Set shadow_mask.png
convert shadow_mask.png rectangle.png -geometry +10+10 -composite rect_shadow.png
convert infile.png rect_shadow.png -geometry +24+674 -composite outfile.png
Is there anything I can do to streamline this at all? Anything I'm doing wrong?

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-17T14:32:48-07:00
by snibgo
For v7, I suggest you use "magick", not "convert" or "composite"

You could do all the work in a single "magick" command, with no intermediate files.

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-17T15:28:02-07:00
by jawbreaker
snibgo wrote: 2019-02-17T14:32:48-07:00 For v7, I suggest you use "magick", not "convert" or "composite"

You could do all the work in a single "magick" command, with no intermediate files.
That's what I said I wanted to do from the start. I was only following your extremely vague suggestions. This is my first time working with IM, so some details would be appreciated.

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-17T19:26:34-07:00
by fmw42
Post your infile.png and outfile.png so we can help your compact your code.

When I try your code with an arbitrary input, the output just has a black rectangle with a slight shading around it inside the original image.

I do not understand your two images that you originally posted. Please clarify what you want or show your input and output from your code.

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-17T20:02:52-07:00
by fmw42
This is a guess at what you want. (IM 7 syntax)

Background:
Image

Foreground:
magick -size 300x100 xc:black -fill white -gravity center -pointsize 24 -annotate +0+0 "TESTING" infile.png

Code: Select all

http://www.fmwconcepts.com/misc_tests/shadows3/infile.png
Processing:

Code: Select all

magick infile.png \
\( -clone 0 -background none -gravity center -extent 325x125 -blur 0x6 +write tmp1.png \) \
+swap -gravity center -compose over -composite +write tmp2.png  \
\( barn.jpg -alpha set -channel a -evaluate set 75% +channel -background white -flatten \) \
+swap -gravity north -compose over -composite \
result.png
I saved some temp files to show you what I was doing. You need to review the use of parenthesis processing. See https://imagemagick.org/Usage/basics/#parenthesis

tmp1:
Image

tmp2:
Image

Note I processed the barn.jpg background image to make it lighter so that the shadows show for you. You do not need to add that code, just the background image. It looked like you wanted a shadow all around, so I used -blur rather than -shadow.

Result:
Image

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-17T20:44:54-07:00
by jawbreaker
fmw42 wrote: 2019-02-17T19:26:34-07:00 Post your infile.png and outfile.png so we can help your compact your code.

When I try your code with an arbitrary input, the output just has a black rectangle with a slight shading around it inside the original image.

I do not understand your two images that you originally posted. Please clarify what you want or show your input and output from your code.
This is just sample code. infile will be a variable, supplied as an argument by the user. I'm working with wallpaper images. Any large image should work. I'm testing with 1366x768 and 1920x1080 right now. The final position of the rectangle (-geometry +24+674) will also be a variable, calculated by the dimensions of infile. I hard-coded the position for testing.

The images I posted were just meant to show what I'm trying to achieve. It's just a screenshot of a terminal on two different wallpapers to show that the resulting rectangle should both have a shadow and be transparent.

Ultimately, what I have works fine. I wanted to do it with one command and without creating a bunch of files I would have to clean up later.

Re: Apply shadow to rectangle with alpha

Posted: 2019-02-17T21:10:18-07:00
by jawbreaker
fmw42 wrote: 2019-02-17T20:02:52-07:00 This is a guess at what you want.
That's pretty close.

This is what I want...
Image

There are really a lot of variable going in to this it's hard to abstract something that makes sense outside of the script.
My sample code works now, so I guess I just need to translate to V7 syntax and without all the temp files.