web-dev-qa-db-fra.com

Flutter: Comment enregistrer un Canvas / CustomPainter dans un fichier image?

J'essaie de collecter une signature de l'utilisateur et de l'enregistrer dans une image. Je l'ai fait assez loin pour pouvoir dessiner sur l'écran, mais maintenant je voudrais cliquer sur un bouton pour enregistrer dans une image et le stocker dans ma base de données.

Voici ce que j'ai jusqu'à présent:

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;
}

Je ne sais pas où aller à partir de là ...

9
Jus10

Vous pouvez capturer la sortie d'un CustomPainter avec PictureRecorder . Passez votre instance PictureRecorder au constructeur de votre Canvas . Le Picture retourné par PictureRecorder.endRecording peut ensuite être converti en Image avec Picture.toImage . Enfin, extrayez les octets d'image à l'aide de Image.toByteData .

Voici un exemple: https://github.com/rxlabz/flutter_canvas_to_image

8
jspcal

Ajoutez la méthode rendue dans votre widget

  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());
  }

Ensuite, en utilisant l'état récupérer l'image rendue

var image = signatureKey.currentState.rendered

Maintenant, vous pouvez produire une image png en utilisant toByteData(format: ui.ImageByteFormat.png) et stocker en utilisant asInt8List()

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

Pour un exemple complet, sur la façon d'exporter le canevas au format png, consultez cet exemple https://github.com/vemarav/signature

5
Aravind Vemula