【问题标题】:Convert WriteableBitmap to BitmapImage using BmpBitmapEncoder WPF使用 BmpBitmapEncoder WPF 将 WriteableBitmap 转换为 BitmapImage
【发布时间】:2015-03-25 23:06:40
【问题描述】:

我在使用 BmpBitmapEncoder 将 WriteableBitmap 转换为 BitmapImage 时遇到问题。 这是我的方法:

    public BitmapImage ConvertWriteableBitmapToBitmapImage(WriteableBitmap wbm)
    {
        bmp = new BitmapImage();
        using (MemoryStream stream = new MemoryStream())
        {
            /*PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(wbm));
            encoder.Save(stream);*/
            BmpBitmapEncoder encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(wbm));
            encoder.Save(stream);

            bmp.BeginInit();
            bmp.UriSource = new Uri(MyImage.Source.ToString());
            bmp.CacheOption = BitmapCacheOption.OnLoad;
            bmp.CreateOptions = BitmapCreateOptions.IgnoreImageCache | BitmapCreateOptions.PreservePixelFormat;
            bmp.StreamSource = stream;
            bmp.EndInit();
            bmp.Freeze();
        }
        return bmp;
    }

我正在使用 BmpBitmapEncoder,因为这是在不更改图像 (*.bmp) 大小的情况下保存的唯一方法。我想用更改的像素表和指定的格式像素(Bgr24)保存图像。使用 BmpBitmapEncoder 强制设置 bmp.UriSource ,这是一个问题。 WriteableBitmap 没有这个属性。此外,当我注释行 //bmp.UriSource 向我显示一个异常:bmp.EndInit() 中的“System.ArgumentNullException”。 当我将我的方法更改为:

    public BitmapImage ConvertWriteableBitmapToBitmapImage(WriteableBitmap wbm)
    {
        bmp = new BitmapImage();
        using (MemoryStream stream = new MemoryStream())
        {
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(wbm));
            encoder.Save(stream);
            /*BmpBitmapEncoder encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(wbm));
            encoder.Save(stream);*/

            bmp.BeginInit();
            //bmp.UriSource = new Uri(MyImage.Source.ToString());
            bmp.CacheOption = BitmapCacheOption.OnLoad;
            //bmp.CreateOptions = BitmapCreateOptions.IgnoreImageCache | BitmapCreateOptions.PreservePixelFormat;
            bmp.StreamSource = stream;
            bmp.EndInit();
            bmp.Freeze();
        }
        return bmp;
    }

一切正常,但结果是图像增加大小并将像素格式更改为 Bgr32,这不是我所期望的结果。我保存图像的方法很好,因为我在未更改的像素上对其进行了测试,结果很好——图像不会改变格式和大小。请帮我解决这个问题。

【问题讨论】:

    标签: c# wpf bitmapimage writeablebitmap


    【解决方案1】:

    为了改变像素格式,WPF 有 FormatConvertedBitmap 类,它是一个 BitmapSource:

    WriteableBitmap wbm;
    ...
    var bm = new FormatConvertedBitmap(wbm, PixelFormats.Bgr24, null, 0);
    

    它不是 BitmapImage,但你在任何地方都不需要它。所有 WPF 方法和属性(例如 Image.Source)都使用 ImageSource 或派生的 BitmapSource 作为它们的类型。没有明确需要 BitmapImage 的 API,因此无需转换为 BitmapImage。

    【讨论】:

      【解决方案2】:

      我解决了这个问题。这是使用 BmpBitmapEncoder 将 WriteableBitmap 转换为 BitmapImage 的代码。使用这种方法可以确保我们的图像在保存时保持不变。不变我的意思是 - 大小不增加,格式像素保持在 Bgr24。

          public BitmapImage ConvertWriteableBitmapToBitmapImage(WriteableBitmap wbm)
          {
              bmp = new BitmapImage();
              using (MemoryStream stream = new MemoryStream())
              {
                  BmpBitmapEncoder encoder = new BmpBitmapEncoder();
                  encoder.Frames.Add(BitmapFrame.Create(wbm));
                  encoder.Save(stream);
                  bmp.BeginInit();
                  bmp.CacheOption = BitmapCacheOption.OnLoad;
                  bmp.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
                  bmp.StreamSource = new MemoryStream(stream.ToArray()); //stream;
                  bmp.EndInit();
                  bmp.Freeze();
              }
              return bmp;
          }
      

      【讨论】:

      • 你还没有告诉我们为什么你需要一个 BitmapImage。通常不需要整个转换,因为您可以将原始 WriteableBitmap 传递给所有接受 BitmapSource 或 ImageSource 的方法或属性。
      猜你喜欢
      • 2018-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多