This documentation is for the old version. Go to the latest Graphics Mill docs

Preserving Transparency During Color Reduction

When reducing colors of a bitmap which has an alpha channel (i.e. some portions of this bitmap are transparent), you may need to keep the transparency. This article describes how you can do it in Graphics Mill for .NET.

Overview of Transparency Modes In Indexed Bitmaps

To keep transparency in indexed bitmaps, two approaches are used:

  1. One of palette entries is marked as transparent. All transparent pixels should equal to the index of this entry. Semi-transparency is not supported.
  2. Each palette entry stores an alpha channel value along with color information. Pixels may be semi-transparent.

Since the palette size is quite small and usually each palette entry is important, first approach is quite popular, although it does not allow to have semi-transparent entries. As a result it may lead to artifacts on edges between opaque and transparent areas of the image. However there is an important reason to use this approach regardless to its drawbacks - GIF file format supports only one transparent entry in a palette.

If semi-transparency in indexed bitmaps is crucial, you have to refuse GIF file format. Hopefully you can save such bitmaps to 8-bit PNG format. But you should keep in mind that if you keep semi-transparent entries in the palette, you can store fewer colors. That's why use this feature carefully.

Now let's see how to configure Graphics Mill for .NET to preserve transparency in various modes.

Preserving Single Transparent Entry

There are two ways to preserve an alpha channel when working with Graphics Mill for .NET:

Both ColorManagementProvider and PixelFormatConverter have a number of properties which should be set prior you start the conversion. These properties are equal for both classes.


Set this property to true to have Graphics Mill for .NET to analyze alpha channel (otherwise it will be just ignored).


Set this property to true to turn single-entry transparency mode on. When this mode is enabled, all pixels which are considered as transparent are merged into a single palette entry.


If you pass a custom palette into the ConvertToIndexed(Int32, ColorPaletteType, ColorPalette) method, make sure that it has at least one fully transparent entry. Otherwise all the transparency information in a bitmap will be lost.


This value depends on a strategy you would like to process semi-transparent pixels with. It means the minimum alpha channel value for pixels which should be considered as opaque. If pixel has smaller alpha channel value, it becomes fully transparent.

Let's see what strategies are possible:

  1. You may just divide the range of alpha channel values into two equal parts. In this case you specify 128.
  2. You may want to make opaque only those pixels which are really 100% opaque. In this case you specify 255.
  3. Vice versa, you may want to make opaque all pixels which are not 100% transparent. In this case you specify 1 (if you set 0, no pixels will be transparent).
  4. You may make transparent not just 100% transparent pixels, but all those pixels which are barely visible (typically pixels on the edge between objects and trasparent background). In this case the value may vary, typically between 10-16. Feel free to experiment to get a result you need.

After you configure these properties, either call the ColorManagementProvider.ConvertToIndexed(Int32, ColorPaletteType, ColorPalette) method, or the PixelFormatConverter.ApplyTransform method, as usual.

Preserving Semi-transparency

Using this mode is even easier than the single-entry one. Just set the BuildAdaptivePaletteWithAlpha to true and PaletteAlphaThresholdUsed to false. Graphics Mill for .NET will do the rest automatically.

Code Example

Here is a code example demonstrating both approaches.

Visual Basic
Dim bitmap As New Aurigma.GraphicsMill.Bitmap("C:\transparency.png")

'Single transparent entry
Dim result1 As Aurigma.GraphicsMill.Bitmap = bitmap.Clone()
result1.ColorManagement.BuildAdaptivePaletteWithAlpha = True
result1.ColorManagement.PaletteAlphaThresholdUsed = True
result1.ColorManagement.PaletteAlphaThreshold = 16
result1.ColorManagement.ConvertToIndexed(8, Aurigma.GraphicsMill.ColorPaletteType.Adaptive, Nothing)

'Multiple semi-transarent entries
Dim result2 As Aurigma.GraphicsMill.Bitmap = bitmap.Clone()
result2.ColorManagement.BuildAdaptivePaletteWithAlpha = True
result2.ColorManagement.PaletteAlphaThresholdUsed = False
result2.ColorManagement.ConvertToIndexed(8, Aurigma.GraphicsMill.ColorPaletteType.Adaptive, Nothing)
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(@"C:\transparency.png");

//Single transparent entry
Aurigma.GraphicsMill.Bitmap result1 = (Aurigma.GraphicsMill.Bitmap)bitmap.Clone();
result1.ColorManagement.BuildAdaptivePaletteWithAlpha = true;
result1.ColorManagement.PaletteAlphaThresholdUsed = true;
result1.ColorManagement.PaletteAlphaThreshold = 16;
result1.ColorManagement.ConvertToIndexed(8, Aurigma.GraphicsMill.ColorPaletteType.Adaptive, null);

//Multiple semi-transarent entries
Aurigma.GraphicsMill.Bitmap result2 = (Aurigma.GraphicsMill.Bitmap)bitmap.Clone();
result2.ColorManagement.BuildAdaptivePaletteWithAlpha = true;
result2.ColorManagement.PaletteAlphaThresholdUsed = false;
result2.ColorManagement.ConvertToIndexed(8, Aurigma.GraphicsMill.ColorPaletteType.Adaptive, null);

See Also