Android 热敏打印机打印二维码

Android 关于佳博和汉印蓝牙热敏打印机开发 PrinterHelper.Text(PrinterHelper.TEXT, “8”, “0”, “0”, “130”, “啦啦啦”);PrinterHelper.Text(PrinterHelper.TEXT, “3”, “0”, “0”, “160”, “啦啦啦”);PrinterHelper.Text(PrinterHelper.TEXT, “3”, “0”, “0”, “190”, “啦啦啦”);/* 设置标签间隙,按照实际尺寸设置,如果为无间隙纸则设置为0 *//* 设置打印方向 */ 阅读详情
      最近项目需要研究下Android通过usbhost和蓝牙连接热敏打印机打印小票,收集了一下资料参考,感觉这块技术比较乱的,每家打印机都有自己的SDK,但其实底层的原理差不多,做个稳定兼容多个品牌热敏打印机的APP还是有难度的。


  昨天晚上说抽时间来写一篇关于Android 热敏打印机打印二维码和图片的文章,所幸在下班之前把它给写了,和大家分享吧。我的是Android机器有内置热敏打印机的,我是把apk跑在我的Android机器上的,操作程序打印的。

  一、打印机的型号

  RP-POS80S或RP-POS80P或RP-POS80CS或RP-POS80CP打印机 高速热敏打印机
  打印方式:直接热敏打印
  打印密度:640点/行
  打印纸宽:80mm
  有效打印宽度:72mm
  最小走纸距离:0.125mm
  打印字符
  ACSII码字符集:12×24点
  国标一、二级汉字字库:24×24点
  采用命令集:ESC/POS打印命令集

  二、打印位图命令

     ESC *m nL nH d1...dk
     [名称]   选择位图模式
     [格式]   ASCII码   ESC  *       m nL nH d1...dk
     十六进制码    1B   2A   m nL nH d1...dk
     十进制码   27  42   m nL nH d1...dk
     [范围]   m= 0, 1, 32, 33
     0 £ nL£ 255
     0 £ nH£ 3
     0 £ d£ 255



[描述]用 m选择位图的模式,位图的点数由 nL和 nH指定,如下所示:
  
m
  
模式
垂直方向
水平方向
点数
点密度
点密度
数据个数 (K)
0
8-点 单密度
8
67.7 dpi
101.6 dpi
nL+ nH´ 256
1
8-点 双密度
8
67.7 dpi
203.2 dpi
nL+ nH´ 256
32
24-点 单密度
24
203.2 dpi
101.6 dpi
(nL+ nH ´ 256) ´3
33
24-点 双密度
24
203.2 dpi
203.2 dpi
(nL+ nH ´ 256) ´3

Dpi:每25.4毫米{1英寸}打印点数

[注意]
·如果m的值超出了指定的范围,那么nL和之后的数据被当作常规数据处理。
· nL和 nH表示水平方向上位图中的点数。通过nL+ nH´ 256计算出点数。
· 如果位图数据输入超出了一行上能被打印的点数,那么超出的数据被忽略。
· d表示位图数据。设置相应的位为 1去打印某点,或设置为 0以不打印某点。
· 如果用GS L 和 GSW 设置的打印范围的宽度比用ESC *命令 发送的数据所要求的宽度小时,则对有问题的行执行下列操作(但是打印不能超出最大可打印范围):

① 打印区域的宽度向右扩展以去适应数据量。
② 如果步骤①不能为数据提供足够的宽度,那么左边缘就被减少以去适应数据。对于在单密度模式(m= 0, 32)中的数据的每一位,打印机打印两个点:对于在双密度模式(m= 1, 33)中的数据的每一位,打印机打印一个点。在计算一行中能打印的数据量时,这些必须要考虑。

· 在打印一个位图之后,打印机返回常规数据处理模式。
· 这个命令不被打印模式(粗体、重叠、下划线、字符大小、或反白打印)影响, 除非是颠倒打印模式。
· 下图描述了图象数据与被打印的点之间的关系。

8-点位图被选定时

:

三、思路

因为所做的是打印图片(或者是二维码) ,先发送一个请求,从网络下载图片或者是二维码,得到这张图片过后,进行压缩到你想要的大小,在对压缩后的图片进行二值化,即黑白化,但是图片本身会有个α的值(即透明度)的问题,如果不进行处理的话,即使是黑白化的图片,得到图片的像素点也不是很精确。对于去透明度处理过后,在对这张图的每个最标点去像素值,即xxx  X  xxx大的图片,会有xxx X xxx个像素点。求出每个像素点的r、g、b的值,通过换算公式进行换算,得到一个像素值(0-255之间)。
如果是0-128是黑色,129-255是白色(非黑即白化),这样每个点的像素值就可以确定了。

因为我的热敏打印机是24*24的,所以会是24个像素点为一组,假设我把图片压缩为360*360像素的大小,就会有15组(纵向的15行,横坐标还是360)。一组的有24*360的像素点,因为8位是一个字节,这样24个像素点可以分为3组,每8位组成一个字节,每个像素点不是0就是1(之前已经非黑即白过),这样会得到一个byte数组,如:byte[] b1 = {1, 0, 0, 1, 0, 0, 0, 1}; 在将这样的数组换成十进制的数值int v1;这样就会得到3*15*360个的int 值,在将这些int的值和打印机的打印头命令拼接起来,组成一个byte[] 数组,就可以打印了。

四、注意

1.热敏打印机是一行一行的打印,所以每一行又得加上打印的头命令,我的打印机头命令是5个,所以byte[]数组的长度会是3*15*360+5*15

2.大家看好自己打印机的打印密度,比如我的是24*24的,所以我剪裁图片的大小会是24的倍数,360*360.大家最好也剪裁成相应的倍数,这样计算会方便点,不然的话,要对空白区域进行白色补缺。

