Home > OS >  Converting ImageSource to String on C# WPF
Converting ImageSource to String on C# WPF

Time:12-20

ESRI Symbology library is slow and sometimes take longer time than expected.

I wish to serialize a selected range of ImageSource to a cache, string in the memory or file.

I have searched the web but not much on ImageSource.

An interesting thing I have found is "ImageSourceValueSerializer".

Being a 3 months old baby in WPF, I am not so sure how to go about this.

here's how I got the ImageSource:

MultilayerPointSymbol multiLayerSym = await result.GetSymbolAsync() as MultilayerPointSymbol;
RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();
ImageSource symbolImage = await swatch.ToImageSourceAsync();

Tested Clemen's, the routine:

MultilayerPointSymbol multiLayerSym = await result.GetSymbolAsync() as MultilayerPointSymbol;
RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();
ImageSource symbolImage = await swatch.ToImageSourceAsync();
byte[] b = ImageSourceBinary(symbolImage);
ImageSource test = BinaryImageSource(b);

In the class:

    private byte[] ImageSourceBinary(ImageSource imageSrc)
    {
        if (imageSrc is BitmapSource bitmapSource)
        {

            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
            using (MemoryStream stream = new MemoryStream())
            {                    
                encoder.Save(stream);
                return stream.ToArray();
            }
        }
        return null;
    }

    private ImageSource BinaryImageSource(byte[] bytes)
    {            
        using (MemoryStream stream = new MemoryStream(bytes))
        {
            PngBitmapDecoder decoder = new PngBitmapDecoder(stream, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.Default);
            BitmapFrame bf = decoder.Frames[0];
            if (bf is ImageSource imagesource)
                return imagesource;
            return null;
        }
    }

The outcome, no image! :(

CodePudding user response:

Check if the ImageSource is a BitmapSource and encode the BitmapSource by one of the BitmapEncoders. Encode into a MemoryStream or a FileStream.

private byte[] ImageSourceToByteArray(ImageSource imageSrc)
{
    if (symbolImage is BitmapSource bitmapSource)
    {
        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmapSource));

        using (var stream = new MemoryStream())
        {
            encoder.Save(stream);
            return stream.ToArray();
        }
    }

    return null;
}

In order to decode an image from a byte array, do not explictly use a specific BitmapDecoder. Better rely on automatic decoder selection, like shown below. It is also important to set BitmapCacheOption.OnLoad when the stream is closed right after decoding.

private ImageSource ByteArrayToImageSource(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        return BitmapFrame.Create(
            stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    }
}
  • Related