最近做项目有碰到使用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 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 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 Command = esc.getCommand();
Vector 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 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 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 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 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
* @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