I'm toying with Flutter and I have implemented a custom-drawn widget using CustomPainter
class.
Primitives are quite well documented. However, it seems that there's Image
(the widget) and Image
(the data structure), because if I istantiate an Image
(the widget) I cannot pass it to the Canvas method drawImage
because it needs another type of Image
.
Problem is, I cannot wrap my head on how to load a resource into an Image
data structure.
Has anyone tackled this problem?
[edit] Thanks to rmtmckenzie I solved it this way:
rootBundle.load("assets/galaxy.jpg").then( (bd) {
Uint8List lst = new Uint8List.view(bd.buffer);
UI.instantiateImageCodec(lst).then( (codec) {
codec.getNextFrame().then(
(frameInfo) {
bkImage = frameInfo.image;
print ("bkImage instantiated: $bkImage");
}
}
);
});
});
A working solution:
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/services.dart' show rootBundle;
/// Load [Image] from asset path.
/// https://stackoverflow.com/a/61338308/1321917
Future<ui.Image> loadUiImage(String assetPath) async {
final data = await rootBundle.load(assetPath);
final list = Uint8List.view(data.buffer);
final completer = Completer<ui.Image>();
ui.decodeImageFromList(list, completer.complete);
return completer.future;
}
To do this, you need to load the image directly, and then instantiate it.
I'll leave the loading part up to you - you're either going to have to do an Http request directly or use AssetBundle.load
; or you could possibly use a NetworkImage/AssetImage (which both inherit ImageProvider - see the docs which contain an example).
If you take the loading directly route, you can then instantiate an image (in the form of a codec -> frame -> image) using instantiateImageCodec.
If you take the other route, you have to listen to streams etc as it is done in the docs, but you should get an Image directly.
Edit: Thanks to the OP who has included the working code in his question. Here is what worked for him:
rootBundle.load("assets/galaxy.jpg").then( (bd) {
Uint8List lst = new Uint8List.view(bd.buffer);
UI.instantiateImageCodec(lst).then( (codec) {
codec.getNextFrame().then(
(frameInfo) {
bkImage = frameInfo.image;
print ("bkImage instantiated: $bkImage");
}
}
);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With