Solved

Convert 24Bit to 32Bit with alpha in C#

Posted on 2009-05-08
5
2,044 Views
Last Modified: 2012-05-06
The Code I wrote below should work. But it will not convert a 24 bit to 32 bit image. It should but apparently Clone doesn't work that way.

Anyone have any alternate solutions?
public static Bitmap SetAlpha(Bitmap Target, int alpha)

        {
 

            /*if (Target.PixelFormat == PixelFormat.Format24bppRgb)

            {
 

                Bitmap newBitmap = new Bitmap(Target.Width, Target.Height, PixelFormat.Format32bppArgb);
 

                BitmapData returnData1 = Target.LockBits(new Rectangle(0, 0, Target.Width, Target.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, Target.PixelFormat);

                BitmapData returnData2 = newBitmap.LockBits(new Rectangle(0, 0, newBitmap.Width, newBitmap.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, newBitmap.PixelFormat);
 
 
 

            }*/
 

            //Clone the Target to return Bitmap, this will change to pixel format correctly

            Bitmap returnBitmap = Target.Clone(new Rectangle(0, 0, Target.Width, Target.Height), PixelFormat.Format32bppArgb);
 
 
 

            //New fast Code using Lock bits to get and set alpha channel. Don't use Get and Set Pixel it's 10x slower

            BitmapData returnData = returnBitmap.LockBits(new Rectangle(0, 0, returnBitmap.Width, returnBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, returnBitmap.PixelFormat);
 

            int PixelSize = 4;
 

            unsafe

            {
 

                for (int y = 0; y < returnData.Height; y++)

                {

                    //Gets the pixelRow for Target Bitmap

                    byte* row = (byte*)returnData.Scan0 + (y * returnData.Stride);
 

                    for (int x = 0; x < returnData.Width; x++)

                    {

                        //Set alpha pixel byte to the same as the mask
 

                        byte oldAlpha = row[x * PixelSize + 3];

                        byte B = row[x * PixelSize + 2];

                        byte G = row[x * PixelSize + 1];

                        byte R = row[x * PixelSize + 0];

                        byte setAlpha = Convert.ToByte(alpha);
 
 

                        //Check for Null pixel

                        if ((R == 0) && (G == 0) && (B == 0) && (oldAlpha < 10)) { R = 254; B = 254; G = 254; setAlpha = oldAlpha; }

                        
 

                        //if (returnBitmap.Height == 290)

                        //{ B = 254; G = 254; R = 254; }

                        //if (alpha > oldAlpha)

                        row[x * PixelSize + 0] = R;

                        row[x * PixelSize + 1] = G;

                        row[x * PixelSize + 2] = B;

                        row[x * PixelSize + 3] = setAlpha;

                    }
 

                }

            }
 
 

            //Restore Bitmap Data Directly back to the bitmap.

            returnBitmap.UnlockBits(returnData);

            
 

            //Dispose of input bitmaps

            Target.Dispose();
 

            return returnBitmap;

        }

Open in new window

0
Comment
Question by:RDdice
  • 3
  • 2
5 Comments
 
LVL 11

Accepted Solution

by:
anyoneis earned 500 total points
ID: 24350255
I don't know why the clone doesn't work as you are using it. Try this tweak:

            //Clone the Target to return Bitmap, this will change to pixel format correctly
            Bitmap returnBitmap = new Bitmap(Target);
            returnBitmap = returnBitmap.Clone(new Rectangle(0, 0, Target.Width, Target.Height), PixelFormat.Format32bppArgb);

dwr
0
 
LVL 11

Expert Comment

by:anyoneis
ID: 24350272
0
 
LVL 7

Author Comment

by:RDdice
ID: 24350286
Ya doesn't work. Passing a 24 bit bitmap to it, it doesn't always return a 32 bit for some reason and i'm not sure why. Could be something to do with the bitmaps I'm using.

Bitmap.MakeTransparent Does return a 32 bit in every instance, but of course makes 1 color transparent.
0
 
LVL 11

Expert Comment

by:anyoneis
ID: 24350422
I can't get it to fail, but I am not trying a bunch of different images. Sorry that didn't help (but it was fun playing with it :-)

Are you saying that a given image does not always convert, or that some images never convert with this code?
0
 
LVL 7

Author Closing Comment

by:RDdice
ID: 31579630
Clone works, but not 100% of the time, seems like an internal bug defendant on the target image.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now