We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
首先,你要了解flutter如何将canvas转换成图片,这里有一个非常好的例子分享给大家flutter_canvas_to_image,这里简单讲解一下思路:
1.首先创建一个 ui.PictureRecorder(记录仪), 然后作为载体创建一个canvas对象
// 创建一个记录仪 final recorder = new ui.PictureRecorder(); final canvas = new Canvas( recorder, new Rect.fromPoints( new Offset(0.0, 0.0), new Offset(200.0, 200.0)));
2.在canvas上进行绘制
final stroke = new Paint() ..color = Colors.grey ..style = PaintingStyle.stroke; canvas.drawRect( new Rect.fromLTWH(0.0, 0.0, 200.0, 200.0), stroke); final paint = new Paint() ..color = color ..style = PaintingStyle.fill; canvas.drawCircle( new Offset( widget.rd.nextDouble() * 200.0, widget.rd.nextDouble() * 200.0, ), 20.0, paint);
// 关闭记录仪 final picture = recorder.endRecording(); final img = picture.toImage(200, 200); final pngBytes = await img.toByteData(format: new ui.EncodingFormat.png()); // 显示图片 new Image.memory(new Uint8List.view(imgBytes.buffer));
当我们懂得如何将canvas转为图片之后,我们简单看下canvas clip的代码(这并不是本文主要讲述的内容,所以不做详细说明),我们以canvas.clipPath截取图片为例
// 绘制一个三角形的path Path _path = Path() ..moveTo(100, 50) ..lineTo(50, 150) ..lineTo(150, 150) ..lineTo(100, 50); canvas.clipPath(_path); canvasClip.drawImageRect( _image, // ui.Image Rect.fromLTWH(0, 0, _image.width.toDouble(), _image.height.toDouble()),, Rect.fromLTWH(0, 0, 200, 200), // 画布Rect Paint() );
我们已经将图片截取了,这个时候获取的图片大小是200*200的,但是我们只想要那个三角形怎么办那?思路如下:
获取path围成的矩形
将这个矩形移到画布的左上角
转成目标大小的图片
思路有了,我们看实际解决办法,首先针对第一点,flutter Path 为我们提供了一个现成的方法 getBounds(), 看下官网的描述
getBounds()
getBounds() → Rect Computes the bounding rectangle for this path.
然后看下第二点,我们可以将之前生成的图片通过位移画在一个新的canvas的左上角,第三步在Step.1 已经充分get了,看下代码:
// 获取Path围成的矩形 Rect _bounds = _path.getBounds(); // 上一步生成的图片 ui.Image img = await picture.toImage(200, 200); // 新建一个新的记录仪和canvas final recorder2 = ui.PictureRecorder(); final canvasClip = Canvas(recorder2, Rect.fromLTWH(0, 0, size.width, size.height)); canvasClip.drawImageRect( img, _bound, // _bound 中已经包含左上角的offset,可以直接拿过来用 Rect.fromLTWH(0, 0, _bound.width, _bound.height), Paint() ); // 停止录制 生成image final picture2 = recorder2.endRecording(); ui.Image img2 = await picture2.toImage(size.width.toInt(), size.height.toInt()); final pngBytes = await img2.toByteData(format: ui.ImageByteFormat.png);
看起来没什么变化?我们可以打印下输出 very nice,大佬们如果有更好的方法麻烦告诉下,非常感谢
import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:myapp/utils/image.dart'; import 'package:flutter/material.dart'; void main() => runApp(App()); const kCanvasSize = 200.0; class App extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: ImageGenerator(), ), debugShowCheckedModeBanner: false, ); } } class ImageGenerator extends StatefulWidget { @override _ImageGeneratorState createState() => _ImageGeneratorState(); } class _ImageGeneratorState extends State<ImageGenerator> { ByteData imgBytes; ui.Image _image; @override void initState() { super.initState(); loadImage('assets/images/face.jpg').then((image) { setState(() { _image = image; }); }); } @override Widget build(BuildContext context) { return Center( child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(12.0), child: RaisedButton( child: Text('Generate image'), onPressed: generateImage), ), imgBytes != null ? Container( child: Image.memory( Uint8List.view(imgBytes.buffer), width: kCanvasSize, height: kCanvasSize, )) : Container() ], ), ); } void generateImage() async { final recorder = ui.PictureRecorder(); final canvas = Canvas(recorder, Rect.fromPoints(Offset(0.0, 0.0), Offset(kCanvasSize, kCanvasSize))); final stroke = new Paint() ..color = Colors.grey ..style = PaintingStyle.stroke; canvas.drawRect(Rect.fromLTWH(0.0, 0.0, kCanvasSize, kCanvasSize), stroke); Path _path = Path() ..moveTo(100, 50) ..lineTo(50, 150) ..lineTo(150, 150) ..lineTo(100, 50); canvas.clipPath(_path); Rect _bound = _path.getBounds(); canvas.drawImageRect( _image, Rect.fromLTWH(0, 0, _image.width.toDouble(), _image.height.toDouble()), Rect.fromLTWH(0, 0, 200, 200), Paint()); final picture = recorder.endRecording(); ui.Image img = await picture.toImage(200, 200); print('img的尺寸: $img'); final recorder2 = ui.PictureRecorder(); final canvasClip = Canvas(recorder2, Rect.fromLTWH(0, 0, _bound.width, _bound.height)); canvasClip.drawImageRect( img, _bound, Rect.fromLTWH(0, 0, _bound.width, _bound.height), Paint()); final picture2 = recorder2.endRecording(); ui.Image img2 = await picture2.toImage(_bound.width.toInt(), _bound.height.toInt()); print('img2的尺寸: $img2'); final pngBytes = await img2.toByteData(format: ui.ImageByteFormat.png); setState(() { imgBytes = pngBytes; }); } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Step.1 Canvas转换为图片
首先,你要了解flutter如何将canvas转换成图片,这里有一个非常好的例子分享给大家flutter_canvas_to_image,这里简单讲解一下思路:
1.首先创建一个 ui.PictureRecorder(记录仪), 然后作为载体创建一个canvas对象
2.在canvas上进行绘制
Step.2 Canvas截取
当我们懂得如何将canvas转为图片之后,我们简单看下canvas clip的代码(这并不是本文主要讲述的内容,所以不做详细说明),我们以canvas.clipPath截取图片为例
Step.3 获取截取之后的图形
我们已经将图片截取了,这个时候获取的图片大小是200*200的,但是我们只想要那个三角形怎么办那?思路如下:
获取path围成的矩形
将这个矩形移到画布的左上角
转成目标大小的图片
思路有了,我们看实际解决办法,首先针对第一点,flutter Path 为我们提供了一个现成的方法
getBounds()
, 看下官网的描述然后看下第二点,我们可以将之前生成的图片通过位移画在一个新的canvas的左上角,第三步在Step.1 已经充分get了,看下代码:
看起来没什么变化?我们可以打印下输出
very nice,大佬们如果有更好的方法麻烦告诉下,非常感谢
Step.4 献上完整代码
The text was updated successfully, but these errors were encountered: