[Solved] Using alpha of programmatically generated image for clipping mask of RGBA background color label?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
cake
Posts: 11
Joined: 2019-09-15T19:39:51-07:00
Authentication code: 1152

[Solved] Using alpha of programmatically generated image for clipping mask of RGBA background color label?

Post by cake » 2019-09-15T21:06:04-07:00

I've been experimenting with an IM label all-in-one command that produces a rounded corner image based on the dimensions of a text label and wanted to use the result as a kind of clipping mask for the subsequent visible text label and RGBA background color (the initial text label is simply used to set the dimensions for the rounded corner mask).

The nice thing about IM is so far this can all be done without writing to temporary files, with the help of command parentheses.

I have a functioning workaround (posted in the code at the bottom) which separates the color background fill color and then changes the opacity of rounded corner mask to create the same effect (since I'm not really that familiar with IM so parts are taken from useful docs examples) but the purpose of this topic is to ask if there's a way to instead allow for the final background fill to be defined as a single RGBA value while using the alpha image of the rounded corners as a kind of clipping mask. This would allow me to simplify the background color to a single variable for a script I have in mind.

A visual representation of the desired effect (the 'Goal' background is 70% opacity):

Image

What I have so far

The generated rounded corner image (here edited to output to an external file for the sake of this topic):

Code: Select all

magick -background "#FFFFFF" -fill "#FFFFFF" -font "Segoe-UI-Semibold" -pointsize "15" label:"Text String" -gravity southeast -splice 6x4 -gravity northwest -splice 6x2 ^( +clone  -alpha extract -draw " fill black polygon 0,0 0,2 2,0 fill white circle 2,2 2,0" ^( +clone -flip ^) -compose Multiply -composite ^( +clone -flop ^) -compose Multiply -composite ^) -alpha off -compose CopyOpacity -composite -channel a -evaluate divide 1 output.png
My current functioning workaround that separates the final background color and changes the opacity of the rounded corner alpha:

Code: Select all

magick -background "#3399FF" -fill "#F26322" -font "Segoe-UI-Semibold" -pointsize "15" label:"Text String" -gravity southeast -splice 6x4 -gravity northwest -splice 6x2 ^( -background "#FFFFFF" -fill "#FFFFFF" -font "Segoe-UI-Semibold" -pointsize "15" label:"Text String" -gravity southeast -splice 6x4 -gravity northwest -splice 6x2 ^( +clone  -alpha extract -draw " fill black polygon 0,0 0,2 2,0 fill white circle 2,2 2,0" ^( +clone -flip ^) -compose Multiply -composite ^( +clone -flop ^) -compose Multiply -composite ^) -alpha off -compose CopyOpacity -composite -channel a -evaluate divide 1.42 ^) -compose CopyOpacity -composite output.png
Note: the parentheses above are escaped for Windows CMD.exe use. They will likely have to be escaped differently for other OSes or console programs.
Last edited by cake on 2019-09-16T08:05:35-07:00, edited 1 time in total.

snibgo
Posts: 12436
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Using alpha of programmatically generated image for clipping mask of RGBA background color label?

Post by snibgo » 2019-09-16T05:16:55-07:00

I suggest you split long commands into logical lines. This makes them easier to build, understand, and debug. For example:

Code: Select all

%IMG7%magick ^
  -background "#3399FF" -fill "#F26322" -font "Segoe-UI-Semibold" -pointsize "15" label:"Text String" ^
  -gravity southeast -splice 6x4 ^
  -gravity northwest -splice 6x2 ^
  ^( -background "#FFFFFF" -fill "#FFFFFF" -font "Segoe-UI-Semibold" -pointsize "15" label:"Text String" ^
    -gravity southeast -splice 6x4 ^
    -gravity northwest -splice 6x2 ^
    ^( +clone -alpha extract +write a.png -draw " fill black polygon 0,0 0,2 2,0 fill white circle 2,2 2,0" ^
      ^( +clone -flip ^) -compose Multiply -composite ^
      ^( +clone -flop ^) -compose Multiply -composite ^
    ^) ^
    -alpha off -compose CopyOpacity -composite ^
    -channel a -evaluate divide 1.42 ^
  ^) ^
  -compose CopyOpacity -composite ^
  output.png
I inserted "+write a.png" to check my suspicion that the image is simply a copy of the first, entirely white. So it could be made more simply.
cake wrote:... the purpose of this topic is to ask if there's a way to instead allow for the final background fill to be defined as a single RGBA value while using the alpha image of the rounded corners as a kind of clipping mask.
Do you mean you want to combine the final "-evaluate divide 1.42" wih the initial "-fill #F26322"? Yes, you could, but would have to rearrange the command because you currently CopyOpacity which will override any alpha you created initially.
snibgo's IM pages: im.snibgo.com

cake
Posts: 11
Joined: 2019-09-15T19:39:51-07:00
Authentication code: 1152

Re: Using alpha of programmatically generated image for clipping mask of RGBA background color label?

Post by cake » 2019-09-16T06:01:24-07:00

snibgo wrote:
2019-09-16T05:16:55-07:00
I suggest you split long commands into logical lines. This makes them easier to build, understand, and debug. For example
Nice tip, thanks. Had seen such formatting in other posts but not in a Windows console escaped fashion so wasn't aware it was possible to break into new lines.
snibgo wrote:
2019-09-16T05:16:55-07:00
I inserted "+write a.png" to check my suspicion that the image is simply a copy of the first, entirely white. So it could be made more simply.
Yeah, that section is generating the white basis for the rounded corners alpha, as shown in the 'Alpha' image in the OP (the a.png you added outputs the pre-rounded version). That particular code was taken from the IM documentation for Thumbnails (first example), which I was glad to find.

I'm rather new to IM's more advanced usage but the only simplification I can tell would be removing the redundant -gravity text positioning functions for the all white alpha, no? I really only left them in that section as I was planning on making the lines from '-background' to the '-splice 6x2' a variable which would be duplicated. Any further ideas for simplification though would be welcome.
snibgo wrote:
2019-09-16T05:16:55-07:00
Do you mean you want to combine the final "-evaluate divide 1.42" wih the initial "-fill #F26322"? Yes, you could, but would have to rearrange the command because you currently CopyOpacity which will override any alpha you created initially.
To effectively combine the -evaluate divide 1.42 (70% opacity) with -background "#3399FF", into -background "rgba(51,153,255,0.7)" (or really any RGBA value for the background color).

However I'm not well versed in how I'd go about achieving this, getting rather stuck with the alpha functions, so I was hoping for some guidance of how I could achieve this.

snibgo
Posts: 12436
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Using alpha of programmatically generated image for clipping mask of RGBA background color label?

Post by snibgo » 2019-09-16T07:00:22-07:00

A simplified version so we don't need to do "label:" and "-splice" etc twice:

Code: Select all

magick ^
  -background "#3399FF" -fill "#F26322" -font "Segoe-UI-Semibold" -pointsize "15" label:"Text String" ^
  -gravity southeast -splice 6x4 ^
  -gravity northwest -splice 6x2 ^
  ^( +clone ^
     -fill White -colorize 100 ^
     -draw " fill black polygon 0,0 0,2 2,0 fill white circle 2,2 2,0" ^
      ^( +clone -flip ^) -compose Multiply -composite ^
      ^( +clone -flop ^) -compose Multiply -composite ^
    -evaluate divide 1.42 ^
  ^) ^
  -alpha off ^
  -compose CopyOpacity -composite ^
  output2.png
Rearranging so we can use alpha directly in the text or background or both:

Code: Select all

magick ^
  -background rgba(51,153,255,0.7) -fill rgba(242,99,34,1) -font "Segoe-UI-Semibold" -pointsize "15" label:"Text String" ^
  -gravity southeast -splice 6x4 ^
  -gravity northwest -splice 6x2 ^
  ^( +clone ^
     -alpha extract ^
     +write mpr:ALP ^
     +delete ^
  ^) ^
  ^( +clone ^
     -alpha off ^
     -fill White -colorize 100 ^
     -draw " fill black polygon 0,0 0,2 2,0 fill white circle 2,2 2,0" ^
      ^( +clone -flip ^) -compose Multiply -composite ^
      ^( +clone -flop ^) -compose Multiply -composite ^
     mpr:ALP ^
     -compose Multiply -composite ^
  ^) ^
  -alpha off ^
  -compose CopyOpacity -composite ^
  output3.png
snibgo's IM pages: im.snibgo.com

cake
Posts: 11
Joined: 2019-09-15T19:39:51-07:00
Authentication code: 1152

Re: Using alpha of programmatically generated image for clipping mask of RGBA background color label?

Post by cake » 2019-09-16T07:59:58-07:00

snibgo wrote:
2019-09-16T07:00:22-07:00
A simplified version so we don't need to do "label:" and "-splice" etc twice:

*snip*

Rearranging so we can use alpha directly in the text or background or both:

*snip*
Very heartily appreciated. I can see now with the first example what you meant with just how much can be simplified, indeed (!). Will keep both these examples for future function references and implement the latter soon in my script.

The mpr function is particularly interesting and seems very useful. Thanks for making me aware of it.

Post Reply