Documents for Imaging .NET Edition | GCDocuments
Features / Transparency Mask
In This Topic
    Transparency Mask
    In This Topic

    GcImaging 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 GcImaging, 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
    A beautiful house A black lizard
    Output Image
    Transparency mask applied on the house with the lizard's 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.
      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");
      

    Back to Top

    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.

    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:

    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");
    

    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:

    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. See  PDF Specification 1.7 (sections 7.3.4 and 7.3.5) or specification 2.0 (sections 11.4.5 and 11.4.6), for details.

    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");
    

    Back to Top

    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.