Flutter自定义CustomPainter中获取ImageShader参数ui.Image对象的方法

ImageShader需要传入dart:ui包里的Image对象,ui.Image需要异步请求获取:

  Future<ui.Image> loadImage() async {
    ByteData byteData = await rootBundle.load('assets/images/target_image.jpg');
    ui.Codec codec =
        await ui.instantiateImageCodec(byteData.buffer.asUint8List());
    ui.FrameInfo frameInfo = await codec.getNextFrame();
    return frameInfo.image;
  }

建议在State初始化的时候获取异步资源,再传入到自定义的CustomPainter中,否则会报错:

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ui.Image _image;

  @override
  void initState() {
    super.initState();
    loadImage().then((value) {
      setState(() {
        _image = value;
      });
    });
  }

  Future<ui.Image> loadImage() async {
    ByteData byteData = await rootBundle.load('assets/images/target_image.jpg');
    ui.Codec codec =
        await ui.instantiateImageCodec(byteData.buffer.asUint8List());
    ui.FrameInfo frameInfo = await codec.getNextFrame();
    return frameInfo.image;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.white,
        child: _image == null
            ? Center(
                child: Text("loading..."),
              )
            : CustomPaint(
                painter: PaperPainter(_image),
              ),
      ),
    );
  }
}

class PaperPainter extends CustomPainter {
  ui.Image _image;
  Paint _paint = Paint();

  PaperPainter(this._image);

  @override
  void paint(Canvas canvas, Size size) async {
    print("image: $_image");

    _paint.shader = ImageShader(_image, TileMode.repeated, TileMode.repeated,
        Float64List.fromList([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]));

    canvas.drawCircle(Offset(100, 100), 50, _paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

网上另一种获取ui.Image对象的方法:

  Future<ui.Image> loadImage() {
    ImageProvider provider = AssetImage('assets/images/target_image.jpg');
    Completer<ui.Image> completer = Completer<ui.Image>();
    ImageStreamListener listener;
    ImageStream stream = provider.resolve(ImageConfiguration());
    listener = ImageStreamListener((info, syno) {
      final ui.Image image = info.image;
      completer.complete(image);
      stream.removeListener(listener);
    });
    stream.addListener(listener);
    return completer.future;
  }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值