コード例 #1
0
        /// <inheritdoc />
        public override async Task InvokeAsync(ILoadingContext <ImageSource> context, LoadingPipeDelegate <ImageSource> next, CancellationToken cancellationToken = default)
        {
            if (context.Current is Stream stream)
            {
                if (!stream.CanSeek)
                {
                    var memoryStream = new MemoryStream();
                    await stream.CopyToAsync(memoryStream);

                    if (!ReferenceEquals(stream, context.OriginSource))
                    {
                        // if the stream generated by the pipe then dispose it.
                        stream.Dispose();
                    }
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    stream = memoryStream;
                }

                var isSvg = IsSvg(stream);

                var tcs = new TaskCompletionSource <object?>();
                context.InvokeOnUIThread(async() =>
                {
                    try
                    {
                        if (isSvg)
                        {
                            var bitmap = new SvgImageSource();
                            context.AttachSource(bitmap);
                            var svgImageLoadStatus = await bitmap.SetSourceAsync(stream.AsRandomAccessStream());
                            if (svgImageLoadStatus != SvgImageSourceLoadStatus.Success)
                            {
                                throw new SvgImageFailedStatusException(svgImageLoadStatus);
                            }
                            cancellationToken.ThrowIfCancellationRequested();
                            context.Current = bitmap;
                        }
                        else
                        {
                            // https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-animations-and-media?redirectedfrom=MSDN#right-sized-decoding
                            // Set source after attached to the XAML tree

                            var bitmap = new BitmapImage();
                            context.AttachSource(bitmap);
                            await bitmap.SetSourceAsync(stream.AsRandomAccessStream());
                            cancellationToken.ThrowIfCancellationRequested();
                            context.Current = bitmap;
                        }
                        tcs.SetResult(null);
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                });
                await tcs.Task;
            }

            await next(context, cancellationToken);
        }
コード例 #2
0
        /// <inheritdoc />
        public override async Task InvokeAsync(ILoadingContext <ICompositionSurface> context, LoadingPipeDelegate <ICompositionSurface> next, CancellationToken cancellationToken = default)
        {
            if (context.Current is Stream stream)
            {
                var tcs          = new TaskCompletionSource <LoadedImageSurface>();
                var imageSurface = LoadedImageSurface.StartLoadFromStream(stream.AsRandomAccessStream());

                context.AttachSource(imageSurface);

                TypedEventHandler <LoadedImageSurface, LoadedImageSourceLoadCompletedEventArgs> handler = null !;
                handler = (sender, args) =>
                {
                    imageSurface.LoadCompleted -= handler;
                    switch (args.Status)
                    {
                    case LoadedImageSourceLoadStatus.Success:
                        tcs.SetResult(sender);
                        break;

                    default:
                        tcs.SetException(new ImageSurfaceFailedStatusException(args.Status));
                        break;
                    }
                };

                imageSurface.LoadCompleted += handler;
                context.Current             = await tcs.Task;
            }

            await next(context, cancellationToken);
        }
コード例 #3
0
        /// <inheritdoc />
        public override async Task InvokeAsync(ILoadingContext <TSource> context, LoadingPipeDelegate <TSource> next, CancellationToken cancellationToken = default)
        {
            if (IsInDesignMode)
            {
                await next(context, cancellationToken);

                return;
            }

            var cacheKey = context.Current;

            if (cacheKey is string || cacheKey is Uri)
            {
                if (MemoryCache.TryGetValue(cacheKey, out var cacheValue))
                {
                    context.Current = cacheValue;
                    context.AttachSource(cacheValue);
                    return;
                }

                await next(context, cancellationToken);

                if (context.Current is TSource finalValue)
                {
                    MemoryCache[cacheKey] = finalValue;
                }

                return;
            }

            await next(context, cancellationToken);
        }
コード例 #4
0
        /// <inheritdoc />
        public override async Task InvokeAsync(ILoadingContext <ImageSource> context, LoadingPipeDelegate <ImageSource> next, CancellationToken cancellationToken = default)
        {
            if (context.Current is Stream stream)
            {
                if (!stream.CanSeek)
                {
                    var memoryStream = new MemoryStream();
                    await stream.CopyToAsync(memoryStream);

                    memoryStream.Seek(0, SeekOrigin.Begin);
                    stream = memoryStream;
                }

                var isWebP = IsWebP(stream);

                var tcs = new TaskCompletionSource <ImageSource>();
                await Task.Run(() =>
                {
                    Image webPImage = null;
                    if (isWebP)
                    {
                        var webPFormat = new WebPFormat();
                        webPImage      = webPFormat.Load(stream);
                    }

                    if (webPImage != null)
                    {
                        var webPMemoryStream = new MemoryStream();
                        webPImage.Save(webPMemoryStream, ImageFormat.Png);
                        stream = webPMemoryStream;
                    }

                    stream.Seek(0, SeekOrigin.Begin);

                    try
                    {
                        var bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.StreamSource = stream;
                        bitmap.EndInit();
                        bitmap.Freeze();
                        context.UIContext.Send(state =>
                        {
                            context.AttachSource(bitmap);
                        }, null);
                        tcs.SetResult(bitmap);
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                }, cancellationToken);

                context.Current = await tcs.Task;
            }

            await next(context, cancellationToken);
        }
コード例 #5
0
        /// <inheritdoc />
        public override async Task InvokeAsync(ILoadingContext <ImageSource> context, LoadingPipeDelegate <ImageSource> next, CancellationToken cancellationToken = default)
        {
            if (context.Current is Stream stream)
            {
                if (!stream.CanSeek)
                {
                    var memoryStream = new MemoryStream();
#if NETCOREAPP3_1
                    await stream.CopyToAsync(memoryStream, cancellationToken);

                    if (!ReferenceEquals(stream, context.OriginSource))
                    {
                        // if the stream generated by the pipe then dispose it.
                        await stream.DisposeAsync();
                    }
#else
                    await stream.CopyToAsync(memoryStream);

                    if (!ReferenceEquals(stream, context.OriginSource))
                    {
                        // if the stream generated by the pipe then dispose it.
                        stream.Dispose();
                    }
#endif
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    stream = memoryStream;
                }

                var tcs = new TaskCompletionSource <ImageSource>();
                await Task.Run(() =>
                {
                    stream.Seek(0, SeekOrigin.Begin);

                    try
                    {
                        var bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.StreamSource = stream;
                        bitmap.EndInit();
                        bitmap.Freeze();
                        context.InvokeOnUIThread(() =>
                        {
                            context.AttachSource(bitmap);
                        });
                        tcs.SetResult(bitmap);
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                }, cancellationToken);

                context.Current = await tcs.Task;
            }

            await next(context, cancellationToken);
        }
コード例 #6
0
        /// <inheritdoc />
        public override async Task InvokeAsync(ILoadingContext <ImageExSource> context, LoadingPipeDelegate <ImageExSource> next, CancellationToken cancellationToken = default)
        {
            if (context.Current is Stream stream)
            {
                if (!stream.CanSeek)
                {
                    var memoryStream = new MemoryStream();
#if NETCOREAPP3_1
                    await stream.CopyToAsync(memoryStream, cancellationToken);

                    if (!ReferenceEquals(stream, context.OriginSource))
                    {
                        // if the stream generated by the pipe then dispose it.
                        await stream.DisposeAsync();
                    }
#else
                    await stream.CopyToAsync(memoryStream);

                    if (!ReferenceEquals(stream, context.OriginSource))
                    {
                        // if the stream generated by the pipe then dispose it.
                        stream.Dispose();
                    }
#endif
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    stream = memoryStream;
                }

                var tcs = new TaskCompletionSource <ImageExSource>();
                await Task.Run(() =>
                {
                    using var codec = SKCodec.Create(stream, out var codecResult);
                    if (codecResult != SKCodecResult.Success)
                    {
                        tcs.SetException(new Exception(codecResult.ToString()));
                        return;
                    }

                    var codecInfo = codec.Info;

                    var frameCount = codec.FrameCount;
                    if (frameCount <= 0)
                    {
                        var source = new ImageExSource
                        {
                            Frames          = new ImageExFrame[1],
                            RepetitionCount = codec.RepetitionCount,
                            Width           = codecInfo.Width,
                            Height          = codecInfo.Height
                        };

                        var bitmap  = new SKBitmap(codecInfo);
                        var pointer = bitmap.GetPixels();
                        codec.GetPixels(bitmap.Info, pointer);

                        source.Frames[0] = new ImageExFrame
                        {
                            Bitmap = bitmap
                        };

                        context.InvokeOnUIThread(() =>
                        {
                            context.AttachSource(source);
                        });

                        tcs.SetResult(source);
                    }
                    else
                    {
                        var source = new ImageExSource
                        {
                            Frames          = new ImageExFrame[frameCount],
                            RepetitionCount = codec.RepetitionCount,
                            Width           = codecInfo.Width,
                            Height          = codecInfo.Height
                        };

                        for (var frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            var bitmap       = new SKBitmap(codecInfo);
                            var pointer      = bitmap.GetPixels();
                            var codecOptions = new SKCodecOptions(frameIndex);
                            codec.GetPixels(bitmap.Info, pointer, codecOptions);

                            var frameInfo = codec.FrameInfo[frameIndex];
                            var duration  = frameInfo.Duration;

                            source.Frames[frameIndex] = new ImageExFrame
                            {
                                Bitmap   = bitmap,
                                Duration = duration
                            };
                        }

                        context.InvokeOnUIThread(() =>
                        {
                            context.AttachSource(source);
                        });

                        tcs.SetResult(source);
                    }
                }, cancellationToken);

                context.Current = await tcs.Task;

#if NETCOREAPP3_1
                if (!ReferenceEquals(stream, context.OriginSource))
                {
                    // if the stream generated by the pipe then dispose it.
                    await stream.DisposeAsync();
                }
#else
                if (!ReferenceEquals(stream, context.OriginSource))
                {
                    // if the stream generated by the pipe then dispose it.
                    stream.Dispose();
                }
#endif
            }

            await next(context, cancellationToken);
        }