android ESC/POS兼容指令集 蓝牙打印图片和图片叠加水印

来源:互联网 发布:友情 知乎 编辑:程序博客网 时间:2024/05/21 09:45

这段时间在搞蓝牙打印,文字打印还好处理,图片打印真心坑爹!

这里手机和蓝牙的连接方式就不做过多的介绍!只说下具体的蓝牙打印图片

环境:android4.03

蓝牙打印机:VMP02-PB为蓝牙便携式微型打印机

打印指令集:ESC/POS兼容指令集 

第一步 读取图片  图片在选取的时候 要注意一点 一定要是黑白纯色的图片  

BufferedInputStream bis = new BufferedInputStream(getAssets()      .open("stamp.bmp"));Bitmap bitmap = BitmapFactory.decodeStream(bis);
这里说下,同样的图片如果使用BitmapFactory.decodeResource(res, id);来创建Bitmap 位图宽高都会变成原图的2倍。所以使用流读取的方式从资源文件夹读取。

在这里我把图片给剪切为 宽高都为 322大小的像素。这是要注意的一点! 

第二步  发送打印图片前导指令

byte[] start = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B,0x40, 0x1B, 0x33, 0x00 };

这个是查看开发文档 获取的前导指令数组,这里就不过多的介绍了。想了解详细的童鞋可以查看ESC/POS兼容指令集 

第三步 解析图片获取打印数据  这是最关键的一步  具体看下边代码  方法有点长 将就这把!没拆

/**解析图片 获取打印数据**/private byte[] getReadBitMapBytes(Bitmap bitmap) {/***图片添加水印**/bitmap = createBitmap(bitmap);byte[] bytes = null;  //打印数据int width = bitmap.getWidth();int height = bitmap.getHeight();System.out.println("width=" + width + ", height=" + height);int heightbyte = (height - 1) / 8 + 1;int bufsize = width * heightbyte;int m1, n1;        byte[] maparray = new byte[bufsize];                byte[] rgb = new byte[3];                int []pixels = new int[width * height]; //通过位图的大小创建像素点数组                bitmap.getPixels(pixels, 0, width, 0, 0, width, height);        /**解析图片 获取位图数据**/for (int j = 0;j < height; j++) {for (int i = 0; i < width; i++) {int pixel = pixels[width * j + i]; /**获取RGB值**/int r = Color.red(pixel);int g = Color.green(pixel);int b = Color.blue(pixel);//System.out.println("i=" + i + ",j=" + j + ":(" + r + ","+ g+ "," + b + ")");rgb[0] = (byte)r;rgb[1] = (byte)g;rgb[2] = (byte)b; if (r != 255 || g != 255 || b != 255){//如果不是空白的话用黑色填充    这里如果童鞋要过滤颜色在这里处理                      m1 = (j / 8) * width + i;                     n1 = j - (j / 8) * 8;                     maparray[m1] |= (byte)(1 << 7 - ((byte)n1));                 }}}byte[] b = new byte[322];int line = 0;int j = 0;ByteArrayOutputStream baos = new ByteArrayOutputStream();/**对位图数据进行处理**/for (int i = 0; i < maparray.length; i++) {b[j] = maparray[i];j++;if (j == 322) {  /**  322图片的宽 **/if (line < ((322 - 1) / 8)) {byte[] lineByte = new byte[329];byte nL = (byte) 322;byte nH = (byte) (322 >> 8);int index = 5;/**添加打印图片前导字符  每行的 这里是8位**/lineByte[0] = 0x1B;lineByte[1] = 0x2A;lineByte[2] = 1;lineByte[3] = nL;lineByte[4] = nH;/**copy 数组数据**/System.arraycopy(b, 0, lineByte, index, b.length);lineByte[lineByte.length - 2] = 0x0D;lineByte[lineByte.length - 1] = 0x0A;baos.write(lineByte, 0, lineByte.length);try {baos.flush();} catch (IOException e) {e.printStackTrace();}line++;}j = 0;}}bytes = baos.toByteArray();return bytes;}
下面附上添加水印方法

 // 给图片添加水印      private Bitmap createBitmap(Bitmap src) {          Time t = new Time();          t.setToNow();           int w = src.getWidth();          int h = src.getHeight();          String mstrTitle = t.year + " 年 " + (t.month +1) + " 月 " + t.monthDay+" 日";          Bitmap bmpTemp = Bitmap.createBitmap(w, h, Config.ARGB_8888);          Canvas canvas = new Canvas(bmpTemp);          Paint p = new Paint();          String familyName = "宋体";          Typeface font = Typeface.create(familyName, Typeface.BOLD);          p.setColor(Color.BLACK);          p.setTypeface(font);          p.setTextSize(33);          canvas.drawBitmap(src, 0, 0, p);          canvas.drawText(mstrTitle, 20, 310, p);          canvas.save(Canvas.ALL_SAVE_FLAG);          canvas.restore();          return bmpTemp;      } 

第四步:发送结束指令 要不发送完图片在打印字符的时候会乱码.

// 发送结束指令byte[] end = { 0x1d, 0x4c, 0x1f, 0x00 };

附上demo链接地址   http://download.csdn.net/detail/whyisjava/5016186