Skip to content

Instantly share code, notes, and snippets.

@jonathanduke
Last active May 2, 2025 16:06
Show Gist options
  • Select an option

  • Save jonathanduke/b3385b350b7fa02019ba9927c5fa3f5a to your computer and use it in GitHub Desktop.

Select an option

Save jonathanduke/b3385b350b7fa02019ba9927c5fa3f5a to your computer and use it in GitHub Desktop.
Wraps a Dart image so that it can be passed as a parameter to synchronous methods while loading asynchronously
/*
* Based on: https://gist.github.com/jonathanduke/b3385b350b7fa02019ba9927c5fa3f5a
* Public domain: http://unlicense.org/
* Modify as you wish, but you are encouraged to leave this comment for future reference in case the original is updated.
*/
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'dart:ui';
class AsyncImage {
late final Future<Image> future;
late Image? _image;
late Uint8List? _bytes;
AsyncImage._();
bool get isLoaded => _image != null;
Image get image => _image!;
bool get hasBytes => _bytes != null;
Uint8List get bytes => _bytes!;
static Future<Image> _loadImageFromBytes(Uint8List bytes) async {
final completer = Completer<Image>();
runZonedGuarded(() {
decodeImageFromList(bytes, (img) {
completer.complete(img);
});
}, (ex, st) {
completer.completeError(ex, st);
});
return await completer.future;
}
static Future<Uint8List> _getBytesFromImage(Image image) async => await image
.toByteData(format: ImageByteFormat.rawUnmodified)
.then((data) => data!.buffer.asUint8List());
factory AsyncImage.fromImage(Image image) {
final instance = AsyncImage._().._image = image;
instance.future = Future.value(image).then((image) async {
instance._bytes = await _getBytesFromImage(image);
return image;
});
return instance;
}
factory AsyncImage.fromUint8List(Uint8List bytes) {
final instance = AsyncImage._().._bytes = bytes;
instance.future = _loadImageFromBytes(bytes).then((image) {
instance._image = image;
return image;
});
return instance;
}
static AsyncImage fromByteData(ByteData byteData) =>
AsyncImage.fromUint8List(byteData.buffer.asUint8List());
static AsyncImage fromBase64(String source) =>
AsyncImage.fromUint8List(base64Decode(source));
String toBase64() => base64Encode(_bytes!);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment