[英]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.