我正在接收来自外部系统的图像,其形式为一系列BGR值,后跟一个空字节。序列看起来有点像......
[B,G,R,0,B,G,R,0,...,B,G,R,0]其中每个BGR0是图像中的单个像素。
我需要在.NET位图中使用它,所以我可以对它进行一些操作并提出以下函数来执行此操作:
private Bitmap fillBitmap(byte[] data, int width, int height)
{
Bitmap map = new Bitmap(width, height);
for (int i = 0; i < data.Length; i += 4)
{
int y = ((i / 4) / width);
int x = ((i / 4) - (y * width));
int b = data[i];
int g = data[i + 1];
int r = data[i + 2];
Color pixel = Color.FromArgb(r, g, b);
map.SetPixel(x, y, pixel);
}
return map;
}
除了我的大多数图像都是1920x1200之外,这通常都可以。所以我有一个迭代超过200万次的循环。即便如此,对于任何现代处理器而言,200万次迭代也不会非常繁重。
但由于某种原因,这个循环可能需要5-15秒才能在我的服务器上运行一个非常强大的Xeon。并行化循环是微不足道的,但我怀疑还有更好的方法来解决这个问题。任何帮助将不胜感激!
答案 0 :(得分:2)
您可以使用SetPixel方法更改图像的颜色,但LockBits方法可以为大规模更改提供更好的性能。
我猜,在创建匹配位图文件格式的Stream后,可能会使用Bitmap(Stream) Constructor。
答案 1 :(得分:0)
检查一些FastBitmap实现,它将帮助您设置可以从中生成图像的阵列。
答案 2 :(得分:0)
对GetPixel和SetPixel的调用会对本机函数进行互操作调用。每次调用其中一个函数时,位图图像都会被锁定,相应的像素/字节会被修改,然后图像最终会被解锁。你可以想象,反复执行这项工作非常低效。
正如其他人建议使用LockBits方法,尽管你必须使用我想象的不安全代码。现在,如果允许,请使用它。它允许直接访问非托管内存缓冲区中的Bitmap像素。