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