Salvar dados indexados de 8 bits em um PNG altera os bytes originais ao usar BitmapSource, PngBitmapEncoder / Decoder
Eu tenho um problema ao salvar e carregar um PNG usando BitmapSource e PngBitmapEncoder / Decoder. Basicamente, eu gostaria de ser capaz de salvar uma imagem que se originou como uma matriz de bytes, e quando o PNG é carregado em meu programa, recarregue exatamente os mesmos bytes. A preservação de dados original é importante.
Ao mesmo tempo, gostaria que o PNG usasse uma paleta personalizada (uma matriz indexada de 256 cores).
Estou tentando salvar meus dados de 8 bits com uma paleta indexada personalizada. Os dados originais podem variar de 0 a 255. A paleta pode ser uma paleta "Thresholded" (por exemplo, 0-20 é a cor # 1, 21-50 é a cor # 2, etc).
O que estou descobrindo é que, quando salvo os dados, recarrego e faço CopyPixels para recuperar os dados "brutos", os valores de dados são definidos com base na paleta, não nos valores originais da matriz de bytes.
Existe uma maneira de preservar a matriz de bytes original dentro do PNG,sem perdendo a paleta personalizada? Ou há uma maneira diferente de recuperar a matriz de bytes do BitmapSource?
Segue-se a minha rotina de salvaguarda:
// 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);
E esta é a minha rotina de carga:
// 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);
Qualquer sugestão seria apreciada. Obrigado.
Adendo # 1: Eu estou achando que parte do problema é que o PNG está sendo salvo como cor de 32 bits, apesar do fato de eu configurá-lo como Indexed8 e usar uma paleta de cores de 256 entradas. Isso também parece depender da paleta que está definida. Alguma ideia do porquê?