0

我从外部系统接收图像,格式为一系列 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 上运行。并行化循环将是微不足道的,但我怀疑有更好的方法来解决这个问题。任何帮助将不胜感激!

4

3 回答 3

2

Bitmap.LockBits 方法的描述说,

您可以使用 SetPixel 方法更改图像的颜色,尽管 LockBits 方法为大规模更改提供了更好的性能。

我猜,另一种方法可能是在创建与位图文件格式匹配的 Stream 之后使用Bitmap(Stream) Constructor 。

于 2012-11-19T22:36:07.883 回答
0

检查一些FastBitmap实现,这将帮助您设置能够从中生成图像的数组。

于 2012-11-19T22:31:36.183 回答
0

对 GetPixel 和 SetPixel 的调用对本机函数进行互操作调用。每次调用其中一个函数时,位图图像被锁定,相应的像素/字节被修改,然后图像最终被解锁。您可以想象重复执行此操作非常低效。

正如其他人建议的那样,使用 LockBits 方法,尽管我想你将不得不使用不安全的代码。现在,如果允许,请使用它。它允许直接访问非托管内存缓冲区中的位图像素。

于 2012-11-19T22:42:46.680 回答