Android 蓝牙打印指令

您所在的位置:网站首页 支持蓝牙打印机的手机软件 Android 蓝牙打印指令

Android 蓝牙打印指令

2024-07-07 14:16| 来源: 网络整理| 查看: 265

一、概述

目前打印打印机支持的无线打印方式一般为wifi和蓝牙。

蓝牙打印关于蓝牙连接部分请查看上篇文章 -> Android 蓝牙连接 ,本篇文章讨论Android中蓝牙打印的指令实现。

蓝牙打印机的种类繁多,支持的打印格式也不尽相同。按照指令集划分,主要可分为:ESC指令集、CPCL指令集。

大部分热敏打印机使用的ESC指令集。部分支持CPCL指令集。

二、ESC指令

指令一览表:

常用打印指令:

1、初始化

2、设置文本对齐方式

3、设置行间距

1)默认行间距

2)指定行间距

4、设定字符打印模式

5、打印图片

参数说明:

m:取值十进制 0、1、32、33。设置打印精度,0、1对应每行8个点,32、33对应每行24个点,对应最高的打印精度(其实这里也没太搞清楚取值0、1或者取值32、33的区别,只要记住取值33,对应每行24个点,后面还有用)n1, n2 : 表示图片的宽度,为什么有两个?其实只是分成了高位和低位两部分,因为每部分只有8bit,最大表示256。所以 n1 = 图片宽度 % 256,n2 = 图片宽度 / 256。假设图片宽300,那么n1=1,n2=44d1 d2 ... dk 这部分就是转换成字节流的图像数据了

更多ESC指令详情跳转 ->  ESC/POS 打印控制命令

需要注意的是:在实际打印中,图片的分辨率需要调整,宽度(每行像素点数)不能超出打印机可支持范围。所以图片需要做一下压缩处理,同时,由于打印图片是黑白的,所以需要灰度转化对图片进行黑白化处理。

 

此处贴出一个ESC打印工具类,未使用到的指令可以依照指令表实现。

