protected async override Task <SelfDisposingBitmapDrawable> GenerateImageAsync(string path, ImageSource source, Stream imageData, ImageInformation imageInformation, bool enableTransformations, bool isPlaceholder) { try { SelfDisposingBitmapDrawable image = null; if (imageInformation.Type == ImageInformation.ImageType.GIF && Configuration.AnimateGifs && GifDecoder.CheckIfAnimated(imageData)) { image = await PlatformGenerateGifImageAsync(path, source, imageData, imageInformation, enableTransformations, isPlaceholder); } else { image = await PlatformGenerateImageAsync(path, source, imageData, imageInformation, enableTransformations, isPlaceholder); } if (image == null || !image.HasValidBitmap) { throw new BadImageFormatException("Bad image format"); } return(image); } 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; } }
private void AddInBitmapOptions(BitmapFactory.Options options) { // inBitmap only works with mutable bitmaps so force the decoder to // return mutable bitmaps. options.InMutable = true; // Try and find a bitmap to use for inBitmap SelfDisposingBitmapDrawable bitmapDrawable = null; try { bitmapDrawable = ImageCache.Instance.GetBitmapDrawableFromReusableSet(options); var bitmap = bitmapDrawable == null ? null : bitmapDrawable.Bitmap; if (bitmap != null && bitmap.Handle != IntPtr.Zero && !bitmap.IsRecycled) { options.InBitmap = bitmapDrawable.Bitmap; } } finally { if (bitmapDrawable != null) { bitmapDrawable.SetIsRetained(false); } } }
protected async override Task SetTargetAsync(SelfDisposingBitmapDrawable image, bool animated) { ThrowIfCancellationRequested(); var ffDrawable = image as FFBitmapDrawable; if (ffDrawable != null) { if (ffDrawable.IsAnimationRunning) { await Task.Delay(ffDrawable.FadeDuration + 25); } if (animated) { SelfDisposingBitmapDrawable placeholderDrawable = null; if (_loadingPlaceholderWeakReference != null && _loadingPlaceholderWeakReference.TryGetTarget(out placeholderDrawable) && placeholderDrawable != null) { int fadeDuration = Parameters.FadeAnimationDuration.HasValue ? Parameters.FadeAnimationDuration.Value : Configuration.FadeAnimationDuration; placeholderDrawable?.SetIsRetained(true); ffDrawable?.SetPlaceholder(placeholderDrawable, fadeDuration); placeholderDrawable?.SetIsRetained(false); } } } await MainThreadDispatcher.PostAsync(() => { ThrowIfCancellationRequested(); PlatformTarget.Set(this, image, animated); }).ConfigureAwait(false); }
private static void Set(ImageView control, SelfDisposingBitmapDrawable drawable) { lock (control) { StopAnimation(control); if (drawable == null) { control.SetImageResource(Android.Resource.Color.Transparent); return; } if (drawable is ISelfDisposingAnimatedBitmapDrawable animatedBitmapDrawable) { UpdateDrawableDisplayedState(drawable, true); control.SetImageDrawable(animatedBitmapDrawable as Drawable); PlayAnimation(control, animatedBitmapDrawable); } else { UpdateDrawableDisplayedState(drawable, true); control.SetImageDrawable(drawable); } } }
protected async override Task SetTargetAsync(SelfDisposingBitmapDrawable image, bool animated) { if (Target == null) { return; } ThrowIfCancellationRequested(); var ffDrawable = image as FFBitmapDrawable; if (ffDrawable != null) { if (ffDrawable.IsAnimationRunning) { var mut = new FFBitmapDrawable(Context.Resources, ffDrawable.Bitmap, ffDrawable); ffDrawable = mut as FFBitmapDrawable; image = ffDrawable; // old hacky workaround //await Task.Delay(ffDrawable.FadeDuration + 50).ConfigureAwait(false); } if (animated) { SelfDisposingBitmapDrawable placeholderDrawable = null; PlaceholderWeakReference?.TryGetTarget(out placeholderDrawable); if (placeholderDrawable == null) { // Enable fade animation when no placeholder is set and the previous image is not null var imageView = PlatformTarget.Control as ImageViewAsync; placeholderDrawable = imageView?.Drawable as SelfDisposingBitmapDrawable; } if (placeholderDrawable.IsValidAndHasValidBitmap()) { int fadeDuration = Parameters.FadeAnimationDuration.HasValue ? Parameters.FadeAnimationDuration.Value : Configuration.FadeAnimationDuration; placeholderDrawable?.SetIsRetained(true); ffDrawable?.SetPlaceholder(placeholderDrawable, fadeDuration); placeholderDrawable?.SetIsRetained(false); } } else { ffDrawable?.SetPlaceholder(null, 0); } } await MainThreadDispatcher.PostAsync(() => { ThrowIfCancellationRequested(); PlatformTarget.Set(this, image, animated); }).ConfigureAwait(false); }
public void Add(string key, SelfDisposingBitmapDrawable bitmap) { if (string.IsNullOrWhiteSpace(key) || bitmap == null || _cache.ContainsKey(key)) { return; } _cache.Add(key, bitmap); }
public void Add(string key, ImageInformation imageInformation, SelfDisposingBitmapDrawable bitmap) { if (string.IsNullOrWhiteSpace(key) || bitmap == null || bitmap.Handle == IntPtr.Zero || !bitmap.HasValidBitmap || _cache.ContainsKey(key)) { return; } _imageInformations.TryAdd(key, imageInformation); _cache.Add(key, bitmap); }
public SelfDisposingBitmapDrawable Get(string key) { SelfDisposingBitmapDrawable drawable = null; if (_cache.TryGetValue(key, out drawable)) { return(drawable); } return(null); }
public static bool IsValidAndHasValidBitmap(this SelfDisposingBitmapDrawable drawable) { try { return(drawable != null && drawable.Handle != IntPtr.Zero && drawable.HasValidBitmap); } catch (ObjectDisposedException) { return(false); } }
public Tuple <SelfDisposingBitmapDrawable, ImageInformation> Get(string key) { SelfDisposingBitmapDrawable drawable = null; if (_cache.TryGetValue(key, out drawable)) { var imageInformation = GetInfo(key); return(new Tuple <SelfDisposingBitmapDrawable, ImageInformation>(drawable, imageInformation)); } return(null); }
public bool TryGet(string key, out SelfDisposingBitmapDrawable drawable) { if (memCache.TryGetValue (new Uri (key), out drawable)) return true; Bitmap bmp; if (!diskCache.TryGet (key, out bmp)) return false; drawable = CreateCacheableDrawable (bmp); return true; }
protected async override Task <SelfDisposingBitmapDrawable> GenerateImageAsync(string path, ImageSource source, Stream imageData, ImageInformation imageInformation, bool enableTransformations, bool isPlaceholder) { try { SelfDisposingBitmapDrawable image = null; string ext = null; if (!string.IsNullOrWhiteSpace(path)) { if (source == ImageSource.Url) { ext = System.IO.Path.GetExtension(new Uri(path).LocalPath).ToLowerInvariant(); } else { ext = System.IO.Path.GetExtension(path).ToLowerInvariant(); } } if (source != ImageSource.Stream && ext == ".gif") { image = await PlatformGenerateGifImageAsync(path, source, imageData, imageInformation, enableTransformations, isPlaceholder); } else { image = await PlatformGenerateImageAsync(path, source, imageData, imageInformation, enableTransformations, isPlaceholder); } if (image == null || !image.HasValidBitmap) { throw new BadImageFormatException("Bad image format"); } return(image); } 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; } }
public bool TryGet(string key, out SelfDisposingBitmapDrawable drawable) { if (memCache.TryGetValue(new Uri(key), out drawable)) { return(true); } Bitmap bmp; if (!diskCache.TryGet(key, out bmp)) { return(false); } drawable = CreateCacheableDrawable(bmp); return(true); }
protected override Task <SelfDisposingBitmapDrawable> GenerateImageFromDecoderContainerAsync(IDecodedImage <Bitmap> decoded, ImageInformation imageInformation, bool isPlaceholder) { try { SelfDisposingBitmapDrawable result; if (decoded.IsAnimated) { result = new FFAnimatedDrawable(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) { if (ex is Java.Lang.Throwable javaException && javaException.Class == Java.Lang.Class.FromType(typeof(Java.Lang.OutOfMemoryError))) { if (Configuration.ClearMemoryCacheOnOutOfMemory) { Java.Lang.JavaSystem.Gc(); } throw new OutOfMemoryException(); } throw; } }
protected async override Task SetTargetAsync(SelfDisposingBitmapDrawable image, bool animated) { ThrowIfCancellationRequested(); var ffDrawable = image as FFBitmapDrawable; if (ffDrawable != null) { if (ffDrawable.IsAnimationRunning) { var mut = new FFBitmapDrawable(Context.Resources, ffDrawable.Bitmap, ffDrawable); ffDrawable = mut as FFBitmapDrawable; image = ffDrawable; // old hacky workaround //await Task.Delay(ffDrawable.FadeDuration + 50).ConfigureAwait(false); } if (animated) { SelfDisposingBitmapDrawable placeholderDrawable = null; if (PlaceholderWeakReference != null && PlaceholderWeakReference.TryGetTarget(out placeholderDrawable) && placeholderDrawable != null) { int fadeDuration = Parameters.FadeAnimationDuration.HasValue ? Parameters.FadeAnimationDuration.Value : Configuration.FadeAnimationDuration; placeholderDrawable?.SetIsRetained(true); ffDrawable?.SetPlaceholder(placeholderDrawable, fadeDuration); placeholderDrawable?.SetIsRetained(false); } } else { ffDrawable?.SetPlaceholder(null, 0); } } await MainThreadDispatcher.PostAsync(() => { ThrowIfCancellationRequested(); PlatformTarget.Set(this, image, animated); }).ConfigureAwait(false); }
public async Task <Bitmap> LoadImageAsync(ImageSource imagesource, Context context, CancellationToken cancelationToken = default(CancellationToken)) { var ffImageSource = imagesource as FFImageSource; ffImageSource.LoadingStarted(); ffImageSource.RegisterCancelToken(cancelationToken); SelfDisposingBitmapDrawable bitmapDrawable = null; try { bitmapDrawable = await Task.Run(() => ffImageSource.TaskParameter.AsBitmapDrawableAsync(), cancelationToken).ConfigureAwait(false); ffImageSource.LoadingCompleted(false); } catch (OperationCanceledException) { ffImageSource.LoadingCompleted(true); throw; } return(bitmapDrawable.Bitmap); }
public override void Set(IImageLoaderTask task, SelfDisposingBitmapDrawable image, bool animated) { if (task == null || task.IsCancelled) { return; } var control = Control; if (control == null || control.Drawable == image) { return; } var isLayoutNeeded = IsLayoutNeeded(task, control.Drawable, image); Set(control, image); control.Invalidate(); if (isLayoutNeeded) { control.RequestLayout(); } }
protected override void AfterLoading(SelfDisposingBitmapDrawable image, bool fromMemoryCache) { base.AfterLoading(image, fromMemoryCache); image?.SetIsRetained(false); }
protected override void BeforeLoading(SelfDisposingBitmapDrawable image, bool fromMemoryCache) { base.BeforeLoading(image, fromMemoryCache); image?.SetIsRetained(true); }
public static bool IsValidAndHasValidBitmap(this SelfDisposingBitmapDrawable drawable) { return(drawable != null && drawable.Handle != IntPtr.Zero && drawable.HasValidBitmap); }
protected async override Task SetTargetAsync(SelfDisposingBitmapDrawable image, bool animated) { if (Target == null) { return; } ThrowIfCancellationRequested(); if (image is FFBitmapDrawable ffDrawable) { if (ffDrawable.IsAnimationRunning) { var mut = new FFBitmapDrawable(Context.Resources, ffDrawable.Bitmap, ffDrawable); ffDrawable = mut as FFBitmapDrawable; image = ffDrawable; // old hacky workaround //await Task.Delay(ffDrawable.FadeDuration + 50).ConfigureAwait(false); } if (animated) { SelfDisposingBitmapDrawable placeholderDrawable = null; PlaceholderWeakReference?.TryGetTarget(out placeholderDrawable); if (placeholderDrawable == null) { // Enable fade animation when no placeholder is set and the previous image is not null var imageView = PlatformTarget.Control as ImageViewAsync; placeholderDrawable = imageView?.Drawable as SelfDisposingBitmapDrawable; } var fadeDuration = Parameters.FadeAnimationDuration ?? Configuration.FadeAnimationDuration; if (placeholderDrawable.IsValidAndHasValidBitmap()) { placeholderDrawable?.SetIsRetained(true); ffDrawable?.SetPlaceholder(placeholderDrawable, fadeDuration); placeholderDrawable?.SetIsRetained(false); } else if (ffDrawable.IsValidAndHasValidBitmap()) { var width = ffDrawable.Bitmap.Width; var height = ffDrawable.Bitmap.Height; var bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); using (var canvas = new Canvas(bitmap)) using (var paint = new Paint() { Color = _placeholderHelperColor }) { canvas.DrawRect(0, 0, width, height, paint); } ffDrawable?.SetPlaceholder(new SelfDisposingBitmapDrawable(Context.Resources, bitmap), fadeDuration); } } else { ffDrawable?.SetPlaceholder(null, 0); } } await MainThreadDispatcher.PostAsync(() => { ThrowIfCancellationRequested(); PlatformTarget.Set(this, image, animated); }).ConfigureAwait(false); }