はじめに
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);
}
}
}
解説
BitmapEditor
は ref
構造体です。リソースを持つため using
パターンで破棄するようにします。
色情報をスパンとして持ち、それを直接操作できます。
色情報は ↓ のようになっています。
file record struct NativeColor
{
public byte B;
public byte G;
public byte R;
public byte A;
}
これでうまいことビットマップのメモリと色情報を対応させられますが、環境依存かもしれません。
BitmapEditor
の寿命はあまり長くないほうがよさそうです。というのも、画像データのハンドルをロックしたままフォーム等で表示しようとするとエラーになります。
参照型にすることも可能ですが、あまりうまくいかなかったため値型で運用するのがよさげです。
おわりに
今回の内容は若干ハック的な感じなので、使用できるなら適当な画像ライブラリを使うのがよさそうです。
WindowsForm アプリで簡単な画像処理をする場合に検討できるかもしれません。