C#で画像を描いてみた(WPFでBitmapSource.Create編)

WPFのC#で画像を描く際にWritableBitmapクラスを使ってみたりしたのですが、一度画像を作ったら書き換えないというのであれば、BitmapSourceクラスで作成できるようです。というメモです。 試した環境は下記です。

  • Visual Studio 2015 Express for Windows Desktop

目次

  1. 処理の流れ
    1. BitmapSource.Createメソッド
  2. 試してみた
    1. 何を作る?
    2. コード
    3. 結果

処理の流れ

MSDNのBitmapSourceクラスの説明を読んでいたら、Create()なるメソッドがあるではないですか。(勉強不足) 大まかには、下記の流れで処理します。

  1. Byte配列の画像データを作る。

  2. Byte配列のデータをBitmapSource.Createメソッドに渡して、BitmapSourceのインスタンスを作る。

  3. ImageコントロールのSourceプロパティにBitmapSourceのインスタンスを渡す。

Setなんたらというようなメソッドが見当たらないので、後から書き換えようと思ったらWritableBitmapクラスを使うのが良いようです。

BitmapSource.Createメソッド

BitmapSource.Create()メソッドは、配列を渡してBitmapSourceを作るパターンと、メモリへのポインタを渡してBitmapSourceを作るパターンがあります。今回は前者を使います。

BitmapSource bitmap = BitmapSource.Create(width, height, dipx, dpiy, format, palette, array, stride);

戻り値はBitmapSourceのインスタンスです。

引数

内容

width

int

画像の横方向のピクセル数。

height

int

画像の縦方向のピクセル数。

dpix

double

画像の横方向の解像度。

dpiy

double

画像の縦方向の解像度。

format

PixelFormat

ピクセルのフォーマット。PixelFormatsクラスのプロパティ値で指定できる。

palette

BitmapPalette

画像のパレット。BitmapPalettesクラスのプロパティ値で指定できる。

array

Array

ピクセルの配列。

stride

int

画像の1列あたりのバイト数。

今回はパレットを使わないので、paletteはnullにします。

試してみた

何を作る?

256x100の画像で、黒から白へのグラデーションを描いて、ウィンドウに表示してみます。

コード

参照の設定はありません。 XAMLとコードを下記の様にしました。

<Window x:Class="image_trial3.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:image_trial3"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="300" Background="LightGray">
    <Grid>
        <Image Name="image" Stretch="None" />
    </Grid>
</Window>

ウィンドウ背景を灰色にしました。あとはImageを置いただけです。

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

namespace image_trial3
{
    ///
    /// MainWindow.xaml の相互作用ロジック
    ///
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            int width = 256;
            int height = 100;
            int dpi = 96;

            int pixelsSize = (int)(width * height * 4);
            byte[] pixels = new byte[pixelsSize];

            // バイト列に色情報を入れる
            byte value = 0;
            for (int x = 0; x < width * height * 4; x = x + 4)
            {
                byte blue = value;
                byte green = value;
                byte red = value;
                byte alpha = 255;
                pixels[x] = blue;
                pixels[x + 1] = green;
                pixels[x + 2] = red;
                pixels[x + 3] = alpha;
                if (value < 255)
                {
                    value++;
                }
                else
                {
                    value = 0;
                }
            }

            // バイト列をBitmapSourceに変換する
            int stride = (width * PixelFormats.Pbgra32.BitsPerPixel + 7) / 8; // 一行あたりのバイトサイズ
            BitmapSource bitmap = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Pbgra32, null, pixels, stride);

            // ウィンドウに表示
            image.Source = bitmap;
        }
    }
}

インスタンスを作るつもりで

BitmapSource bitmap = new BitmapSource();

とやるとVisual Studioさんに怒られます。いきなりCreate()メソッドでインスタンスを作るのですね。

結果

実行すると、下記が表示されます。 160219-2-01 きれいなグラデーションになってます。画像の変更をしないのであれば、WritableBitmapよりもこっちの方が楽かも。

公開日

広告