I have a problem when saving and loading a PNG using BitmapSource and PngBitmapEncoder/Decoder. Basically, I'd like to be able to save an image that originated as an array of bytes, and when the PNG is loaded into my program, reload the exact same bytes. Original data preservation is important.
At the same time, I'd like the PNG to use a custom palette (an indexed array of 256 colors).
I'm trying to save my 8-bit data with a custom indexed palette. The original data can range from 0-255. The palette may be a "Thresholded" palette (e.g. 0-20 is color #1, 21-50 is color #2, etc).
What I'm finding is that when I save the data, reload, and do CopyPixels to retrieve the "raw" data, the data values are set based on the the palette, not the original byte array values.
Is there a way to preserve the original byte array within the PNG, without losing the custom palette? Or is there a different way to retrieve the byte array from the BitmapSource?
The following is my Save routine:
// 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);
And this is my load routine:
// 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);
Any suggestions would be appreciated. Thanks.
Addendum #1: I'm finding that part of the problem is that the PNG is being saved as 32-bit color, despite the fact that I set it to Indexed8 and use a 256-entry color palette. This also seems to depend on the palette that is set. Any idea why?
See Question&Answers more detail:
os