Eliminating alpha channel garbage

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
mickeyportilla

Eliminating alpha channel garbage

Post by mickeyportilla »

I am using magick++/c++. I would like to set all the pixel RGB components of a PNG32 that are completely transparent ( as determined by the Alpha channel ) to black or some specified color. The problem I am having is that some images have 'garbage' or left over values in these areas the user never sees because they are transparent and this of course effects how well the images can be compressed. Any help appreciated, thanks!
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Eliminating alpha channel garbage

Post by anthony »

The closest thing currently in IM is -transparent-color but that only works for GIF images (and PNG8 indexed images)] which is not a good solution as that is a Color reduced indexed Image File format.
So don't even bother trying it!

To experiment you will need an example image with colorful transparent pixels.
The "moon.png" image used in IM examples, on Controlling Image Transparency was designed for this purpose, so as to help explain the -alpha and -matte operations. It has very colorful transparent pixels in the fractal pattern that was used during its creation.
You can download using

Code: Select all

    convert http://www.imagemagick.org/Usage/images/moon.png moon.png
or

Code: Select all

wget http://www.imagemagick.org/Usage/images/moon.png
You can check on the color of its transparent pixels using

Code: Select all

    convert moon.png -alpha off show:
or negate the alpha channel using

Code: Select all

    convert moon.png -channel A -negate show:
A direct method is to directly set fully-transparent pixels to black

Code: Select all

  convert moon.png  -fx 'a==0 ? 0 : u'  moon_fixed.png
This replaces each 'color' value with '0' if the alpha of that pixel is fully-transparent. You can replace the '0' with a specific color name if you want some other color. For example HotPink...

Code: Select all

  convert moon.png  -fx 'a==0 ? HotPink : u'  moon_fixed.png
Remember you need to turn off, or negate the alpha if you want to look at the actual color of the fully-transparent pixels

This can be made a LOT faster if done using a API to loop through the pixels yourself (see the PerlMagick example script "pixel_fx.pl" to get a idea on how to do this)

However many operations on image will make fully transparent pixels, black.
Probably the simplest is to use a Alpha Composition method.

Here is one method that composites the image with a copy of itself to produce the same image, BUT with fully transparent pixels becoming black,

Code: Select all

   convert moon.png \( +clone -alpha off \) -compose SrcIn -composite  moon_fixed.png
Can you find a simplier one?

A NOOP blur which includes the alpha channel in its operation, will also set fully-transparent to black.

Code: Select all

   convert moon.png -channel RGBA -blur 1x.000000001 moon_fixed.png
that is a decimal point, followed by eight zeros, and a 1. You can not use a 'zero' in the above otherwise IM will short circuit the operation and do nothing.

Better still full 2-D gaussian blur does nto short-circuit

Code: Select all

   convert moon.png -channel RGBA -gaussian 0x0 moon_fixed.png
that may be the simplest 'fast' solution I have been able to find. The question is where should I put this in IM examples. 8)

Perhaps a new -alpha method should be created to set fully-transparent color to some specific color (say background color).

UPDATE: -alpha background will now do this.. See
http://www.imagemagick.org/Usage/maskin ... background
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
mickeyportilla

Re: Eliminating alpha channel garbage

Post by mickeyportilla »

Thank you for your help! I went ahead and wrote the c++ code that achieves what I want, hopefully it will help someone else.

const Color color( 0, 0, 0, MaxRGB );
unsigned int row( image.baseRows() );

while( row-- )
{
unsigned col( image.baseColumns() );

while( col-- )
{
if( image.pixelColor( col, row ).alphaQuantum() == MaxRGB )
image.pixelColor( col, row, color );
}
}
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Eliminating alpha channel garbage

Post by anthony »

MaxRGB is a depreciated defination. QuantumRange is what should be used.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
mickeyportilla

Re: Eliminating alpha channel garbage

Post by mickeyportilla »

Thanks again!
Post Reply