字节级别的颜色操作问题 [英] Problem with color manipulation on byte level

查看:80
本文介绍了字节级别的颜色操作问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

我当前项目还有一个问题:

我想通过对其应用比例来为位图着色。比例的颜色存储在SynchronizedCollection中,以使Thread安全。当我想为我的Bitmap着色时,一切正常,但是位图中的颜色不是刻度的颜色(这应该是不可能的)。所以我认为我对Bitmap的Bytewise操作有问题。我找不到错,所以也许你可以帮助我:



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:

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 []每个像素保存一个值,因此每4个字节有一个值位图



结果如下:



点击我



如你所见,图像中有颜色,不在缩放中上面: - (



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 :-(

推荐答案

问题是计算机是little-endian,这意味着虽然格式是ARGB,但字节存储在内存中的顺序是B - G - R - A(即B存储在比G低的存储器地址,然后是R,然后是A)。



你的代码是假设的为了得到预期的结果,你应该反转分配顺序:



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:

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.


这篇关于字节级别的颜色操作问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