Холст drawImage масштабировать высоту и ширину в CustomPainter - PullRequest
0 голосов
/ 23 июня 2019

Я разрабатываю приложение во Flutter, где использую CustomPainter для рисования изображения, которое пользователь выбирает из галереи / камеры.В дополнение к этому использование может рисовать линии, а также самостоятельно изменять значение обводки, цвет непрозрачности и цвет.Для этого я создал 2 класса DrawEditor и DrawingPainter, код для этих двух классов можно найти ниже.Как только пользователь выбирает изображение, оно передается в класс DrawingPainter, где вызывается paint (), и я рисую свои линии и изображение.Проблема в _paintBackgroundImage (), в этом методе я рисую изображение с помощью canvas.drawImage (aintedImage, Offset.zero, Paint ());который не масштабирует изображение.

Ранее я пытался использовать другой подход вместо рисования изображения с canvas.drawImage (paintImage, Offset.zero, Paint ()). Я использовал canvas.drawImageRect (aintedImage, inputSubRect, outputSubRect, Paint ());как можно увидеть ниже.Однако при таком подходе рисованное изображение является пиксельным, поэтому я предпочитаю canvas.drawImage (paintImage, 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 }
...