ImageSource from 3 IntPtr

本文关键字:IntPtr from ImageSource | 更新日期: 2023-09-27 18:24:52

我从外部库中获得RGB通道阵列的三个IntPtr。目前,我将三个数组合并为一,并从新数组中创建一个ImageSource。

但图像可能非常巨大(目前高达8000 x 4000像素),因此已经存储在内存中的数据的转换需要太长时间。

有没有一种方法可以使用这些指针在画布中显示图像而不进行复制?例如,使用costum-OnRender方法或其他方法的ImageSource派生类?

我没有发现任何属于我问题的东西。

更新:我当前的代码如下:

int unmapByes = Math.Abs(stride) - (width * 3);
        byte* _ptrR = (byte*)ptrR;
        byte* _ptrG = (byte*)ptrG;
        byte* _ptrB = (byte*)ptrB;
        BitmapSource bmpsrc = null;
        App.Current.Dispatcher.Invoke(() =>
        {
            bmpsrc = BitmapSource.Create(width,
                                                  height,
                                                  96,
                                                  96,
                                                  PixelFormats.Bgr24,
                                                  null,
                                                  new byte[bytes],
                                                  stride);
        });
        BitmapBuffer bitmapBuffer = new BitmapBuffer(bmpsrc);
        byte* buffer = (byte*)bitmapBuffer.BufferPointer;

        Parallel.For(0, bytes / 3 - height, (offset) =>
        {
            int i = offset * 3 + (((offset + 1) / width)) * unmapByes;
            *(buffer + i) = *(_ptrB + offset);
            *(buffer + i + 1) = *(_ptrG + offset);
            *(buffer + i + 2) = *(_ptrR + offset);
        });
        return bmpsrc;

ImageSource from 3 IntPtr

WPF图像源实际上是GPU上的纹理,因此它们必须具有非常特定的格式。在这个世界上,你不会用你的三个数组过日子的。

然而,8000x4000只有32MB(乘以彩色字节),这在RAM中没有什么可复制的。如果你真的把你的减速描述为这样,我敢打赌你做错了什么(使用List<>或类似的可增长数组,而不是预先分配整个缓冲区,多次重新计算等等)

作为我脑海中的一个优化提示,我建议不要使用3个指针同时前进的天真实现,一次执行一个数组以将其保留在L1缓存中。

正确答案是:

去掉循环中的计算,因为它们的成本很高。在这种情况下,它是分裂。具有高成本的计算是不在CPU的指令集中的每一个计算。

第二个是,Parallel.For循环可以提高速度,但前提是循环的每个线程都有更大的工作量。否则,处理成本太高。

所以现在我修改了代码,对每一行使用Parallel.For循环,对这一行的每个像素使用内部For循环。

现在我可以在32ms内转换8000x4000 24rgb大小的图像(在我的系统上,我可以说1兆像素=1ms)。

对于未来:每个有问题的人都想知道,为什么他的问题被否决了。如果你不知道答案或者只写bull***t,停止它。