-
-
Save darmawan01/9be266df44594ea59f07032e325ffa3b to your computer and use it in GitHub Desktop.
import 'dart:ui'; | |
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/foundation.dart'; | |
class CacheMemoryImageProvider extends ImageProvider<CacheMemoryImageProvider> { | |
final String tag; //the cache id use to get cache | |
final Uint8List img; //the bytes of image to cache | |
CacheMemoryImageProvider(this.tag, this.img); | |
@override | |
ImageStreamCompleter loadImage( | |
CacheMemoryImageProvider key, ImageDecoderCallback decode) { | |
return MultiFrameImageStreamCompleter( | |
codec: _loadAsync(decode), | |
scale: 1.0, | |
debugLabel: tag, | |
informationCollector: () sync* { | |
yield ErrorDescription('Tag: $tag'); | |
}, | |
); | |
} | |
Future<Codec> _loadAsync(ImageDecoderCallback decode) async { | |
// the DefaultCacheManager() encapsulation, it get cache from local storage. | |
final Uint8List bytes = img; | |
if (bytes.lengthInBytes == 0) { | |
// The file may become available later. | |
PaintingBinding.instance.imageCache.evict(this); | |
throw StateError('$tag is empty and cannot be loaded as an image.'); | |
} | |
final buffer = await ImmutableBuffer.fromUint8List(bytes); | |
return await decode(buffer); | |
} | |
@override | |
Future<CacheMemoryImageProvider> obtainKey(ImageConfiguration configuration) { | |
return SynchronousFuture<CacheMemoryImageProvider>(this); | |
} | |
@override | |
bool operator ==(Object other) { | |
if (other.runtimeType != runtimeType) return false; | |
bool res = other is CacheMemoryImageProvider && other.tag == tag; | |
return res; | |
} | |
@override | |
int get hashCode => tag.hashCode; | |
@override | |
String toString() => | |
'${objectRuntimeType(this, 'CacheImageProvider')}("$tag")'; | |
} |
Your code is perfect for what I wanted to do, thanks ! Here is the updated version that takes into account last versions of Flutter
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class CacheImageProvider extends ImageProvider<CacheImageProvider> {
final String tag; //the cache id use to get cache
final Uint8List img; //the bytes of image to cache
CacheImageProvider(this.tag, this.img);
@override
ImageStreamCompleter load(
CacheImageProvider key,
Future<Codec> Function(Uint8List,
{bool allowUpscaling, int? cacheHeight, int? cacheWidth})
decode) {
return MultiFrameImageStreamCompleter(
codec: _loadAsync(decode),
scale: 1.0,
debugLabel: tag,
informationCollector: () sync* {
yield ErrorDescription('Tag: $tag');
},
);
}
Future<Codec> _loadAsync(
Future<Codec> Function(Uint8List,
{bool allowUpscaling, int? cacheHeight, int? cacheWidth})
decode) async {
// the DefaultCacheManager() encapsulation, it get cache from local storage.
final Uint8List bytes = img;
if (bytes.lengthInBytes == 0) {
// The file may become available later.
PaintingBinding.instance.imageCache.evict(this);
throw StateError('$tag is empty and cannot be loaded as an image.');
}
return await decode(bytes);
}
@override
Future<CacheImageProvider> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<CacheImageProvider>(this);
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) return false;
bool res = other is CacheImageProvider && other.tag == tag;
return res;
}
@override
int get hashCode => tag.hashCode;
@override
String toString() =>
'${objectRuntimeType(this, 'CacheImageProvider')}("$tag")';
}
Alsome @amalherbe-deuse . Enjoy the code and thanks for the update 🥂
The load
method is deprecated. loadBuffer
is used instead including performance improvements.
class CacheMemoryImageProvider extends ImageProvider<CacheMemoryImageProvider> {
final String tag; //the cache id use to get cache
final Uint8List img; //the bytes of image to cache
CacheMemoryImageProvider(this.tag, this.img);
@override
ImageStreamCompleter loadBuffer(
CacheMemoryImageProvider key, DecoderBufferCallback decode) {
return MultiFrameImageStreamCompleter(
codec: _loadAsync(decode),
scale: 1.0,
debugLabel: tag,
informationCollector: () sync* {
yield ErrorDescription('Tag: $tag');
},
);
}
Future<Codec> _loadAsync(DecoderBufferCallback decode) async {
// the DefaultCacheManager() encapsulation, it get cache from local storage.
final Uint8List bytes = img;
if (bytes.lengthInBytes == 0) {
// The file may become available later.
PaintingBinding.instance.imageCache.evict(this);
throw StateError('$tag is empty and cannot be loaded as an image.');
}
final buffer = await ImmutableBuffer.fromUint8List(bytes);
return await decode(buffer);
}
@override
Future<CacheMemoryImageProvider> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<CacheMemoryImageProvider>(this);
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) return false;
bool res = other is CacheMemoryImageProvider && other.tag == tag;
return res;
}
@override
int get hashCode => tag.hashCode;
@override
String toString() =>
'${objectRuntimeType(this, 'CacheImageProvider')}("$tag")';
}
loadBuffer was deprecated after v3.7.0-1.4.pre
loadImage is used instead including performance improvements.
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
class CacheMemoryImageProvider extends ImageProvider<CacheMemoryImageProvider> {
final String tag; //the cache id use to get cache
final Uint8List img; //the bytes of image to cache
CacheMemoryImageProvider(this.tag, this.img);
@override
ImageStreamCompleter loadImage(
CacheMemoryImageProvider key, ImageDecoderCallback decode) {
return MultiFrameImageStreamCompleter(
codec: _loadAsync(decode),
scale: 1.0,
debugLabel: tag,
informationCollector: () sync* {
yield ErrorDescription('Tag: $tag');
},
);
}
Future<Codec> _loadAsync(ImageDecoderCallback decode) async {
// the DefaultCacheManager() encapsulation, it get cache from local storage.
final Uint8List bytes = img;
if (bytes.lengthInBytes == 0) {
// The file may become available later.
PaintingBinding.instance.imageCache.evict(this);
throw StateError('$tag is empty and cannot be loaded as an image.');
}
final buffer = await ImmutableBuffer.fromUint8List(bytes);
return await decode(buffer);
}
@override
Future<CacheMemoryImageProvider> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<CacheMemoryImageProvider>(this);
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) return false;
bool res = other is CacheMemoryImageProvider && other.tag == tag;
return res;
}
@override
int get hashCode => tag.hashCode;
@override
String toString() =>
'${objectRuntimeType(this, 'CacheImageProvider')}("$tag")';
}
I tried it and it didn't work. Just rendering blanks
loadBuffer was deprecated after v3.7.0-1.4.pre
loadImage is used instead including performance improvements.
import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; class CacheMemoryImageProvider extends ImageProvider<CacheMemoryImageProvider> { final String tag; //the cache id use to get cache final Uint8List img; //the bytes of image to cache CacheMemoryImageProvider(this.tag, this.img); @override ImageStreamCompleter loadImage( CacheMemoryImageProvider key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(decode), scale: 1.0, debugLabel: tag, informationCollector: () sync* { yield ErrorDescription('Tag: $tag'); }, ); } Future<Codec> _loadAsync(ImageDecoderCallback decode) async { // the DefaultCacheManager() encapsulation, it get cache from local storage. final Uint8List bytes = img; if (bytes.lengthInBytes == 0) { // The file may become available later. PaintingBinding.instance.imageCache.evict(this); throw StateError('$tag is empty and cannot be loaded as an image.'); } final buffer = await ImmutableBuffer.fromUint8List(bytes); return await decode(buffer); } @override Future<CacheMemoryImageProvider> obtainKey(ImageConfiguration configuration) { return SynchronousFuture<CacheMemoryImageProvider>(this); } @override bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; bool res = other is CacheMemoryImageProvider && other.tag == tag; return res; } @override int get hashCode => tag.hashCode; @override String toString() => '${objectRuntimeType(this, 'CacheImageProvider')}("$tag")'; }
Perfect 👍
I tried it and it didn't work. Just rendering blanks
Can you share how you use it ?
loadBuffer was deprecated after v3.7.0-1.4.pre
loadImage is used instead including performance improvements.import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; class CacheMemoryImageProvider extends ImageProvider<CacheMemoryImageProvider> { final String tag; //the cache id use to get cache final Uint8List img; //the bytes of image to cache CacheMemoryImageProvider(this.tag, this.img); @override ImageStreamCompleter loadImage( CacheMemoryImageProvider key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(decode), scale: 1.0, debugLabel: tag, informationCollector: () sync* { yield ErrorDescription('Tag: $tag'); }, ); } Future<Codec> _loadAsync(ImageDecoderCallback decode) async { // the DefaultCacheManager() encapsulation, it get cache from local storage. final Uint8List bytes = img; if (bytes.lengthInBytes == 0) { // The file may become available later. PaintingBinding.instance.imageCache.evict(this); throw StateError('$tag is empty and cannot be loaded as an image.'); } final buffer = await ImmutableBuffer.fromUint8List(bytes); return await decode(buffer); } @override Future<CacheMemoryImageProvider> obtainKey(ImageConfiguration configuration) { return SynchronousFuture<CacheMemoryImageProvider>(this); } @override bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; bool res = other is CacheMemoryImageProvider && other.tag == tag; return res; } @override int get hashCode => tag.hashCode; @override String toString() => '${objectRuntimeType(this, 'CacheImageProvider')}("$tag")'; }Perfect 👍
Can you please give an example how to use it?
loadBuffer was deprecated after v3.7.0-1.4.pre
loadImage is used instead including performance improvements.import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; class CacheMemoryImageProvider extends ImageProvider<CacheMemoryImageProvider> { final String tag; //the cache id use to get cache final Uint8List img; //the bytes of image to cache CacheMemoryImageProvider(this.tag, this.img); @override ImageStreamCompleter loadImage( CacheMemoryImageProvider key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(decode), scale: 1.0, debugLabel: tag, informationCollector: () sync* { yield ErrorDescription('Tag: $tag'); }, ); } Future<Codec> _loadAsync(ImageDecoderCallback decode) async { // the DefaultCacheManager() encapsulation, it get cache from local storage. final Uint8List bytes = img; if (bytes.lengthInBytes == 0) { // The file may become available later. PaintingBinding.instance.imageCache.evict(this); throw StateError('$tag is empty and cannot be loaded as an image.'); } final buffer = await ImmutableBuffer.fromUint8List(bytes); return await decode(buffer); } @override Future<CacheMemoryImageProvider> obtainKey(ImageConfiguration configuration) { return SynchronousFuture<CacheMemoryImageProvider>(this); } @override bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; bool res = other is CacheMemoryImageProvider && other.tag == tag; return res; } @override int get hashCode => tag.hashCode; @override String toString() => '${objectRuntimeType(this, 'CacheImageProvider')}("$tag")'; }Perfect 👍
Can you please give an example how to use it?
Like this:
Image(image: CacheMemoryImageProvider(uid, image))
Reference: https://stackoverflow.com/a/65950055/7334197