微信小程序连接蓝牙打印机示例

小程序连接蓝牙打印机打印文本与二维码等示例在 github 上都能找到一些,唯独打印图片这个案例几乎没有。希望能帮助到有打印图片需求的小伙伴。
测试打印机:凯盛诺 PTP-II-UBC 58mm 便携热敏打印机
测试环境有:Android微信 , IOS微信;其中 Android 和 IOS 在打印文本与二维码速率相对一致,但 IOS 打印图片几乎慢到无法打印的情况(听说蓝牙打印机在 IOS 中受限制,需要与 IOS 合作授权,在斑马品牌的一款打印机用 IOS 就能打印出来。即使是 Android ,小程序打印图片比打印文本会慢许多,并不是打印机的问题,而是小程序只能使用低功率蓝牙,受限在一次发送 20 个字节的数据,需要分段递归发送,图片数据可以达到几万、几十万个字节。)
打印机指令类型:ESC/POS 指令集 (打印机产家都会提供对应的指令文档,此 demo 中使用十进制的数据格式的指令,十六进制的指令或者更多指令的使用方式可以参考另一个示例小程序蓝牙打印 miniprogram-bluetoothprinter)
示例功能
连接蓝牙打印机
打印文本 (打印中文出现乱码,因为打印机默认的编码是 GB2312,需要将 UTF-8 转 GB2312,这里用的轻小的GBK 库,也可以使用text-encoding)
打印二维码(使用指令打印内置二维码样式,或者用图片方式打印定制二维码)
打印任意图片(此示例的重点, canvas 绘制图片,wx.canvasGetImageData()取得 Uint8ClampedArray后再转成位图数据,使用图片水平取模数据打印指令打印位图数据)
效果图




Demo 中连接打印机的流程
关于找蓝牙设备中能用的 Characteristic,这里贴出对应的代码,关注注释部分
图片来源
在 Demo 中手机选任意一张图片用 canvas 绘制,wx.canvasGetImageData()取得 Uint8ClampedArray 类型的图像像素点数据。
位图数据
需要把 Uint8ClampedArray 类型的数据转成打印机识别的点阵位图数据(也可以让后台实现图片转位图数据,参考热敏打印机编程 ESC/POS 指令)。
不同打印机厂家的指令集可能不同,但打印图片的位图数据是一样的。
贴出递归发送二进制数据到蓝牙的代码
贴出发送逐行图片数据的代码
主要参考
微信低功率蓝牙
小程序蓝牙打印 miniprogram-bluetoothprinter
热敏打印机编程 ESC/POS 指令