Flutter 绘制番外 | 将你的 Canvas 绘制保存为图片

这篇具有很好参考价值的文章主要介绍了Flutter 绘制番外 | 将你的 Canvas 绘制保存为图片。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


theme: cyanosis

前言

光阴似箭,《Flutter 绘制指南 - 妙笔生花》 转眼间已经发布两年半了,不知道各位练习得怎么样。有不少朋友问过如何将 Canvas 绘制的内容保存为图片,最近在做的东西刚好涉及了这块,通过本文来分享一下。

提到保存图片,很多人可能会想到 RepaintBoundary, 但它使用起来有点繁琐,同时也存在一些局限性。而且 Canvas 有更灵活的生成图片方式,没有必要使用 RepaintBoundary,下面一起来看看吧!


1. 自己创建 Canvas 对象

如果我问:

如何得到 Canvas 对象,来进行绘制操作?

可能绝大多数朋友都知道继承自 CustomPainter,在 paint 回调中获取 Canvas 对象,它是在 Flutter 框架中创建的。你有没有想过,我可不可以自己创建一个 Canvas 对象呢?

canvas 保存成图片,flutter,ui,android,ios


实例化对象,最重要的是 构造方法,可以进入 Canvas 源码中瞄一眼。 可以看到它有一个构造方法,说明允许外界进行实例化。其中必须传入一个 PictureRecorder 对象;

canvas 保存成图片,flutter,ui,android,ios

PictureRecorder 类有无参构造,这样就为我们自己创建 Canvas 对象提供了可能性,代码如下:

dart void createCanvas(){ PictureRecorder recorder = PictureRecorder(); Canvas canvas = Canvas(recorder); }


2. 得到 Picture 对象

可能很少人知道 Picture 对象,但它在框架层渲染机制中的出场率挺高,看过渲染小册的应该知道它。 通过PictureRecorder#endRecording 可以得到 Picture 对象,期间 Canvas 绘制的内容将被 记录Picture 中。比如下面绘制了 100*100 尺寸的蓝色盒子:

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

void createCanvas(){ PictureRecorder recorder = PictureRecorder(); Canvas canvas = Canvas(recorder); Size boxSize = const Size(100, 100); canvas.drawRect(Offset.zero&boxSize, Paint()..color=Colors.blue); Picture picture = recorder.endRecording(); } ```


生成图片的核心方法是 PicturetoImage 方法,可以异步生成 ui.Image 对象:

canvas 保存成图片,flutter,ui,android,ios


3. 存储图片

有了 ui.Image 对象,就可以得到图片的字节数组,存入到文件中即可:这里在 Windows 中测试的,其他平台也是类似。

canvas 保存成图片,flutter,ui,android,ios

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

void createCanvas() async{ PictureRecorder recorder = PictureRecorder(); Canvas canvas = Canvas(recorder); Size boxSize = const Size(100, 100); canvas.drawRect(Offset.zero&boxSize, Paint()..color=Colors.blue); Picture picture = recorder.endRecording(); ui.Image image = await picture.toImage(boxSize.width.toInt(), boxSize.height.toInt()); // 获取字节,存入文件 ByteData? byteData = await image.toByteData(format:ImageByteFormat.png ); if(byteData!=null){ File file = File(r"E:\Temp\desk\box.png"); file.writeAsBytes(byteData.buffer.asUint8List()); } } ```


通过这种方式绘制生成图片,好处是可以自由操作 Canvas 的绘制内容,而且必依赖于组件,只要在任何需要的地方触发方法即可。如下所示,在 FloatingActionButton 中触发 createCanvas 方法即可保存图片。

canvas 保存成图片,flutter,ui,android,ios

另外,这种方式还有另一个很大的优势,可以通过 canvas 的操作让图片放大,获得非常大尺寸的图片。比如将绘制内容放大 100 倍存储,这是 RepaintBoundary 无法做到的。还有 RepaintBoundary 无法获取到没有渲染到的内容,无法做到长屏图片的生成。而掌握 Canvas 我们可以控制一切。


4. CustomPainter 与 PictureRecorder

上面说了,可以在不显示的情况下将画板内容保存为图片。但很多时候,我们会通过 CustomPainter 先画出来,这时候如何通过保存 CustomPainter 类中绘制的内容呢?比如这里也就就有一个 ShapePainter,是一个 100*100 尺寸的蓝色盒子,上面放着半径 40 的红色边线圆:

canvas 保存成图片,flutter,ui,android,ios

现在想要点击按钮,将 ShapePainter 的绘制内容保存起来,该怎么办呢?在生成图片的地方再写一遍绘制逻辑吗?

``` class ShapePainter extends CustomPainter {

@override void paint(Canvas canvas, Size size) { Paint paint = Paint()..color = Colors.blue; canvas.drawRect(Offset.zero & size,paint ); paint..style=PaintingStyle.stroke..color=Colors.redAccent..strokeWidth=2; canvas.drawCircle(Offset(size.width/2 , size.height/2),40, paint); }

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


其中仔细思考一下,上图红框的区域 canvas 的操作在 Picture 中留下 "痕迹",而 CustomPainter 正好有个方法,可以操作一个 canvas 对象,于是乎:将 ShapePainter 作为成员变量,可以通过 _painter#paint 方法去操作自己创建的 Canvas 对象,从而在 Picture 中留下对应的 "痕迹"

canvas 保存成图片,flutter,ui,android,ios

```dart // 作为成员变量 ShapePainter _painter = ShapePainter();

