android pos机打印

来源:互联网 发布:rar解压王 for mac 编辑:程序博客网 时间:2024/05/15 23:47

    研究了好几天的pos机打印,终于搞好了,在此做个笔记。第一次写博客 ,如有不对,望提出。

 由于pos机可打印多种类型图片,我打印的是光栅位图,另外pos机也可打印其他多种类型图片,在此只说明光栅位图的打印。
  
  给pos机传的都是16进制,所以以下指令都是16进制的字符串。
  先贴出我用到的打印机指令:
  
String MIDDLE="1B 61 01"; //居中String LEFT="1B 61 00";  //靠左String LINE="0A";  //换行


 居中、靠左、换行这几个指令对于文本和图片都是可用的

 下面是打印光栅位图的指令:

String i1 = "1D";String i2 = "76";String i3 ="30";String i4 ="00" ; String xL;String xH;String yL;String yH;

以上指令中:i4值可 根据需求制定:0普通模式,1倍宽模式,2倍高模式,3四倍大小

                   xL+xH*256=图片的宽/8  

                  yL+yH*256=图片的高

为什么这里宽要除8呢?  

一个像素点需要把自己的信息传递给pos机,信息中1代表打印 0代表不打印,而1byte=8bit;一个像素点是一个byte; 需要用8位二进制传递信息,传给打印机的时候8位二进制会转成高位和低位的十六进制.

对于这个的理解我也不是很透彻,还不太理解的自行百度.


有了以上指令就可以pos机打印啦 直接贴代码

打印文本: 

StringBuffer sb=new StringBuffer();sb.append(MIDDLE).append(title).append(LINE)        .append(LEFT).append(name).append(LINE)        .append(time).append(LINE)        .append(money).append(LINE);

以上代码居中命令在需要居中的文本之前调用,靠左只需调用一次,pos机默认靠左, title,name,time,money是需要打印的信息 这些信息也是需要转成十六进制滴

文本信息转十六进制代码:

/** * 字符串转换为16进制字符 */public  static String str2HexStr(String str){    char[] chars = "0123456789ABCDEF".toCharArray();    StringBuilder sb = new StringBuilder("");    byte[] bs = new byte[0];    try {        bs = str.getBytes("GBK");    } catch (UnsupportedEncodingException e) {        e.printStackTrace();    }    int bit;    for (int i = 0; i < bs.length; i++)    {        bit = (bs[i] & 0x0f0) >> 4;            sb.append(chars[bit]);        bit = bs[i] & 0x0f;          sb.append(chars[bit]);        sb.append(' ');    }    return sb.toString().trim();}

通过以上就拿到文本的16进制字符串,当然打印机需要的是16进制字节, 16进制字符串转16进制byte数组代码在文章最后


打印图片:

//打印机打印图片指令  xl+xh*256= yl+yh*256=int width= bitmap.getWidth()/8;int height=bitmap.getHeight();int   xl=width%256;  //低位取余 高位取商int   xh=width/256;int   yl=height%256;  int   yh=height/256;

xl,xh,yl,yh在这里还是十进制的 需要转成十六进制, 十进制转十六进制代码:

//10进制转16进制public static String IntToHex(int n){        char[] ch = new char[20];        int nIndex = 0;        while ( true ){            int m = n/16;                int k = n%16;                if ( k == 15 )                       ch[nIndex] = 'F';                else if ( k == 14 )                        ch[nIndex] = 'E';                else if ( k == 13 )                        ch[nIndex] = 'D';                else if ( k == 12 )                        ch[nIndex] = 'C';               else if ( k == 11 )                        ch[nIndex] = 'B';                else if ( k == 10 )                        ch[nIndex] = 'A';                else                    ch[nIndex] = (char)('0' + k);               nIndex++;                if ( m == 0 )                        break;                n = m;            }        StringBuffer sb = new StringBuffer();        sb.append(ch, 0, nIndex);        sb.reverse();        String result=sb.toString();    if(result.length()==1){        result="0"+result;    }        return result;    }

现在打印图片的头指令有了,后面再加上图片的数据就可以了  图片转byte :

   public static byte[] sendBWImage(Bitmap img, Context ctx) {        int width = img.getWidth();         //获取位图的宽        int height = img.getHeight();       //获取位图的高        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组        img.getPixels(pixels, 0, width, 0, 0, width, height);        int[] gray=new int[height*width];        for (int i = 0; i < height; i++) {            for (int j = 0; j < width; j++) {                int grey = pixels[width * i + j];                int red = ((grey  & 0x00FF0000 ) >> 16);                gray[width*i+j]=red;            }        }        //551        int e=0;        int byteLen = width/8;        byte[] result=new byte[byteLen*height];        int k=0;        for (int i = 0; i < height; i++) {            byte[] bt = new byte[byteLen];            for (int j = 0; j < width; j++) {                int g=gray[width*i+j];                int byteIndex = j/8;                int bitIndex = j%8;                if (g>=128) {                    pixels[width*i+j]=0xffffffff;                    e=g-255;                }else {                    pixels[width*i+j]=0xff000000;                    if(j < byteLen*8){                        bt[byteIndex] += 1<<(7-bitIndex);                    }                    e=g-0;                }                if (j<width-1&&i<height-1) {//右边像素处理                    gray[width*i+j+1]+=3*e/8; //                    gray[width*(i+1)+j]+=3*e/8;//右下                    gray[width*(i+1)+j+1]+=e/4;                }else if (j==width-1&&i<height-1) {//靠右或靠下边s的像素的情况                    //下方像素处理                    gray[width*(i+1)+j]+=3*e/8;                }else if (j<width-1&&i==height-1) {                    //右边像素处理                    gray[width*(i)+j+1]+=e/4;                }            }            for(int m=0;m<bt.length;m++){                result[k++]=bt[m];            }        }                Bitmap mBitmap=Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);//        ImageUtils.saveMyBitmap("0001", mBitmap);        return result;    }


现在头指令和图片数据都有了 怎么把String类型的16进制和byte类型的结合在一起呢?

16进制字符串转byte数组代码:

/** * 将指定字符串src,以每两个字符分割转换为16进制形式 如:"2B44EFD9" –> byte[]{0x2B, 0×44, 0xEF, * 0xD9} * * @param src *            String * @return byte[] */public static byte[] HexString2Bytes(String src) {    if (null == src || 0 == src.length()) {        return null;    }    byte[] ret = new byte[src.length() / 2];    byte[] tmp = src.getBytes();    for (int i = 0; i < (tmp.length / 2); i++) {        ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);    }    return ret;}/** * 将两个ASCII字符合成一个字节; 如:"EF"–> 0xEF * * @param src0 *            byte * @param src1 *            byte * @return byte */public static byte uniteBytes(byte src0, byte src1) {    byte _b0 = Byte.decode("0x" + new String(new byte[] {src0})).byteValue();    _b0 = (byte) (_b0 << 4);    byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 })).byteValue();    byte ret = (byte) (_b0 ^ _b1);    return ret;}

把16进制字节发给打印机就ok了.


第一次写博客 排版可能不太好  望谅解 有不对的地方多谢指出.




0 0
原创粉丝点击