private void PlayGif(FFGifDrawable gifDrawable, CancellationTokenSource tokenSource) { var token = tokenSource.Token; var animatedImages = gifDrawable.AnimatedImages; _animationTimer?.Stop(); _animationTimer = new HighResolutionTimer <Android.Graphics.Bitmap>(gifDrawable.AnimatedImages, async(image) => { if (_animationFrameSetting) { return; } _animationFrameSetting = true; try { var bitmap = image.Image; if (_isDisposed || !_animationTimer.Enabled) { return; } if (bitmap != null && bitmap.Handle != IntPtr.Zero && !bitmap.IsRecycled) { if (_isDisposed || !_animationTimer.Enabled) { return; } await ImageService.Instance.Config.MainThreadDispatcher.PostAsync(() => { if (_isDisposed || !_animationTimer.Enabled) { return; } base.SetImageBitmap(bitmap); ; }).ConfigureAwait(false); } } catch (Exception ex) { ImageService.Instance.Config.Logger.Error("GIF", ex); } finally { _animationFrameSetting = false; } }) { DelayOffset = -2 }; _animationTimer.Start(); }
void PlayGif(FFGifDrawable gifDrawable, CancellationTokenSource tokenSource) { var token = tokenSource.Token; Task.Run(async() => { try { token.ThrowIfCancellationRequested(); var gifDecoder = gifDrawable.GifDecoder; int n = gifDecoder.GetFrameCount(); //int ntimes = gifDecoder.GetLoopCount(); //TODO DISABLED for endless loop int ntimes = 0; int repetitionCounter = 0; do { for (int i = 0; i < n; i++) { token.ThrowIfCancellationRequested(); var bitmap = gifDecoder.GetFrame(i); int t = gifDecoder.GetDelay(i); if (bitmap != null && bitmap.Handle != IntPtr.Zero && !bitmap.IsRecycled) { await MainThreadDispatcher.Instance.PostAsync(() => base.SetImageBitmap(bitmap)).ConfigureAwait(false); } token.ThrowIfCancellationRequested(); await Task.Delay(t, token).ConfigureAwait(false); } if (ntimes != 0) { repetitionCounter++; } } while (repetitionCounter <= ntimes); } catch (Exception) { } finally { tokenSource.TryDispose(); } }, token); }
protected override Task <SelfDisposingBitmapDrawable> GenerateImageFromDecoderContainerAsync(IDecodedImage <Bitmap> decoded, ImageInformation imageInformation, bool isPlaceholder) { try { SelfDisposingBitmapDrawable result; if (decoded.IsAnimated) { result = new FFGifDrawable(Context.Resources, decoded.AnimatedImages[0].Image, decoded.AnimatedImages); } else { if (isPlaceholder) { result = new SelfDisposingBitmapDrawable(Context.Resources, decoded.Image); } else { result = new FFBitmapDrawable(Context.Resources, decoded.Image); } } if (result == null || !result.HasValidBitmap) { throw new BadImageFormatException("Not a valid bitmap"); } return(Task.FromResult(result)); } catch (Exception ex) { var javaException = ex as Java.Lang.Throwable; if (javaException != null && javaException.Class == Java.Lang.Class.FromType(typeof(Java.Lang.OutOfMemoryError))) { throw new OutOfMemoryException(); } throw; } }
async void PlayGif(FFGifDrawable gifDrawable, CancellationToken token) { try { var gifDecoder = gifDrawable.GifDecoder; int n = gifDecoder.GetFrameCount(); //int ntimes = gifDecoder.GetLoopCount(); //TODO DISABLED for endless loop int ntimes = 0; int repetitionCounter = 0; do { token.ThrowIfCancellationRequested(); for (int i = 0; i < n; i++) { token.ThrowIfCancellationRequested(); var bitmap = gifDecoder.GetFrame(i); int t = gifDecoder.GetDelay(i); token.ThrowIfCancellationRequested(); if (bitmap != null && bitmap.Handle != IntPtr.Zero && !bitmap.IsRecycled) { SetImageBitmap(bitmap); } token.ThrowIfCancellationRequested(); await Task.Delay(t); } if (ntimes != 0) { repetitionCounter++; } }while (repetitionCounter <= ntimes); } catch (ObjectDisposedException) { } catch (OperationCanceledException) { } }