【问题标题】:WPF equivalent to Bitmap.LockBitsWPF 等效于 Bitmap.LockBits
【发布时间】:2011-08-22 12:20:25
【问题描述】:

我在 Win Forms 应用程序中有以下工作代码:

Bitmap bitmap = new Bitmap(imageWidth, imageHeight, PixelFormat.Format32bppArgb);
Rectangle rect = new Rectangle(0, 0, imageWidth, imageHeight);
BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

Tao.DevIl.Il.ilConvertImage(Tao.DevIl.Il.IL_BGRA, Tao.DevIl.Il.IL_UNSIGNED_BYTE);
Tao.DevIl.Il.ilCopyPixels(0, 0, 0, imageWidth, imageHeight, 1, Tao.DevIl.Il.IL_BGRA, Tao.DevIl.Il.IL_UNSIGNED_BYTE, bitmapData.Scan0);

bitmap.UnlockBits(bitmapData);

我想将此代码转换为与 WPF 兼容并可以在 UI 中显示。这意味着我可能必须将 System.Drawing.Bitmap 转换为 System.Windows.Media.Imaging.BitmapImage。

但是,我没有在两者之间进行转换,而是想知道是否有更直接/更快的方法来做到这一点?就像在 BitmapImage 上做 LockBits() 之类的事情。

ilCopyPixels() 将 IntPtr 作为最后一个 baram。在旧代码中,我得到了这个表单 BitmapData.Scan0。

编辑:

感谢 Erno 的回答,我得出以下结论:

WriteableBitmap bitmap = new WriteableBitmap(imageWidth, imageHeight, 96, 96, PixelFormats.Bgra32, null);
bitmap.Lock();
Tao.DevIl.Il.ilCopyPixels(0, 0, 0, imageWidth, imageHeight, 1, Tao.DevIl.Il.IL_BGRA, Tao.DevIl.Il.IL_UNSIGNED_BYTE, bitmap.BackBuffer);
bitmap.Unlock();

但是,当我将位图设置为图像的来源时,我什么也看不到。不过我没有遇到任何异常。

谢谢!

【问题讨论】:

    标签: .net wpf winforms image image-processing


    【解决方案1】:

    看看WriteableBitmap,它处理了大部分这些细节。

    【讨论】:

    • 您能否说明如何将位图指定为图像源?我也有点担心 iLCopyPixels 中的所有参数。像素格式必须正确。您可以尝试将像素复制到数组中,然后分配位图的 Pixels 属性吗?
    • 我只是将图像的 Source 属性设置为我的 WriteableBitmap。我正在使用 Tao 框架,所以除了 CopyPixels 之外别无选择。我希望它适用于数组,会看到。
    • 顺便说一句,Bitmap 和 WriteableBitmap 都没有 Pixels 属性。
    • 抱歉,我倾向于混淆 WPF 和 Silverlight WriteableBitmaps。
    【解决方案2】:

    我目前的临时修复是使用以下代码将位图转换为位图源:

    Bitmap bitmap = new Bitmap(imageWidth, imageHeight, PixelFormat.Format32bppArgb);
    Rectangle rect = new Rectangle(0, 0, imageWidth, imageHeight);
    BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    
    Tao.DevIl.Il.ilCopyPixels(0, 0, 0, imageWidth, imageHeight, 1, Tao.DevIl.Il.IL_BGRA, Tao.DevIl.Il.IL_UNSIGNED_BYTE, bitmapData.Scan0);
    Tao.DevIl.Il.ilDeleteImages(1, ref imageId);
    
    bitmap.UnlockBits(bitmapData);
    
    using (MemoryStream str = new MemoryStream())
    {
        bitmap.Save(str, ImageFormat.Bmp);
        str.Seek(0, SeekOrigin.Begin);
        BitmapDecoder bdc = new BmpBitmapDecoder(str, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
        // Retrieve the BitmapSource
        image1.Source = bdc.Frames[0];
    }
    

    显然,我宁愿直接创建 BitmapSource,而不需要先创建 Bitmap 的额外开销。仍然欢迎任何建议!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      • 2011-03-23
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多