修改C#color int或uint的一个字节

修改C#color int或uint的一个字节,c#,pointers,colors,bitmap,int,C#,Pointers,Colors,Bitmap,Int,我正在使用C#中的位图,正如您所知,位图通常以24bpp或32bpp的形式存储在内存中(锁定时)。在提取像素的int-color值后,我需要一次读取一个字节以获得R、G、B,并编辑相同的字节以分别修改RGB。有没有一种方法可以使用指针修改4字节32位int的任何给定字节?或者我可以创建一个struct并将int转换为允许访问/修改单个字节的struct int color = 0xFFAABB // attempt to read individual bytes of an int int

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

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;

我需要这样一种方法来快速读取/写入单个字节。如果有一个
不安全的
方法来处理这样的指针,我也不介意。我无法将每个像素转换为
颜色
对象,因为它对于高速图像处理来说太慢了。

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

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);
\u bitmapData
是通过
锁位返回的
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;

未经测试,但应该可以。

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

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);
\u bitmapData
是通过
锁位返回的
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);

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

// 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);


没有正确地理解它。。您正在尝试修改位图每个像素的颜色吗?为什么不使用color.FromArgb()?然后你可以使用color.R/G/B.@Carra-你的方法慢得可怜。只要试着将每一个数字颜色值转换为每像素一个OOP颜色对象,就可以看到图像处理的速度。我需要非常快地处理字节,因此我试图避免位移位方法。OOP是不可能的。@Geotarget。你说得对,很慢。当我不得不这样做的时候,我使用了一个名为FastBitmap的类,它使用了不安全的方法,而且速度更快。。您正在尝试修改位图每个像素的颜色吗?为什么不使用color.FromArgb()?然后你可以使用color.R/G/B.@Carra-你的方法慢得可怜。只要试着将每一个数字颜色值转换为每像素一个OOP颜色对象,就可以看到图像处理的速度。我需要非常快地处理字节,因此我试图避免位移位方法。OOP是不可能的。@Geotarget。你说得对,很慢。当我不得不这样做时,我使用了一个名为FastBitmap的类,它使用了不安全的方法,而且速度更快。为什么不安全?如果你担心性能,我告诉你按位运算符非常快。为什么要使用不安全的代码?“我告诉你”按位运算符不如直接字节访问快。只需计算读/写操作的数量,然后自己查看。尝试解决方案并测试按位操作的性能,然后告诉我知道的结果。为什么不安全?如果你担心性能,我告诉你按位运算符非常快。为什么要使用不安全的代码?“我告诉你”按位运算符不如直接字节访问快。只需计算读/写操作的数量,并亲自查看。尝试使用按位操作测试解决方案和性能,并告诉我知道结果。没有不安全的代码?你在改变你的要求。。如上所述,您需要不安全的代码。。(在@Hamlet的回答中)不,你的代码很好,我的意思是没有像Scan0之类的图像指针代码。这让我很困惑,我只需要查看将int转换为Pixel结构并返回.Editted的代码。希望这就是你的意思。太棒了!非常感谢。所以把整型转换成像素和像素是没有成本的?我希望它不会像普通OOP对象那样为新的像素对象分配内存?您的
Pixel
对象将被分配。。这是无法避免的。它是一个
struct
,因此它将在堆栈上分配..没有不安全的代码?你在改变你的要求。。如上所述,您需要不安全的代码。。(在@Hamlet的回答中)不,你的代码很好,我的意思是没有像Scan0之类的图像指针代码。这让我很困惑,我只需要查看将int转换为Pixel结构并返回.Editted的代码。希望这就是你的意思。太棒了!非常感谢。所以把整型转换成像素和像素是没有成本的?我希望它不会像普通OOP对象那样为新的像素对象分配内存?您的
Pixel
对象将被分配。。这是无法避免的。但它是一个
结构
,因此将在堆栈上分配它。。