贴代码
  1. package com.woyou.util;

  2. import android.graphics.Bitmap;
  3. import android.graphics.Canvas;
  4. import android.graphics.Matrix;
  5. import android.graphics.Rect;
  6. import android.util.Log;

  7. /**
  8. * 将图片转化为二进制
  9. * @author nsz
  10. * 2015年1月30日
  11. */
  12. public class PicFromPrintUtils {
  13.         
  14.         
  15.         public void init(){
  16. //                Gray = 0.29900 * R + 0.58700 * G + 0.11400 * B
  17.         }
  18.         
  19.         /*************************************************************************
  20.          * 我们的热敏打印机是RP-POS80S或RP-POS80P或RP-POS80CS或RP-POS80CP打印机
  21.          * 360*360的图片,8个字节(8个像素点)是一个二进制,将二进制转化为十进制数值
  22.          * y轴:24个像素点为一组,即360就是15组(0-14)
  23.          * x轴:360个像素点(0-359)
  24.          * 里面的每一组(24*360),每8个像素点为一个二进制,(每组有3个,3*8=24)
  25.          **************************************************************************/
  26.         /**
  27.          * 把一张Bitmap图片转化为打印机可以打印的bit(将图片压缩为360*360)
  28.          * 效率很高(相对于下面)
  29.          * @param bit
  30.          * @return
  31.          */
  32.         public static byte[] draw2PxPoint(Bitmap bit) {    
  33.                 byte[] data = new byte[16290];
  34.                 int k = 0;
  35.                 for (int j = 0; j < 15; j++) {
  36.                         data[k++] = 0x1B;
  37.                         data[k++] = 0x2A;
  38.                         data[k++] = 33; // m=33时,选择24点双密度打印,分辨率达到200DPI。
  39.                         data[k++] = 0x68;
  40.                         data[k++] = 0x01;
  41.                         for (int i = 0; i < 360; i++) {
  42.                                 for (int m = 0; m < 3; m++) {
  43.                                         for (int n = 0; n < 8; n++) {
  44.                                                 byte b = px2Byte(i, j * 24 + m * 8 + n, bit);
  45.                                                 data[k] += data[k] + b;
  46.                                         }
  47.                                         k++;
  48.                                 }
  49.                         }
  50.                         data[k++] = 10;
  51.                 }
  52.                 return data;
  53.         }
  54.         
  55.         /**
  56.          * 把一张Bitmap图片转化为打印机可以打印的bit
  57.          * @param bit
  58.          * @return
  59.          */
  60.         public static byte[] pic2PxPoint(Bitmap bit){
  61.                 long start = System.currentTimeMillis();
  62.                 byte[] data = new byte[16290];
  63.                 int k = 0;
  64.                 for (int i = 0; i < 15; i++) {
  65.                         data[k++] = 0x1B;
  66.                         data[k++] = 0x2A;
  67.                         data[k++] = 33; // m=33时,选择24点双密度打印,分辨率达到200DPI。
  68.                         data[k++] = 0x68;
  69.                         data[k++] = 0x01;
  70.                         for (int x = 0; x < 360; x++) {
  71.                                 for (int m = 0; m < 3; m++) {
  72.                                         byte[]  by = new byte[8];
  73.                                         for (int n = 0; n < 8; n++) {
  74.                                                 byte b = px2Byte(x, i * 24 + m * 8 +7-n, bit);
  75.                                                 by[n] = b;
  76.                                         }
  77.                                         data[k] = (byte) changePointPx1(by);
  78.                                         k++;
  79.                                 }
  80.                         }
  81.                         data[k++] = 10;
  82.                 }
  83.                 long end = System.currentTimeMillis();
  84.                 long str = end - start;
  85.                 Log.i("TAG", "str:" + str);
  86.                 return data;
  87.         }
  88.         
  89.         /**
  90.          * 图片二值化,黑色是1,白色是0
  91.          * @param x  横坐标
  92.          * @param y         纵坐标                        
  93.          * @param bit 位图
  94.          * @return
  95.          */
  96.         public static byte px2Byte(int x, int y, Bitmap bit) {
  97.                 byte b;
  98.                 int pixel = bit.getPixel(x, y);
  99.                 int red = (pixel & 0x00ff0000) >> 16; // 取高两位
  100.                 int green = (pixel & 0x0000ff00) >> 8; // 取中两位
  101.                 int blue = pixel & 0x000000ff; // 取低两位
  102.                 int gray = RGB2Gray(red, green, blue);
  103.                 if ( gray < 128 ){
  104.                         b = 1;
  105.                 } else {
  106.                         b = 0;
  107.                 }
  108.                 return b;
  109.         }
  110.         
  111.         /**
  112.          * 图片灰度的转化
  113.          * @param r  
  114.          * @param g
  115.          * @param b
  116.          * @return
  117.          */
  118.         private static int RGB2Gray(int r, int g, int b){
  119.                 int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b);  //灰度转化公式
  120.                 return  gray;
  121.         }
  122.         
  123.         /**
  124.          * 对图片进行压缩(去除透明度)
  125.          * @param bitmapOrg
  126.          */
  127.         public static Bitmap compressPic(Bitmap bitmapOrg) {
  128.                 // 获取这个图片的宽和高
  129.                 int width = bitmapOrg.getWidth();
  130.                 int height = bitmapOrg.getHeight();
  131.                 // 定义预转换成的图片的宽度和高度
  132.                 int newWidth = 360;
  133.                 int newHeight = 360;
  134.                 Bitmap targetBmp = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);  
  135.                 Canvas targetCanvas = new Canvas(targetBmp);
  136.                 targetCanvas.drawColor(0xffffffff);
  137.                 targetCanvas.drawBitmap(bitmapOrg, new Rect(0, 0, width, height), new Rect(0, 0, newWidth, newHeight), null);
  138.                 return targetBmp;
  139.         }
  140.         
  141.         
  142.         /**
  143.          * 对图片进行压缩(不去除透明度)
  144.          * @param bitmapOrg
  145.          */
  146.         public static Bitmap compressBitmap(Bitmap bitmapOrg) {
  147.                 // 加载需要操作的图片,这里是一张图片
  148. //                Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.alipay);
  149.                 // 获取这个图片的宽和高
  150.                 int width = bitmapOrg.getWidth();
  151.                 int height = bitmapOrg.getHeight();
  152.                 // 定义预转换成的图片的宽度和高度
  153.                 int newWidth = 360;
  154.                 int newHeight = 360;
  155.                 // 计算缩放率,新尺寸除原始尺寸
  156.                 float scaleWidth = ((float) newWidth) / width;
  157.                 float scaleHeight = ((float) newHeight) / height;
  158.                 // 创建操作图片用的matrix对象
  159.                 Matrix matrix = new Matrix();
  160.                 // 缩放图片动作
  161.                 matrix.postScale(scaleWidth, scaleHeight);
  162.                 // 创建新的图片
  163.                 Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width,height, matrix, true);
  164.                 // 将上面创建的Bitmap转换成Drawable对象,使得其可以使用在ImageView, ImageButton中
  165. //                BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
  166.                 return resizedBitmap;
  167.         }
  168.         
  169.         /**
  170.          * 将[1,0,0,1,0,0,0,1]这样的二进制转为化十进制的数值(效率更高)
  171.          * @param arry
  172.          * @return
  173.          */
  174.         public static int changePointPx1(byte[] arry){
  175.                 int v = 0;
  176.                 for (int j = 0; j <arry.length; j++) {
  177.                         if( arry[j] == 1) {
  178.                                 v = v | 1 << j;
  179.                         }
  180.                 }
  181.                 return v;
  182.         }
  183.         
  184.         /**
  185.          * 将[1,0,0,1,0,0,0,1]这样的二进制转为化十进制的数值
  186.          * @param arry
  187.          * @return
  188.          */
  189.         public byte changePointPx(byte[] arry){
  190.                 byte v = 0;
  191.                 for (int i = 0; i < 8; i++) {
  192.                         v += v + arry[i];
  193.                 }
  194.                 return v;
  195.         }
  196.         
  197.         /**
  198.          * 得到位图的某个点的像素值
  199.          * @param bitmap
  200.          * @return
  201.          */
  202.         public byte[] getPicPx(Bitmap bitmap){
  203.                 int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];// 保存所有的像素的数组,图片宽×高
  204.                 bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
  205.                 for (int i = 0; i < pixels.length; i++) {
  206.                         int clr = pixels[i];
  207.                         int red = (clr & 0x00ff0000) >> 16; // 取高两位
  208.                 int green = (clr & 0x0000ff00) >> 8; // 取中两位
  209.                                 int blue = clr & 0x000000ff; // 取低两位
  210.                                 System.out.println("r=" + red + ",g=" + green + ",b=" + blue);
  211.                 }
  212.                 return null;
  213.         }
  214.         
  215. }
