[C# WPF] WriteableBitmapで描画してみる

最近はWPFの描画速度と戦っています。

描画はWriteableBitmapを使うのが最速だという話を聞いたので、使ってみました。

スポンサーリンク

環境

  • Visual Studio 2019
  • .NET Framework 4.7.2

Windowの背景をWriteableBitmapで描いてみる

WriteableBitmapを使用して、ウィンドウの背景を真っ青にしてみます。

xaml側にCanvasを宣言しておいて、そこにWriteableBitmapをSourceにしたImageを追加します。

MSDNの注釈によると、PixelFormatは「Bgr32」か「Pbgra32」がいいと言うことなので、ここでは「Pbgra32」を使用します。

・MainWindow.xaml

<Window x:Class="Sample_WriteableBitmap.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Sample_WriteableBitmap"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Canvas x:Name="xCanvas"/>

</Window>

・MainWindow.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Sample_WriteableBitmap
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DrawImage();
        }

        private void DrawImage()
        {
            // 描画先になるImageを生成する
            var image = new Image();

            // WritableBitmapを生成する
            var width = (int)Width;
            var height = (int)Height;
            var bitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Pbgra32, null);

            // 描画データを格納するバイト列を生成する
            var size = width * height * 4;
            var pixels = new byte[size];

            // バイト列に描画データを格納する
            for (int i = 0; i < size; i += 4)
            {
                pixels[i] = 255;        // Blue
                pixels[i + 1] = 0;      // Green
                pixels[i + 2] = 0;      // Red
                pixels[i + 3] = 255;    // Alpha
            }

            // バイト列 -> BitmapImage
            var stride = width * 4;    // 1行あたりのバイト数
            bitmap.WritePixels(new Int32Rect(0, 0, width, height), pixels, stride, 0, 0);

            // Image.Sourceに作成したWriteableBitmapを指定する
            image.Source = bitmap;

            // Canvasに登録する
            xCanvas.Children.Add(image);
        }
    }
}

WriteableBitmapの中身

.NET Frameworkのコードを見ると、WriteableBitmapはmilcoreの「MILSwDoubleBufferedBitmap」を使用しています。

milcoreはDirectXを叩くので、WriteableBitmapを使うとDirectXで描画していることになります。

WriteableBitmapでの描画は、MFCのBitBlt()に近いものかと思いましたが違うっぽいです。

おしまい。

スポンサーリンク

C#,WPFC#,WPF

Posted by peliphilo