Flutter 浅析之 自定义view (自定义图形 绘制drawImage 加载本地图片 ui.Image的使用) 四

17 篇文章 0 订阅
12 篇文章 2 订阅

技术无止境,只怕不学习啊,Flutter 我们开始吧

绘制drawImage的时候遇到一个问题获取要绘制的图片,查询的一些资料找出来一个方法可以回去本地图片 ,因为绘制的时候Image对象必须使用ui.Image

 /// 通过assets路径,获取资源图片
  Future<ui.Image> load(String asset) async {
    ByteData data = await rootBundle.load(asset);
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    ui.FrameInfo fi = await codec.getNextFrame();
    return fi.image;
  }

使用的时候怎么都回去不到图片,分析这个函数中使用了async 和await 在Dart中他们是异步执行,问题就在这里了,异步回去图片,那应该在哪里初始化绘制的时候才能回去到图片那?
答案是在页面初始化的时候获取图片然后把ui.Image传给自定义的view,初始化函数initState。

@override
  void initState() {
    super.initState();
    /**
     * 注意在初始化函数里面加加载图片
     * build 函数中把图片传给TestPainter对象
     */
    load("images/timg.jpg").then((i) {
      setState(() {
        _image = i;
      });
    });
  }

传入值:

@override
  Widget build(BuildContext context) {
    // TODO: implement build
    var paint = CustomPaint(
        size: Size(300,300),
        painter: TestPainter(_image),
    );
    return Scaffold(
      appBar: AppBar(
        title: Text( "Canvas的用法"),
      ),
      body: Container(
        child: paint,
      ),
    );
  }

整体的代码如下:

import 'dart:ui';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutterapptest/NewRoute.dart';
import 'TestPainter.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.red, // 风格颜色
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      routes:{
        "new_page":(context) => NewRoute(),
      },
      home: MyHomePage(title: '测试项目'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

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

  @override
  void initState() {
    super.initState();
    /**
     * 注意在初始化函数里面加加载图片
     * build 函数中把图片传给TestPainter对象
     */
    load("images/timg.jpg").then((i) {
      setState(() {
        _image = i;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    var paint = CustomPaint(
        size: Size(300,300),
        painter: TestPainter(_image),
    );
    return Scaffold(
      appBar: AppBar(
        title: Text( "Canvas的用法"),
      ),
      body: Container(
        child: paint,
      ),
    );
  }

  /// 通过assets路径,获取资源图片
  Future<ui.Image> load(String asset) async {
    ByteData data = await rootBundle.load(asset);
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    ui.FrameInfo fi = await codec.getNextFrame();
    return fi.image;
  }

}

import 'dart:ui' as ui;
import 'dart:ui';
import 'package:flutter/material.dart';

class TestPainter extends CustomPainter {
  Paint _paint = new Paint()
    ..color = Colors.blueAccent // 画笔颜色
    ..strokeCap = StrokeCap.round //画笔笔触类型
    ..isAntiAlias = true //是否启动抗锯齿
    ..strokeWidth = 6.0 //画笔的宽度
    ..style = PaintingStyle.stroke // 样式
    ..blendMode = BlendMode.colorDodge; // 模式


  ui.Image _image;

  TestPainter(this._image) {
    this._image = _image;
  }

  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
      if (_image != null) {
          canvas.drawImage(_image, Offset(0, 0), _paint);
//      canvas.drawImageRect(_image, Offset(0.0, 0.0) & Size(_image.width.toDouble(), _image.height.toDouble()), Offset(0.0, 0.0) & Size(200, 200), _paint);
      }
  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    ///是否需要重绘
    return false;
  }
}

在这里插入图片描述
绘制图片时候遇到的问题记录一下,搜了还就没有找到相关的问题。加油吧童鞋们!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值