繁体   English   中英

修改C#color int或uint的字节

[英]Modify a byte of a C# color int or uint

我正在C#中处理位图,并且您知道位图通常在内存中(锁定时)存储为24bpp或32bpp。 提取像素的int颜色值后,我需要一次读取一个字节以获得R,G,B,并编辑相同的字节分别修改RGB。 有没有一种方法可以使用指针修改4字节32位int的任何给定字节? 或者,也许我可以创建一个struct并将int强制转换为允许访问/修改单个字节的结构?

int color = 0xFFAABB

// attempt to read individual bytes of an int
int R = *((*color));
int G = *((*color)+1);
int B = *((*color)+2);

// attempt to modify individual bytes of an int
*((*color)) = R;
*((*color)+1) = G;
*((*color)+2) = B;

我需要一种用于快速读取/写入单个字节的方法。 如果有使用这种指针的unsafe方法,我也不介意。 我无法将每个像素转换为Color对象,因为它对于高速图像处理而言太慢了。

通常,我要做的就是创建一个结构,如您所说:

public struct Pixel {
    public byte Blue;
    public byte Green;
    public byte Red;
    public byte Alpha;
}

然后,我有一个实用程序功能,例如:

public void SetPixel(int x, int y, Pixel colour) {
    Pixel* pixel = GetPixelAt(x, y);
    *pixel = colour;
}

public Pixel* GetPixelAt(int x, int y) {
    return (Pixel*)((byte*)_bitmapData.Scan0.ToPointer() + y * _width + x * sizeof(Pixel));
}

然后,您可以这样称呼它:

Pixel p;
p.Red = 255;
p.Green = 0;
p.Blue = 0;
p.Alpha = 255;

SetPixel(0, 0, p);

_bitmapData是通过LockBits返回的BitmapData结构。

编辑:

从评论。 这是转换它们的方式:

// from pixel to int
Pixel p;
p.Red = 0;
p.Green = 0;
p.Blue = 0;
p.Alpha = 0;

int* i = (int*)&p;

// from int to pixel
Pixel p2;

p2 = *(Pixel*)&i;

未经测试,但应该可以。

要使用指针,必须使用不安全的代码。 但是,您可以使用移位和按位运算符来实现所需的功能。

// attempt to read individual bytes of an int
int r = (color & 0x00FF0000)>>16;
int g = (color & 0x0000FF00)>>8;
int b = (color & 0x000000FF);

Console.WriteLine("R-{0:X}, G-{1:X}, B-{2:X}", r, g, b);
// attempt to modify individual bytes of an int
int r1 = 0x1A;
int g1 = 0x2B;
int b1 = 0x3C;
color = (color & ~0x00FF0000) | r1 << 16;
color = (color & ~0x0000FF00) | g1 << 8;
color = (color & ~0x000000FF) | b1;

Console.WriteLine("Color-{0:X}", color);

您可以根据需要将此片段包装为结构。

这是不安全代码的解决方案,您必须在构建选项中设置允许不安全代码。

using System;

namespace PixelTest
{
    public unsafe struct Pixel
    {
        private int _color;

        public Pixel(int color)
        {
            _color = color;
        }

        public int GetColor()
        {
            return _color;
        }

        public int GetR()
        {
            fixed(int* c = &_color)
            {
                return *((byte*)c + 2);
            }
        }

        public int GetG()
        {
            fixed(int* c = &_color)
            {
                return *((byte*)c + 1);
            }
        }

        public int GetB()
        {
            fixed(int* c = &_color)
            {
                return *(byte*)c;
            }
        }

        public void SetR(byte red)
        {
            fixed (int* c = &_color)
            {
                *((byte*)c + 2) = red;
            }
        }

        public void SetG(byte green)
        {
            fixed (int* c = &_color)
            {
                *((byte*)c + 1) = green;
            }
        }

        public void SetB(byte blue)
        {
            fixed (int* c = &_color)
            {
                *(byte*)c = blue;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Pixel c = new Pixel(0xFFAABB);
            Console.WriteLine("R-{0:X}, G-{1:X}, B-{2:X}", c.GetR(), c.GetG(), c.GetB());
            c.SetR(0x1A);
            c.SetG(0x2B);
            c.SetB(0x3D);
            Console.WriteLine("Color - {0:X}", c.GetColor());
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM