使用BmpBitmapEncoder WPF将WriteableBitmap转换为BitmapImage

时间:2015-03-25 23:06:41

标签: c# wpf bitmapimage writeablebitmap

我在使用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,因为这只是保存而不改变Image大小(* .bmp)的方法。我想用更改的像素表和指定的格式像素(Bgr24)保存图像。使用BmpBitmapEncoder强制设置bmp.UriSource,这是一个问题。 WriteableBitmap没有此属性。而且,当我对注释行//bmp.UriSource显示异常时:" System.ArgumentNullException"在bmp.EndInit()中。 当我将我的方法更改为:

    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,这不是结果,我的期望。我保存图像的方法很好,因为我在未更改的像素上测试它,结果很好 - 图像不会改变格式和大小。 Plz帮助我。

2 个答案:

答案 0 :(得分:0)

对于更改像素格式,WPF具有FormatConvertedBitmap类,这是一个BitmapSource:

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

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

答案 1 :(得分:0)

我解决了这个问题。这是一个使用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;
    }