复制代码

下面楼层继续...


   

  1. package com.woyou.util;

  2. import java.io.ByteArrayOutputStream;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. import java.security.InvalidParameterException;
  8. import java.text.DecimalFormat;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. import java.util.Locale;

  12. import android.content.Context;
  13. import android_serialport_api.SerialPort;

  14. /**
  15. * 打印机辅助
  16. * 
  17. * @author nsz        2015年1月30日
  18. */
  19. public class PrintUtil {
  20.         final static int BUFFER_SIZE = 4096;

  21.         /**
  22.          * 对一个byte[] 进行打印
  23.          * @param printText
  24.          * @return
  25.          * add by yidie
  26.          */
  27.         public static boolean printBytes(byte[] printText) {
  28.                 boolean returnValue = true;
  29.                 try {
  30.                         OutputStream mOutputStream = getSerialPort().getOutputStream();
  31.                         mOutputStream.write(printText);
  32.                 } catch (Exception ex) {
  33.                         returnValue = false;
  34.                 }
  35.                 return returnValue;
  36.         }

  37.         /**
  38.          * "\n" 就是换行
  39.          * @param paramString
  40.          * @return
  41.          * add by yidie
  42.          */
  43.         public static boolean printString(String paramString) {
  44.                 return printBytes(getGbk(paramString));
  45.         }

  46.         /***************************************************************************
  47.          * add by yidie 2012-01-10 功能:设置打印绝对位置 参数: int 在当前行,定位光标位置,取值范围0至576点 说明:
  48.          * 在字体常规大小下,每汉字24点,英文字符12点 如位于第n个汉字后,则position=24*n
  49.          * 如位于第n个半角字符后,则position=12*n
  50.          ****************************************************************************/

  51.         public static byte[] setCusorPosition(int position) {
  52.                 byte[] returnText = new byte[4]; // 当前行,设置绝对打印位置 ESC $ bL bH
  53.                 returnText[0] = 0x1B;
  54.                 returnText[1] = 0x24;
  55.                 returnText[2] = (byte) (position % 256);
  56.                 returnText[3] = (byte) (position / 256);
  57.                 return returnText;
  58.         }

  59.         /**
  60.          * 设置打印机的行高
  61.          * @param h
  62.          * @return
  63.          */
  64.         public static byte[] setLineHeight(byte h) {
  65.                 byte[] returnText = new byte[] { 0x1B, 0x33, h }; // 切纸; 1B 33 n
  66.                 return returnText;
  67.         }

  68.         public static byte[] setDefaultLineHeight() {
  69.                 byte[] returnText = new byte[] { 0x1B, 0x32 }; // 切纸; 1B 32
  70.                 return returnText;
  71.         }

  72.         public static byte[] InputStreamTOByte(InputStream in) throws IOException {

  73.                 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
  74.                 byte[] data = new byte[BUFFER_SIZE];
  75.                 int count = -1;
  76.                 while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
  77.                         outStream.write(data, 0, count);

  78.                 data = null;
  79.                 return outStream.toByteArray();
  80.         }
  81.         
  82.         /**
  83.          * 打印我有外卖的logo
  84.          * @param c
  85.          */
  86.         public static void printLogo(Context c) {
  87.                 PrintUtil.printBytes(PrintUtil.setLineHeight((byte) 0));
  88.                 InputStream is = c.getClass().getResourceAsStream("/assets/bill.bin");
  89.                 byte[] b;
  90.                 try {
  91.                         b = InputStreamTOByte(is);
  92.                         PrintUtil.printBytes(b);
  93.                         PrintUtil.printBytes(PrintUtil.setDefaultLineHeight());
  94.                 } catch (Exception e) {
  95.                         e.printStackTrace();
  96.                 }
  97.         }

  98.          public static byte[] getLogo(Context c) {
  99.                 InputStream is = c.getClass().getResourceAsStream("/assets/bill.bin");
  100.                 byte[] b;
  101.                 try {
  102.                         b = InputStreamTOByte(is);
  103.                         return b;
  104.                 } catch (Exception e) {
  105.                         e.printStackTrace();
  106.                 }
  107.                 return null;
  108.          }
  109.          
  110.          /**
  111.           * 得到店铺logo
  112.           * @param c
  113.           * @param bit
  114.           * @return
  115.           */
  116.         public static byte[] getLogo(Context c, byte[] bit) {
  117.                 InputStream is = c.getClass().getResourceAsStream("/assets/bill.bin");
  118.                 byte[] b = bit;
  119.                 try {
  120.                         b = InputStreamTOByte(is);
  121.                         return b;
  122.                 } catch (Exception e) {
  123.                         e.printStackTrace();
  124.                 }
  125.                 return null;
  126.         }
  127.         
  128.         public static byte[] getLogo(byte[] bs) {
  129.                 byte[] b;
  130.                 try {
  131.                         b = bs;
  132.                         return b;
  133.                 } catch (Exception e) {
  134.                         e.printStackTrace();
  135.                 }
  136.                 return null;
  137.         }        
  138.         
  139.         /**
  140.          * 支付打印(二维码)
  141.          * @param b
  142.          * @param money
  143.          * @return
  144.          * [url=home.php?mod=space&uid=2643633]@throws[/url] InvalidParameterException
  145.          * @throws SecurityException
  146.          * @throws IOException
  147.          */
  148.         public static boolean printAlipayTitle(byte[] b, String money) 
  149.                         throws InvalidParameterException, SecurityException, IOException {
  150.                 
  151.                 int iNum = 0;
  152.                 byte[] tempBuffer = new byte[1000];
  153.                 
  154.                 byte[]  oldText = setAlignCenter('2');
  155.                 System.arraycopy(oldText, 0,  tempBuffer,  iNum,  oldText.length);
  156.                 iNum += oldText.length;
  157.                 oldText = setWH('4'); 
  158.                 System.arraycopy(oldText, 0, tempBuffer,  iNum,  oldText.length);
  159.                 iNum += oldText.length;
  160.                 oldText = setBold(true);
  161.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  162.                 iNum += oldText.length;
  163.                 oldText = getGbk("支付凭证\n");
  164.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  165.                 iNum += oldText.length;
  166.                 
  167.                 oldText = getGbk("\n");
  168.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  169.                 iNum += oldText.length;
  170.                 
  171.                 oldText = setAlignCenter('2');
  172.                 System.arraycopy(oldText, 0,  tempBuffer,  iNum,  oldText.length);
  173.                 iNum += oldText.length;
  174.                 oldText = setWH('3'); 
  175.                 System.arraycopy(oldText, 0, tempBuffer,  iNum,  oldText.length);
  176.                 iNum += oldText.length;
  177.                 oldText = setBold(true);
  178.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  179.                 iNum += oldText.length;
  180.                 oldText = getGbk("您共消费了" + money + "元\n");
  181.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  182.                 iNum += oldText.length;
  183.                 
  184.                 oldText = getGbk("\n");
  185.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  186.                 iNum += oldText.length;
  187.                 
  188.                 oldText = setAlignCenter('2');
  189.                 System.arraycopy(oldText, 0,  tempBuffer,  iNum,  oldText.length);
  190.                 iNum += oldText.length;
  191.                 oldText = setWH('3'); 
  192.                 System.arraycopy(oldText, 0, tempBuffer,  iNum,  oldText.length);
  193.                 iNum += oldText.length;
  194.                 oldText = setBold(true);
  195.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  196.                 iNum += oldText.length;
  197.                 oldText = getGbk("请扫码支付\n\n");
  198.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  199.                 iNum += oldText.length;
  200.                 
  201.                 SerialPort mSerialPort = getSerialPort();
  202.                 OutputStream mOutputStream = mSerialPort.getOutputStream();
  203.                 try {
  204.                         mOutputStream.write(tempBuffer);
  205.                         printBytes(b);
  206.                         printString("\n\n\n");
  207.                         printBytes(CutPaper());
  208.                 } catch (IOException e) {
  209.                         e.printStackTrace();
  210.                         return false;
  211.                 }
  212.                 return true;
  213.         }

  214.         /***************************************************************************
  215.          * add by yidie 2012-01-10 功能:订单打印 参数: String 订单短号 OrderDetail 打印内容,包含
  216.          * GoodsInfo[] String 打印标题
  217.          ****************************************************************************/

  218.         public static boolean printOrder(Context c, byte[] b)
  219.                         throws InvalidParameterException, SecurityException, IOException {

  220.                 DecimalFormat dcmFmt = new DecimalFormat("0.00");
  221.                 int iNum = 0, i;

  222.                 byte[] tempBuffer = new byte[8000];
  223.                 String stTmp = "";

  224.                 byte[] oldText = setAlignCenter('2');
  225.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  226.                 iNum += oldText.length;

  227.                 oldText = getLogo(c, b);
  228.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  229.                 iNum += oldText.length;

  230.                 oldText = setWH('1');
  231.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  232.                 iNum += oldText.length;

  233.                 oldText = getGbk("\n");
  234.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  235.                 iNum += oldText.length;

  236.                 oldText = setAlignCenter('2');
  237.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  238.                 iNum += oldText.length;

  239.                 oldText = setWH('4');
  240.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  241.                 iNum += oldText.length;

  242.                 oldText = setBold(true);
  243.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  244.                 iNum += oldText.length;

  245.                 oldText = setWH('1');
  246.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  247.                 iNum += oldText.length;

  248.                 oldText = getGbk("\n");
  249.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  250.                 iNum += oldText.length;

  251.                 oldText = setAlignCenter('1');
  252.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  253.                 iNum += oldText.length;

  254.                 oldText = setCusorPosition(324);
  255.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  256.                 iNum += oldText.length;

  257.                 String strTime = new SimpleDateFormat("yyyy-MM-dd HH:mm",
  258.                                 Locale.SIMPLIFIED_CHINESE).format(new Date());
  259.                 oldText = getGbk(strTime + "打印\n");
  260.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  261.                 iNum += oldText.length;

  262.                 oldText = setBold(false);
  263.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  264.                 iNum += oldText.length;

  265.                 oldText = getGbk("----------------------------------------------\n");
  266.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  267.                 iNum += oldText.length;

  268.                 oldText = setWH('3');
  269.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  270.                 iNum += oldText.length;

  271.                 oldText = getGbk("   商品名称              单价    数量    金额\n");
  272.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  273.                 iNum += oldText.length;

  274.                 oldText = getGbk("----------------------------------------------\n");
  275.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  276.                 iNum += oldText.length;

  277.                 oldText = setWH('3');
  278.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  279.                 iNum += oldText.length;

  280.                 oldText = setAlignCenter('2');
  281.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  282.                 iNum += oldText.length;

  283.                 oldText = setWH('1');
  284.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  285.                 iNum += oldText.length;

  286.                 oldText = getGbk("\n感谢使用[我有外卖]订餐,24小时服务热线 4008519517\n\n\n");
  287.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  288.                 iNum += oldText.length;

  289.                 oldText = CutPaper();
  290.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  291.                 iNum += oldText.length;
  292.                 
  293.                 SerialPort mSerialPort = getSerialPort();
  294.                 OutputStream mOutputStream = mSerialPort.getOutputStream();
  295.                 try {
  296.                         mOutputStream.write(tempBuffer);
  297.                 } catch (IOException e) {
  298.                         e.printStackTrace();
  299.                         return false;
  300.                 }
  301.                 return true;
  302.         }

  303.         /***************************************************************************
  304.          * add by yidie 2012-01-12 功能:报表打印 参数: String 打印标题,如“月报表:2013-01”
  305.          * ReportUserSale 打印内容,包含 UserSaleInfo[]
  306.          ****************************************************************************/

  307.         public static boolean printReportUser() throws InvalidParameterException,
  308.                         SecurityException, IOException {

  309.                 int iNum = 0;
  310.                 String stTmp = "";

  311.                 byte[] tempBuffer = new byte[8000];
  312.                 SerialPort mSerialPort = getSerialPort();
  313.                 OutputStream mOutputStream = mSerialPort.getOutputStream();

  314.                 byte[] oldText = setAlignCenter('1');
  315.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  316.                 iNum += oldText.length;

  317.                 oldText = setWH('3');
  318.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  319.                 iNum += oldText.length;

  320.                 oldText = setCusorPosition(324);
  321.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  322.                 iNum += oldText.length;

  323.                 String strTime = new SimpleDateFormat("yyyy-MM-dd HH:mm",
  324.                                 Locale.SIMPLIFIED_CHINESE).format(new Date());
  325.                 oldText = getGbk(strTime + "打印\n");
  326.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  327.                 iNum += oldText.length;

  328.                 oldText = setWH('1');
  329.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  330.                 iNum += oldText.length;

  331.                 oldText = setAlignCenter('2');
  332.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  333.                 iNum += oldText.length;

  334.                 oldText = setWH('4');
  335.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  336.                 iNum += oldText.length;

  337.                 oldText = setBold(true);
  338.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  339.                 iNum += oldText.length;

  340.                 oldText = setWH('1');
  341.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  342.                 iNum += oldText.length;

  343.                 oldText = getGbk("\n\n");
  344.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  345.                 iNum += oldText.length;

  346.                 oldText = setAlignCenter('1');
  347.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  348.                 iNum += oldText.length;

  349.                 oldText = setBold(false);
  350.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  351.                 iNum += oldText.length;

  352.                 oldText = setWH('1');
  353.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  354.                 iNum += oldText.length;

  355.                 oldText = getGbk("     用户           售出数量 售出金额\n");
  356.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  357.                 iNum += oldText.length;

  358.                 oldText = getGbk("----------------------------------------------\n");
  359.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  360.                 iNum += oldText.length;

  361.                 oldText = CutPaper();
  362.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  363.                 iNum += oldText.length;
  364.                 try {
  365.                         mOutputStream.write(tempBuffer);
  366.                 } catch (IOException e) {
  367.                         e.printStackTrace();
  368.                         return false;
  369.                 }

  370.                 return true;
  371.         }

  372.         /***************************************************************************
  373.          * add by yidie 2012-01-12 功能:报表打印 参数: String 打印标题,如“月报表:2013-01” ReportSale
  374.          * 打印内容,包含 SaleInfo[]
  375.          ****************************************************************************/

  376.         private static SerialPort mSerialPort = null;

  377.         public static SerialPort getSerialPort() throws SecurityException,
  378.                         IOException, InvalidParameterException {
  379.                 if (mSerialPort == null) {
  380.                         String spFile = null;
  381.                         String model = MainBoardUtil.getModel(); // android.os.Build.MODEL.toLowerCase();
  382.                         if (model.contains(Constants.MAIN_BOARD_SMDKV210)) {
  383.                                 spFile = "/dev/s3c2410_serial0";
  384.                         } else if (model.contains(Constants.MAIN_BOARD_RK30)) {
  385.                                 spFile = "/dev/ttyS1";
  386.                         } else if (model.contains(Constants.MAIN_BOARD_C500)) {
  387.                                 spFile = "/dev/ttyS1";
  388.                         } else {
  389.                                 throw new IOException("unknow hardware!");
  390.                         }

  391.                         int baudrate = 115200;
  392.                         boolean flagCon = true;

  393.                         File myFile = new File(spFile);

  394.                         /* Open the serial port */
  395.                         mSerialPort = new SerialPort(myFile, baudrate, 0, flagCon);
  396.                 }
  397.                 return mSerialPort;
  398.         }

  399.         public static void closeSerialPort() {
  400.                 if (mSerialPort != null) {
  401.                         mSerialPort.close();
  402.                         mSerialPort = null;
  403.                 }
  404.         }

  405.         public static byte[] getGbk(String stText) {
  406.                 byte[] returnText = null;
  407.                 try {
  408.                         returnText = stText.getBytes("GBK"); // 必须放在try内才可以
  409.                 } catch (Exception ex) {
  410.                         ;
  411.                 }
  412.                 return returnText;
  413.         }

  414.         public static byte[] setWH(char dist) {
  415.                 byte[] returnText = new byte[3]; // GS ! 11H 倍宽倍高
  416.                 returnText[0] = 0x1D;
  417.                 returnText[1] = 0x21;

  418.                 switch (dist) // 1-无;2-倍宽;3-倍高; 4-倍宽倍高
  419.                 {
  420.                 case '2':
  421.                         returnText[2] = 0x10;
  422.                         break;
  423.                 case '3':
  424.                         returnText[2] = 0x01;
  425.                         break;
  426.                 case '4':
  427.                         returnText[2] = 0x11;
  428.                         break;
  429.                 default:
  430.                         returnText[2] = 0x00;
  431.                         break;
  432.                 }

  433.                 return returnText;
  434.         }

  435.         /**
  436.          * 打印的对齐方式
  437.          * @param dist
  438.          * @return
  439.          */
  440.         public static byte[] setAlignCenter(char dist) {
  441.                 byte[] returnText = new byte[3]; // 对齐 ESC a
  442.                 returnText[0] = 0x1B;
  443.                 returnText[1] = 0x61;

  444.                 switch (dist) // 1-左对齐;2-居中对齐;3-右对齐
  445.                 {
  446.                 case '2':
  447.                         returnText[2] = 0x01;
  448.                         break;
  449.                 case '3':
  450.                         returnText[2] = 0x02;
  451.                         break;
  452.                 default:
  453.                         returnText[2] = 0x00;
  454.                         break;
  455.                 }
  456.                 return returnText;
  457.         }

  458.         public static byte[] setBold(boolean dist) {
  459.                 byte[] returnText = new byte[3]; // 加粗 ESC E
  460.                 returnText[0] = 0x1B;
  461.                 returnText[1] = 0x45;

  462.                 if (dist) {
  463.                         returnText[2] = 0x01; // 表示加粗
  464.                 } else {
  465.                         returnText[2] = 0x00;
  466.                 }
  467.                 return returnText;
  468.         }

  469.         public static byte[] PrintBarcode(String stBarcode) {
  470.                 int iLength = stBarcode.length() + 4;
  471.                 byte[] returnText = new byte[iLength];

  472.                 returnText[0] = 0x1D;
  473.                 returnText[1] = 'k';
  474.                 returnText[2] = 0x45;
  475.                 returnText[3] = (byte) stBarcode.length(); // 条码长度;

  476.                 System.arraycopy(stBarcode.getBytes(), 0, returnText, 4,
  477.                                 stBarcode.getBytes().length);

  478.                 return returnText;
  479.         }

  480.         /**
  481.          * 切纸
  482.          * @return
  483.          */
  484.         public static byte[] CutPaper() {
  485.                 byte[] returnText = new byte[] { 0x1D, 0x56, 0x42, 0x00 }; // 切纸; GS V
  486.                                                                                                                                         // 66D 0D
  487.                 return returnText;
  488.         }
  489. }
