Flutter工具类插件yjy_esc_utils的使用

Flutter工具类插件yjy_esc_utils的使用

ESC_Utils

小票打印机 ESC 数据转换工具,主要用于将 image 图像转换成小票打印机可识别的字节数组。

内部图像处理使用 image: ^3.0.2

使用示例

esc_utils: ^0.0.1
1. 获取图片数据转 Uint8List
// 通过文件路径获取图片
static Future<Uint8List> getImage(String imgPath) async {
  final imgFile = File(imgPath);
  final exist = await imgFile.exists();
  if(exist) {
    return imgFile.readAsBytes();
  } else {
    throw Exception('print imgFile is not exist');
  }
}
2. Unit8List 转 ESC 字节数组
import 'package:image/image.dart' as img;

// unit8List 转 esc 字节数组
static Future<List<int>> decodeBytes(Uint8List imgData) async {
  final img.Image image = await cropImage(imgData);
  Generator generator = Generator();
  List<int> bytes = [];
  // 打印机状态重置
  bytes += generator.reset();
  // 打印光栅位图
  bytes += generator.imageRaster(image);
  // 走纸 2mm
  bytes += generator.feed(2);
  // 切刀
  bytes += generator.cut();
  return bytes;
}

注意事项

  1. 通常不会把一整张图片直接发给打印机,那样太大。都会分割成小图片逐个发送。比如数据太大导致打印机内存溢出输出乱码。
  2. 小票机,目前常用尺寸为 80mm、58mm。通常 1mm 等于 8个像素,因此,适合小票打印机打印的图片像素尺寸应为:558px、372px。(因为宽度适配在实际打印中有偏差,不宜设置为完全吻合)
  3. 打印的图片宽度像素太大会造成打印无反应。

长图切割为多张小图示例

static Future<List<img.Image>> decodeImage(
    Uint8List imgData, {
    int imgSizeLimit = 550 * 1000,
  }) async {
    final img.Image crop = await cropImage(imgData);
    final cropWidth = crop.width;
    img.Image targetImg = crop;
    // 缩放处理,保持图片宽度能被8整除
    if (cropWidth % 8 != 0) {
      targetImg = await resizeImage(
        crop,
        targetWidth: cropWidth ~/ 8 * 8,
        targetHeight: crop.height,
      );
    }
    final targetWidth = targetImg.width;
    final targetHeight = targetImg.height;
    final result = <img.Image>[];
    if (targetWidth * targetHeight > imgSizeLimit) {
      LogTool.log('esc 长图开启切割');
      int splitItemHeight = imgSizeLimit ~/ targetWidth;

      int splitCount = targetHeight ~/ splitItemHeight;

      int lastItemHeight = targetHeight % splitItemHeight;

      for (int index = 0; index < splitCount; index++) {
        final splitItem = img.copyCrop(
          targetImg,
          0,
          splitItemHeight * index,
          targetWidth,
          splitItemHeight,
        );
        result.add(splitItem);
      }
      LogTool.log(
          '切图 * $splitCount 份 width($targetWidth) height($splitItemHeight)');

      if (lastItemHeight > 0) {
        final lastItem = img.copyCrop(
          crop,
          0,
          splitItemHeight * splitCount,
          targetWidth,
          lastItemHeight,
        );
        result.add(lastItem);
        LogTool.log('切图 * 1 份 width($targetWidth) height($lastItemHeight)');
      }
    } else {
      result.add(crop);
      LogTool.log('esc 无需切割 width($targetWidth) height($targetHeight)');
    }
    return result;
  }

更多关于Flutter工具类插件yjy_esc_utils的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter工具类插件yjy_esc_utils的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


yjy_esc_utils 是一个用于处理 ESC/POS 打印指令的 Flutter 插件。它可以帮助开发者生成适用于 ESC/POS 打印机的指令,并支持通过蓝牙、WiFi 或 USB 连接打印机进行打印。

安装

首先,你需要在 pubspec.yaml 文件中添加 yjy_esc_utils 依赖:

dependencies:
  flutter:
    sdk: flutter
  yjy_esc_utils: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

使用指南

1. 导入包

import 'package:yjy_esc_utils/yjy_esc_utils.dart';

2. 创建 ESC/POS 指令

yjy_esc_utils 提供了多种方法来生成 ESC/POS 指令。以下是一些常见的操作:

初始化打印机
List<int> initializePrinter() {
  return EscPosUtils.init();
}
设置文本样式
List<int> setTextStyle({bool bold = false, bool underline = false, bool doubleHeight = false, bool doubleWidth = false}) {
  return EscPosUtils.textStyle(bold: bold, underline: underline, doubleHeight: doubleHeight, doubleWidth: doubleWidth);
}
设置对齐方式
List<int> setAlignment(TextAlign align) {
  return EscPosUtils.textAlign(align);
}
打印文本
List<int> printText(String text) {
  return EscPosUtils.text(text);
}
打印换行
List<int> printLineFeed([int lines = 1]) {
  return EscPosUtils.lineFeed(lines);
}
打印二维码
List<int> printQRCode(String data, {int size = 4}) {
  return EscPosUtils.qrCode(data, size: size);
}
打印条形码
List<int> printBarcode(String data, {BarcodeType type = BarcodeType.CODE128}) {
  return EscPosUtils.barcode(data, type: type);
}
切纸
List<int> cutPaper() {
  return EscPosUtils.cut();
}

3. 连接打印机并发送指令

你可以使用 Flutter 的蓝牙、WiFi 或 USB 插件来连接打印机,并将生成的 ESC/POS 指令发送给打印机。

以下是一个简单的示例,展示如何通过蓝牙连接打印机并发送指令:

import 'package:flutter/material.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:yjy_esc_utils/yjy_esc_utils.dart';

class PrintPage extends StatefulWidget {
  [@override](/user/override)
  _PrintPageState createState() => _PrintPageState();
}

class _PrintPageState extends State<PrintPage> {
  BluetoothConnection? _connection;

  [@override](/user/override)
  void initState() {
    super.initState();
    _connectToPrinter();
  }

  void _connectToPrinter() async {
    // 搜索并连接打印机
    BluetoothDevice? device = // 选择你的打印机设备
    BluetoothConnection.toAddress(device.address).then((connection) {
      setState(() {
        _connection = connection;
      });
    });
  }

  void _printReceipt() {
    if (_connection == null) return;

    List<int> bytes = [];
    bytes.addAll(EscPosUtils.init());
    bytes.addAll(EscPosUtils.textAlign(TextAlign.center));
    bytes.addAll(EscPosUtils.text('收据示例\n'));
    bytes.addAll(EscPosUtils.text('商品1\t\t10元\n'));
    bytes.addAll(EscPosUtils.text('商品2\t\t20元\n'));
    bytes.addAll(EscPosUtils.lineFeed(2));
    bytes.addAll(EscPosUtils.cut());

    _connection!.output.add(Uint8List.fromList(bytes));
    _connection!.output.allSent.then((_) {
      print('打印完成');
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('打印收据'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _printReceipt,
          child: Text('打印'),
        ),
      ),
    );
  }
}
回到顶部