我正在使用自定义画家在图像上绘制,绘制后,我想保存绘制的图像,我该怎么做?,我认为我应该将记录器传递给画布,但在这种情况下,我使用的是覆盖绘制函数的画布,我不知道如何将记录器传递给画布。
import 'dart:ui';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:image/image.dart' as IMG;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:async';
import 'dart:typed_data';
void main() {
runApp(App());
}
class App extends StatelessWidget {
const App({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ui.Image image;
// IMG.Image image;
bool isImageLoaded = false;
GlobalKey _myCanvasKey = GlobalKey();
ImageEditor editor;
void initState() {
super.initState();
init();
}
Future<Null> init() async {
final ByteData data =
await rootBundle.load('assets/images/prescription.jpeg');
image = await loadImage(Uint8List.view(data.buffer));
editor = ImageEditor(image: image);
}
Future<ui.Image> loadImage(List<int> data) async {
final IMG.Image image = IMG.decodeImage(data);
final IMG.Image resized = IMG.copyResize(image, width: 380, height: 500);
final List<int> resizedBytes = IMG.encodePng(resized);
final Completer<ui.Image> completer = Completer();
ui.decodeImageFromList(
resizedBytes, (ui.Image img) => completer.complete(img));
setState(() {
isImageLoaded = true;
});
return completer.future;
}
Widget _buildImage() {
if (isImageLoaded) {
return CustomPaint(
key: _myCanvasKey,
painter: editor,
);
} else {
return Center(child: Text('loading'));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
GestureDetector(
onPanDown: (detailData) {
editor.update(detailData.localPosition);
_myCanvasKey.currentContext
.findRenderObject()
.markNeedsPaint();
},
onPanUpdate: (detailData) {
editor.update(detailData.localPosition);
_myCanvasKey.currentContext
.findRenderObject()
.markNeedsPaint();
},
child: Container(
width: 380,
height: 500,
color: Colors.white,
child: _buildImage())),
SizedBox(
height: 25,
),
Container(
width: 120,
child: ElevatedButton(
onPressed: () async {
final pngBytes =
await image.toByteData(format: ImageByteFormat.png);
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => SecondScreen(
image: pngBytes,
)));
},
child: Text("Send")))
],
),
);
}
}
class ImageEditor extends CustomPainter {
ImageEditor({
this.image,
});
ui.Image image;
List<Offset> points = List();
final Paint painter = Paint()
..color = Colors.blue[400]
..style = PaintingStyle.fill;
void update(Offset offset) {
points.add(offset);
}
@override
void paint(Canvas canvas, Size size) {
canvas.drawImage(image, Offset(0.0, 0.0), Paint());
for (Offset offset in points) {
canvas.drawCircle(offset, 10, painter);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class SecondScreen extends StatelessWidget {
final ByteData image;
SecondScreen({Key key, this.image}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Image.memory(Uint8List.view(image.buffer)),
);
}
}