Как реализовать Flutter CustomPainter для точной визуализации поверх изображения? - PullRequest
1 голос
/ 29 марта 2020

Я плохо знаком с флаттером. Я реализую приложение для рисования поверх фотографий с помощью Custom Painter. Я могу успешно закрасить изображение, но, к сожалению, точка холста не совпадает с точкой, которую я нарисовал на предыдущем экране.

Вот суть кода файлов,
https://gist.github.com/ahsanalidev/5665f47d3393c23193881c7e32b2061f

merge_image.dart - это место, где у меня возникла проблема. paperwidget.dart и papaerpainter.dart - это место, где я добавляю смещения в список. Я искал StackOverflow, я нашел много решений для рисования в Canvas и показывал его с помощью CustomPainter, но ни одного для сохранения этих смещений с помощью устройства записи изображений, любая помощь очень ценится. Заранее спасибо.

Код для рисования на изображении

class MergedImage extends StatefulWidget {
  MergedImage({Key key, this.image, this.points, this.color}) : super(key: key);
  final File image;
  final List<PointsData> points;
  final Color color;

  @override
  _MergedImageState createState() => _MergedImageState();
}

class _MergedImageState extends State<MergedImage> {
  //ImageInfo so that I can get the Size of the picture on which i want to render custom painter
  ImageInfo myimageinfo;

  //The variable where i will save my converted image
  ui.Image myuiImage;

  //Saving my size
  Size size;

  //Convert File Image to ui.Image
  Future<ui.Image> converttoImage() {
    Uint8List imageBytes = widget.image.readAsBytesSync();
    final Completer<ui.Image> completer = new Completer();
    ui.decodeImageFromList(imageBytes, (ui.Image img) {
      return completer.complete(img);
    });
    return completer.future;
  }

  //Method for getting the dimensons of the image
  Future<ImageInfo> getImageDimensions() {
    Completer<ImageInfo> completer = Completer();
    FileImage(widget.image)
        .resolve(new ImageConfiguration())
        .addListener(ImageStreamListener((ImageInfo info, bool _) {
      completer.complete(info);
    }));
    return completer.future;
  }



  //Method that will paint the image 
  Future<ByteData> getPaintedImage() async {
    final Completer<ByteData> completer = Completer();
    final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
    final Canvas canvas = Canvas(pictureRecorder);
    await Future.wait([converttoImage(), getImageDimensions()]).then((val) {
      myimageinfo = val[1];
      myuiImage = val[0];
      Paint paint = Paint()
        ..color = widget.color ?? Color(0xFFFFFFFF)
        ..strokeCap = StrokeCap.round
        ..strokeWidth = 5.0;
      Rect rect = Offset(0, 0) &
          Size((myimageinfo.image.width).toDouble(),
              myimageinfo.image.height.toDouble());
      paintImage(
          canvas: canvas, image: myuiImage, rect: rect, fit: BoxFit.cover);

      //  canvas.drawImage(myuiImage, Offset(0, 0), paint);

      for (int i = 0; i < widget.points.length - 1; i++) {
        if (widget.points[i] != null && widget.points[i + 1] != null) {
          paint.color = widget.points[i].pen.color;
          canvas.drawLine(
              Offset(widget.points[i].offset.dx, widget.points[i].offset.dy),
              Offset(widget.points[i + 1].offset.dx,
                  widget.points[i + 1].offset.dy),
              paint);
        }
      }

      size = Size((myimageinfo.image.width).toDouble(),
          myimageinfo.image.height.toDouble());
    });

    final ui.Image image = await pictureRecorder
        .endRecording()
        .toImage(myimageinfo.image.width, myimageinfo.image.height);

    final ByteData byteData =
        await image.toByteData(format: ui.ImageByteFormat.png);
    completer.complete(byteData);
    return completer.future;
  }

  void showDelayedImageDialog() {
    (getPaintedImage()).then((result) {
      myImage = result;

      showPreviewDialog(myImage.buffer.asUint8List());
    });
  }

  ByteData myImage = ByteData(10);

  void showPreviewDialog(Uint8List image) {
    showDialog(
      context: context,
      builder: (ctx) => GestureDetector(
        onTap: () => Navigator.pop(context),
        child: Container(
          color: Colors.grey.withOpacity(0.5),
          child: Center(
            child: Container(
              child: Image.memory(image),
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: RaisedButton(
        onPressed: () async {
          showDelayedImageDialog();
        },
      )),
    );
  }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...