问题
My flutter app captures the widget to image and then creates PDF file to printer, but it shows ridiculous result as below picture.
Let me know if you have any better method to print Chinese character and qr image to a receipt (bluetooth printer with paper width 75mm)
Here with the widget:
RepaintBoundary(
key: _renderObjectKey,
child: ListView(
children: <Widget>[
Form(
key: tableNumberFormKey,
child:
ListTile(
title: TextFormField(
initialValue: "",
style: TextStyle(fontSize: 48.0),
textAlign: TextAlign.center,
maxLength: 4,
keyboardType: TextInputType.phone,
onSaved: (val) => inputTableNumber = val.toString(),
validator: (val) => val.isEmpty ? '' : null,
decoration: new InputDecoration(
labelText: "輸入檯號",
hintText: "例如:12",
),
),
),
),
FlatButton(
textColor: Colors.blueAccent,
child: Text(
"列印 QR CODE",
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0),
),
color: Colors.transparent,
onPressed: () {
_showQRandPrint();
SystemChannels.textInput.invokeMethod('TextInput.hide');
},
),
inputTableNumber == ""
? ListTile(title: Text(''),)
: Center(
child: QrImage(
data: qrString,
size: 300.0,
version: 10,
backgroundColor: Colors.white,
),
),
],
),
);
Here with the function to create image and pdf to printer.
void _showQRandPrint() {
final FormState form = tableNumberFormKey.currentState;
if (form.validate()) {
form.save();
_getWidgetImage().then((img) {
final pdf = new PDFDocument();
final page = new PDFPage(pdf, pageFormat: PDFPageFormat(75.0, 100.0));
final g = page.getGraphics();
final font = new PDFFont(pdf);
PDFImage image = new PDFImage(
pdf,
image: img,
width: 75,
height: 100);
g.drawImage(image, 0.0, 0.0);
Printing.printPdf(document: pdf);
});
}
else {
setState(() {
inputTableNumber = "";
});
}
}
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) {}
}
result picture preview:
The widget on the screen is:
回答1:
Few errors:
PDFPageFormat(75.0, 100.0) is in pdf native dimensions. If you want milimeters, do:
PDFPageFormat(75.0 * PDFPageFormat.MM, 100.0 * PDFPageFormat.MM)
When you declare an image, you have to pass the pixel size
And the image cannot be png, but rawRgba data:
// var img = await image.toByteData(format: ui.ImageByteFormat.rawRgba); PDFImage image = new PDFImage( pdf, image: img.buffer.asUint8List(), width: img.width, height: img.height);
the pdf coordinate system has 0,0 at the bottom left corner of the page and still in pdf units so you have to use:
g.drawImage(image, 100.0 * PDFPageFormat.MM, 0.0, 75.0* PDFPageFormat.MM);
the third parameter set the width. the height is calculated to keep the aspect ratio.
maybe you will have to adapt this to center the image, but there is an example on the library page.
来源:https://stackoverflow.com/questions/53089690/flutter-capture-the-widget-to-image-and-then-create-pdf-file-to-printer