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