1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C#】セーフコードでビットマップ画像を高速に操作する

Posted at

はじめに

C# で画像データをやり取りする機能として、標準ライブラリに System.Drawing.Bitmap クラスがあります。

今では少し古くさいクラスのようで、デメリットが存在します。

  • パフォーマンスが微妙
  • WebP 画像に対応していない
  • Windows でしか使えない

しかしながら WindowsForms では画像を扱うならこのクラスが必要になりますし、枯れた技術としての需要はまだありそうです。

このビットマップをもう少し使いやすくしたい、というのが今回のお話です。

  • 色情報をスパンで扱う
  • プロジェクトで unsafe コードの許可なしで使えるようにする

サンプルコード

使い方

// 適宜ファイルやストリームから画像をロード
using var bitmap = new Bitmap(100, 100);
{
    // 画像に対する操作はこのスコープ内で行い、画像のロックを解除するようにする
    using var editor = new BitmapEditor(bitmap);
    for (int y = 0; y < editor.Height; y++)
    {
        for (int x = 0; x < editor.Width; x++)
        {
            // グラデーション
            var c = (byte)((x + y) / 200f * 255);
            editor.Span[y * editor.Width + x] = new NativeColor(c, c, c, 255);
        }
    }
}

a

解説

BitmapEditorref 構造体です。リソースを持つため using パターンで破棄するようにします。
色情報をスパンとして持ち、それを直接操作できます。

色情報は ↓ のようになっています。

file record struct NativeColor
{
    public byte B;
    public byte G;
    public byte R;
    public byte A;
}

これでうまいことビットマップのメモリと色情報を対応させられますが、環境依存かもしれません。

BitmapEditor の寿命はあまり長くないほうがよさそうです。というのも、画像データのハンドルをロックしたままフォーム等で表示しようとするとエラーになります。
参照型にすることも可能ですが、あまりうまくいかなかったため値型で運用するのがよさげです。

おわりに

今回の内容は若干ハック的な感じなので、使用できるなら適当な画像ライブラリを使うのがよさそうです。
WindowsForm アプリで簡単な画像処理をする場合に検討できるかもしれません。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?