Android网络打印机的那些事

最近做项目有碰到使用Android手机连接网络打印机打印小票,把研究了好几天东西记录分享下。

基于环境
测试网络打印机爱普生(Epson),测试手机华为Meta9,P9,Meta8。

  • 打印一维码,我这边测试不行,有大神知道可以告诉我,可以使用zxing生成一维码二维码,在转图片,反正我用的是这种方式
  • 打印二维码OK
  • 文本打印完要记得多带几个回车在切纸

连接网络打印机

    /**
     * 网络打印机 打开网络打印机
     * 端口都是9100
     * @param ipaddress
     * @param netport
     * @return
     */
    public boolean connction(String ipaddress, int netport)
    {
        try
        {
            Socket socket;
            if (socket!=null){
                socket.close();
            }
            SocketAddress ipe = new InetSocketAddress(ipaddress,9100);
            socket = new Socket();  //Socket(ipaddress, netport,true);
            socket.connect(ipe);
            socket.setSoTimeout(1500);

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

打印的工具类


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Base64;
import android.util.Log;



import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Vector;

/**
 * @author: ZhuHuaHua
 * @data 2016/11/24 17:48
 */

public class PrinterTest
{

    Vector<Byte> Command = null;
    public PrinterTest() {
        this.Command = new Vector(4096, 1024);
    }

    /**
     * 初始化打印机,主要清空打印机缓存数据,这步很重要,要不打印机容易内存溢出,打印出乱码
     */
    public void printInit()
    {
        byte[] command = {27, 64};
        addArrayToCommand(command);
    }

    private void addArrayToCommand(byte[] array) {
        for (int i = 0; i < array.length; i++) {
            this.Command.add(Byte.valueOf(array[i]));
        }
    }

    /**
     * 换行回车
     */
    public void printEnter()
    {
        byte[] command = {10};
        addArrayToCommand(command);
    }



    /**
     * 功能:选择对齐方式
     * @param 0:左对齐 1:居中对齐 2:右对齐
     */
    public void printTextAlign(int align) {
        byte[] command = {27,97,(byte) align};
        addArrayToCommand(command);
    }

    /**
     *
     * @param bitmap  位图
     * @param nWidth  打印宽度(可以用于缩放图片)
     * @param nMode 打印模式 0: 正常 1:倍宽 2:倍高 3:倍宽 倍高
     */
    public void addRastBitImage(Bitmap bitmap, int nWidth, int nMode) {
        if (bitmap != null) {
            int width = (nWidth + 7) / 8 * 8;
            int height = bitmap.getHeight() * width / bitmap.getWidth();
            Bitmap grayBitmap = GpUtils.toGrayscale(bitmap);
            Bitmap rszBitmap = GpUtils.resizeImage(grayBitmap, width, height);
            byte[] src = GpUtils.bitmapToBWPix(rszBitmap);
            byte[] command = new byte[8];
            height = src.length / width;
            command[0] = 29;
            command[1] = 118;
            command[2] = 48;
            command[3] = ((byte) (nMode & 0x1));
            command[4] = ((byte) (width / 8 % 256));
            command[5] = ((byte) (width / 8 / 256));
            command[6] = ((byte) (height % 256));
            command[7] = ((byte) (height / 256));
            addArrayToCommand(command);
            byte[] codecontent = GpUtils.pixToEscRastBitImageCmd(src);
            for (int k = 0; k < codecontent.length; k++) {
                this.Command.add(Byte.valueOf(codecontent[k]));
            }
        } else {
            Log.d("BMP", "bmp.  null ");
        }
    }
    /**
     * 打印图片
     * @param mbitmap  对象bitmap
     */
    public Vector<Byte> CMD_Image(Bitmap mbitmap) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inScaled = false;
            byte[] decodedByte = Base64.decode(bitmapToBase64(mbitmap), Base64.DEFAULT);
            Bitmap bitmap = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
            final int imgWidth = bitmap.getWidth();
            final int imgHeight = bitmap.getHeight();
            final int[] argb = new int[imgWidth * imgHeight];
            bitmap.getPixels(argb, 0, imgWidth, 0, 0, imgWidth, imgHeight);

            EscCommand esc = new EscCommand();

            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addRastBitImage(bitmap, imgWidth, 0);
            esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);
            Vector<Byte> Command  = esc.getCommand();
            Vector<Byte> data = new Vector<>(Command.size());
            for (int i = 0; i < Command.size(); i++) {
                data.add(Command.get(i));
            }
            bitmap.recycle();
        return  data;
    }

    /**
     * bitmap转为base64
     * @param bitmap
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    /**
     * 打印二维条形码
     * @param printData  打印的内容
     */
    public Vector<Byte> CMD_Qrcode(String printData) {
        EscCommand esc = new EscCommand();
        esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
        esc.addSelectErrorCorrectionLevelForQRCode((byte) 0x31); //设置纠错等级
        esc.addSelectSizeOfModuleForQRCode((byte) 3);//设置qrcode模块大小
        esc.addStoreQRCodeData(printData);//设置qrcode内容
        esc.addPrintQRCode();//打印QRCode
        esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);
        esc.addPrintAndLineFeed();
        return esc.getCommand();
    }
    /**
     * 打印的一维码
     * @param printData  需要打印的数据
     */
    public Vector<Byte> CMD_Barcode(String printData, Context context) {

         EscCommand esc = new EscCommand();
//        Bitmap b = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
//        px2Byte(0,0,b);
//        esc.addRastBitImage(b, 384, 0); //打印图片
//            esc.addText("printData");
            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
//             /*打印一维条码*/
            esc.addSetBarcodeWidth((byte) 2);
            esc.addSetBarcodeHeight((byte) 60); //设置条码高度为60点
                esc.addSelectPrintingPositionForHRICharacters(EscCommand.HRI_POSITION.BELOW);//设置条码可识别字符位置在条码下方
            esc.addCODE128(printData);  //打印Code128码
            esc.addPrintAndLineFeed();
//            esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);
//            esc.addPrintAndLineFeed();
            return  esc.getCommand();
    }


    /**
     * 走纸
     * @param line  走纸的行数
     */
    public void printLine(int line)
    {
        byte[] command = {27,100,(byte) line};
        addArrayToCommand(command);
    }



    /**
     * 切纸
     */
    public void printCutPage()
    {
        byte[] command = {27,109};
        addArrayToCommand(command);
    }

    /**
     * 打开钱箱
     * @return
     */
    public void printQianXiang() {
        byte[] command = {27,112,0,60,(byte) 255};
        addArrayToCommand(command);
    }
}


