.net – How to Draw a Bitmap with 50% Opacity

gdi+net

I have a .png file, with alpha channel, that I use as the BackgroundImage on a Panel control. Under certain circumstances the control is disabled. When it is disabled I want the background image to be 50% transparent so that the user gets some sort of visual indication as to the controls state.

Does anyone know how I can make a Bitmap image 50% transparent?

The only possible solution I have at this stage is to draw the bitmap image to a new bitmap and then draw over the top of it using the background colour of the panel. Whilst this works it is not my prefered solution, hence this question.

Best Answer

Here is some code that adds an alpha channel to an image. If you want 50% alpha, you would set 128 as the alpha argument. Note this creates a copy of the bitmap...

    public static Bitmap AddAlpha(Bitmap currentImage, byte alpha)
    {
        Bitmap alphaImage;
        if (currentImage.PixelFormat != PixelFormat.Format32bppArgb)
        {
            alphaImage = new Bitmap(currentImage.Width, currentImage.Height, PixelFormat.Format32bppArgb);
            using (Graphics gr = Graphics.FromImage(tmpImage))
            {
                gr.DrawImage(currentImage, 0, 0, currentImage.Width, currentImage.Height);
            }
        }
        else
        {
            alphaImage = new Bitmap(currentImage);
        }

        BitmapData bmData = alphaImage.LockBits(new Rectangle(0, 0, alphaImage.Width, alphaImage.Height),
            ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

        const int bytesPerPixel = 4;
        const int alphaPixel = 3;
        int stride = bmData.Stride;

        unsafe
        {
            byte* pixel = (byte*)(void*)bmData.Scan0;


            for (int y = 0; y < currentImage.Height; y++)
            {
                int yPos = y * stride;
                for (int x = 0; x < currentImage.Width; x++)
                {
                    int pos = yPos + (x * bytesPerPixel); 
                    pixel[pos + alphaPixel] = alphaByte;
                }
            }
        }

        alphaImage.UnlockBits(bmData);

        return alphaImage;
    }