Hi guys,

I have to create a C# application which is able to mask images but I don't really get on with it...

I thought I will use this example for the project:
http://www.camera-sdk.com/p_248-how-to-implement-image-masking-in-c-onvif.html

Any ideas or experiences? Has anyboby here used this? Any help would be appreciated.

Thanks!!

Dani AI

Generated

If by "mask" you mean show the source image only where a mask image is white and hide it where the mask is black, the most robust approach is to copy the mask into the alpha channel of a 32bpp ARGB bitmap (per‑pixel alpha works only with 32bpp). Then you can draw the result with normal alpha blending. Alpha blending in GDI (per‑pixel alpha requires 32bpp ARGB).

multiplies grayscale values and copies pixels when the product is nonzero. That yields a hard, binary cutout and discards any partial transparency. If you want soft edges and accurate translucency, set alpha from the mask instead. With LockBits this is fast and avoids SetPixel. Bitmap.LockBits documentation.

// Assume srcData, mskData, dstData are BitmapData from LockBits on 32bpp ARGB bitmaps
unsafe
{
    for (int y = 0; y < height; y++)
    {
        byte* s = (byte*)srcData.Scan0 + y * srcData.Stride;
        byte* m = (byte*)mskData.Scan0 + y * mskData.Stride;
        byte* d = (byte*)dstData.Scan0 + y * dstData.Stride;

        for (int x = 0; x < width; x++)
        {
            int i = x * 4; // BGRA
            byte a = (byte)((m[i + 2] * 77 + m[i + 1] * 150 + m[i] * 29) >> 8); // mask luminance
            d[i]     = s[i];     // B
            d[i + 1] = s[i + 1]; // G
            d[i + 2] = s[i + 2]; // R
            d[i + 3] = a;        // A from mask (invert for "hole" effect)
        }
    }
}

Tips:

  • Do not Dispose() the input bitmaps inside your helper; let the caller own them. Also clamp to the overlapping rectangle like hinted.
  • If you are doing this in ASP.NET today, note System.Drawing.Common is Windows‑only in .NET 6+; prefer Windows hosting or a cross‑platform library (e.g., ImageSharp/SkiaSharp). System.Drawing.Common is Windows‑only (.NET 6), config switch removed in .NET 7.

Recommended Answers

All 2 Replies

Your question is not very clear. Are you trying to do something similar to this forum post?

Try this sir.

//
// This functon used to mask(multiply) two images bitmap.
//
public Bitmap MaskImagePtr(Bitmap SrcBitmap1, Bitmap SrcBitmap2, out string Message)
{
    int width;
    int height;

    Message = "";

    if (SrcBitmap1.Width < SrcBitmap2.Width)
        width = SrcBitmap1.Width;
    else
        width = SrcBitmap2.Width;

    if (SrcBitmap1.Height < SrcBitmap2.Height)
        height = SrcBitmap1.Height;
    else
        height = SrcBitmap2.Height;

    bitmap = new Bitmap(width, height);
    int clr1, clr2;

    try
    {
        BitmapData Src1Data = SrcBitmap1.LockBits(new Rectangle(0, 0, SrcBitmap1.Width, SrcBitmap1.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

        BitmapData Src2Data = SrcBitmap2.LockBits(new Rectangle(0, 0, SrcBitmap2.Width, SrcBitmap2.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

        BitmapData DestData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

        unsafe
        {
            int xOffset = 3;

            for (int col = 0; col < bitmap.Height - 1; col++)
            {
                byte* Src1Ptr = (byte*)Src1Data.Scan0 + col * Src1Data.Stride;
                byte* Src2Ptr = (byte*)Src2Data.Scan0 + col * Src2Data.Stride;
                byte* DestPtr = (byte*)DestData.Scan0 + col * DestData.Stride;

                for (int row = 0; row < bitmap.Width - 1; row++)
                {
                    clr1 = (Src1Ptr[row * xOffset] + Src1Ptr[row * xOffset + 1] + Src1Ptr[row * xOffset + 2]) / 3;
                    clr2 = (Src2Ptr[row * xOffset] + Src2Ptr[row * xOffset + 1] + Src2Ptr[row * xOffset + 2]) / 3;

                    clr1 *= clr2;

                    if (clr1 == 0)
                    {
                        DestPtr[row * xOffset] = (byte)(0);
                        DestPtr[row * xOffset + 1] = (byte)(0);
                        DestPtr[row * xOffset + 2] = (byte)(0);
                    }
                    else
                    {
                        DestPtr[row * xOffset] = (byte)(Src2Ptr[row * xOffset]);
                        DestPtr[row * xOffset + 1] = (byte)(Src2Ptr[row * xOffset + 1]);
                        DestPtr[row * xOffset + 2] = (byte)(Src2Ptr[row * xOffset + 2]);
                    }
                }
            }
        }

        bitmap.UnlockBits(DestData);
        SrcBitmap1.UnlockBits(Src1Data);
        SrcBitmap2.UnlockBits(Src2Data);

        SrcBitmap1.Dispose();
        SrcBitmap2.Dispose();
    }
    catch (Exception ex)
    {
        Message = ex.Message;
    }

    return bitmap;
}

Source

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.