发送指令



import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.util.Vector;

public class EscCommand {
  private static final String DEBUG_TAG = "EscCommand";
  Vector<Byte> Command = null;

  public  enum STATUS {
    PRINTER_STATUS(1),
    PRINTER_OFFLINE(2),
    PRINTER_ERROR(3),
    PRINTER_PAPER(4);

    private final int value;

     STATUS(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum ENABLE {
    OFF(0),
    ON(1);

    private final int value;

     ENABLE(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum UNDERLINE_MODE {
    OFF(0),
    UNDERLINE_1DOT(1),
    UNDERLINE_2DOT(2);

    private final int value;

     UNDERLINE_MODE(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum FONT {
    FONTA(0),
    FONTB(1);

    private final int value;

     FONT(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum CHARACTER_SET {
    USA(0),
    FRANCE(1),
    GERMANY(2),
    UK(3),
    DENMARK_I(4),
    SWEDEN(5),
    ITALY(6),
    SPAIN_I(7),
    JAPAN(8),
    NORWAY(9),
    DENMARK_II(10),
    SPAIN_II(11),
    LATIN_AMERCIA(12),
    KOREAN(13),
    SLOVENIA(14),
    CHINA(15);

    private final int value;

     CHARACTER_SET(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum JUSTIFICATION {
    LEFT(0),
    CENTER(1),
    RIGHT(2);

    private final int value;

     JUSTIFICATION(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum CODEPAGE {
    PC437(0),
    KATAKANA(1),
    PC850(2),
    PC860(3),
    PC863(4),
    PC865(5),
    WEST_EUROPE(6),
    GREEK(7),
    HEBREW(8),
    EAST_EUROPE(9),
    IRAN(10),
    WPC1252(16),
    PC866(17),
    PC852(18),
    PC858(19),
    IRANII(20),
    LATVIAN(21),
    ARABIC(22),
    PT151(23),
    PC747(24),
    WPC1257(25),
    VIETNAM(27),
    PC864(28),
    PC1001(29),
    UYGUR(30),
    THAI(255);

    private final int value;

     CODEPAGE(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum WIDTH_ZOOM {
    MUL_1(0), MUL_2(16), MUL_3(32), MUL_4(48), MUL_5(64), MUL_6(80), MUL_7(96), MUL_8(112);

    private final int value;

     WIDTH_ZOOM(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum HEIGHT_ZOOM {
    MUL_1(0), MUL_2(1), MUL_3(2), MUL_4(3), MUL_5(4), MUL_6(5), MUL_7(6), MUL_8(7);

    private final int value;

     HEIGHT_ZOOM(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public  enum HRI_POSITION {
    NO_PRINT(0), ABOVE(1), BELOW(2), ABOVE_AND_BELOW(3);

    private final int value;

     HRI_POSITION(int value) {
      this.value = value;
    }

    public byte getValue() {
      return (byte) this.value;
    }
  }

  public EscCommand() {
    this.Command = new Vector(4096, 1024);
  }

  private void addArrayToCommand(byte[] array) {
    for (int i = 0; i < array.length; i++) {
      this.Command.add(Byte.valueOf(array[i]));
    }
  }


  private void addStrToCommand(String str, String charset) {
    byte[] bs = null;
    if (!str.equals("")) {
      try {
        bs = str.getBytes(charset);
      } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }
      for (int i = 0; i < bs.length; i++) {
        this.Command.add(Byte.valueOf(bs[i]));
      }
    }
  }

  private void addStrToCommand(String str, int length) {
    byte[] bs = null;
    if (!str.equals("")) {
      try {
        bs = str.getBytes("GB2312");
      } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }
      Log.d("EscCommand", "bs.length" + bs.length);
      if (length > bs.length) {
        length = bs.length;
      }
      Log.d("EscCommand", "length" + length);
      for (int i = 0; i < length; i++) {
        this.Command.add(Byte.valueOf(bs[i]));
      }
    }
  }


  public void addText(String text, String charsetName) {
    addStrToCommand(text, charsetName);
  }

  public void addPrintAndLineFeed() {
    byte[] command = {10};
    addArrayToCommand(command);
  }



  public Vector<Byte> getCommand() {
    return this.Command;
  }




  public void addInitializePrinter() {
    byte[] command = {27, 64};
    addArrayToCommand(command);
  }

  public void addTurnEmphasizedModeOnOrOff(ENABLE enabel) {
    byte[] command = new byte[]{(byte)27, (byte)32, enabel.getValue()};
    addArrayToCommand(command);
  }




  /**
   * addSelectJustification(JUSTIFICATION just)
   功能:选择对齐方式
   参数: enum JUSTIFICATION{
   LEFT(0), // 左对齐
   CENTER(1),// 居中对齐
   RIGHT(2);//右对齐
   }

   * @param just
     */
  public void addSelectJustification(JUSTIFICATION just) {

    byte[] command = new byte[]{(byte)27, (byte)97, just.getValue()};
    addArrayToCommand(command);


  }

  /**
   * 添加打印行的指令
   * @param n
     */
  public void addPrintAndFeedLines(byte n) {
    byte[] command = new byte[]{(byte)27, (byte)100, n};
    addArrayToCommand(command);
  }

  public void addGeneratePlus(TscCommand.FOOT foot, byte t1, byte t2) {
    byte[] command = {27, 112, 0, 0, 0};
    command[2] = ((byte) foot.getValue());
    command[3] = t1;
    command[4] = t2;
    addArrayToCommand(command);
  }

  public void addSelectCodePage(CODEPAGE page) {
    byte[] command = {27, 116, 0};
    command[2] = page.getValue();
    addArrayToCommand(command);
  }

  public void addTurnUpsideDownModeOnOrOff(ENABLE enable) {
    byte[] command = {27, 123, 0};
    command[2] = enable.getValue();
    addArrayToCommand(command);
  }

  public void addSetCharcterSize(WIDTH_ZOOM width, HEIGHT_ZOOM height) {
    byte[] command = {29, 33, 0};
    byte temp = 0;
    temp = (byte) (temp | width.getValue());
    temp = (byte) (temp | height.getValue());
    command[2] = temp;
    addArrayToCommand(command);
  }

  public void addTurnReverseModeOnOrOff(ENABLE enable) {
    byte[] command = {29, 66, 0};
    command[2] = enable.getValue();
    addArrayToCommand(command);
  }

  public void addSelectPrintingPositionForHRICharacters(HRI_POSITION position) {
    byte[] command = {29, 72, 0};
    command[2] = position.getValue();
    addArrayToCommand(command);
  }



  public void addSetBarcodeHeight(byte height) {
    byte[] command = new byte[]{(byte) 29, (byte) 104, height};
    this.addArrayToCommand(command);
  }

  public void addSetBarcodeWidth(byte width) {
    byte[] command = new byte[]{(byte)29, (byte)119, (byte)0};
    if(width > 6) {
      width = 6;
    }

    if(width < 2) {
      width = 2;
    }

    command[2] = width;
    this.addArrayToCommand(command);
  }

  public void addSetKanjiFontMode(ENABLE DoubleWidth, ENABLE DoubleHeight, ENABLE Underline) {
    byte[] command = {28, 33, 0};
    byte temp = 0;
    if (DoubleWidth == ENABLE.ON) {
      temp = (byte) (temp | 0x4);
    }
    if (DoubleHeight == ENABLE.ON) {
      temp = (byte) (temp | 0x8);
    }
    if (Underline == ENABLE.ON) {
      temp = (byte) (temp | 0x80);
    }
    command[2] = temp;
    addArrayToCommand(command);
  }

 

  /**
   *
   * @param bitmap  位图
   * @param nWidth  打印宽度(可以用于缩放图片)
     * @param nMode 打印模式 0: 正常 1:倍宽 2:倍高 3:倍宽 倍高
     */
  public void addRastBitImage(Bitmap bitmap, int nWidth, int nMode) {
    if (bitmap != null) {
      int width = (nWidth + 7) / 8 * 8;
      int height = bitmap.getHeight() * width / bitmap.getWidth();
      Bitmap grayBitmap = GpUtils.toGrayscale(bitmap);
      Bitmap rszBitmap = GpUtils.resizeImage(grayBitmap, width, height);
      byte[] src = GpUtils.bitmapToBWPix(rszBitmap);
      byte[] command = new byte[8];
      height = src.length / width;
      command[0] = 29;
      command[1] = 118;
      command[2] = 48;
      command[3] = ((byte) (nMode & 0x1));
      command[4] = ((byte) (width / 8 % 256));
      command[5] = ((byte) (width / 8 / 256));
      command[6] = ((byte) (height % 256));
      command[7] = ((byte) (height / 256));
      addArrayToCommand(command);
      byte[] codecontent = GpUtils.pixToEscRastBitImageCmd(src);
      for (int k = 0; k < codecontent.length; k++) {
        this.Command.add(Byte.valueOf(codecontent[k]));
      }
    } else {
      Log.d("BMP", "bmp.  null ");
    }
  }

  public void addDownloadNvBitImage(Bitmap[] bitmap) {
    if (bitmap != null) {
      Log.d("BMP", "bitmap.length " + bitmap.length);
      int n = bitmap.length;
      if (n > 0) {
        byte[] command = new byte[3];
        command[0] = 28;
        command[1] = 113;
        command[2] = ((byte) n);
        addArrayToCommand(command);
        for (int i = 0; i < n; i++) {
          int height = (bitmap[i].getHeight() + 7) / 8 * 8;
          int width = bitmap[i].getWidth() * height / bitmap[i].getHeight();
          Bitmap grayBitmap = GpUtils.toGrayscale(bitmap[i]);
          Bitmap rszBitmap = GpUtils.resizeImage(grayBitmap, width, height);
          byte[] src = GpUtils.bitmapToBWPix(rszBitmap);
          height = src.length / width;
          Log.d("BMP", "bmp  Width " + width);
          Log.d("BMP", "bmp  height " + height);
          byte[] codecontent = GpUtils.pixToEscNvBitImageCmd(src, width, height);
          for (int k = 0; k < codecontent.length; k++) {
            this.Command.add(Byte.valueOf(codecontent[k]));
          }
        }
      }
    } else {
      Log.d("BMP", "bmp.  null ");
      return;
    }
  }

  public void addPrintNvBitmap(byte n, byte mode) {
    byte[] command = {28, 112, 0, 0};

    command[2] = n;
    command[3] = mode;
    addArrayToCommand(command);
  }

  public void addUPCA(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 65;
    command[3] = 11;
    if (content.length() < command[3]) {
      return;
    }
    addArrayToCommand(command);
    addStrToCommand(content, 11);
  }

  public void addUPCE(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 66;
    command[3] = 11;
    if (content.length() < command[3]) {
      return;
    }
    addArrayToCommand(command);
    addStrToCommand(content, command[3]);
  }

  public void addEAN13(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 67;
    command[3] = 12;
    if (content.length() < command[3]) {
      return;
    }
    addArrayToCommand(command);
    Log.d("EscCommand", "content.length" + content.length());
    addStrToCommand(content, command[3]);
  }

  public void addEAN8(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 68;
    command[3] = 7;
    if (content.length() < command[3]) {
      return;
    }
    addArrayToCommand(command);
    addStrToCommand(content, command[3]);
  }

  @SuppressLint({"DefaultLocale"})
  public void addCODE39(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 69;
    command[3] = ((byte) content.length());
    content = content.toUpperCase();
    addArrayToCommand(command);
    addStrToCommand(content, command[3]);
  }

  public void addITF(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 70;
    command[3] = ((byte) content.length());
    addArrayToCommand(command);
    addStrToCommand(content, command[3]);
  }

  public void addCODABAR(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 71;
    command[3] = ((byte) content.length());
    addArrayToCommand(command);
    addStrToCommand(content, command[3]);
  }

  public void addCODE93(String content) {
    byte[] command = new byte[4];
    command[0] = 29;
    command[1] = 107;
    command[2] = 72;
    command[3] = ((byte) content.length());
    addArrayToCommand(command);
    addStrToCommand(content, command[3]);
  }

  public void addCODE128(String content) {
    byte[] data = content.getBytes();

    if (data[0] != 123)
    {
      byte[] command = new byte[]{(byte)29, (byte)107, (byte)73, (byte)(content.length() + 2), (byte)123, (byte)66};
      this.addArrayToCommand(command);
    }
    else {
      byte[] command = new byte[]{(byte)29, (byte)107, (byte)73, (byte)content.length()};
      this.addArrayToCommand(command);
    }

    this.addStrToCommand(content, content.length());


  }

  /**
   * 功能:设置QRCode的单元模块大小
   参数:n: 单元模块为n点 默认为3点
   返回值:无
   相关指令:GP58编程手册 GS ( k <Function 167>

   * @param n
     */
  public void addSelectSizeOfModuleForQRCode(byte n) {
    byte[] command = {29, 40, 107, 3, 0, 49, 67, 3};
    command[7] = n;
    addArrayToCommand(command);
  }

  public void addSelectErrorCorrectionLevelForQRCode(byte n) {
    byte[] command = new byte[]{29, 40, 107, 3, 0, 49, 69, n};
    addArrayToCommand(command);
  }

  public void addStoreQRCodeData(String content) {
    byte[] command = {29, 40, 107, 0, 0, 49, 80, 48};
    command[3] = ((byte) ((content.length() + 3) % 256));
    command[4] = ((byte) ((content.length() + 3) / 256));
    addArrayToCommand(command);
    addStrToCommand(content, content.length());
  }

  public void addPrintQRCode() {

    byte[] command = {29, 40, 107, 3, 0, 49, 81, 48};
    addArrayToCommand(command);
  }

  public void addUserCommand(byte[] command) {
    addArrayToCommand(command);
  }
}


工具类



  import android.graphics.Bitmap;
  import android.graphics.Canvas;
  import android.graphics.ColorMatrix;
  import android.graphics.ColorMatrixColorFilter;
  import android.graphics.Matrix;
  import android.graphics.Paint;
  import android.graphics.Bitmap.CompressFormat;
  import android.graphics.Bitmap.Config;
  import android.os.Environment;
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.UnsupportedEncodingException;

public class GpUtils {
  private static int[] p0 = new int[]{0, 128};
  private static int[] p1 = new int[]{0, 64};
  private static int[] p2 = new int[]{0, 32};
  private static int[] p3 = new int[]{0, 16};
  private static int[] p4 = new int[]{0, 8};
  private static int[] p5 = new int[]{0, 4};
  private static int[] p6 = new int[]{0, 2};
  private static int[][] Floyd16x16 = new int[][]{{0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170}, {192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106}, {48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154}, {240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90}, {12, 140, 44, 172, 4, 132, 36, 164, 14, 142, 46, 174, 6, 134, 38, 166}, {204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102}, {60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150}, {252, 124, 220, 92, 244, 116, 212, 84, 254, 126, 222, 94, 246, 118, 214, 86}, {3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169}, {195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105}, {51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153}, {243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89}, {15, 143, 47, 175, 7, 135, 39, 167, 13, 141, 45, 173, 5, 133, 37, 165}, {207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101}, {63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149}, {254, 127, 223, 95, 247, 119, 215, 87, 253, 125, 221, 93, 245, 117, 213, 85}};
  private static int[][] Floyd8x8 = new int[][]{{0, 32, 8, 40, 2, 34, 10, 42}, {48, 16, 56, 24, 50, 18, 58, 26}, {12, 44, 4, 36, 14, 46, 6, 38}, {60, 28, 52, 20, 62, 30, 54, 22}, {3, 35, 11, 43, 1, 33, 9, 41}, {51, 19, 59, 27, 49, 17, 57, 25}, {15, 47, 7, 39, 13, 45, 5, 37}, {63, 31, 55, 23, 61, 29, 53, 21}};
  public static final int ALGORITHM_DITHER_16x16 = 16;
  public static final int ALGORITHM_DITHER_8x8 = 8;
  public static final int ALGORITHM_TEXTMODE = 2;
  public static final int ALGORITHM_GRAYTEXTMODE = 1;

  public GpUtils() {
  }

  public static Bitmap resizeImage(Bitmap bitmap, int w, int h) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    float scaleWidth = (float)w / (float)width;
    float scaleHeight = (float)h / (float)height;
    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    return resizedBitmap;
  }

  public static void saveMyBitmap(Bitmap mBitmap) {
    File f = new File(Environment.getExternalStorageDirectory().getPath(), "Btatotest.jpeg");

    try {
      f.createNewFile();
    } catch (IOException var6) {
      ;
    }

    FileOutputStream fOut = null;

    try {
      fOut = new FileOutputStream(f);
      mBitmap.compress(CompressFormat.PNG, 100, fOut);
      fOut.flush();
      fOut.close();
    } catch (FileNotFoundException var4) {
      ;
    } catch (IOException var5) {
      ;
    }

  }

  public static Bitmap toGrayscale(Bitmap bmpOriginal) {
    int height = bmpOriginal.getHeight();
    int width = bmpOriginal.getWidth();
    Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Config.RGB_565);
    Canvas c = new Canvas(bmpGrayscale);
    Paint paint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0.0F);
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
    paint.setColorFilter(f);
    c.drawBitmap(bmpOriginal, 0.0F, 0.0F, paint);
    return bmpGrayscale;
  }

  static byte[] pixToEscRastBitImageCmd(byte[] src, int nWidth, int nMode) {
    int nHeight = src.length / nWidth;
    byte[] data = new byte[8 + src.length / 8];
    data[0] = 29;
    data[1] = 118;
    data[2] = 48;
    data[3] = (byte)(nMode & 1);
    data[4] = (byte)(nWidth / 8 % 256);
    data[5] = (byte)(nWidth / 8 / 256);
    data[6] = (byte)(nHeight % 256);
    data[7] = (byte)(nHeight / 256);
    int i = 8;

    for(int k = 0; i < data.length; ++i) {
      data[i] = (byte)(p0[src[k]] + p1[src[k + 1]] + p2[src[k + 2]] + p3[src[k + 3]] + p4[src[k + 4]] + p5[src[k + 5]] + p6[src[k + 6]] + src[k + 7]);
      k += 8;
    }

    return data;
  }

  public static byte[] pixToEscRastBitImageCmd(byte[] src) {
    byte[] data = new byte[src.length / 8];
    int i = 0;

    for(int k = 0; i < data.length; ++i) {
      data[i] = (byte)(p0[src[k]] + p1[src[k + 1]] + p2[src[k + 2]] + p3[src[k + 3]] + p4[src[k + 4]] + p5[src[k + 5]] + p6[src[k + 6]] + src[k + 7]);
      k += 8;
    }

    return data;
  }

  static byte[] pixToEscNvBitImageCmd(byte[] src, int width, int height) {
    byte[] data = new byte[src.length / 8 + 4];
    data[0] = (byte)(width / 8 % 256);
    data[1] = (byte)(width / 8 / 256);
    data[2] = (byte)(height / 8 % 256);
    data[3] = (byte)(height / 8 / 256);
    boolean k = false;

    for(int i = 0; i < width; ++i) {
      int var7 = 0;

      for(int j = 0; j < height / 8; ++j) {
        data[4 + j + i * height / 8] = (byte)(p0[src[i + var7]] + p1[src[i + var7 + 1 * width]] + p2[src[i + var7 + 2 * width]] + p3[src[i + var7 + 3 * width]] + p4[src[i + var7 + 4 * width]] + p5[src[i + var7 + 5 * width]] + p6[src[i + var7 + 6 * width]] + src[i + var7 + 7 * width]);
        var7 += 8 * width;
      }
    }

    return data;
  }

  public static byte[] pixToTscCmd(byte[] src) {
    byte[] data = new byte[src.length / 8];
    int k = 0;

    for(int j = 0; k < data.length; ++k) {
      byte temp = (byte)(p0[src[j]] + p1[src[j + 1]] + p2[src[j + 2]] + p3[src[j + 3]] + p4[src[j + 4]] + p5[src[j + 5]] + p6[src[j + 6]] + src[j + 7]);
      data[k] = (byte)(~temp);
      j += 8;
    }

    return data;
  }

  public static byte[] pixToTscCmd(int x, int y, int mode, byte[] src, int nWidth) {
    int height = src.length / nWidth;
    int width = nWidth / 8;
    String str = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ",";
    byte[] bitmap = null;

    try {
      bitmap = str.getBytes("GB2312");
    } catch (UnsupportedEncodingException var13) {
      var13.printStackTrace();
    }

    byte[] arrayOfByte = new byte[src.length / 8];
    int data = 0;

    for(int j = 0; data < arrayOfByte.length; ++data) {
      byte temp = (byte)(p0[src[j]] + p1[src[j + 1]] + p2[src[j + 2]] + p3[src[j + 3]] + p4[src[j + 4]] + p5[src[j + 5]] + p6[src[j + 6]] + src[j + 7]);
      arrayOfByte[data] = (byte)(~temp);
      j += 8;
    }

    byte[] var14 = new byte[bitmap.length + arrayOfByte.length];
    System.arraycopy(bitmap, 0, var14, 0, bitmap.length);
    System.arraycopy(arrayOfByte, 0, var14, bitmap.length, arrayOfByte.length);
    return var14;
  }

  private static void format_K_dither16x16(int[] orgpixels, int xsize, int ysize, byte[] despixels) {
    int k = 0;

    for(int y = 0; y < ysize; ++y) {
      for(int x = 0; x < xsize; ++x) {
        if((orgpixels[k] & 255) > Floyd16x16[x & 15][y & 15]) {
          despixels[k] = 0;
        } else {
          despixels[k] = 1;
        }

        ++k;
      }
    }

  }

  public static byte[] bitmapToBWPix(Bitmap mBitmap) {
    int[] pixels = new int[mBitmap.getWidth() * mBitmap.getHeight()];
    byte[] data = new byte[mBitmap.getWidth() * mBitmap.getHeight()];
    Bitmap grayBitmap = toGrayscale(mBitmap);
    grayBitmap.getPixels(pixels, 0, mBitmap.getWidth(), 0, 0, mBitmap.getWidth(), mBitmap.getHeight());
    format_K_dither16x16(pixels, grayBitmap.getWidth(), grayBitmap.getHeight(), data);
    return data;
  }

  private static void format_K_dither16x16_int(int[] orgpixels, int xsize, int ysize, int[] despixels) {
    int k = 0;

    for(int y = 0; y < ysize; ++y) {
      for(int x = 0; x < xsize; ++x) {
        if((orgpixels[k] & 255) > Floyd16x16[x & 15][y & 15]) {
          despixels[k] = -1;
        } else {
          despixels[k] = -16777216;
        }

        ++k;
      }
    }

  }

  private static void format_K_dither8x8_int(int[] orgpixels, int xsize, int ysize, int[] despixels) {
    int k = 0;

    for(int y = 0; y < ysize; ++y) {
      for(int x = 0; x < xsize; ++x) {
        if((orgpixels[k] & 255) >> 2 > Floyd8x8[x & 7][y & 7]) {
          despixels[k] = -1;
        } else {
          despixels[k] = -16777216;
        }

        ++k;
      }
    }

  }

  public static int[] bitmapToBWPix_int(Bitmap mBitmap, int algorithm) {
    int[] pixels = new int[0];
    Bitmap grayBitmap;
    switch(algorithm) {
      case 2:
        break;
      case 8:
        grayBitmap = toGrayscale(mBitmap);
        pixels = new int[grayBitmap.getWidth() * grayBitmap.getHeight()];
        grayBitmap.getPixels(pixels, 0, grayBitmap.getWidth(), 0, 0, grayBitmap.getWidth(), grayBitmap.getHeight());
        format_K_dither8x8_int(pixels, grayBitmap.getWidth(), grayBitmap.getHeight(), pixels);
        break;
      case 16:
      default:
        grayBitmap = toGrayscale(mBitmap);
        pixels = new int[grayBitmap.getWidth() * grayBitmap.getHeight()];
        grayBitmap.getPixels(pixels, 0, grayBitmap.getWidth(), 0, 0, grayBitmap.getWidth(), grayBitmap.getHeight());
        format_K_dither16x16_int(pixels, grayBitmap.getWidth(), grayBitmap.getHeight(), pixels);
    }

    return pixels;
  }

  public static Bitmap toBinaryImage(Bitmap mBitmap, int nWidth, int algorithm) {
    int width = (nWidth + 7) / 8 * 8;
    int height = mBitmap.getHeight() * width / mBitmap.getWidth();
    Bitmap rszBitmap = resizeImage(mBitmap, width, height);
    int[] pixels = bitmapToBWPix_int(rszBitmap, algorithm);
    rszBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return rszBitmap;
  }
}

参考以下指令集

【esc/pos打印指令 (小寿转载)-xiaoshou330-ChinaUnix博客】 http://m.blog.chinaunix.net/uid-7491192-id-2051201.html

【esc打印控制命令集 - 豆丁网】
http://m.docin.com/p2-1229264477.html

android 控制POS机图文打印(二)
http://blog.csdn.net/sdvch/article/details/45096057

Android 蓝牙连接 ESC/POS 热敏打印机打印(ESC/POS指令篇)
http://www.jianshu.com/p/c0b6d1a4823b

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容