flutter如何实现图片加马赛克
实现些功能的原理就是将图片缩小到十几分之一的大小,然后利用ImageShader再将缩小后的图片放大到原图大小,然后进行绘制即可。 在放大和缩小的时候,关键的地方就在于采样方式
只能使用FilterQuality.none 不然达不到想要的效果。
下面看具体实现代码,代码中也有一些重要地方的注释,完整代码就不展示了,只展示关键的地方。
import 'dart:ui' as ui;
...
...
...
ui.Image? image;
ui.Image? moasicImg;
init(String picFilepath)async{
//加载图片
var list = await File(picFilepath).readAsBytes();
ui.Codec codec = await ui.instantiateImageCodec(list);
ui.FrameInfo frame = await codec.getNextFrame();
image = frame.image;
//缩小图片,生成moasicImg
int targetWidth = image!.width / 15;
int targetHeight = image!.height / 15;
PictureRecorder pictureRecorder = PictureRecorder();
Canvas canvas = Canvas(pictureRecorder);
//要设置这个filter 为none
FilterQuality filterQuality = FilterQuality.none;
canvas.drawImageRect(
image,
Rect.fromLTWH(0, 0, image!.width.toDouble(), image!.height.toDouble()),
Rect.fromLTWH(0, 0, targetWidth.toDouble(), targetHeight.toDouble()),
Paint()
..isAntiAlias = fasle
..filterQuality = filterQuality);
Picture picture = pictureRecorder.endRecording();
moasicImg = await picture.toImage(targetWidth, targetHeight);
picture.dispose();
}
...
...
...
//手指划的点
List<Offset> pointList = [];
void onDraw(Canvas canvas){
Paint imgShaderPaint = Paint();
var matrix = Matrix4.identity();
matrix.scale(15, 15);
//将缩小的图片设置给ImageShader 然后使用Matrix4将其放大为原图的大小,这里注意,一定要使用FilterQuality.none
imgShaderPaint.shader = ImageShader(
moasicImg!, TileMode.clamp, TileMode.clamp, matrix.storage,
filterQuality: FilterQuality.none);
imgShaderPaint.strokeWidth = size;
imgShaderPaint.strokeJoin = StrokeJoin.round;
imgShaderPaint.strokeCap = StrokeCap.round;
imgShaderPaint.style = PaintingStyle.stroke;
Path path = Path();
for (int i = 0; i < pointList.length; i++) {
Offset point = pointList[i];
if (i == 0) {
path.moveTo(point.dx, point.dy);
} else {
path.lineTo(point.dx, point.dy);
}
}
canvas.save();
canvas.drawPath(path, imgShaderPaint);
canvas.restore();
}
...
...
...
//这样效果就出来了。
版权声明:本文为凸然网站的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:flutter如何实现图片加马赛克