From b08c60bd1466b31cbe9b2b4a5ecf81b9865e53c9 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 11 May 2020 18:09:46 -0300 Subject: [PATCH] wrap stream in skmanagedstream to prevent collection of underlying stream, dispose codec. --- src/Skia/Avalonia.Skia/ImmutableBitmap.cs | 74 +++++++++++------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs index 9410895f80..e84c7e34de 100644 --- a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs +++ b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs @@ -54,59 +54,59 @@ namespace Avalonia.Skia Dpi = new Vector(96, 96); } - //NOTE: SKCodec.Create randomly crashes when optimizations are enabled. - [MethodImpl(MethodImplOptions.NoOptimization)] public ImmutableBitmap(Stream stream, int decodeSize, bool horizontal, BitmapInterpolationMode interpolationMode) { - // create the codec - var codec = SKCodec.Create(stream); - var info = codec.Info; + using (var skStream = new SKManagedStream(stream)) + using (var codec = SKCodec.Create(skStream)) + { + var info = codec.Info; - // get the scale that is nearest to what we want (eg: jpg returned 512) - var supportedScale = codec.GetScaledDimensions(horizontal ? ((float)decodeSize / info.Width) : ((float)decodeSize / info.Height)); + // get the scale that is nearest to what we want (eg: jpg returned 512) + var supportedScale = codec.GetScaledDimensions(horizontal ? ((float)decodeSize / info.Width) : ((float)decodeSize / info.Height)); - // decode the bitmap at the nearest size - var nearest = new SKImageInfo(supportedScale.Width, supportedScale.Height); - var bmp = SKBitmap.Decode(codec, nearest); + // decode the bitmap at the nearest size + var nearest = new SKImageInfo(supportedScale.Width, supportedScale.Height); + var bmp = SKBitmap.Decode(codec, nearest); - // now scale that to the size that we want - var realScale = horizontal ? ((double)info.Height / info.Width) : ((double)info.Width / info.Height); + // now scale that to the size that we want + var realScale = horizontal ? ((double)info.Height / info.Width) : ((double)info.Width / info.Height); - SKImageInfo desired; + SKImageInfo desired; - if (horizontal) - { - desired = new SKImageInfo(decodeSize, (int)(realScale * decodeSize)); - } - else - { - desired = new SKImageInfo((int)(realScale * decodeSize), decodeSize); - } + if (horizontal) + { + desired = new SKImageInfo(decodeSize, (int)(realScale * decodeSize)); + } + else + { + desired = new SKImageInfo((int)(realScale * decodeSize), decodeSize); + } - if (bmp.Width != desired.Width || bmp.Height != desired.Height) - { - if (bmp.Height != bmp.Width) + if (bmp.Width != desired.Width || bmp.Height != desired.Height) { + if (bmp.Height != bmp.Width) + { + } + var scaledBmp = bmp.Resize(desired, interpolationMode.ToSKFilterQuality()); + bmp.Dispose(); + bmp = scaledBmp; } - var scaledBmp = bmp.Resize(desired, interpolationMode.ToSKFilterQuality()); - bmp.Dispose(); - bmp = scaledBmp; - } - _image = SKImage.FromBitmap(bmp); - bmp.Dispose(); + _image = SKImage.FromBitmap(bmp); + bmp.Dispose(); - if (_image == null) - { - throw new ArgumentException("Unable to load bitmap from provided data"); - } + if (_image == null) + { + throw new ArgumentException("Unable to load bitmap from provided data"); + } - PixelSize = new PixelSize(_image.Width, _image.Height); + PixelSize = new PixelSize(_image.Width, _image.Height); - // TODO: Skia doesn't have an API for DPI. - Dpi = new Vector(96, 96); + // TODO: Skia doesn't have an API for DPI. + Dpi = new Vector(96, 96); + } } ///