C# 来自3 IntPtr的图像源

C# 来自3 IntPtr的图像源,c#,wpf,pointers,imagesource,C#,Wpf,Pointers,Imagesource,我从一个外部库中获得三个指向RGB通道阵列的IntPtr。 此时,我将三个数组合并为一个,并从新数组创建一个ImageSource 但是图像可能非常巨大(目前高达8000 x 4000 px),因此已经存储在内存中的数据转换需要花费太长时间 有没有一种方法可以使用这些指针在画布中显示图像而不进行复制?即,使用costum OnRender方法或其他方法的ImageSource派生类 我没有发现任何属于我的问题 更新: 我当前的代码如下所示: int unmapByes = Math.Abs(st

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

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

有没有一种方法可以使用这些指针在画布中显示图像而不进行复制?即,使用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;

WPF图像源实际上是驻留在GPU上的纹理,因此它们必须具有非常特定的格式。在这个世界上,你无法用你的三个阵列生存

然而,8000x4000只有32MB(乘以颜色字节),这在RAM中是不可复制的。如果你真的将你的减速归结为这一点,我敢打赌你做错了什么(使用
List
或类似的可扩展数组,而不是预先分配整个缓冲区,多次重复计算等等)


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

正确的答案是:

摆脱循环中的计算,因为循环中的计算成本很高。在这种情况下,它是分区。高成本的计算是指CPU指令集中没有的每一次计算

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

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

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


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

我必须重新排序数据。所以R[0]转到Res[0],G[0]=>Res[1],B[0]=>Res[2]等等。所以我的循环次数是32000000次。显然不是32MB。它是96MB(每个通道32MB。有问题吗?一次只做一个数组以将其保存在一级缓存中是什么意思?我添加了我当前的代码,所以你可以帮我优化它吗?我在这里不知所措。我可以让它更快吗?当然,摆脱
并行。对于
,这不是CPU限制的操作,你只是让它慢了很多。我的意思是一次复制一个字节的数组,增加目标指针(是的,使用指针)一次复制4个。这是你能得到的最笨拙的格式,与支持的像素格式完全不兼容。必须复制100兆字节是不可避免的,需要一段时间。购买其他库或使用电话。我不知道你在做什么。但是最高性能的图像处理库正在使用它图像类型。大多数线摄像机都会给你3个指向阵列的指针。为什么你认为我在寻求解决方案?因为我别无选择。所以请拿起你的电话,做些不同的事情。