【发布时间】:2019-11-05 09:57:12
【问题描述】:
我正在 Flutter 中开发一个应用程序,我正在使用 CustomPainter 绘制用户从图库/相机中选择的图像。除此之外,用户还可以自己绘制线条以及更改笔触值、不透明度颜色和颜色。为此,我创建了 2 个类 DrawEditor 和 DrawingPainter,这两个类的代码可以在下面找到。一旦用户选择了一张图片 图像被传递给调用paint() 的DrawingPainter 类,然后我绘制线条和图像。问题出在 _paintBackgroundImage() 中,我使用 canvas.drawImage(paintedImage, Offset.zero, Paint()); 绘制图像这不会缩放图像。
之前我尝试了一种不同的方法,而不是使用 canvas.drawImage(paintedImage, Offset.zero, Paint()) 绘制图像,我使用了 canvas.drawImageRect(paintedImage, inputSubRect, outputSubRect, Paint());如下所示。但是使用这种方法,绘制图片是像素化的,所以我更喜欢 canvas.drawImage(paintedImage, Offset.zero, Paint()) 因为这不会损坏图片。
任何有关缩放图像的帮助将不胜感激。
//Example 1 : Code with canvas.drawImageRect but image pixelated
final UI.Rect rect = UI.Offset.zero & _canvasSize;
final Size imageSize =Size(paintedImage.width.toDouble(), paintedImage.height.toDouble());
FittedSizes sizes = applyBoxFit(BoxFit.contain, imageSize, _canvasSize);
final Rect inputSubRect =
Alignment.center.inscribe(sizes.source, Offset.zero & imageSize);
final Rect outputSubRect =
Alignment.center.inscribe(sizes.destination, rect);
canvas.drawImageRect(paintedImage, inputSubRect, outputSubRect, Paint());
//Example 2 : Code with canvas.drawImageRect but image pixelated
canvas.drawRect(Rect.fromPoints(blurStartOffset, blurIndicatorOffset),
blurPaintSettings)
class DrawingPainter extends CustomPainter {
static int blurColor = 0xFFB3E5FC;
UI.Image paintedImage;
List<DrawingPoints> pointsList;
List<DrawingPoints> blurPointsList;
List<Offset> offsetPoints = List();
Size _canvasSize;
Offset blurIndicatorOffset;
Offset blurStartOffset;
bool isBlur;
List<BlurIndicatorOffsetWrapper> wrapperList = new List();
/// To blur an image we need a [MaskFilter]
Paint blurPaintSettings = new Paint()
..style = PaintingStyle.fill
..color = Color(blurColor)
..maskFilter = MaskFilter.blur(BlurStyle.normal, 3.0);
DrawingPainter(
{this.pointsList,
this.paintedImage,
this.blurPointsList,
this.blurIndicatorOffset,
this.blurStartOffset}) {
isBlur = blurIndicatorOffset != null;
}
@override
void paint(Canvas canvas, Size size) {
_canvasSize = size;
_paintBackgroundImage(canvas);
_drawPoints(canvas);
_drawBlurIndicator(canvas);
}
/// Paints the image onto the canvas
void _paintBackgroundImage(Canvas canvas) {
if (paintedImage == null) {
return;
}
final UI.Rect rect = UI.Offset.zero & _canvasSize;
final Size imageSize =
Size(paintedImage.width.toDouble(), paintedImage.height.toDouble());
FittedSizes sizes = applyBoxFit(BoxFit.contain, imageSize, _canvasSize);
final Rect inputSubRect =
Alignment.center.inscribe(sizes.source, Offset.zero & imageSize);
final Rect outputSubRect =
Alignment.center.inscribe(sizes.destination, rect);
canvas.drawImageRect(paintedImage, inputSubRect, outputSubRect, Paint());
}
/// Paints the lines onto the canvas
void _drawPoints(Canvas canvas) {
for (int i = 0; i < pointsList.length - 1; i++) {
if (pointsList[i] != null && pointsList[i + 1] != null) {
canvas.drawLine(pointsList[i].points, pointsList[i + 1].points,
pointsList[i].paint);
}
}
}
/// Paints the blur indicator onto the canvas
void _drawBlurIndicator(Canvas canvas) {
if (blurStartOffset != null && blurIndicatorOffset != null) {
canvas.drawRect(Rect.fromPoints(blurStartOffset, blurIndicatorOffset),
blurPaintSettings);
}
}
void setBlurIndicator(Offset localOffset) {
blurIndicatorOffset = localOffset;
}
@override
bool shouldRepaint(DrawingPainter oldDelegate) {
return true;
}
Future<Uint8List> save() async {
//Create canvas
// Set PictureRecorder on the canvas and start recording
UI.PictureRecorder recorder = UI.PictureRecorder();
Canvas canvas = Canvas(recorder);
//Draw image on new canvas
if (paintedImage != null) {
final Size imageSize = Size(paintedImage.width.toDouble(), paintedImage.height.toDouble());
//Here image is the problem
canvas.drawImage(paintedImage, Offset.zero, Paint());
}
//Draw points on new canvas
for (int i = 0; i < pointsList.length - 1; i++) {
if (pointsList[i] != null && pointsList[i + 1] != null) {
canvas.drawLine(
pointsList[i].points,
pointsList[i + 1].points,
pointsList[i].paint,
);
}
}
//End recording
final resultImage = await recorder.endRecording().toImage(
_canvasSize.width.floor(),
_canvasSize.height.floor(),
);
final imageBytes =
await resultImage.toByteData(format: UI.ImageByteFormat.png);
return imageBytes.buffer.asUint8List();
}
}
class DrawingPoints {
Paint paint;
Offset points;
DrawingPoints({this.points, this.paint});
}
enum SelectedMode { StrokeWidth, Opacity, Color, Blur }
【问题讨论】:
-
使用来自
painting库的顶级paintImage函数 -
你好@pskink 谢谢你的评论可以分享。我可以关注一些示例代码或链接,我不太清楚你的意思。
-
我的意思是paintImage函数-在这里你可以使用
rect、fit、alignment、filterQuality和许多其他参数 -
感谢@pskink 它可以工作,在画布上图像没有像素化,但是当我保存这是图像像素化的地方时,我认为 toImage() 方法是原因:(。
-
当然,欢迎您