Capturing a Canvas as an Image in Flutter Web
1,838
I reported it as a bug. It seems that the only way to do it, at least until they fix it (it's end of May 2020, for future reference), is by doing it using the HTML5 canvas:
import 'dart:html' as html;
final canvas = html.CanvasElement(width: width, height: height);
var context = canvas.context2D;
context.draw...(); // do whatever drawing you need
final blob = await canvas.toBlob('image/jpeg', 0.8);
Converting from blob to byte array can be done with this:
Future<Uint8List> _getBlobData(html.Blob blob) {
final completer = Completer<Uint8List>();
final reader = html.FileReader();
reader.readAsArrayBuffer(blob);
reader.onLoad.listen((_) => completer.complete(reader.result));
return completer.future;
}
Author by
Vasanthakumar V
Updated on December 11, 2022Comments
-
Vasanthakumar V over 1 year
I am trying to capture the content of a Canvas as an Image using PictureRecorder in Flutter Web, but have trouble in doing so
While experimenting I drew a simple circle and tried recording it, but I keep getting 'null' for the Picture recorded
import 'package:flutter_web/material.dart'; import 'package:flutter_web_ui/ui.dart' as ui; import 'dart:typed_data'; void main() => runApp(App()); class App extends StatelessWidget { void generateImage() async { final ui.Paint paint = ui.Paint() ..style = ui.PaintingStyle.stroke ..strokeWidth = 1.0; final ui.PictureRecorder recorder = ui.PictureRecorder(); final ui.Canvas pictureCanvas = ui.Canvas(recorder); pictureCanvas.drawCircle(Offset.zero, 20.0, paint); final ui.Picture picture = recorder.endRecording(); ui.Image referenceImage = picture.toImage(50, 50); ByteData img = await referenceImage.toByteData(format: ui.ImageByteFormat.png); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Column( children: <Widget>[ Padding( padding: const EdgeInsets.all(12.0), child: RaisedButton( child: Text('Generate image'), onPressed: generateImage, ), ), ], ), ), ); } }
This is the error I get in chrome console,
main.dart:24 Uncaught (in promise) TypeError: Cannot read property 'toByteData' of null at generateImage (main.dart:24) at generateImage.next (<anonymous>) at runBody (dart_sdk.js:22330) at Object.async.async (dart_sdk.js:22358) at main.App.new.generateImage (main.dart:15) at src__material__ink_well.InkWell.new.<anonymous> (main.dart:38) at _InkResponseState.new.[_handleTap] (ink_well.dart:511) at ink_well.dart:565 at src__gestures__tap.TapGestureRecognizer.new.invokeCallback (recognizer.dart:169) at src__gestures__tap.TapGestureRecognizer.new.[_checkUp] (tap.dart:251) at src__gestures__tap.TapGestureRecognizer.new.handlePrimaryPointer (tap.dart:176) at src__gestures__tap.TapGestureRecognizer.new.handleEvent (recognizer.dart:439) at src__gestures__pointer_router.PointerRouter.new.[_dispatch] (pointer_router.dart:73) at src__gestures__pointer_router.PointerRouter.new.route (pointer_router.dart:100) at src__widgets__binding.WidgetsFlutterBinding.new.handleEvent (binding.dart:223) at src__widgets__binding.WidgetsFlutterBinding.new.dispatchEvent (binding.dart:201) at src__widgets__binding.WidgetsFlutterBinding.new.[_handlePointerEvent] (binding.dart:156) at src__widgets__binding.WidgetsFlutterBinding.new.[_flushPointerEventQueue] (binding.dart:103) at src__widgets__binding.WidgetsFlutterBinding.new.[_handlePointerDataPacket] (binding.dart:87) at src__engine.PointerBinding.new.[_onPointerData] (pointer_binding.dart:80) at pointer_binding.dart:194 at HTMLElement.<anonymous> (pointer_binding.dart:135)