Eliminating alpha channel garbage
Eliminating alpha channel garbage
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!
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Eliminating alpha channel garbage
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 usingor
You can check on the color of its transparent pixels using
or negate the alpha channel using
A direct method is to directly set fully-transparent pixels to black
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...
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,
Can you find a simplier one?
A NOOP blur which includes the alpha channel in its operation, will also set fully-transparent to black.
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
that may be the simplest 'fast' solution I have been able to find. The question is where should I put this in IM examples.
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
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
Code: Select all
wget http://www.imagemagick.org/Usage/images/moon.png
Code: Select all
convert moon.png -alpha off show:
Code: Select all
convert moon.png -channel A -negate show:
Code: Select all
convert moon.png -fx 'a==0 ? 0 : u' moon_fixed.png
Code: Select all
convert moon.png -fx 'a==0 ? HotPink : u' moon_fixed.png
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
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
Better still full 2-D gaussian blur does nto short-circuit
Code: Select all
convert moon.png -channel RGBA -gaussian 0x0 moon_fixed.png
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/
https://imagemagick.org/Usage/
Re: Eliminating alpha channel garbage
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 );
}
}
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 );
}
}
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Eliminating alpha channel garbage
MaxRGB is a depreciated defination. QuantumRange is what should be used.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/