BitmapSource および PngBitmapEncoder/Decoder を使用して PNG を保存およびロードするときに問題が発生します。基本的に、バイトの配列として作成された画像を保存し、PNG がプログラムにロードされたときに、まったく同じバイトをリロードできるようにしたいと考えています。元データの保存は重要です。
同時に、PNG でカスタム パレット (256 色のインデックス付き配列) を使用したいと考えています。
カスタム インデックス パレットを使用して 8 ビット データを保存しようとしています。元のデータの範囲は 0 ~ 255 です。パレットは「しきい値」パレットの場合があります (たとえば、0 ~ 20 は色 #1、21 ~ 50 は色 #2 など)。
私が見つけたのは、データを保存し、リロードし、CopyPixels を実行して「生」データを取得すると、元のバイト配列値ではなく、パレットに基づいてデータ値が設定されることです。
カスタム パレットを失うことなく、PNG 内の元のバイト配列を保持する方法はありますか? または、BitmapSource からバイト配列を取得する別の方法はありますか?
以下は私の保存ルーチンです:
// This gets me a custom palette that is an array of 256 colors
List<System.Windows.Media.Color> colors = PaletteToolsWPF.TranslatePalette(this, false, true);
BitmapPalette myPalette = new BitmapPalette(colors);
// This retrieves my byte data as an array of dimensions _stride * sizeY
byte[] ldata = GetData();
BitmapSource image = BitmapSource.Create(
sizeX,
sizeY,
96,
96,
PixelFormats.Indexed8,
myPalette,
ldata,
_stride);
PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Interlace = PngInterlaceOption.On;
enc.Frames.Add(BitmapFrame.Create(image));
// save the data via FileStream
enc.Save(fs);
そして、これは私のロードルーチンです:
// Create an array to hold the raw data
localData = new byte[_stride * sizeY];
// Load the data via a FileStream
PngBitmapDecoder pd = new PngBitmapDecoder(Fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = pd.Frames[0];
// When I look at the byte data, it is *not* the same as my original data
bitmapSource.CopyPixels(localData, _stride, 0);
任意の提案をいただければ幸いです。ありがとう。
補遺 #1: PNG を Indexed8 に設定し、256 エントリのカラー パレットを使用しているにもかかわらず、PNG が 32 ビット カラーとして保存されていることが問題の一部であることがわかりました。これも設定されているパレットに依存するようです。理由はありますか?