Reputation: 1161
I'm using qr_flutter to create QrImage. It's ok but I would like to convert QrImage into image in order to create a PDF file to print on the printer. Please kindly help!
QrImage(
data: qrString,
size: 300.0,
version: 10,
backgroundColor: Colors.white,
),
Upvotes: 4
Views: 9858
Reputation: 29320
A more updated typed answer, that adds responsibility seggregation and null-safety, extending the correct one from @Zroq would be:
Future<Uint8List> createImageFromRenderKey({GlobalKey<State<StatefulWidget>>? renderKey}) async {
try {
final RenderRepaintBoundary boundary = renderKey?.currentContext?.findRenderObject()! as RenderRepaintBoundary;
final ui.Image image = await boundary.toImage(pixelRatio: 3);
final ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
return byteData!.buffer.asUint8List();
} catch(_) {
rethrow;
}
}
The idea is based on the same principle: using the global render key to create the ByteData
that allows you to create the Uint8List
buffer. However, the new versions of Flutter change the type of the boundary to become a RenderyObject?
instead of a RenderRepaintBoundary
.
The rethrow
is (dirty) way of bypassing the limitation/small bug where RepaintBoundary
may be being used in the UI to repaint the boundary (exposed as boundary.debugNeedsPaint
), so it can potentially throw an unhandled exception or create a low-quality image buffer. So if the view is being used I rethrow the method.
More details about the stack trace: https://github.com/theyakka/qr.flutter/issues/112
Upvotes: 1
Reputation: 503
Future<Uint8List> toQrImageData(String text) async {
try {
final image = await QrPainter(
data: text,
version: QrVersions.auto,
gapless: false,
color: hexToColor('#000000'),
emptyColor: hexToColor('#ffffff'),
).toImage(300);
final a = await image.toByteData(format: ImageByteFormat.png);
return a.buffer.asUint8List();
} catch (e) {
throw e;
}
}
Upvotes: 8
Reputation: 8382
Use a RepaintBoundary
widget with a key to export the widget to a a b64 string which then you can export as an image.
Example:
Future<Uint8List> _getWidgetImage() async {
try {
RenderRepaintBoundary boundary =
_renderObjectKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
ByteData byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
var pngBytes = byteData.buffer.asUint8List();
var bs64 = base64Encode(pngBytes);
debugPrint(bs64.length.toString());
return pngBytes;
} catch (exception) {}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: [
RepaintBoundary(
key: _renderObjectKey,
child: QrImage(
data: "some text",
size: 300.0,
version: 10,
backgroundColor: Colors.white,
),
),
RaisedButton(onPressed: () {
_getWidgetImage();
})
]));
}
Upvotes: 13