复制代码
  1. package com.woyou.woyoupay;

  2. import java.io.IOException;
  3. import java.net.URL;
  4. import java.util.ArrayList;
  5. import java.util.List;

  6. import org.json.JSONException;
  7. import org.json.JSONObject;

  8. import android.app.Activity;
  9. import android.app.ProgressDialog;
  10. import android.content.Intent;
  11. import android.graphics.Bitmap;
  12. import android.graphics.BitmapFactory;
  13. import android.graphics.drawable.Drawable;
  14. import android.os.Bundle;
  15. import android.text.Html;
  16. import android.util.Log;
  17. import android.view.View;
  18. import android.view.View.OnClickListener;
  19. import android.view.Window;
  20. import android.widget.ImageView;
  21. import android.widget.TextView;

  22. import com.anjoyo.net.AsyncHttpClient;
  23. import com.anjoyo.net.JsonHttpResponseHandler;
  24. import com.anjoyo.net.RequestParams;
  25. import com.woyou.R;
  26. import com.woyou.bean.ScanCodeRes;
  27. import com.woyou.util.Constants;
  28. import com.woyou.util.PicFromPrintUtils;
  29. import com.woyou.util.PrintUtil;
  30. import com.woyou.util.ThreadPoolManager;

  31. public class Print2DCodeAct extends Activity implements OnClickListener {
  32.         private static final String TAG = "Print2DCodeAct";
  33.         TextView back, print, motifiscan;
  34.         TextView oId, money, price;
  35.         ImageView printImg;
  36.         ProgressDialog dialog;

  37.         @Override
  38.         protected void onCreate(Bundle savedInstanceState) {
  39.                 super.onCreate(savedInstanceState);
  40.                 requestWindowFeature(Window.FEATURE_NO_TITLE);
  41.                 setContentView(R.layout.activity_print2dcode);
  42.                 initView();
  43.         }

  44.         String extra;
  45.         private void initView() {
  46.                 Intent intent = getIntent();
  47.                 extra = intent.getStringExtra("money");
  48.                 back = (TextView) this.findViewById(R.id.back);
  49.                 oId = (TextView) this.findViewById(R.id.order_id);
  50.                 back.setOnClickListener(this);
  51.                 motifiscan = (TextView) this.findViewById(R.id.motifiscan);
  52.                 print = (TextView) this.findViewById(R.id.print_image);
  53.                 printImg = (ImageView) this.findViewById(R.id.print_two_image);
  54.                 money = (TextView) this.findViewById(R.id.money);
  55.                 print.setOnClickListener(this);
  56.                 motifiscan.setOnClickListener(this);
  57.                 money.setText(Html.fromHtml("¥<big>" + extra + "</big>"));
  58.                 
  59.                 //显示图片
  60. //                Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(), R.drawable.alipay);
  61. //                Bitmap bitmap = compressPic(bitmapOrg);
  62. //                image_alipy.setImageBitmap(bitmap);
  63.                 
  64.                 //请求数据
  65.                 getData();
  66.         }

  67.         private void showDialog() {
  68.                 if (dialog == null) {
  69.                         dialog = new ProgressDialog(this);
  70.                         dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
  71.                         dialog.setCancelable(true);
  72.                         dialog.setMessage("正在加载中,请稍候...");
  73.                 }
  74.                 dialog.show();
  75.         }
  76.         private void hideDialog() {
  77.                 runOnUiThread(new Runnable() {
  78.                         
  79.                         @Override
  80.                         public void run() {
  81.                                 if (dialog != null) {
  82.                                         dialog.dismiss();
  83.                                 }
  84.                         }
  85.                 });
  86.         }
  87.         
  88.         
  89.         
  90.         @Override
  91.         protected void onResume() {
  92.                 super.onResume();
  93.                 Constants.ACTIVITY_INSTANCE = Print2DCodeAct.this;
  94.         }

  95.         List<ScanCodeRes> list = new ArrayList<ScanCodeRes>();
  96.         Bitmap compressPic = null;
  97.         String big_pic_url;
  98.         String pic_url;
  99.         String small_pic_url;
  100.         private void getData() {
  101.                 float f = Float.parseFloat(extra) * 100;
  102.                 int inte = (int) f;
  103.                 long parseLong = Long.parseLong(String.valueOf(inte));
  104.                 
  105.                 String sign = Constants.md5("100512354" + "150039203" + Constants.KEY);
  106.                 String url = "http://api.coupon.dev.wosai.cn/Upay/alipayQrCodeOffline";
  107.                 AsyncHttpClient client = new AsyncHttpClient();
  108.                 RequestParams params = new RequestParams();
  109.                 params.put("store_own_order_id", "1234");
  110.                 params.put("subject", "喔噻体验商品");
  111.                 params.put("total_fee", parseLong+"");
  112.                 params.put("wosai_store_id", "100512354");
  113.                 params.put("wosai_app_id", "150039203");
  114.                 params.put("sign", sign);
  115.                 params.put("notify_url", "http://www.woyouwaimai.com/get");   //推送支付成功的通知
  116.                 Log.i(TAG, url + params);
  117.                 
  118.                 client.get(url, params, new JsonHttpResponseHandler() {
  119.                         @Override
  120.                         public void onStart() {
  121.                                 super.onStart();
  122.                                 showDialog();
  123.                         }
  124.                         @Override
  125.                         public void onSuccess(JSONObject response) {
  126.                                 super.onSuccess(response);
  127.                                 try {
  128.                                         String code = response.getString("code");
  129.                                         String msg = response.getString("msg");
  130.                                         Log.i(TAG, "code:" + code);
  131.                                         Log.i(TAG, "msg:" + msg);
  132.                                         if ("10000".equals(code)) {
  133.                                                 JSONObject data = response.getJSONObject("data");
  134.                                                 String order_sn = data.getString("order_sn");
  135.                                                 String wosai_store_id = data.getString("wosai_store_id");
  136.                                                 int status = data.getInt("status");
  137.                                                 String ctime = data.getString("ctime");
  138.                                                 JSONObject order_pay_detail = data.getJSONObject("order_pay_detail");
  139.                                                 String order_detail = data.getString("order_detail");
  140.                                                 String pay_way = data.getString("pay_way");
  141.                                                 long total_fee = data.getLong("total_fee");

  142.                                                 String is_success = order_pay_detail.getString("is_success");
  143.                                                 JSONObject responses = order_pay_detail.getJSONObject("response");
  144.                                                 String sign = order_pay_detail.getString("sign");
  145.                                                 String sign_type = order_pay_detail.getString("sign_type");

  146.                                                 JSONObject alipay = responses.getJSONObject("alipay");
  147.                                                 big_pic_url = alipay.getString("big_pic_url");
  148.                                                 String out_trade_no = alipay.getString("out_trade_no");
  149.                                                 pic_url = alipay.getString("pic_url");
  150.                                                 String qr_code = alipay.getString("qr_code");
  151.                                                 String result_code = alipay.getString("result_code");
  152.                                                 small_pic_url = alipay.getString("small_pic_url");
  153.                                                 String voucher_type = alipay.getString("voucher_type");
  154.                                                 Log.i(TAG, "big_pic_url:" + big_pic_url);
  155.                                                 Log.i(TAG, "pic_url:" + pic_url);
  156.                                                 Log.i(TAG, "small_pic_url:" + small_pic_url);
  157.                                                 
  158.                                                 ScanCodeRes res = new ScanCodeRes();
  159.                                                 res.setOrder_sn(order_sn);
  160.                                                 res.setWosai_store_id(wosai_store_id);
  161.                                                 res.setStatus(status);
  162.                                                 res.setCtime(ctime);
  163.                                                 res.setIs_success(is_success);
  164.                                                 res.setOrder_detail(order_detail);
  165.                                                 res.setTotal_fee(total_fee);
  166.                                                 res.setPay_way(pay_way);
  167.                                                 list.add(res);
  168.                                                 
  169.                                                 Constants.memoryCache.put(Constants.SCAN_CODE_RESULT, list);
  170.                                                 
  171.                                         }
  172.                                 } catch (JSONException e) {
  173.                                         e.printStackTrace();
  174.                                         hideDialog();
  175.                                 }
  176.                         }

  177.                         @Override
  178.                         public void onFinish() {
  179.                                 super.onFinish();
  180.                                 ThreadPoolManager.getInstance().executeTask(new Runnable() {
  181.                                         @Override
  182.                                         public void run() {
  183.                                                 try {
  184.                                                         Bitmap bitmap = BitmapFactory.decodeStream(new URL(pic_url).openStream());
  185.                                                         compressPic = PicFromPrintUtils.compressPic(bitmap);
  186.                                                 }catch (IOException e) {
  187.                                                         e.printStackTrace();
  188.                                                 }
  189.                                                 runOnUiThread(new Runnable() {
  190.                                                         
  191.                                                         @Override
  192.                                                         public void run() {
  193.                                                                 printImg.setImageBitmap(compressPic);
  194.                                                                 print2Code(compressPic);
  195.                                                                 hideDialog();
  196.                                                         }
  197.                                                 });
  198.                                                 
  199.                                         }
  200.                                 });
  201.                         }

  202.                 });
  203.         }
  204.         
  205.         //打印二维码
  206.         private void print2Code(Bitmap bitmap){
  207.                 final byte[] bs = PicFromPrintUtils.draw2PxPoint(bitmap);
  208.                 ThreadPoolManager.getInstance().executeTask(new Runnable() {
  209.                         @Override
  210.                         public void run() {
  211.                                 try {
  212.                                         PrintUtil.printAlipayTitle(bs, extra);
  213.                                 } catch (Exception e) {
  214.                                         e.printStackTrace();
  215.                                 }
  216.                         }
  217.                 });
  218.         }
  219.         
  220.         @Override
  221.         public void onClick(View v) {
  222.                 switch (v.getId()) {
  223.                 case R.id.print_image:
  224.                         if ( compressPic != null ){
  225.                                 print2Code(compressPic);
  226.                         }
  227.                         break;

  228.                 case R.id.back:
  229.                         finish();
  230.                         break;

  231.                 case R.id.motifiscan:
  232.                         Intent intent = new Intent(this, HomeAct.class);
  233.                         intent.putExtra("money", extra);
  234.                         startActivity(intent);
  235.                         break;
  236.                 }
  237.         }
  238.         
  239.         public Drawable loadImageFromNetwork(String urladdr) {
  240.                 Drawable drawable = null;
  241.                 try {
  242.                         drawable = Drawable.createFromStream(new URL(urladdr).openStream(),"image.jpg");
  243.                 } catch (IOException e) {
  244.                         Log.d("test", e.getMessage());
  245.                 }
  246.                 if (drawable == null) {
  247.                         Log.d("test", "null drawable");
  248.                 } else {
  249.                         Log.d("test", "not null drawable");
  250.                 }
  251.                 return drawable;
  252.         }
  253.         
  254.         // 计算图片的缩放值
  255.         public static int calculateInSampleSize(BitmapFactory.Options options,
  256.                         int reqWidth, int reqHeight) {
  257.                 final int height = options.outHeight;
  258.                 final int width = options.outWidth;
  259.                 int inSampleSize = 1;
  260.                 if (height > reqHeight || width > reqWidth) {
  261.                         final int heightRatio = Math.round((float) height
  262.                                         / (float) reqHeight);
  263.                         final int widthRatio = Math.round((float) width / (float) reqWidth);
  264.                         inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
  265.                 }
  266.                 return inSampleSize;
  267.         }

  268. }
