Флаттер захватывает виджет для изображения, а затем создает PDF-файл на принтер - PullRequest
0 голосов
/ 31 октября 2018

Мое приложение флаттера захватывает виджет для изображения, а затем создает PDF-файл на принтере, но показывает нелепый результат, как показано на рисунке ниже.

Дайте мне знать, если у вас есть какой-либо лучший способ печати китайских иероглифов и изображений в квитанции (Bluetooth-принтер с шириной бумаги 75 мм)

Здесь с виджетом:

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

        ],
      ),
    );

Здесь с функцией создания изображения и 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) {}
  }

просмотр изображения результата:

enter image description here

Виджет на экране:

enter image description here

1 Ответ

0 голосов
/ 11 ноября 2018

Несколько ошибок:

  • PDFPageFormat (75.0, 100.0) в собственном формате pdf. Если вы хотите миллиметры, сделайте:

    PDFPageFormat(75.0 * PDFPageFormat.MM, 100.0 * PDFPageFormat.MM)
    
  • Когда вы объявляете изображение, вам нужно передать размер пикселя

  • И изображение не может быть 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);
    
  • Система координат PDF имеет 0,0 в левом нижнем углу страницы и все еще в единицах PDF поэтому вы должны использовать:

    g.drawImage(image, 100.0 * PDFPageFormat.MM, 0.0, 75.0* PDFPageFormat.MM);
    

    третий параметр задает ширину. высота рассчитывается для сохранения соотношения сторон.

    возможно, вам придется адаптировать это для центрирования изображения, но есть пример на странице библиотеки .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...