flutter 捕获小部件到图像,然后创建 PDF 文件到打印机

GPH*_*GPH 2 printing flutter

我的 flutter 应用程序将小部件捕获为图像,然后将 PDF 文件创建到打印机,但它显示如下图所示的荒谬结果。

如果您有更好的方法将汉字和qr图像打印到收据(纸宽75mm的蓝牙打印机),请告诉我

这里有小部件:

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,
            ),
          ),

        ],
      ),
    );
Run Code Online (Sandbox Code Playgroud)

这里有创建图像和pdf到打印机的功能。

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) {}
  }
Run Code Online (Sandbox Code Playgroud)

结果图片预览:

在此处输入图片说明

屏幕上的小部件是:

在此处输入图片说明

Dav*_*Dav 6

几个错误:

  • PDFPageFormat(75.0, 100.0) 是 pdf 原生尺寸。如果您想要毫米,请执行以下操作:

    PDFPageFormat(75.0 * PDFPageFormat.MM, 100.0 * PDFPageFormat.MM)
    
    Run Code Online (Sandbox Code Playgroud)
  • 声明图像时,必须传递像素大小

  • 并且图像不能是 png,而是 rawRgba 数据:

    // var img = await image.toByteData(format: ui.ImageByteFormat.rawRgba);
    PDFImage image = new PDFImage(
            pdf,
            image: img.buffer.asUint8List(),
            width: img.width,
            height: img.height);
    
    Run Code Online (Sandbox Code Playgroud)
  • pdf 坐标系在页面的左下角有 0,0 并且仍然是 pdf 单位,所以你必须使用:

    g.drawImage(image, 100.0 * PDFPageFormat.MM, 0.0, 75.0* PDFPageFormat.MM);
    
    Run Code Online (Sandbox Code Playgroud)

    第三个参数设置宽度。计算高度以保持纵横比。

    也许您将不得不调整它以使图像居中,但库页面上有一个示例。