Flutter Web:隐蔽 ui.Image 到 ImageProvider

Flutter Web: Covert ui.Image to ImageProvider

我正在使用 CustomPainter 画一些东西到 canvas

稍后我想在 Image 小部件(采用 ImageProvider<Object> 类型的图像参数)中显示该绘图。

经过一番研究,我发现了一种基本上只需两步即可到达那里的方法:

  1. 根据 canvas 绘图创建一个 ui.Image 对象
  2. 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);
  }