oao
oao

Reputation: 3

Can't put image data into WriteableBitmap variable from xml file that I saved before

I have a problem with the reading of a WriteableBitmap data from xml that I previously saved. Could you help me please?

Structure of data:

WriteableBitmap painter;
painter = new WriteableBitmap(
    pixelWidth: 100,
    pixelHeight: 100,
    dpiX: 96,
    dpiY: 96,
    pixelFormat: PixelFormats.Bgra32,
    palette: null);
byte[] sourcePixelData = new byte[] { 0, 0, 255, 255 };
Image image = new Image
{
    Source = painter,
    Width = painter.PixelWidth,
    Height = painter.PixelHeight
};

How I saved:

using (FileStream fs = new FileStream(data.saveName, FileMode.Create))
using (XmlWriter writer = XmlWriter.Create(fs))
{
...
writer.WriteStartElement("itemSpecial");
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(painter));
using (MemoryStream _ms = new MemoryStream())
{
    encoder.Save(_ms);
    byte[] _imageBytes = _ms.ToArray();
    string _base64Image = Convert.ToBase64String(_imageBytes);
    writer.WriteStartElement("imageData");
    writer.WriteValue(_base64Image);
    writer.WriteEndElement();
}
writer.WriteEndElement();
...

}

The data from XML (it was just a few random moving of red brush under the image 100x100 pixels):

<itemSpecial>
    <imageData>iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIbSURBVHhe7dmLcoMgEIXhtO//zm3WwIQQVEyAPej/TZ2oWC97BE17A7DhJ3xO42/5ebpfwHTXcBoWRhpIHg4GKwVg6wjGwV7RCWWgmmITyEC1xSaUAY4UmUA6O1pgAunskwITSiffFHbmUH7DJ0QQyA7rbTP3uCa+LUCrArbazxGn7CH2B0ePYrbAkIVtre7sb/fT6jyOoocUWBhe/2c5bSCzPkekAvG8M1UwZGW8bwoCEUMgCYUhUyYQnh8P9BAxBCKGQMQQiBgCCVReKghEDIHcKb1yE4gYiUD4Uvh0+R6idjMwZIkhEDHugfD8eEUPEUMgYlwDYbh6d+keonhDMGSJcQuE4aqMHiKGQPBgQ1aY7WJv/72P/6lL9RALIU5xeWlA/2Lk+19bts84LQ1XNOLi02PYfH7MfFnFqYesGIS9Xte8YquG1J3ChZfOQeG8XHhf+Nbxvc+N7yFiCCRjzxrPXnK5QKzYNQ94L8MDUS+IN4YsMQQiZmggDFf7pu0hFm5pCs2o0bJga/uy9XEKq16srU/VbNPLsB4y6iJtSJx5WJz2xNcCTsNIt4nrbV26TUnNNlNLC9OLHSOfQtPL8dP5kr323k7z2lu6o624NllbnA9NRXvtI5yyW1phY0BHihx/B42VQrB1R8JBY2vFVw/l1F00LX4+hDE8ObMg4hSXlwb4S4MBAAAAAAAAAAAAAAAAAAAAgHe32z/UyfWrWv086AAAAABJRU5ErkJggg==</imageData>
</itemSpecial>

How I try to read it:

byte[] _imageData = {0};
using (XmlReader reader = XmlReader.Create(data.loadName))
{
    while (reader.Read())
    {
        ...
        if (reader.Name == "imageData")
        {
            _imageData = Convert.FromBase64String(_str);
        }
        ...
        WriteableBitmap painter = new WriteableBitmap(100,100,96,96,System.Windows.Media.PixelFormats.Bgra32,null);
        var stride = (100 * painter.Format.BitsPerPixel + 7) / 8;
        var bufferSize = 100 * stride;
        painter.WritePixels(new System.Windows.Int32Rect(0, 0, 100, 100), _imageData, bufferSize, 0);
     ...
    }
}

The exception is: Not enough buffer size.

What I tried: to play directly with buffer size. (100 * painter.Format.BitsPerPixel + 7) / 8 is just a last variation, I also tried to put here thousands of bytes. I tried to re-save a new xml-file, but without success.

Upvotes: 0

Views: 59

Answers (1)

Clemens
Clemens

Reputation: 128013

The base64 string contains an encoded PNG frame, not a raw pixel buffer. In order to create a WriteableBitmap from the string, you must first decode a BitmapSource:

WriteableBitmap painter;

using (var ms = new MemoryStream(_imageData))
{
    var decoder = BitmapDecoder.Create(
        ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);

    painter = new WriteableBitmap(decoder.Frames[0]);
}

or

using (var ms = new MemoryStream(_imageData))
{
    var bitmap = BitmapFrame.Create(
        ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);

    painter = new WriteableBitmap(bitmap);
}

or

using (var ms = new MemoryStream(_imageData))
{
    var bitmap = new BitmapImage();
    bitmap.BeginInit();
    bitmap.StreamSource = ms;
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.EndInit();

    painter = new WriteableBitmap(bitmap);
}

Upvotes: 2

Related Questions