上一篇 主要介绍了如何通过蓝牙连接到打印机。这一篇,我们就介绍如何向打印机发送打印指令,来打印字符和图片。

1. 构造输出流
首先要明确一点,就是蓝牙连接打印机这种场景下,手机是 Client 端,打印机是 Server 端。
在上一篇的最后,我们从 BluetoothSocket 得到了一个OutputStream。这里我们做一层包装,得到一个OutputStreamWriter 对象:
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "GBK");
这样做主要是为了后面可以直接输出字符串,不然只能输出 int 或 byte 数据;
2. 常用打印指令
手机通过蓝牙向打印机发送的都是纯字节流,那么打印机如何知道该打印的是一个文本,还是条形码,还是图片数据呢?
初始化打印机 :
在每次打印开始之前要调用该指令对打印机进行初始化。向打印机发送这条指令对应的代码就是:
protected void initPrinter() throws IOException {
writer.write(0x1B);
writer.write(0x40);
writer.flush();
}
打印文本:
没有对应指令,直接输出
protected void printText(String text) throws IOException {
writer.write(text);
writer.flush();
}
设置文本对齐方式:
对应的发送指令的代码:
/* 设置文本对齐方式
* @param align 打印位置 0:居左(默认) 1:居中 2:居右
* @throws IOException
*/
protected void setAlignPosition(int align) throws IOException {
writer.write(0x1B);
writer.write(0x61);
writer.write(align);
writer.flush();
}
与初始化指令不同的是,这条指令带有一个参数n。
换行和制表符:
直接输出对应的字符:
protected void nextLine() throws IOException {
writer.write("\n");
writer.flush();
}
protected void printTab(int length) throws IOException {
for (int i = 0; i < length; i++) {
writer.write("\t");
}
writer.flush();
}
这两个指令在打印订单详情的时候使用最多。尤其是制表符,可以让每一列的文字对齐。
设置行间距:
n表示行间距为n个像素点,最大值256
protected void setLineGap(int gap) throws IOException {
writer.write(0x1B);
writer.write(0x33);
writer.write(gap);
writer.flush();
}
这个指令在后面打印图片的时候会用到。
3. 打印图片
很多小票上面都会附上一个二维码,用户扫描之后,可以获得更多的信息。因为热敏打印机只能打印黑白两色,所以首先把图片转成纯黑白的,再调用图片打印指令进行打印。
3.1 打印图片指令
这个指令的参数很多,一个一个来说:
3.2 图片分辨率调整
如果分辨率过大,超过了打印机可打印的最大宽度,那么超出的部分将无法打印。我试验的这台最大宽度是 384 个像素点,超过这个宽度的数据无法被打印出来。所以在开始打印之前,我们需要调整图片的分辨率。代码如下:
/**
* 对图片进行压缩(去除透明度)
*
* @param bitmapOrg
*/
public static Bitmap compressPic(Bitmap bitmap) {
// 获取这个图片的宽和高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// 指定调整后的宽度和高度
int newWidth = 240;
int newHeight = 240;
Bitmap targetBmp = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
Canvas targetCanvas = new Canvas(targetBmp);
targetCanvas.drawColor(0xffffffff);
targetCanvas.drawBitmap(bitmap, new Rect(0, 0, width, height), new Rect(0, 0, newWidth, newHeight), null);
return targetBmp;
}
3.2 图片黑白化处理
因为能够打印的图像只有黑白两色,所以需要先做黑白化的处理。这一部分其实又细分为彩色图片->灰度图片,灰度图片->黑白图片两步。直接上代码:
/**
* 灰度图片黑白化,黑色是1,白色是0
*
* @param x 横坐标
* @param y 纵坐标
* @param bit 位图
* @return
*/
public static byte px2Byte(int x, int y, Bitmap bit) {
if (x < bit.getWidth() && y < bit.getHeight()) {
byte b;
int pixel = bit.getPixel(x, y);
int red = (pixel & 0x00ff0000) >> 16; // 取高两位
int green = (pixel & 0x0000ff00) >> 8; // 取中两位
int blue = pixel & 0x000000ff; // 取低两位
int gray = RGB2Gray(red, green, blue);
if (gray < 128) {
b = 1;
} else {
b = 0;
}
return b;
}
return 0;
}
/**
* 图片灰度的转化
*/
private static int RGB2Gray(int r, int g, int b) {
int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b); //灰度转化公式
return gray;
}
其中的灰度化转换公式是一个广为流传的公式,具体原理不明。我们直接看灰度转化为黑白的函数 px2Byte(int x, int y, Bitmap bit)。对于一个 Bitmap 中的任意一个坐标点,取出其 RGB 三色信息后做灰度化处理,然后对于灰度小于128的,用黑色表示,灰度大于128的,用白色表示。
3.3 逐行打印图片
其实打印图片和打印文本是一样的,也是一行一行的打印。直接上代码吧,注释已经尽量详细了。
/*************************************************************************
* 假设一个240*240的图片,分辨率设为24, 共分10行打印
* 每一行,是一个 240*24 的点阵, 每一列有24个点,存储在3个byte里面。
* 每个byte存储8个像素点信息。因为只有黑白两色,所以对应为1的位是黑色,对应为0的位是白色
**************************************************************************/
/**
* 把一张Bitmap图片转化为打印机可以打印的字节流
*
* @param bmp
* @return
*/
public static byte[] draw2PxPoint(Bitmap bmp) {
//用来存储转换后的 bitmap 数据。为什么要再加1000,这是为了应对当图片高度无法
//整除24时的情况。比如bitmap 分辨率为 240 * 250,占用 7500 byte,
//但是实际上要存储11行数据,每一行需要 24 * 240 / 8 =720byte 的空间。再加上一些指令存储的开销,
//所以多申请 1000byte 的空间是稳妥的,不然运行时会抛出数组访问越界的异常。
int size = bmp.getWidth() * bmp.getHeight() / 8 + 1000;
byte[] data = new byte[size];
int k = 0;
//设置行距为0的指令
data[k++] = 0x1B;
data[k++] = 0x33;
data[k++] = 0x00;
// 逐行打印
for (int j = 0; j < bmp.getHeight() / 24f; j++) {
//打印图片的指令
data[k++] = 0x1B;
data[k++] = 0x2A;
data[k++] = 33;
data[k++] = (byte) (bmp.getWidth() % 256); //nL
data[k++] = (byte) (bmp.getWidth() / 256); //nH
//对于每一行,逐列打印
for (int i = 0; i < bmp.getWidth(); i++) {
//每一列24个像素点,分为3个字节存储
for (int m = 0; m < 3; m++) {
//每个字节表示8个像素点,0表示白色,1表示黑色
for (int n = 0; n < 8; n++) {
byte b = px2Byte(i, j * 24 + m * 8 + n, bmp);
data[k] += data[k] + b;
}
k++;
}
}
data[k++] = 10;//换行
}
return data;
}
4. 总结
用两篇介绍了一个比较冷门的应用,纯粹是因为自己花了很多时间去搞懂原理,所以希望记录下来。尤其是图片打印部分,废了好多纸啊哈哈哈,一个字节操作错误,打印出来就是一堆乱码。感觉和 java 的 .class 文件很像,每一个指令占用多少位,每一位表示什么都是严格规定好的,不能超出也不能缺少。
最后希望能帮到需要的人吧,感觉网上这部分资料还是比较少的。也希望大家多多支持。
# android
# esc
# pos
# android蓝牙连接pos机
# Android实现PDF预览打印功能
# Android gradle插件打印时间戳的方法详解
# Android编程实现计算两个日期之间天数并打印所有日期的方法
# Android中如何安全地打印日志详解
# Mac 下 Android Studio 不打印日志的解决办法
# Android jni调试打印char阵列的实例详解
# Android下的POS打印机调用的简单实现
# Android 蓝牙连接 ESC/POS 热敏打印机打印实例(蓝牙连接篇)
# Android打印机--小票打印格式及模板设置实例代码
# Android进阶——安卓调用ESC/POS打印机打印实例
# Android手机通过蓝牙连接佳博打印机的实例代码
# Android实现系统打印功能
# 两位
# 的是
# 都是
# 是一个
# 这一
# 行间
# 尤其是
# 这部
# 这条
# 两色
# 转化为
# 热敏
# 的人
# 换行
# 打印出来
# 这是
# 是因为
# 成了
# 也没
# 最多
相关文章:
再谈Python中的字符串与字符编码(推荐)
C#如何使用XPathNavigator高效查询XML
如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法
一键制作网站软件下载安装,一键自动采集网页文档制作步骤?
制作网页的网站有哪些,电脑上怎么做网页?
济南企业网站制作公司,济南社保单位网上缴费步骤?
建站之星展会模板:智能建站与自助搭建高效解决方案
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
如何挑选高效建站主机与优质域名?
,在苏州找工作,上哪个网站比较好?
如何撰写建站申请书?关键要点有哪些?
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
如何在IIS中新建站点并配置端口与IP地址?
C#怎么创建控制台应用 C# Console App项目创建方法
宝华建站服务条款解析:五站合一功能与SEO优化设置指南
外贸公司网站制作,外贸网站建设一般有哪些步骤?
如何用IIS7快速搭建并优化网站站点?
如何快速选择适合个人网站的云服务器配置?
建站主机与虚拟主机有何区别?如何选择最优方案?
简历在线制作网站免费版,如何创建个人简历?
建站之星安装后界面空白如何解决?
制作企业网站建设方案,怎样建设一个公司网站?
官网网站制作腾讯审核要多久,联想路由器newifi官网
如何制作算命网站,怎么注册算命网站?
如何高效完成自助建站业务培训?
较简单的网站制作软件有哪些,手机版网页制作用什么软件?
Python路径拼接规范_跨平台处理说明【指导】
Android自定义listview布局实现上拉加载下拉刷新功能
如何选择高效响应式自助建站源码系统?
建站之星安装需要哪些步骤及注意事项?
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
兔展官网 在线制作,怎样制作微信请帖?
如何在Golang中使用replace替换模块_指定本地或远程路径
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
高性能网站服务器配置指南:安全稳定与高效建站核心方案
如何获取PHP WAP自助建站系统源码?
如何通过服务器快速搭建网站?完整步骤解析
如何在阿里云购买域名并搭建网站?
网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?
网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何通过宝塔面板实现本地网站访问?
微网站制作教程,不会写代码,不会编程,怎么样建自己的网站?
零服务器AI建站解决方案:快速部署与云端平台低成本实践
如何安全更换建站之星模板并保留数据?
整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?
建站之星多图banner生成与模板自定义指南
建站之星代理如何优化在线客服效率?
在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
如何快速搭建FTP站点实现文件共享?
*请认真填写需求信息,我们会在24小时内与您取得联系。