如何用BitmapImage中的字节写WriteableBitmap中的像素?

时间:2016-08-20 11:54:22

标签: c# .net wpf .net-4.5 writeablebitmap

目标是存储许多相同大小的图像的字节,并在WriteableBitmap中绘制它们以创建高性能视频。

我尝试了下一个代码:

    public MainWindow()
    {
        InitializeComponent();

        Method();
    }

    private void Method()
    {
        BitmapImage bi = new BitmapImage(new Uri(@"Image.png", UriKind.Relative));
        int pw = bi.PixelWidth;
        int ph = bi.PixelHeight;

        WriteableBitmap wb = new WriteableBitmap(
            pw,
            ph,
            96,
            96,
            PixelFormats.Bgra32,
            null);

        byte[] data;
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bi));
        using (MemoryStream ms = new MemoryStream())
        {
            encoder.Save(ms);
            data = ms.ToArray();
        }

        int stride = 4 * pw;

        wb.Lock();
        wb.WritePixels(new Int32Rect(0, 0, pw, ph), data, 4 * pw, 0);
        wb.Unlock();
    }

错误:

  

抛出异常:' System.Windows.Markup.XamlParseException'在PresentationFramework.dll中   附加信息:'在类型' WpfApplication2.MainWindow'上调用构造函数。匹配指定的绑定约束引发异常。'行号' 6'和行位置' 9'。   如果存在此异常的处理程序,则可以安全地继续该程序。

如果我在UserControl中放置相同的代码,则会出现下一个错误:

  

未处理的类型' System.ArgumentException'发生在PresentationCore.dll中   附加信息:缓冲区大小不足。

1 个答案:

答案 0 :(得分:1)

您应该使用CopyPixels。

<强> MainWindow.xaml

<Grid>
    <Image x:Name="image"></Image>
</Grid>

<强> MainWindow.xaml.cs

    private void Method()
    {
        BitmapImage bi = new BitmapImage(new Uri(@"Image.png", UriKind.Relative));

        int stride = bi.PixelWidth * (bi.Format.BitsPerPixel + 7) / 8;
        byte[] data = new byte[stride * bi.PixelHeight];

        bi.CopyPixels(data, stride, 0);

        WriteableBitmap wb = new WriteableBitmap(
            bi.PixelWidth,
            bi.PixelHeight,
            bi.DpiX, bi.DpiY,
            bi.Format, null);

        wb.WritePixels(
            new Int32Rect(0, 0, bi.PixelWidth, bi.PixelHeight),
            data, stride, 0);

        image.Source = wb; // an Image class instance from XAML.
    }