ColorPaletteクラスにpublic constructorが登場!
.NET 9でColorPalette
クラスにpublic constructorが登場します。何が嬉しいのか説明します。
.NET Framework 1.0時代より、画像を扱うにはBitmap
クラスを使用します。これはWindows XPで標準搭載されたGDI+ライブラリを.NETで扱うためのクラスです。ここで256色パレットカラーの場合、Bitmap.Patelle
プロパティでColorPalette
クラスにアクセスします。Bitmap.Patelle
プロパティはこのような実装になっています。
つまり、Bitmap.Patelle
プロパティにアクセスすると新しいColorPalette
インスタンスを生成して返してきます。これが何を意味するかというと、
void SetRed(Bitmap bitmap) {
bitmap.Palette.Entries[0] = Color.Red;
}
と値を設定しても、新しいColorPalette
インスタンスが変更されるだけで元のbitmap
には反映されません。正しくは、
void SetRed(Bitmap bitmap) {
var palette = bitmap.Palette;
palette.Entries[0] = Color.Red;
bitmap.Palette = palette;
}
ColorPalette
インスタンスを保存しておき、bitmap.Palette
に書き戻してやる必要があります。
つまり、ColorPalette
インスタンスを強く意識した操作が必要になります。ではColorPalette
クラスとはどういったものでしょうか? ソースコードを見ると…
…はい、概ねColor
配列を持つだけでした。にもかかわらず、コンストラクターがinternal
と隠されています。
まとめると、256色パレットカラーを扱う場合、
-
ColorPalette
インスタンスを意識する -
ColorPalette
クラスは単にColor
配列を持つだけ -
ColorPalette
コンストラクターは公開されていない
という頭お菓子なる設計に立ち向かう必要があります。具体的には
ColorPalette CreatePalette() {
using var bitmap = new Bitmap(1, 1, PixelFormat.Indexed);
return bitmap.Palette;
}
とか、
ColorPalette CreatePalette() {
return (ColorPalette)typeof(ColorPalette).InvokeMember(
null,
BindingFlags.NonPublic | BindingFlags.CreateInstance,
null,
null,
new object[]{ 256 }
);
}
する必要がありました。
これが.NET 9からは
ColorPalette CreatePalette() {
return new ColorPalette(new Color[256]);
}
と書けるようです!
従来 .NET Frameworkはソースコードが公開されておらず、試行錯誤とildasmで調べたものです。referencesourceとかできる前ね。(遠い目)
Discussion