# Transparency Mask

DsImaging allows you to apply transparency mask on an image to hide some of its portion. You can also set the background color of semi-transparent images.

## Content

DsImaging allows you to use transparency masks for all drawing and filling operations.

## Apply Transparency Mask

Transparency masks are used in imaging to hide some portion of the image while retaining rest of the image. The mask is either an image that already has transparency set on it or it is a bilevel/grayscale image which can serve the purpose because in that case, the black or white pixels are used as a mask. 
In DsImaging, the transparency mask can be defined using [BilevelBitmap](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.BilevelBitmap.html) or [GrayscaleBitmap](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GrayscaleBitmap.html) class. The image to be used as a transparency mask is loaded in a GcBitmap instance and converted to a BilevelBitmap or GrayscaleBitmap by using the [ToBilevelBitmap](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GcBitmap.ToBilevelBitmap.html) or [ToGrayscaleBitmap](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GcBitmap.ToGrayscaleBitmap.html) methods of the [GcBitmap](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GcBitmap.html) class. To use the defined mask, you need to draw the image on which the mask is to be applied on the target GcBitmap and then apply a mask using the [ApplyTransparencyMask](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GcBitmap.ApplyTransparencyMask.html) method of the **GcBitmap** class.

| **Base Image** | **Mask** | **Output Image** |
| ---------- | ---- | ------------ |
| ![A beautiful house](https://cdn.mescius.io/document-site-files/images/a5680f0e-2d32-45dc-8048-d3ef11d0dae7/images/tudor.jpg?width=400) | ![A black lizard](https://cdn.mescius.io/document-site-files/images/a5680f0e-2d32-45dc-8048-d3ef11d0dae7/images/logo.png?width=400) | ![image](https://cdn.mescius.io/document-site-files/images/a5680f0e-2d32-45dc-8048-d3ef11d0dae7/image.ddb4ce.png?width=400) |

To set the transparency mask:

1. Initialize an instance of the GcBitmap class to load the semi-transparent image which is to be applied as a mask.
2. Convert this **GcBitmap** to **GrayscaleBitmap** which will be used as the image mask, using the **ToGrayscaleBitmap** method of the GcBitmap class.
3. Initialize another instance of the GcBitmap class to load the image on which the transparency mask is to be applied.
4. Apply the transparency mask to the resulting bitmap using the **ApplyTransparencyMask** method of the GcBitmap class.
5. Convert the resulting bitmap to an opaque image with specified background color using the [ConvertToOpaque](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GcBitmap.ConvertToOpaque.html) method of the GcBitmap class.

    ```csharp
    //Initialize bitmap for generating mask image
    GcBitmap mask = new GcBitmap("logo.png");
    
    //Draw image to which the tranparency mask has to be applied
    GcBitmap bmp = new GcBitmap("tudor.jpg");
    
    //Define the transparency mask using mask image
    GrayscaleBitmap grayscaleMask = mask.ToGrayscaleBitmap(ColorChannel.Blue, true);
    
    //Apply the transparency mask to the result bitmap
    bmp.ApplyTransparencyMask(grayscaleMask);
    
    //Convert the result bitmap to opaque
    bmp.ConvertToOpaque(Color.Beige);
    
    //Save the result bitmap to save transparent image
    bmp.SaveAsJpeg("TransparentImg.jpg");
    ```

You can use the [TransparencyMaskBitmap](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.BitmapRenderer.TransparencyMaskBitmap.html) property of **BitmapRenderer** class to specify a transparency mask that will be used for any subsequent drawing on the bitmap. Pixels in the mask with value 0 are fully opaque and will completely mask any drawing (meaning, the pixels of the target bitmap will remain unchanged). Pixels in the mask with value 255 are fully transparent, meaning that any drawing will have the same effect as if there was no mask. Pixels with values between 0 and 255 will modify the transparency of the pixels being drawn according to their value.

> !type=note
> **Note:** The transparency mask bitmap must be of the same pixel size as the target bitmap.

| **With Transparency Mask** | **Without Transparency Mask** |
| ---------------------- | ------------------------- |
| ![](https://cdn.mescius.io/document-site-files/images/a5680f0e-2d32-45dc-8048-d3ef11d0dae7/images/transparency_mask.png?width=400) | ![](https://cdn.mescius.io/document-site-files/images/a5680f0e-2d32-45dc-8048-d3ef11d0dae7/images/without_transparency_mask.png?width=400) |

The following example shows how to set the transparency mask and prevent opacity while working with overlapping images:

```csharp
// Prepare a linear gradient transparency mask,
 // from 0 (transparent) to 255 (opaque):
 using var mask = new GcBitmap(500, 500, true);
 using var gmask = mask.CreateGraphics();
 var grad = new LinearGradientBrush(Color.Black, Color.White);
 gmask.FillRectangle(new RectangleF(0, 0, mask.Width, mask.Height), grad);
 // Convert to GrayscaleBitmap to be used as Renderer.TransparencyMaskBitmap:
 using var gsb = mask.ToGrayscaleBitmap();

 // Fill target bitmap with yellow background:
 using var bmp = new GcBitmap(500, 500, false);
 using var g = bmp.CreateGraphics(Color.Yellow);

 // Apply the transparency mask (comment out to see the results without the mask):
 g.Renderer.TransparencyMaskBitmap = gsb;

 // Fill 3 circles, note how the fill gradually changes
 // from transparent to opaque (left to right) along with the gradient:
 g.FillEllipse(new RectangleF(100, 20, 300, 300), Color.Red);
 g.FillEllipse(new RectangleF(180, 180, 300, 300), Color.Green);
 g.FillEllipse(new RectangleF(20, 180, 300, 300), Color.Blue);
 bmp.SaveAsPng("transpmask.png");
```

## Remove Transparency

You can check whether an image contains any transparent pixels by using the [HasTransparentPixels](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GcBitmap.HasTransparentPixels.html) method of **GcBitmap** class. It scans the image and returns true if there are any pixels with the alpha channel value different from 255. You can also convert images with transparent pixels to opaque with a specified solid background color by using the [ConvertToOpaque](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.GcBitmap.ConvertToOpaque.html) method of the **GcBitmap** class, as shown in the below example code:

```csharp
// Initialize a GcBitmap and load a transparent image into it:
using GcBitmap origBmp = new GcBitmap("Tranparent.png");
            
// Check for transparent pixels and convert to opaque if any:
if (origBmp.HasTransparentPixels())
{
    origBmp.ConvertToOpaque(Color.LightBlue);
    origBmp.SaveAsJpeg("NotTransparent.jpg");
}
else
    Console.WriteLine("No transparent pixels");
```

When drawing semi-transparent graphic objects, usually the resulting color of a pixel is a combination of the target bitmap pixel's color and the color of the graphic object's pixel. But if the [BackgroundBitmap](/document-solutions/dot-net-imaging-api/api/online/DS.Documents.Imaging/GrapeCity.Documents.Imaging.BitmapRenderer.BackgroundBitmap.html) is set on the **BitmapRenderer**, pixels of that bitmap will be used instead of the target bitmap's pixels when determining the resulting color (the BackgroundBitmap must have the same pixel size as the target bitmap). Background bitmaps are used to support Isolated and Knockout groups when rendering PDFs to images.
![](https://cdn.mescius.io/document-site-files/images/a5680f0e-2d32-45dc-8048-d3ef11d0dae7/images/background_image.png)
The following example shows the use of **BackgroundBitmap** to reproduce isolated and knockout groups rendering from the PDF specification:

```csharp
// The target bitmap will be 1000x10000 pixels containing 4 demo quadrants:
using var bmp = new GcBitmap(500 * 2, 500 * 2, false, 96f, 96f);
// The spectrum image used for the backdrop:
using var bmp1 = new GcBitmap("spectrum-pastel-500x500.png");

using var bmpBackdrop = new GcBitmap(500, 500, false, 96f, 96f);
using var bmpInitial = new GcBitmap(500, 500, false, 96f, 96f);
using var gB = bmpBackdrop.CreateGraphics();
using var gI = bmpInitial.CreateGraphics();

gB.Renderer.Aliased = true;
gB.Renderer.BlendMode = BlendMode.Multiply;
gI.Renderer.Aliased = true;
gI.Renderer.BlendMode = BlendMode.Multiply;

// Isolated, Knockout
bmpBackdrop.BitBlt(bmp1, 0, 0);
bmpInitial.Clear(Color.Transparent);
gB.Renderer.BackgroundBitmap = bmpInitial;
gB.FillEllipse(new RectangleF(50, 50, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(200, 50, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(50, 200, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(200, 200, 250, 250), Color.LightGray);
bmp.BitBlt(bmpBackdrop, 0, 0);

// Isolated, Non-knockout
gI.FillEllipse(new RectangleF(50, 50, 250, 250), Color.LightGray);
gI.FillEllipse(new RectangleF(200, 50, 250, 250), Color.LightGray);
gI.FillEllipse(new RectangleF(50, 200, 250, 250), Color.LightGray);
gI.FillEllipse(new RectangleF(200, 200, 250, 250), Color.LightGray);
bmpBackdrop.BitBlt(bmp1, 0, 0);
bmpBackdrop.AlphaBlend(bmpInitial, 0, 0);
bmp.BitBlt(bmpBackdrop, 500, 0);

// Non-isolated, Knockout
bmpBackdrop.BitBlt(bmp1, 0, 0);
bmpInitial.BitBlt(bmp1, 0, 0);
gB.FillEllipse(new RectangleF(50, 50, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(200, 50, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(50, 200, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(200, 200, 250, 250), Color.LightGray);
bmp.BitBlt(bmpBackdrop, 0, 500);

// Non-isolated, Non-knockout:
bmpBackdrop.BitBlt(bmp1, 0, 0);
gB.Renderer.BackgroundBitmap = null;
gB.FillEllipse(new RectangleF(50, 50, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(200, 50, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(50, 200, 250, 250), Color.LightGray);
gB.FillEllipse(new RectangleF(200, 200, 250, 250), Color.LightGray);
bmp.BitBlt(bmpBackdrop, 500, 500);

// Adornments:
using var g = bmp.CreateGraphics();
g.DrawLine(0, 500, 1000, 500, new Pen(Color.Black));
g.DrawLine(500, 0, 500, 1000, new Pen(Color.Black));
var tf = new TextFormat() { FontSize = 14 };
g.DrawString("Isolated, Knockout", tf, new RectangleF(0, 460, 500, 30), TextAlignment.Center, ParagraphAlignment.Center, false);
g.DrawString("Isolated, Non-knockout", tf, new RectangleF(500, 460, 500, 30), TextAlignment.Center, ParagraphAlignment.Center, false);
g.DrawString("Non-isolated, Knockout", tf, new RectangleF(0, 960, 500, 30), TextAlignment.Center, ParagraphAlignment.Center, false);
g.DrawString("Non-isolated, Non-knockout", tf, new RectangleF(500, 960, 500, 30), TextAlignment.Center, ParagraphAlignment.Center, false);

// Done:
bmp.SaveAsPng("isolated-knockout.png");
```

> !type=note
> **Note:** Please dispose off the **BackgroundBitmap** and **TransparencyMaskBitmap** bitmaps after using them.

**Limitation**
The bitmaps assigned to the **BackgroundBitmap** or **TransparencyMaskBitmap** properties must be of the same pixel size as the target bitmap of the current **GcBitmapGraphics**.