/// <summary> /// Decode and resize <paramref name="encodedData"/> so that it fits in /// <paramref name="thumbnailAreaSize"/> but preserves its aspect ratio. /// </summary> /// <param name="encodedData">Encoded image data</param> /// <param name="thumbnailAreaSize">Size of the area for thumbnail</param> /// <param name="entity">Image metadata</param> /// <param name="save">If true, the generated thumbnail will be cached</param> /// <returns>Processed thumbnail image</returns> private Thumbnail Process(byte[] encodedData, Size thumbnailAreaSize, IEntity entity, bool save) { using (var input = new MemoryStream(encodedData)) { // read image metadata var info = new ImageFileInfo(input); Size original = Size.Empty; if (info.Frames.Length > 0) { original.Width = info.Frames[0].Width; original.Height = info.Frames[0].Height; } input.Position = 0; // create thumbnail image var decoded = _imageLoader.Decode(entity, input, thumbnailAreaSize); // save processed thumbnail if (save) { SaveThumbnail(entity, decoded); } // Create thumbnail wrapper return(new Thumbnail( Image.FromStream(new MemoryStream(decoded), false), original)); } }
/// <summary> /// Add a new load request to the queue /// </summary> /// <param name="entity">Entity to load</param> /// <returns> /// Task finished when <paramref name="entity"/> is loaded or the loading failed. /// </returns> public Task <SKBitmap> EnqueueAsync(IEntity entity) { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } var version = _queueVersion; var promise = new TaskCompletionSource <SKBitmap>(); _queue = _queue.ContinueWith(_ => { // check if this request has been cancelled if (version != _queueVersion) { promise.SetResult(null); return; } try { var image = SKBitmap.Decode(_imageLoader.Decode(entity)); // if the request has been canceled, dispose the image if (version != _queueVersion) { image?.Dispose(); image = null; } promise.SetResult(image); } catch (OperationCanceledException) { promise.SetCanceled(); } catch (Exception e) { promise.SetException(e); } }); return(promise.Task); }