1.ui.Image轉(zhuǎn)ImageProvider
最近用photo_view做圖片預(yù)覽時(shí),有個(gè)需求是加一張canvas生成的海報(bào)圖片,因?yàn)镃ustomPainter返回的時(shí)候可以toImage,于是就有了這些東西。
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'dart:ui' as ui;
/**
* 學(xué)知乎大佬思路,
* 模仿NetworkImage制作一個(gè)自定義ImageProvider
*/
class LoadImage extends ImageProvider<LoadImage> {
const LoadImage(this.image, { this.scale = 1.0 })
: assert(image != null),
assert(scale != null);
final ui.Image image;
final double scale;
@override
ImageStreamCompleter load(LoadImage key, decode) {
return MultiFrameImageStreamCompleter(
codec: _loadAsync(key),
scale: key.scale,
);
}
Future<ui.Codec> _loadAsync(LoadImage key) async {
assert(key == this);
//image轉(zhuǎn)ByteData
final a = await image.toByteData(format: ui.ImageByteFormat.png);
var codec = await PaintingBinding.instance
.instantiateImageCodec(a.buffer.asUint8List());
return codec;
}
@override
Future<LoadImage> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<LoadImage>(this);
}
@override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final LoadImage typedOther = other;
return image == typedOther.image && scale == typedOther.scale;
}
@override
int get hashCode => hashValues(image.hashCode, scale);
@override
String toString() =>
'$runtimeType(${describeIdentity(image)}, scale: $scale)';
}
實(shí)際使用
LoadImage loadImage = LoadImage(image);
ImageProvider轉(zhuǎn)ui.Image
static Future<ui.Image> loadImageByProvider(
ImageProvider provider, {
ImageConfiguration config = ImageConfiguration.empty,
}) async {
Completer<ui.Image> completer = Completer<ui.Image>(); //完成的回調(diào)
ImageStreamListener listener;
ImageStream stream = provider.resolve(config); //獲取圖片流
listener = ImageStreamListener((ImageInfo frame, bool sync) {
//監(jiān)聽(tīng)
final ui.Image image = frame.image;
completer.complete(image); //完成
stream.removeListener(listener); //移除監(jiān)聽(tīng)
});
stream.addListener(listener); //添加監(jiān)聽(tīng)
return completer.future; //返回
}
//實(shí)際使用 ImageProvider轉(zhuǎn)ui.Image
ui.Image image = await ImageUtils.loadImageByProvider(
CachedNetworkImageProvider(imgUrl));
ui.Image轉(zhuǎn)asUint8List
// 轉(zhuǎn)asUint8List
var a = await image.toByteData(format: ui.ImageByteFormat.png);
print(a.buffer.asUint8List());
ByteData轉(zhuǎn)Widget
Widget image = Image.memory(a.buffer.asUint8List())
2.ByteData、ui.Image互轉(zhuǎn)
//ui.Image轉(zhuǎn)ByteData
final a = await image.toByteData(format: ImageByteFormat.png);
var codec = await ui.instantiateImageCodec(a.buffer.asUint8List());
//ByteData轉(zhuǎn)ui.Image
FrameInfo fi = await codec.getNextFrame();
ui.Image image = fi.image;