复制代码


代码不是很全,只上了一些核心的代码,因为这是公司的项目,不适合把工程贴上来,忘大家见谅。中间会有一些简单的算法,是为提高效率用的,代码的整合力度也不是很好,大家将就点吧。



原文

http://www.eoeandroid.com/thread-564903-1-1.html?_dsign=50a25db8

Android 关于佳博和汉印蓝牙热敏打印机开发,kotlin爬虫app Log.e(TAG, “printCPCL: =======>443”); if (PrinterHelper.IsOpened()) { Log.e(TAG, "run: " + PrinterHelper.IsOpened()); //连接成功 PrinterHelper.Align(PrinterHelper.CENTER); PrinterHelper.SetBold(“1”); PrinterHelper.SetMag(“2”, “2”); PrinterHelper.Text(Printe 阅读详情

相关推荐

Android 关于佳博和汉印蓝牙热敏打印机开发,android面试必看书籍

PrinterHelper.SetBold(“1”); PrinterHelper.SetMag(“2”, “2”); PrinterHelper.Text(PrinterHelper.TEXT, “8”, “0”, “10”, “30”, “啦啦啦”) PrinterHelper.SetMag(“1”, “1”); PrinterHelper.SetBold(“0”); PrinterHelper.InverseLine(“0”, “0”, “700”, “0”, “100”); PrinterHelpe

m0_64382950的博客 553

对#Hello,2015征文#+Android 热敏打印机打印二维码(图片)博客的尝试

原博客链接  #Hello,2015征文#+Android 热敏打印机打印二维码   昨天晚上说抽时间来写一篇关于Android 热敏打印机打印二维码和图片的文章,所幸在下班之前把它给写了,和大家分享吧。我的是Android机器有内置热敏打印机的,我是把apk跑在我的Android机器上的,操作程序打印的。   一、打印机的型号

秦时明月 2257

Android 关于佳博和汉印蓝牙热敏打印机开发,安卓databinding

PrinterHelper.SetMag(“1”, “1”); PrinterHelper.SetBold(“0”); PrinterHelper.InverseLine(“0”, “0”, “700”, 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》 【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享 “0”, “100”); PrinterHelper.Text(PrinterHelper.TEXT, “8”, “0”, “

m0_64603776的博客 961

Android USB串口打印结账单小票

最近公司在做点餐相关的项目,需要通过USB串口连接打印机打印订单的小票,自己也是在网上查了一些相关的资料做了一些总结,最后把总结的代码贡献出来,给有需要的朋友做参考,废话不多说了,先看打印出来的效果,58mm和80mm的纸张都有。 ...

u012866962的博客 2227

Android打印机--小票打印格式及模板设置

小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式一般需要去查询对应打印机的API文档。

学无止境 2万+

AndroidUSB热敏打印机使用动态申请权限绕过系统权限对话框

AndroidUSB热敏打印机使用动态申请权限绕过系统权限对话框

Android集成佳博热敏打印机打印小票功能

一、说明 最近公司项目需要做打印机打印小票功能,首先公司买了一个佳博小票打印机作为测试用机。然后在开发的过程中也遇到一些坑,在此记录一下。 二、集成过程 1. 下载开发文档 首先需要去其官网下载SDK可开发文档:http://www.gainscha.cn/download/24 2. 在manifest中添加必要的声明 // 权限声明 &lt;uses-per...

Eric的博客 1万+

android使用POS打印小票带二维码

android通过lan口控制小票打印机打印小票,可以打印二维码,和各种图片

Android打印二维码对热敏打印机的适配

经过一段时间的研究,目前得出了Android连接蓝牙打印机打印二维码的方式有2种:第一种:采用ESC/POS二维码指令打印的方式打印,代码如下    /** * 设置二维码大小 */ public static final byte[] setCodeSize = new byte[8]; /** * 设置纠错正等级 */ publi...

qq_25149477的专栏 4807

Figma汉化教程

Figma汉化教程

cc蒲公英的博客 1万+

告别手动标注!PDMS NakiToolkit插件安装与初体验:以Pipeline工具为例

本文详细介绍了PDMS NakiToolkit插件的安装与使用,特别是其Pipeline工具如何通过自动化标注和材料统计功能大幅提升三维工厂设计效率。从环境准备到实战演示,帮助工程师告别繁琐的手动标注工作,实现项目交付周期的大幅缩短。

weixin_30047059的博客 350

Android 热敏打印机打印二维码(转载)

一、打印机的型号   RP-POS80S或RP-POS80P或RP-POS80CS或RP-POS80CP打印机 高速热敏打印机   打印方式:直接热敏打印   打印密度:640点/行   打印纸宽:80mm   有效打印宽度:72mm   最小走纸距离:0.125mm   打印字符   ACSII码字符集:12×24点   国标一、二级汉字字库:24×24点   采用命

gaaa1113的博客 2430

阻抗匹配与史密斯(Smith)圆图

在找到点B和B'后,我们就能够测量A'到B和B'到D的弧长,前者就是C的归一化电纳值,后者为L的归一化电抗值。当然,表面上看新的点好像是一个不同的阻抗,实际上Z和1/Y表示的是同一个元件(这个新值在圆图上呈现为一个不同的点,而且反射系数也不相同,依次类推)。出现这种情况的原因是我们的图形本身是一个阻抗图,而新的点代表的是一个导纳。这个方程是在复平面(Γr, Γi)上、圆的参数方程(x - a)² + (y - b)² = R²,它以[r/(r + 1), 0]为圆心,半径为1/(1 + r)。

qq_55759599的博客 3962

资江热敏打印二维码指令android

非位图打印指令 // 设置对齐方式 initPrinter(); byte[] alignByte = { 0x1B, 0x61, 1 };// 0:左对齐;1:居中;2:右对齐 mBluetoothService.write(alignByte); byte[] hb = null; hb = conetnt.getBytes();//二维码内容 // 0x1f,0x1c,

a632213470的专栏 860

如何在R中高效安装ropls及其依赖包

本文详细介绍了在R语言中高效安装ropls包及其依赖的完整流程。作为Bioconductor生物信息学分析包,ropls的安装需通过BiocManager管理器进行。文章提供了标准安装步骤、跨系统避坑指南及安装后验证方法,帮助用户解决R版本、编译环境和网络镜像等常见问题,确保代谢组学数据分析工具顺利部署。

efc123456的博客 908

5分钟快速上手:用AI生成3D虚拟场景的保姆级教程

你是否想过:不用学复杂的3D建模软件,不用懂“多边形”“UV贴图”这些专业术语,也能快速生成一个梦幻的森林、未来感的城市,甚至外太空基地?本文的目的就是教完全没接触过3D技术的新手,用AI工具5分钟生成3D虚拟场景。我们会覆盖主流AI工具的选择、提示词编写技巧、生成后的简单调整,以及常见问题解决。本文会像“游戏任务指南”一样,从“认识工具”→“写提示词”→“生成场景”→“调整优化”逐步讲解,最后还会教你把生成的3D场景用起来!提示词:你给AI的“订单备注”,越详细效果越好。扩散模型。

AI 原生应用开发的博客 1962

Android连接USB打印机

项目中需要用到android设备通过USB连接热敏打印机打印图文混排的小条,总结一下。 外部主要是用这个方法来打印: /** * 打印核验小条 * 子线程中运行 */ private static int times = 0; public void printVerifyData(String tmpName, ...

dami_lixm的专栏 4191

【人工智能】《Deep Dive into LLMs like ChatGPT 》—— Andrej Karpathy 第三阶段:强化学习(Reinforcement Learning, RL)

摘要:强化学习(RL)阶段通过让模型自主生成并验证答案,突破SFT阶段的模仿局限,使其在数学、代码等领域形成独特的推理路径。RL流程包括批量生成解答、自动批改筛选正确路径,并采用PPO/GRPO算法优化模型。模型会自发涌现自我检查、回滚等策略,显著提升正确率(如AIME竞赛准确率从15%升至56%)。与SFT模型相比,RL模型具备主动链式思维、验算能力,响应时间更长但效果更优,形成真正的“思考模型”。三阶段对比显示,RL通过可验证题的对错奖励机制,赋予模型超越人类范式的推理能力。

奶爸的编程之路,也就一周冷个三天 149

安卓连接pos小票机和钱箱

安卓连接pos小票机和钱箱 2017-2-13来源:iOS开发人气:75 测试工具具体用到: 1、58热敏打印机 2、钱箱 3、Android Studio 2.2.2 4、测试平板一台 端口号打印机一般都是9100 首先把打印机固定ip设置好,然后所有设备连接到同一网络(不在同一网络连接不上) 钱箱看需求,直接插在打印机上就行了 布局就

技术博客 1979

损失函数大汇总(八)(IoU Loss附公式推导与代码)

本文详细介绍了IoU Loss及其在图像分割中的应用。IoU(交并比)是衡量预测区域与真实区域重叠程度的指标,IoU Loss定义为1-IoU,直接优化区域重叠质量。文章推导了IoU的数学表达式和梯度计算,分析了其函数特性:全局耦合梯度、对漏检误检的双重惩罚、适合类别不平衡任务。与Dice Loss相比,IoU更强调覆盖质量而非相似度。实际应用中IoU Loss常与BCE组合使用,前者保证训练稳定性,后者优化整体区域质量。文章还提供了IoU Loss的代码实现,适用于二值分割、小目标提取等场景,特别当任务评

悦学共鸣,温柔以待,汇聚光芒,共同成长 414

OpenCV实战之人脸美颜美型(八)——大眼(上)

从大众审美的角度来看,眼睛适当的“变大”会让人显得更加年轻。因此美型中就有一项大眼功能,其效果就是让眼睛适当变大,这章内容就围绕着大眼算法展开。

On my way 1211

uniapp实现了热敏打印机的图片打印经历 [写的一坨]

但是如果这里依旧想着直接把汉字也转成HEX去执行,我发现没什么用,打出来的要么黑乎乎一片要么还是英文,(这里有人说是要转化成GBK之类的再转回来,但是我试了也没有成功,于是放弃这条路,当然你也可以试试),这里我转而想到打印带着文字的图片去实现打印小票的效果。最后我寻找了不少教程,终于得到一个具体能走通的打印,不过我这里只做了一些笼统的操作,一些关于宽度适应切纸等东西写的并不完善(因为我自己都不完全懂),下面大体操作如下,choose获取图片,图片转化成数据,数据拼接成带有打印头的数组。

qq_49221992的博客 660

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Android Drawable 转 bitmap 热敏打印

最近工作需要Android设备连接热敏打印机(送餐单子),需要打印两种图片,一种是生成的二维码,一种是drawable图片,第一种按照打印机的API来没有问题,第二种打印机有提供接口,但是当把图片放进去后打印出来往往都被拉伸或缩小变形了,后来只能转为 bitmap的图片,但是不同的打印机要求不同,有的需要重新画成bitmap有的直接转为bitmap就可以了,这个需要根据具体的打印机打印尝试: 方法一: var widthTemp = width - 25 var heightTemp = height

ysthuigui的专栏 2168

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

上一篇: 基于webpack搭建前端工程解决方案探索
下一篇: Android Service创建USB HOST通信
offbye
offbye 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄24年 1309粉丝 252原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值