如何在C#中以像素级操作图像?
我需要能够分别读取/修改每个位图像素RGB值。
我们将非常感谢代码示例。
答案 0 :(得分:49)
答案 1 :(得分:15)
示例代码例程(我将其用于简单的合并和比较功能。它需要两个图像并生成第三个灰度图像,显示两个图像之间的差异作为灰度色调级别。它越暗,差异越大。):
public static Bitmap Diff(Bitmap src1, Bitmap src2, int x1, int y1, int x2, int y2, int width, int height)
{
Bitmap diffBM = new Bitmap(width, height, PixelFormat.Format24bppRgb);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
//Get Both Colours at the pixel point
Color col1 = src1.GetPixel(x1 + x, y1 + y);
Color col2 = src2.GetPixel(x2 + x, y2 + y);
// Get the difference RGB
int r = 0, g = 0, b = 0;
r = Math.Abs(col1.R - col2.R);
g = Math.Abs(col1.G - col2.G);
b = Math.Abs(col1.B - col2.B);
// Invert the difference average
int dif = 255 - ((r+g+b) / 3);
// Create new grayscale RGB colour
Color newcol = Color.FromArgb(dif, dif, dif);
diffBM.SetPixel(x, y, newcol);
}
}
return diffBM;
}
Marc's post注意到LockBits并使用它直接在内存中修改图像。如果表现是一个问题,我建议看一下而不是我发布的内容。谢谢马克!
答案 2 :(得分:5)
System.Drawing.Bitmap有一个GetPixel(int x,int y)公共方法,它返回一个System.Drawing.Color结构。该结构具有字节成员R,G,B和A,您可以直接修改它们,然后再次在Bitmap上调用SetPixel(Color)。
不幸的是,这将是相对缓慢的,但它是用C#做最简单的方法。如果您正在处理单个像素并且发现性能不足,并且您需要更快的东西,则可以使用LockBits ...虽然它要复杂得多,因为您需要了解该颜色深度和类型的位结构,并使用位图的步幅和什么不...所以如果你发现它是必要的,请确保你找到一个很好的教程!网上有几个,谷歌搜索“C#LockBits”将为您提供六打值得阅读。
答案 3 :(得分:3)
如果性能至关重要,LockBits的另一种替代方法是管理DirectX。
有关详情,请参阅早期的Stack Overflow问题 Rendering graphics in C# 。
与Lockbits一样,您需要使用unsafe关键字/编译器开关,但您可以获得高性能的像素级访问。
与使用普通的Bitmap类和PictureBox控件相比,通过DirectX后缓冲也可以获得更高性能的屏幕渲染。