【发布时间】:2011-06-08 03:23:45
【问题描述】:
我写了函数:
public static byte[, ,] Bitmap2Byte(Bitmap image)
{
int h = image.Height;
int w = image.Width;
byte[, ,] result= new byte[w, h, 3];
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
Color c= image.GetPixel(i, j);
result[i, j, 0] = c.R;
result[i, j, 1] = c.G;
result[i, j, 2] = c.B;
}
}
return result;
}
但转换 1800x1800 图像需要将近 6 秒。我可以更快地做到这一点吗?
编辑:
好的,我找到了这个:http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx
有很好的例子。我唯一的问题是关于Marshal.Copy。我可以让它直接将数据复制到byte[,,]吗?
编辑 2:
好的,有时我得到奇怪的像素值,它们似乎不遵循 r0 g0 b0 r1 g1 b1 规则。为什么? 没关系。想通了。
编辑 3: 做好了。 0,13s 与 5,35s :)
【问题讨论】:
-
尝试交换循环:您当前正在迭代图像的列,但位图存储在行中。交换循环允许更好的缓存行为,这应该在一定程度上提高性能(尽管可能不会太多)。
-
你是对的。 5,65 秒前。 5.35 秒后。
-
@Miko:您可能想再次运行该测试几次。两者之间应该没有任何区别。
-
@MusiGenesis:虽然我无法消除在 这种情况 或通常在 C# 中无法检测到差异的可能性,但我可以向您保证其背后的理论是合理的。它与 CPU 缓存的工作方式有关:它始终存储 X 字节的块,即使请求较少,因此通过按实际存储的顺序迭代数据,可以更频繁地使用缓存。当然,这是一种微优化,但它不会损害可读性,如果您正在寻找使代码运行得更快的方法,那么每一点都会有所帮助。
-
@Miko:这是我告诉你谷歌的错,但不要使用
Marshal.Copy。请参阅此答案:stackoverflow.com/questions/740555/…
标签: c# winforms image-processing bitmap