How to write pixels in WriteableBitmap by bytes from BitmapImage?

c# .net wpf .net-4.5 writeablebitmap

2042 просмотра

1 ответ

The goal is to store bytes of many same sized images and draw them in WriteableBitmap to create high performance video.

I tried next code:

    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();
    }

Error:

Exception thrown: 'System.Windows.Markup.XamlParseException' in PresentationFramework.dll Additional information: 'The invocation of the constructor on type 'WpfApplication2.MainWindow' that matches the specified binding constraints threw an exception.' Line number '6' and line position '9'. If there is a handler for this exception, the program may be safely continued.

If I place the same code in UserControl, it gives next error:

An unhandled exception of type 'System.ArgumentException' occurred in PresentationCore.dll Additional information: Buffer size is not sufficient.

Автор: Ziya Jafarov Источник Размещён: 08.11.2019 11:16

Ответы (1)


1 плюс

Решение

You should use 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.
    }
Автор: Ziya Jafarov Размещён: 20.08.2016 04:10
Вопросы из категории :
32x32