问题描述
我想裁剪一个矩形图像文件,使其成为圆形、正方形或六边形,然后将其保存为本地图像文件.我有一个位图,我想从这个位图中裁剪一个圆形或六边形区域.圆圈外的所有像素都应该是透明的.我该怎么做?
我在
将图像画布保存为 png
完整源代码:
导入 'dart:io';导入包:颤振/material.dart";导入 'dart:ui' 作为 ui;导入 'package:flutter/services.dart' 显示 rootBundle;导入飞镖:异步";导入'dart:typed_data';导入飞镖:数学"作为数学;导入包:路径/path.dart";导入'包:path_provider/path_provider.dart';类 CustomImageCanvas 扩展 StatefulWidget {CustomImageCanvas({Key key, this.title}) : super(key: key);最终字符串标题;@覆盖_CustomImageCanvasState createState() =>_CustomImageCanvasState();}类 _CustomImageCanvasState 扩展状态<CustomImageCanvas>{ui.Image图像;布尔 isImageloaded = false;无效初始化状态(){super.initState();在里面();}未来<空>初始化()异步{最终 ByteData 数据 = 等待 rootBundle.load('assets/image.jpeg');图像 = 等待 loadImage(Uint8List.view(data.buffer));}未来<ui.Image>loadImage(Listimg) 异步 {最终完成者<ui.Image>完成者 = 完成者();ui.decodeImageFromList(img, (ui.Image img) {设置状态((){isImageloaded = true;});返回完成者.完成(img);});返回完成者.future;}小部件 _buildImage() {如果(this.isImageloaded){返回自定义油漆(画家:PngImagePainter(图像:图像),);} 别的 {返回中心(子:文本('正在加载'));}}@覆盖小部件构建(BuildContext 上下文){返回脚手架(应用栏:应用栏(标题:文本(widget.title),),身体:容器(孩子:_buildImage(),));}}类 PngImagePainter 扩展 CustomPainter {PngImagePainter({这个图片,});ui.Image图像;@覆盖无效油漆(帆布画布,尺寸大小){_drawCanvas(大小,画布);_saveCanvas(大小);}画布_drawCanvas(大小,画布画布){最终中心 = 偏移量(150, 50);最终半径 = math.min(size.width, size.height)/8;//圆圈应该在之前绘制,否则它会被路径隐藏油漆paintCircle = Paint()..color = Colors.black;绘制paintBorder = Paint()..color = 颜色.white..strokeWidth = size.width/36..style = 绘画风格.stroke;canvas.drawCircle(中心,半径,paintCircle);canvas.drawCircle(中心,半径,paintBorder);双drawImageWidth = 0;var drawImageHeight = -size.height * 0.8;路径 path = Path()..addOval(Rect.fromLTWH(drawImageWidth, drawImageHeight,image.width.toDouble(), image.height.toDouble()));canvas.clipPath(路径);canvas.drawImage(图像,偏移量(drawImageWidth,drawImageHeight),Paint());返回画布;}_saveCanvas(大小)异步{var pictureRecorder = ui.PictureRecorder();var canvas = Canvas(pictureRecorder);var 油漆 = 油漆();paint.isAntiAlias = true;_drawCanvas(大小,画布);var pic = pictureRecorder.endRecording();ui.Image img = await pic.toImage(image.width, image.height);var byteData = await img.toByteData(格式: ui.ImageByteFormat.png);var buffer = byteData.buffer.asUint8List();//var response = await get(imgUrl);var documentDirectory = 等待 getApplicationDocumentsDirectory();文件 file = File(join(documentDirectory.path,'${DateTime.now().toUtc().toIso8601String()}.png'));file.writeAsBytesSync(缓冲区);打印(文件.路径);}@覆盖bool shouldRepaint(CustomPainter oldDelegate) {返回假;}}
I want to crop a rectangular image-file and make it circular or square or hexagon shape and save it as image-file locally. I have a bitmap and I want to crop a circular or hexagon region from this bitmap. All pixels outside the circle should be transparent. How can I do this?
I found the similar question in android platform. But unable to find a good resource that really help or direct me to achieve this in flutter. Please share me the idea to achieve this result.
These simple steps get the required result.
- Create a PictureRecorder.
- Create a Canvas with your PictureRecorder.
- Draw circle in canvas using canvas.drawCircle().
- Call endRecording() on the PictureRecorder to get a Picture.
- Call toImage() on the Picture.
- Convert image toByteData() .
- Save image locally using getApplicationDocumentsDirectory().
Canvas Screen
Saved Image Canvas as png
Full Source Code:
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:async';
import 'dart:typed_data';
import 'dart:math' as math;
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
class CustomImageCanvas extends StatefulWidget {
CustomImageCanvas({Key key, this.title}) : super(key: key);
final String title;
@override
_CustomImageCanvasState createState() => _CustomImageCanvasState();
}
class _CustomImageCanvasState extends State<CustomImageCanvas> {
ui.Image image;
bool isImageloaded = false;
void initState() {
super.initState();
init();
}
Future<Null> init() async {
final ByteData data = await rootBundle.load('assets/image.jpeg');
image = await loadImage(Uint8List.view(data.buffer));
}
Future<ui.Image> loadImage(List<int> img) async {
final Completer<ui.Image> completer = Completer();
ui.decodeImageFromList(img, (ui.Image img) {
setState(() {
isImageloaded = true;
});
return completer.complete(img);
});
return completer.future;
}
Widget _buildImage() {
if (this.isImageloaded) {
return CustomPaint(
painter: PngImagePainter(image: image),
);
} else {
return Center(child: Text('loading'));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: _buildImage(),
));
}
}
class PngImagePainter extends CustomPainter {
PngImagePainter({
this.image,
});
ui.Image image;
@override
void paint(Canvas canvas, Size size) {
_drawCanvas(size, canvas);
_saveCanvas(size);
}
Canvas _drawCanvas(Size size, Canvas canvas) {
final center = Offset(150, 50);
final radius = math.min(size.width, size.height) / 8;
// The circle should be paint before or it will be hidden by the path
Paint paintCircle = Paint()..color = Colors.black;
Paint paintBorder = Paint()
..color = Colors.white
..strokeWidth = size.width / 36
..style = PaintingStyle.stroke;
canvas.drawCircle(center, radius, paintCircle);
canvas.drawCircle(center, radius, paintBorder);
double drawImageWidth = 0;
var drawImageHeight = -size.height * 0.8;
Path path = Path()
..addOval(Rect.fromLTWH(drawImageWidth, drawImageHeight,
image.width.toDouble(), image.height.toDouble()));
canvas.clipPath(path);
canvas.drawImage(image, Offset(drawImageWidth, drawImageHeight), Paint());
return canvas;
}
_saveCanvas(Size size) async {
var pictureRecorder = ui.PictureRecorder();
var canvas = Canvas(pictureRecorder);
var paint = Paint();
paint.isAntiAlias = true;
_drawCanvas(size, canvas);
var pic = pictureRecorder.endRecording();
ui.Image img = await pic.toImage(image.width, image.height);
var byteData = await img.toByteData(format: ui.ImageByteFormat.png);
var buffer = byteData.buffer.asUint8List();
// var response = await get(imgUrl);
var documentDirectory = await getApplicationDocumentsDirectory();
File file = File(join(documentDirectory.path,
'${DateTime.now().toUtc().toIso8601String()}.png'));
file.writeAsBytesSync(buffer);
print(file.path);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
这篇关于如何在 Flutter 中从画布上裁剪圆形(或方形或六边形)区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2