Click here to Skip to main content
15,890,282 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
I have one more problem with my current project:
I want to color a bitmap by applying a scale to it. The colors of the scale are stored in a SynchronizedCollection, to make things Thread safe. When I want to color my Bitmap everything works fine except, that there are colors in the bitmap which are not in the colors of the scale (which should be impossible). So I think there is something wrong with my Bytewise manipulation of the Bitmap. I can't find the fault, so maybe you can help me:

C#
private unsafe Bitmap COLOR_BMP(double min_press, double max_press, double f_p_b, Bitmap bmp)
        {
            try
            {
                Bitmap result = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format32bppArgb);
                BitmapData bitmapData = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.ReadWrite, result.PixelFormat);
                IntPtr ptr = bitmapData.Scan0;
                int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(result.PixelFormat) / 8;
                int numBytes = bitmapData.Stride * bmp.Height;
                byte[] rgbValues = new byte[numBytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes);
                int list_ct = 0;

                for (int counter = 0; counter < rgbValues.Length; counter++)
                {
                    if (BR_LIST[list_ct] >= BORDER)
                    {
                        double brightness = BR_LIST[list_ct];
                        double force = brightness * f_p_b;
                        double percent = force / (max_press - min_press);
                        int pos = (int)(percent * (double)SCALE_LIST.Count);
                        Color color = SCALE_LIST[pos];

                        if (counter % 4 == 0)   //A
                            rgbValues[counter] = color.A;
                        if (counter % 4 == 1)   //R
                            rgbValues[counter] = color.R;
                        if (counter % 4 == 2)   //G
                            rgbValues[counter] = color.G;
                        if (counter % 4 == 3)   //B
                        {
                            rgbValues[counter] = color.B;
                            list_ct++;
                        }
                    }
                    else
                    {
                        rgbValues[counter] = 0;
                        counter = counter + 3;
                        list_ct++;
                    }
                        
                }

                System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes);
                result.UnlockBits(bitmapData);
                return result;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return bmp;
            }
        }


BR_LIST[] holds one value per pixel, so one value for every 4 bytes of the bitmap

The result looks like this:

CLICK ME

As you can see, there are colors in the image, that are not in the scaling above :-(
Posted
Updated 12-Oct-15 23:47pm
v2

1 solution

The problem is that the computer is little-endian, which means that although the format is ARGB, the order the bytes are stored in memory is B - G - R - A (i.e., B is stored in a lower memory address than G, then R, and then A).

Your code is assuming the opposite ordering of bytes. To get the intended result, you should just invert the assignment order:

C#
if (counter % 4 == 0)   //B    
    rgbValues[counter] = color.B;
if (counter % 4 == 1)   //G
    rgbValues[counter] = color.G;
if (counter % 4 == 2)   //R
    rgbValues[counter] = color.R;
if (counter % 4 == 3)   //A
{
    rgbValues[counter] = color.A;
    list_ct++;
}


This should solve the problem.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900