Page 1 of 1

[SOLVED] Multiplying color by alpha

Posted: 2013-05-22T06:40:01-07:00
by noggs
I've been struggling trying to figure out a command line which will let me to create premultiplied alpha images out of my PNGs, can someone help me out please?

The process I'm after is:

Take input image (PNG)
Multiply each pixel color value by the pixel alpha value
Output PNG with the modified colors and the original alpha

Cheers, Noel

Re: Multiplying color by alpha

Posted: 2013-05-22T07:52:11-07:00
by glennrp
Compose the image over a black canvas, then copy the alpha channel into the output:

Code: Select all

convert -size WxH xc:black -alpha on -draw "image over 0,0 0,0 in.png" -draw "image copy-opacity 0,0 0,0 in.png" out.png
(probably should write to out.somethingelse because the output isn't really a PNG if it contains premultiplied colors!)

Re: Multiplying color by alpha

Posted: 2013-05-22T08:01:20-07:00
by GreenKoopa
There are many ways to do this. Even glennrp's solution of composing on a black background could be done without -size and -draw. Here was my first thought:

Code: Select all

convert in.png ( +clone -alpha Extract ) -channel RGB -compose Multiply -composite out.png

Re: Multiplying color by alpha

Posted: 2013-05-22T08:07:24-07:00
by noggs
Thanks both of you - I appreciate avoiding the -size option!

If I wanted to do some other operation, and as a final step do this, how would I set that up. For instance (note resize is not always happening so I may not know the size up front):

convert in.png -resize 128x128! -blur 1 [now apply the premultiply operations] out.png

Or would I be better writing this to a temporary image then running the premult as a separate pass?

Re: Multiplying color by alpha

Posted: 2013-05-22T08:13:47-07:00
by GreenKoopa
I believe my operation could simply be pasted as the final step, but only in the case of working with a single image.

Re: Multiplying color by alpha

Posted: 2013-05-22T10:02:16-07:00
by GreenKoopa
An alternative using glennrp's thinking, using different operators. This is an intuitive approach because most people don't want to keep the alpha channel after it is used

Code: Select all

convert in.png -background black -alpha Remove out.png
but we simply copy it back in.

Code: Select all

convert in.png -background black -alpha Remove in.png -compose Copy_Opacity -composite out.png
Here is the same thing, but with only reading in the image once. This is not only more efficient, it allows you to paste it into a longer set of operations.

Code: Select all

convert in.png -write mpr:temp -background black -alpha Remove mpr:temp -compose Copy_Opacity -composite out.png
This should yield the same result as my other solution. I don't know which may be better for you.

Re: Multiplying color by alpha

Posted: 2013-05-23T01:22:22-07:00
by noggs
Fantastic! The last command line lets me chain additional options and works great.

Your help is much appreciated!

Re: [SOLVED] Multiplying color by alpha

Posted: 2013-05-23T03:39:44-07:00
by noggs
Sorry to resurrect this but if I run the command on an image without an alpha channel it gets screwed up (if it's 24 bit it seems to get alpha'd by maybe 50%, if it's 8-bit paletised it went super bright and also very alpha'd).

Is it possible to change the command line to handle this case and not do any multiplication or create an alpha channel?

Alternatively maybe the command line could be changed to promote all input images to full 32 bit?

Re: Multiplying color by alpha

Posted: 2013-05-23T10:03:29-07:00
by GreenKoopa
Sure, we can make this work for a new case.

For the second solution I offered:

Code: Select all

convert in.png -write mpr:temp -background black -alpha Remove mpr:temp -compose Copy_Opacity -composite out.png
First we handle the multiply, then we use Copy_Opacity to add the alpha channel back in. Copy_Opacity copies the alpha channel if there is one, but otherwise it uses the image itself, grayscaled, as the alpha channel. Instead of copying the alpha back into the original image, we could copy the newly multiplied RGB channels back into the original image, leaving the alpha, present or not, alone.

For the first solution I offered:

Code: Select all

convert in.png ( +clone -alpha Extract ) -channel RGB -compose Multiply -composite out.png
we didn't copy the alpha channel back in, we modified the RGB channels in place. So I believe it should work in this new case. If it doesn't, let me know.

I never work with palette images, so if they act differently someone else will have to help. For a color modification such as this, I can imagine operating on the palette directly, making this very fast regardless of image size.

Re: Multiplying color by alpha

Posted: 2013-05-23T10:17:46-07:00
by fmw42
I never work with palette images
Palette images only support binary transparency. So what you need to do is save to PNG32:out.png to make it keep it as 32-bit result.

Re: Multiplying color by alpha

Posted: 2013-05-23T13:57:02-07:00
by noggs
GreenKoopa wrote:First we handle the multiply, then we use Copy_Opacity to add the alpha channel back in. Copy_Opacity copies the alpha channel if there is one, but otherwise it uses the image itself, grayscaled, as the alpha channel. Instead of copying the alpha back into the original image, we could copy the newly multiplied RGB channels back into the original image, leaving the alpha, present or not, alone.
Ok that explains why the 24 bit images become transparent!

It seems I'm not going to be able to find a command line which will effectively ignore 8bit or 24bit but do premultiplication on 32 bit PNGs. I can detect the image type during the build process and skip the extra command line options.

Thanks again guys!

Re: Multiplying color by alpha

Posted: 2013-05-23T22:46:59-07:00
by snibgo
Possibly: insert "-alpha set" immediately after the input file. If the file has no alpha, alpha is created as fully opaque. If it has one, this makes no change.

Re: Multiplying color by alpha

Posted: 2013-05-24T02:04:22-07:00
by noggs
YES! That's nailed it.

Thanks very much!