【发布时间】:2016-03-22 09:18:08
【问题描述】:
我正在尝试学习用于图像处理的 LockBitmap 类,我发现了下面发布的这段代码。基本上它返回 x-y 坐标的颜色。
当然这种方法只有在我执行source.LockBits()和Marshal.Copy()/unsafe context之后才有效。
public Color GetPixel(int x, int y, Bitmap source)
{
int Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);
int Width = source.Width;
int Height = source.Height;
Color clr = Color.Empty;
// Get color components count
int cCount = Depth / 8;
int PixelCounts = Width * Height;
byte[] Pixels = new byte[cCount * PixelCounts];
// Get start index of the specified pixel
int i = ((y * Width) + x) * cCount;
byte b = Pixels[i];
byte g = Pixels[i + 1];
byte r = Pixels[i + 2];
byte a = Pixels[i + 3]; // a
clr = Color.FromArgb(a, r, g, b);
return clr;
}
- 什么是
cCount,为什么总是Depth / 8? -
int i = ((y * Width) + x) * cCount,这是从 (x,y) 坐标转换为Pixels[i]的固定公式吗?为什么?
【问题讨论】:
-
这非常简单,并且仅适用于简单的 32 位位图(忽略
Pixels从一开始就不会获取任何数据)。它不处理调色板、对齐、位对齐(并非所有位图都是“字节对齐”)等。如果你想绕过安全的 GDI+ 方法,你需要做一些研究——快速编码的关键通常会忽略与您无关的边缘情况,但这意味着首先要知道边缘情况是什么,并了解您是否可以安全地忽略它们。 -
@Luaan,感谢您的回复。我真的很想对此做更多的研究。你有什么教程/网站可以推荐吗?我什至不知道谷歌用什么关键字。
-
问题是,所有这些都是古老的,低级的东西。您必须从许多不同的来源拼凑出大部分知识,而且很可能根本不值得。如今,甚至游戏都在使用 32 位 ARGB(好吧,除了那些转向 HDR 的游戏:P)。例如,如果您可以假设某种像素格式,您可以忽略几乎所有的复杂性 - 确保这一点的一种可能方法是简单地选择最常见的格式(MSPaint 的 32 位是当今 Windows 上最常见的格式),并回退到 GDI+ 以从其他格式转换。