[]
        
(Showing Draft Content)

Transparency Mask

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 or GrayscaleBitmap 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 or ToGrayscaleBitmap methods of the GcBitmap 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 method of the GcBitmap class.

Base Image

Mask

Output Image

A beautiful house

A black lizard

image

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 method of the GcBitmap class.

    //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 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



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

// 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 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 method of the GcBitmap class, as shown in the below example code:

// 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 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.


The following example shows the use of BackgroundBitmap to reproduce isolated and knockout groups rendering from the PDF specification:

// 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.