Flutter Web:隐蔽 ui.Image 到 ImageProvider
Flutter Web: Covert ui.Image to ImageProvider
我正在使用 CustomPainter
画一些东西到 canvas
。
稍后我想在 Image
小部件(采用 ImageProvider<Object>
类型的图像参数)中显示该绘图。
经过一番研究,我发现了一种基本上只需两步即可到达那里的方法:
- 根据 canvas 绘图创建一个
ui.Image
对象
- 将
ui.Image
转换为可以传递给 Image
小部件的 ImageProvider
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:bitmap/bitmap.dart';
class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
//drawing some stuff here
//canvas.drawRect(...);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
Future<ui.Image> getImage() {
final ui.PictureRecorder recorder = ui.PictureRecorder();
try {
//500 x 500 pixels
paint(Canvas(recorder), const Size(500, 500));
} catch (e) {
debugPrint(e.toString());
}
final ui.Picture picture = recorder.endRecording();
final img = picture.toImage(500, 500);
return img;
}
static Future<ImageProvider> getProviderFromImage(ui.Image image) async {
final ByteData? bytedata = await image.toByteData();
if (bytedata == null) {
return Future.error("some error msg");
}
final Bitmap bitmap = Bitmap.fromHeadless(
image.width, image.height, bytedata.buffer.asUint8List());
final Uint8List headedIntList = bitmap.buildHeaded();
return MemoryImage(headedIntList);
}
}
这里的问题是这对 Flutter Web 不起作用,因为 bitmap package 不支持 Web。
我已经尝试在没有 位图包的情况下将 ByteData
转换为 Uint8List
:
static Future<ImageProvider> getProviderFromImage(ui.Image image) async {
final ByteData? bytedata = await image.toByteData();
if (bytedata == null) {
return Future.error("some error msg");
}
final Uint8List headedIntList =
Uint8List.view(bytedata.buffer);
return MemoryImage(headedIntList);
}
但是 ImageProvider
不会被 Image
小部件接受:
════════ Exception caught by image resource service
════════════════════════════ The following ImageCodecException was
thrown resolving an image codec: Failed to decode image data. Image
source: encoded image bytes
如果传递 toByteData()
的 format
参数,我的方法实际上有效:
static Future<ImageProvider> getProviderFromImage(ui.Image image) async {
final ByteData? bytedata = await image.toByteData(format: ui.ImageByteFormat.png);
if (bytedata == null) {
return Future.error("some error msg");
}
final Uint8List headedIntList =
Uint8List.view(bytedata.buffer);
return MemoryImage(headedIntList);
}
我正在使用 CustomPainter
画一些东西到 canvas
。
稍后我想在 Image
小部件(采用 ImageProvider<Object>
类型的图像参数)中显示该绘图。
经过一番研究,我发现了一种基本上只需两步即可到达那里的方法:
- 根据 canvas 绘图创建一个
ui.Image
对象 - 将
ui.Image
转换为可以传递给Image
小部件的ImageProvider
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:bitmap/bitmap.dart';
class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
//drawing some stuff here
//canvas.drawRect(...);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
Future<ui.Image> getImage() {
final ui.PictureRecorder recorder = ui.PictureRecorder();
try {
//500 x 500 pixels
paint(Canvas(recorder), const Size(500, 500));
} catch (e) {
debugPrint(e.toString());
}
final ui.Picture picture = recorder.endRecording();
final img = picture.toImage(500, 500);
return img;
}
static Future<ImageProvider> getProviderFromImage(ui.Image image) async {
final ByteData? bytedata = await image.toByteData();
if (bytedata == null) {
return Future.error("some error msg");
}
final Bitmap bitmap = Bitmap.fromHeadless(
image.width, image.height, bytedata.buffer.asUint8List());
final Uint8List headedIntList = bitmap.buildHeaded();
return MemoryImage(headedIntList);
}
}
这里的问题是这对 Flutter Web 不起作用,因为 bitmap package 不支持 Web。
我已经尝试在没有 位图包的情况下将 ByteData
转换为 Uint8List
:
static Future<ImageProvider> getProviderFromImage(ui.Image image) async {
final ByteData? bytedata = await image.toByteData();
if (bytedata == null) {
return Future.error("some error msg");
}
final Uint8List headedIntList =
Uint8List.view(bytedata.buffer);
return MemoryImage(headedIntList);
}
但是 ImageProvider
不会被 Image
小部件接受:
════════ Exception caught by image resource service ════════════════════════════ The following ImageCodecException was thrown resolving an image codec: Failed to decode image data. Image source: encoded image bytes
如果传递 toByteData()
的 format
参数,我的方法实际上有效:
static Future<ImageProvider> getProviderFromImage(ui.Image image) async {
final ByteData? bytedata = await image.toByteData(format: ui.ImageByteFormat.png);
if (bytedata == null) {
return Future.error("some error msg");
}
final Uint8List headedIntList =
Uint8List.view(bytedata.buffer);
return MemoryImage(headedIntList);
}