Example #1
0
        protected override void OnDispose()
        {
            if (_cache != null)
            {
                _cache.Count--;
                _cache = null;
                TryRemoveSourceCache(Source);
            }

            base.OnDispose();
        }
Example #2
0
        private async void UpdateSource(string oldValue, string newValue)
        {
            // 重置字段
            if (_cache != null)
            {
                _cache.Count--;
                _cache   = null;
                _current = 0;
                // 尝试清理之前的缓存
                TryRemoveSourceCache(oldValue);
            }
            // 更新字段
            GIFCache cache = null;

            try
            {
                await _slim.WaitAsync();

                if (!string.IsNullOrWhiteSpace(newValue) && !_caches.TryGetValue(newValue, out cache))
                {
                    var name = newValue.TrimEnd(".gif", StringComparison.OrdinalIgnoreCase);
                    // 获取资源
                    using (var stream = await Storage.GetResourceStreamAsync(name, "gif"))
                    {
                        if (stream != null)
                        {
                            // 异步解码 GIF,防止卡 UI 线程
                            await Task.Run(() =>
                            {
                                using (var codec = SKCodec.Create(stream))
                                {
                                    // 获取图片帧数并分配
                                    var count = codec.FrameCount;
                                    //codec.RepetitionCount
                                    var images        = new SKBitmap[count];
                                    var accumulations = new int[count];
                                    var total         = 0;
                                    // 循环图片帧
                                    for (int i = 0; i < count; i++)
                                    {
                                        // 获取每帧的时长
                                        var duration = codec.FrameInfo[i].Duration;
                                        // 计算总时长
                                        total += duration;
                                        // 计算累加时长
                                        var former       = i == 0 ? 0 : accumulations[i - 1];
                                        accumulations[i] = duration + former;
                                        // 创建图片
                                        var info  = new SKImageInfo(codec.Info.Width, codec.Info.Height);
                                        images[i] = new SKBitmap(info);
                                        // 获取像素地址
                                        var address = images[i].GetPixels();
                                        // 创建 SKCodecOptions 描述图片帧
                                        var options = new SKCodecOptions(i);
                                        // 将像素复制到图片中
                                        codec.GetPixels(info, address, options);
                                    }
                                    cache = new GIFCache(images, accumulations, total);
                                }
                            });
                        }
                    }
                    // 加入缓存
                    _caches.Add(newValue, cache);
                }
            }
            finally
            {
                _slim.Release();
            }
            // 重绘界面
            if (_isAnimating)
            {
                if (cache == null)
                {
                    StopGIF();
                }
                else
                {
                    _cache = cache;
                    _cache.Count++;

                    InvalidateSurface();
                }
            }
            else
            {
                if (cache == null)
                {
                    return;
                }

                switch (State)
                {
                case ViewState.Unloaded:
                {
                    _cache = cache;
                    _cache.Count++;
                }
                break;

                case ViewState.Loaded:
                {
                    _cache = cache;
                    _cache.Count++;

                    PlayGIF();
                }
                break;

                case ViewState.Disposed:
                {
                    TryRemoveSourceCache(newValue);
                    break;
                }
                }
            }
        }