void createCanvas() async { PictureRecorder recorder = PictureRecorder(); Canvas canvas = Canvas(recorder); Size boxSize = const Size(100, 100); // 通过 _painter 对象操作 canvas _painter.paint(canvas, boxSize); Picture picture = recorder.endRecording(); //略同... } ```

这里想说明一点: paint 虽然是 ShapePainter 类中覆写的方法,它会在框架中某些时机被触发(俗称回调)。但它本身仍是该对象的成员方法,可以通过对象来调用。不要固化思维,觉得回调的方法一定要等着被底层调用。

这样,任何的 CustomPainter 实现类都可以很容易地通过 PictureRecorder->Canvas->Picture 这套组合拳生成图片来保存:

canvas 保存成图片,flutter,ui,android,ios


5. 绘制永无止境

绘制本身是一个创造过程,而创造是没有上限的。将 Canvas 保存为图片,可以让你创造的、在界面上的呈现物,转化为可传输的图片资源。让它可以脱离 Flutter 绘制体系,通过图片展示在任何设备屏幕上。通过 Canvas 绘制可以完成很多事:

比如,通过 绘制+手势 可以操作图片,进行裁剪图像,最终根据矩形区域使用上面的方式,将选取的局部图片绘制到自己创建的画板上,保存为图片。

canvas 保存成图片,flutter,ui,android,ios

另外,截图、图片编辑器也少不了绘制的技能,箭头、基本图形、文字都是在图片之上绘制的内容。最终保存图片时也都可以使用上面的方式。

canvas 保存成图片,flutter,ui,android,ios

最后,比如掘金的这种分享的卡片图片,也可以通过绘制来处理,分享时本质上是分享图片。保存图片也是上面 PictureRecorder->Canvas->Picture 这套组合拳。


总的来看, Canvas 保存成图片的过程非常简单,也就十几行代码。但对于很多人来说,不知道就做不出来,让更多人知道一些力所能及知识,这也是分享的意义所在。希望本文可以在你想要保存绘制成图片时,对你有所帮助。那本文就到这里,谢谢观看 ~

本文正在参加「金石计划」文章来源地址https://www.toymoban.com/news/detail-753163.html

到了这里,关于Flutter 绘制番外 | 将你的 Canvas 绘制保存为图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序使用canvas绘制海报并保存本地相册

    在做微信小程序的时候,很多都会用到生成海报分享功能,刚好最近项目有这个需求,今天就发出来记录下 首先是使用canvas绘制一张海报,微信小程序的canvas有老版本和新版本我是用的是新版本 代码如下 js部分 我的做法是给canvas隐藏了不看到 ,等canvas绘制完毕后导出的url直接赋给

    2023年04月08日
    浏览(42)
  • 小程序 canvas 绘制图片

    绘制图片的问题 1、canvas不能绘制网络图片需要转换成本地图片进行使用 2、多张图片绘制需要调用 img.onload,进行嵌套绘制 html

    2024年02月14日
    浏览(41)
  • uniapp小程序使用canvas绘制内容并保存到本地相册

    需求: 根据不同用户自动生成对应证书,并且可以下载该证书(下载后得到的是一张图片),故要想实现该功能,则需要借助canvas将动态生成的内容绘制到页面中,然后再实现下载功能。 1.html代码 页面很简单,只包含一个canvas和下载按钮即可。 2.js代码 3.效果图展示 注:下

    2024年02月09日
    浏览(43)
  • canvas 绘制图片 - ctx.drawImage()

    canvas的左上角位置为 (0, 0) ctx.drawImage(图片对象, x位置, y位置) 图片的原始比例,图片的左上角在画布的(x, y) ctx.drawImage(图片对象, x位置, y位置, 宽度, 高度) 图片的左上角在画布的(x, y),指定图片的宽高 ctx.drawImage(图片对象, 图像裁剪的x位置, 图像裁剪的y位置, 裁剪的宽度, 裁剪

    2024年02月10日
    浏览(31)
  • 小程序中通过canvas生成并保存图片

    2024年02月12日
    浏览(44)
  • 微信小程序canvas生成图片并保存

    需求: 做一个类似下图的功能。图片内容是动态的,用canvas画出来,生成临时图片,再保存。 实现:  其他使用,查看微信开发文档  

    2024年02月13日
    浏览(53)
  • 小程序采用html2canvas实现html转canvas保存图片

    mpaas小程序中采用html2canvas实现html转canvas保存图片 使用uniapp将代码打包一份h5部署到服务器 h5要保存的图片组件页面report.vue 安装 npm install --save html2canvas 或 yarn add html2canvas 引入import html2canvas from ‘html2canvas’; ts 小程序中采用webview跳转到h5页面

    2024年02月11日
    浏览(46)
  • 小程序使用canvas标签生成海报并保存图片

    先说一下做功能前的感受,简直一脸懵逼,第一次用canvas,只知道是个画布,其余什么都不知道…琢磨了一天才画出来… 开始之前百度了很久,想看看别人怎么写的,但是目前网上基本上用的都是wx.createCanvasContext这个api,但是这个api已经停止维护了,要求使用canvas代替,  

    2024年02月11日
    浏览(80)
  • (小程序)canvas 绘制图片做背景(新手向)

    小程序绘制图片为背景,首先我们需要把图片先下载下来(这里最好是封装一个函数,因为背景不可能只有一张的)下面是代码,一般直接复制就能使用,有可能需要微调

    2024年02月07日
    浏览(38)
  • 微信小程序新版canvas绘制图片方法

    今天在做项目使用到了canvas绘制二维码,发现以前的方法被弃用了。 wxml: 如果想要绘制需要将起临时存储起来,写入成功的就可以进行绘制了。(如果是点击展示二维码,最好是先将数据写到onLoad事件中,在将要绘制的东西写到点击事件中去,在点击事件中去获取数据);

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包