tags:

views:

125

answers:

3

Hello,

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.

+1  A: 

You cant just swap it out for another image that does in fact have a 50% transparency?

leppie
Yup, did think of that.
Keith Moore
A: 

You can use .LockBits to get a pointer to the pixel values of the image, and then change the alpa value of each pixel. See this question: http://stackoverflow.com/questions/1018868/gdiplus-mask-image-from-another-image/1027241#1027241

danbystrom
+1  A: 

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;
    }
Kris Erickson
Thanks Kris, I made a slight change, using Mashal.Copy, so that I didn't need an unsafe block, but otherwise, works a treat.
Keith Moore