public class PrinterManagerForESC extends PrinterManager{ private OutputStreamWriter writer = null; private OutputStream outputStream = null; public PrinterManagerForESC(OutputStream outputStream, String encoding) throws IOException { writer = new OutputStreamWriter(outputStream, encoding); this.outputStream = outputStream; initPrinter(); } //初始化 protected void initPrinter() throws IOException { writer.write(0x1B); writer.write(0x40); completeFlush(); } public void completeFlush() throws IOException { writer.flush(); } public void printString(String str){ try { writer.write(str); completeFlush(); } catch (IOException e) { e.printStackTrace(); } } @Override void printStrWithAlign(String value, int alignment) { try { writer.write(0x1b); writer.write(0x61); writer.write(alignment); writer.write(value); writer.write("\n"); completeFlush(); } catch (IOException e) { e.printStackTrace(); } } /** * 打印分割线 */ public void printSeparateLine(int paperpoints){ String res = ""; int count = Math.round(paperpoints/12); for (int i=0; i< count; i++){ res = res + "-"; if (i== (count-1)){ res = res + "\n"; } } printString(res); } private void printBytes(byte[] bytes){ try { outputStream.write(bytes); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } public void printBitmap(Bitmap bitmap, int paperwidth) throws IOException { Bitmap resizeBitmap = compressPic(bitmap,paperwidth); byte[] bmpByteArray = draw2PxPoint(resizeBitmap); printBytes(bmpByteArray); } /** * 打印换行 * * @return length 需要打印的换行数 * @throws IOException */ public void printNextLine(int lineNum) { try { for (int i = 0; i < lineNum; i++) { writer.write("\n"); } writer.flush(); } catch (IOException e) { e.printStackTrace(); } } /************************************************************************* * 假设一个360*360的图片,分辨率设为24, 共分15行打印 每一行,是一个 360 * 24 的点阵,y轴有24个点,存储在3个byte里面。 * 即每个byte存储8个像素点信息。因为只有黑白两色,所以对应为1的位是黑色,对应为0的位是白色 **************************************************************************/ private byte[] draw2PxPoint(Bitmap bmp) { //计算所需字节空间大小 int bitmapsize = (int) (Math.ceil(bmp.getHeight() / 24f)) * bmp.getWidth() * 3; int cmdsize = (int) (Math.ceil(bmp.getHeight() / 24f)) * 6 + 5; int size = bitmapsize + cmdsize; byte[] tmp = new byte[size]; int k = 0; // 设置行距为0 tmp[k++] = 0x1B; tmp[k++] = 0x33; tmp[k++] = 0x00; for (int j = 0; j < bmp.getHeight() / 24f; j++) { tmp[k++] = 0x1B; tmp[k++] = 0x2A;// 0x1B 2A 表示图片打印指令 tmp[k++] = 33; // m=33时,选择24点密度打印 tmp[k++] = (byte) (bmp.getWidth() % 256); // nL tmp[k++] = (byte) (bmp.getWidth() / 256); // nH for (int i = 0; i < bmp.getWidth(); i++) { for (int m = 0; m < 3; m++) { for (int n = 0; n < 8; n++) { byte b = px2Byte(i, j * 24 + m * 8 + n, bmp); tmp[k] += tmp[k] + b; } k++; } } tmp[k++] = 10;// 换行 } // 恢复默认行距 tmp[k++] = 0x1B; tmp[k++] = 0x32; byte[] result = new byte[k]; System.arraycopy(tmp, 0, result, 0, k); return result; } /** * 图片二值化,黑色是1,白色是0 * * @param x 横坐标 * @param y 纵坐标 * @param bit 位图 * @return */ private 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 int RGB2Gray(int r, int g, int b) { int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b); // 灰度转化公式 return gray; } public byte[] getGbkStr(String stText) { byte[] returnText = null; try { returnText = stText.getBytes("GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return returnText; } private int getStringPixLength(String str) { int pixLength = 0; char c; for (int i = 0; i < str.length(); i++) { c = str.charAt(i); if (Pinyin.isChinese(c)) { pixLength += 24; } else { pixLength += 12; } } return pixLength; } /** * 图片压缩 */ public static Bitmap compressPic(Bitmap bitmap, int paperwidth) { // 获取这个图片的宽和高 int width = bitmap.getWidth(); int height = bitmap.getHeight(); int newWidth = paperwidth; int newHeight = Math.round ( height * newWidth / width); 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; } }

三、CPCL指令

常用指令:

1、打印机起始命令

2、打印命令

3、结束命令

4、文本命令

5、图片命令

更多CPCL指令文档跳转 -> CPCL指令集 

 

此处贴出一个CPCL指令工具类,未实现的指令可按照文档实现。

public class PrinterManagerForCPCL extends PrinterManager{ private OutputStreamWriter writer = null; private OutputStream outputStream = null; private String dpi; private StringBuffer buffer; public PrinterManagerForCPCL(OutputStream outputStream, String encoding, String dpi) throws IOException { writer = new OutputStreamWriter(outputStream,encoding); this.outputStream = outputStream; this.dpi = dpi; this.buffer = new StringBuffer(""); } //开始指令 public void beginInstruction(int height) throws IOException { // {offset} {hegiht} {qty} buffer = new StringBuffer(""); String begincmd = "! 0 " + dpi + " " + dpi + " " + height + " " + 1 + "\r\n"; buffer.append(begincmd); } //结束指令 public void endInstructionFlush() throws IOException { buffer.append("FORM\r\n"); buffer.append("PRINT\r\n"); byte[] res = buffer.toString().getBytes(); outputStream.write(res); outputStream.flush(); } public void endPrintForStr() throws IOException { buffer.append("PRINT\r\n"); byte[] res = buffer.toString().getBytes("GBK"); outputStream.write(res); outputStream.flush(); } public void printString(String str){ try { writer.write(str); completeFlush(); } catch (IOException e) { e.printStackTrace(); } } public void completeFlush() throws IOException { writer.flush(); } /** * 打印CPCL字符串 */ public void printCPCLString(String data) throws IOException { //TEXT(或T) {font} {size} {x} {y} {data} String strCmd = "TEXT " + 1 + " " + 0 + " " + 0 + " " + 0 + " " + data + "\r\n"; buffer.append(strCmd); } /** * 打印图片 * * @param bitmap * @throws IOException */ public void printImage(Bitmap bitmap){ int loopWidth = 8 - (bitmap.getWidth() % 8); if (loopWidth == 8) { loopWidth = bitmap.getWidth(); } else { loopWidth += bitmap.getWidth(); } buffer.append("EG "+ (loopWidth / 8) + " "+ bitmap.getHeight() + " 0 0 "+""); for (int y = 0; y < bitmap.getHeight(); y++) { int bit = 128; int currentValue = 0; for (int x = 0; x < loopWidth; x++) { int intensity; if (x < bitmap.getWidth()) { int color = bitmap.getPixel(x, y); intensity = 255 - ((Color.red(color) + Color.green(color) + Color.blue(color)) / 3); } else { intensity = 0; } if (intensity >= 128) currentValue |= bit; bit = bit >> 1; if (bit == 0) { String hex = IntegerToHexString(currentValue); buffer.append(hex.toUpperCase() + " "); bit = 128; currentValue = 0; } } } buffer.append("\r\n"); } private String IntegerToHexString(int data) { String s = Integer.toHexString(data); return s.length() < 2 ? s = "0" + s : s; } public void printSeparateLine(int paperpoints){ String res = ""; int count = Math.round(paperpoints / 12); for (int i = 0; i < count; i++) { res = res + "-"; if (i == (count - 1)) { res = res + "\n"; } } printString(res); } @Override void printStrWithAlign(String value, int alignment) { try { //居中特殊处理 if (1 == alignment){ beginInstruction(24); buffer.append("CENTER\r\n"); printCPCLString(value); endPrintForStr(); }else { writer.write(value); writer.write("\n"); completeFlush(); } } catch (IOException e) { e.printStackTrace(); } } private void printBytes(byte[] bytes) { try { outputStream.write(bytes); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } /** * 打印换行 * * @return length 需要打印的换行数 * @throws IOException */ public void printNextLine(int lineNum){ try { for (int i = 0; i < lineNum; i++) { writer.write("\r\n"); } writer.flush(); } catch (IOException e) { e.printStackTrace(); } } public byte[] getGbkStr(String stText) { byte[] returnText = null; try { returnText = stText.getBytes("GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return returnText; } private int getStringPixLength(String str) { int pixLength = 0; char c; for (int i = 0; i < str.length(); i++) { c = str.charAt(i); if (Pinyin.isChinese(c)) { pixLength += 24; } else { pixLength += 12; } } return pixLength; } /** * 图片压缩 * @param bitmap */ public static Bitmap compressPic(Bitmap bitmap, int paperwidth) { // 获取这个图片的宽和高 int width = bitmap.getWidth(); int height = bitmap.getHeight(); int newWidth = paperwidth; int newHeight = Math.round ( height * newWidth / width); 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; } }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3