2007年11月22日木曜日

ColorPalette

複数のBitmapが同一のColorPaletteを持つとき、このColorPaletteが非常に扱いづらい。

  1. なぜかコンストラクタがない。
  2. そのためBitmap.Paletteプロパティから取得する必要がある。
  3. ところがBitmap.Paletteプロパティにアクセスするたびに新しいインスタンスが生成される。
文章だと説明しづらいので問題になるコードを
Bitmap[] bitmaps; // ここにColorPaletteを設定したい
Color[] colors; // このColorを設定したい

foreach( Bitmap bitmap in bitmaps ){
for( int i = 0; i < 256; i++ )
bitmap.Palette.Entries[i] = color[i];
bitmap.MakeTransparent(); // ついでに透明色の設定
}
ちゃんとColorを設定しているつもりでも、毎回ColorPaletteが生成され直してColor値が保存されない。じゃあ、どうするかというと
Bitmap[] bitmaps; // ここにColorPaletteを設定したい
Color[] colors; // このColorを設定したい

foreach( Bitmap bitmap in bitmaps ){
ColorPalette palette = bitmap.Palette; // ColorPaletteを取得、この時点でBitmapとは切り離されている
for( int i = 0; i < 256; i++ )
palette.Entries[i] = color[i];
bitmap.Palette = palette;
bitmap.MakeTransparent(); // ついでに透明色の設定
}
こんな感じ。コンストラクタが提供されないにも係わらず、インスタンスの設定が求められるのはおかしい。
ここでふと気づく。ループごとにColorPaletteを作成し直すのは無駄では? つまり
Bitmap[] bitmaps; // ここにColorPaletteを設定したい
Color[] colors; // このColorを設定したい

ColorPalette palette = bitmaps[0].Palette; // ColorPaletteを取得、この時点でBitmapとは切り離されている
for( int i = 0; i < 256; i++ )
palette.Entries[i] = color[i];
foreach( Bitmap bitmap in bitmaps ){
bitmap.Palette = palette;
bitmap.MakeTransparent(); // ついでに透明色の設定
}
こうすればColorPaletteの作成は1回で済む…というのは罠です。ColorPaletteはクラスなので、複数のBitmapでインスタンスが共有されてしまいます。具体的にはMakeTransparent()でAccessViolationExceptionが発生したりする。
インスタンスを独立させたくてもICloneable.Clone()も提供されないので、ひたすらコピーするしかない。なんとも迷惑な話です。

0 件のコメント: