Flutter: Как сохранить Canvas / CustomPainter в файл изображения? - PullRequest
0 голосов
/ 13 мая 2018

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

Это то, что я имею до сих пор:

import 'package:flutter/material.dart';

class SignaturePadPage extends StatefulWidget {
  SignaturePadPage({Key key}) : super(key: key);

  @override
  _SignaturePadPage createState() => new _SignaturePadPage();
}
class _SignaturePadPage extends State<SignaturePadPage> {

  List<Offset> _points = <Offset>[];

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: GestureDetector(
        onPanUpdate: (DragUpdateDetails details) {
          setState(() {
            RenderBox referenceBox = context.findRenderObject();
            Offset localPosition =
            referenceBox.globalToLocal(details.globalPosition);
            _points = new List.from(_points)..add(localPosition);
          });
        },
        onPanEnd: (DragEndDetails details) => _points.add(null),
        child: new CustomPaint(painter: new SignaturePainter(_points)),
      ),
    );
  }
}

class SignaturePainter extends CustomPainter {
  SignaturePainter(this.points);
  final List<Offset> points;
  void paint(Canvas canvas, Size size) {
    Paint paint = new Paint()
      ..color = Colors.black
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 5.0;
    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null)
        canvas.drawLine(points[i], points[i + 1], paint);
    }
  }
  bool shouldRepaint(SignaturePainter other) => other.points != points;
}

Не уверен, куда идти дальше ...

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Добавьте метод рендеринга в ваш виджет

  ui.Image get rendered {
    // [CustomPainter] has its own @canvas to pass our
    // [ui.PictureRecorder] object must be passed to [Canvas]#contructor
    // to capture the Image. This way we can pass @recorder to [Canvas]#contructor
    // using @painter[SignaturePainter] we can call [SignaturePainter]#paint
    // with the our newly created @canvas
    ui.PictureRecorder recorder = ui.PictureRecorder();
    Canvas canvas = Canvas(recorder);
    SignaturePainter painter = SignaturePainter(points: _points);
    var size = context.size;
    painter.paint(canvas, size);
    return recorder.endRecording()
        .toImage(size.width.floor(), size.height.floor());
  }

Затем с помощью состояния извлекайте рендеринг изображения

var image = signatureKey.currentState.rendered

Теперь вы можете создать png-изображение, используя toByteData(format: ui.ImageByteFormat.png), и сохранить, используя asInt8List()

var pngBytes = await image.toByteData(format: ui.ImageByteFormat.png)
File('your-path/filename.png')
    .writeAsBytesSync(pngBytes.buffer.asInt8List())

Для полного примера того, как экспортировать холст как png, посмотрите этот пример https://github.com/vemarav/signature

0 голосов
/ 13 мая 2018

Вы можете захватить выход CustomPainter с помощью PictureRecorder.Передайте ваш экземпляр PictureRecorder конструктору для вашего Canvas.Picture, возвращаемый PictureRecorder.endRecording, затем может быть преобразован в Image с Picture.toImage.Наконец, извлеките байты изображения, используя Image.toByteData.

Вот пример: https://github.com/rxlabz/flutter_canvas_to_image

...