我想在WPF应用程序中对图像进行一些处理。但是,我想在运行时修改内存中的BitMapsource的像素。

我目前正在使用“不安全”代码来实现与老式的系统。drawing.bitmap,它可以使用(锁定工作区域,用像素的小提琴)工作来完成此操作。在这篇文章中描述了该方法: http://blogs.msdn.com/b/ericgu/archive/2007/06/20/lost-column-2-unsafe-image-processing.aspx

为了在WPF中获得此功能,我然后使用这种方法创建了WPF BitMapsource:

    BitmapSource destination;
    IntPtr hBitmap = bitmap.GetHbitmap();
    BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions();
    destination = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, sizeOptions);
    destination.Freeze();
    return destination;

但是,这在内存中创建了很多副本,我真的很想进入那里,并在Bitmapsource内部的底层摆弄,就像Ericgu在Bitmap示例中显示的那样。这可能吗?

我意识到PixelShaders可能可以做到这一点,但这是一项涉及多个线程的学术练习(在不安全模式下编辑位图时得到支持)。

提前致谢

有帮助吗?

解决方案

我会尽可能多地告诉你。

首先,您似乎已经知道冻结位图,然后再将其还给主线程。那是一个好的开始。

我曾经尝试通过从BitMapsource得出新的实现来减少复制,并覆盖将数据从位图中复制出的虚拟函数。它起作用,但产生了大量的内存泄漏。从来没有想过。

当然,您当然可以直接从一系列字节(并丢失GDI位图的开销)来创建一个bitmapsource。 MSDN文档

你考虑过一个 可写的?那就是WPF团队对所有复制的共同投诉的回应。

编辑: :MSDN明确说明(在Wraithitbitmap.backbuffer文档中)可以从背景线程中使用:

您可以将Backbuffer指针传递给外部组件和其他线程进行处理,但是如果这样做,则必须提供自己的线程协调。特别是,您必须通过调用AddDirtyRect方法来确保UI线程指定更改的区域,并且UI线程通过调用Unlock方法来解锁缓冲区。

因此,如果让UI线程Aquire锁定锁定和指针,则可以让Worker线程编写像素。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top