3

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

我目前正在设法使用针对老式 System.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 可能可以做到这一点,但这是一个涉及多个线程的学术练习(在不安全模式下编辑位图时支持)。

提前致谢

4

1 回答 1

3

我会告诉你我所知道的。

首先,在将位图返回主线程之前,您似乎已经了解冻结位图。这是一个好的开始。

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

当然,您也可以直接从字节数组创建 BitmapSource(并减少 GDI 位图的开销)。msdn 文档

您是否考虑过WriteableBitmap?这是 WPF 团队对所有复制的普遍抱怨的回应。

编辑:MSDN 明确表示(在 WritableBitmap.BackBuffer 文档中)它可以从后台线程中使用:

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

因此,如果您让 UI 线程获取锁和指针,您可以让工作线程写入像素。

于 2010-10-13T13:10:05.787 回答