DsImaging allows you to use transparency masks for all drawing and filling operations.
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 | |
To set the transparency mask:
C# |
Copy Code
|
---|---|
//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.
With Transparency Mask | Without Transparency Mask |
---|---|
The following example shows how to set the transparency mask and prevent opacity while working with overlapping images:
C# |
Copy Code
|
---|---|
// 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"); |
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:
C# |
Copy 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:
Example Title |
Copy Code
|
---|---|
// 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"); |
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.