Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印
程序员文章站
2022-03-21 18:40:26
Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印一、前言Android 打印解决文字显示?问好 乱码最近在处理打印的时候,打印机有些繁体的字无法打印出来,或者其它韩文打印出来显示 ? 问题解决思路:将需要打印的 String 文本内容,先转换成 Bitmap 位图 , 然后将图片转换成打印机能打印的byte[]类型不同印机 最终丢给印机打印的方法不同。如下图,打印的是一栏地址,原来第三个字呢打印出来是 ? 号的 ,这张图是用以下的转换方法修复...
Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印
一、前言
Android 打印解决文字显示?问好 乱码
最近在处理打印的时候,打印机有些繁体的字无法打印出来,或者其它韩文打印出来显示 ? 问题
解决思路:
将需要打印的 String 文本内容,先转换成 Bitmap 位图 , 然后将图片转换成打印机能打印的byte[]类型
不同印机 最终丢给印机打印的方法不同。
如下图,打印的是一栏地址,原来第三个字呢打印出来是 ? 号的 ,这张图是用以下的转换方法修复后的。
使用印机都是 EPSON,其它也类似。
左边的是 网络打印 (通过 OutputStream 流的方式 将 byte[] 写入 到缓冲区)
右边的是 USB 连接 EPSON 打印 (通过EPSON SDK的方法,addImage() ) 打印出来的很OK
其实还有一个问题就是,通过网络传递的Esc 指令打印之后,打印文字可能打印像素有点不全的问题 ,我感觉是 下面的 genBitmapCode 方法 转换出来的时候,像素精度还是什么问题 ,如果有好的解决方式 请给我留言 谢谢。
下面提供了 ,创建Bitmap 图片, 创建 QRCode 二维码图片 ,转换成 Bytes 数组 进行打印
二、将文字转换成Bitmap
/**
* 根据文字创建一个 bitmap , 打印的位图需要 黑字 白底
*
* @param text
* @param height
* @param width
* @return
*/
public Bitmap getNewBitMap(String text, int height, int width) {
Bitmap newBitmap = createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(newBitmap, 0, 0, null);
TextPaint textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(height * 2 / 3);
// textPaint.setColor(Color.rgb(0, 0, 0));
textPaint.setColor(Color.BLACK);
// "在Android开发中,Canvas.drawText不会换行,即使一个很长的字符串也只会显示一行,超出部分会隐藏在屏幕之外.StaticLayout是android中处理文字的一个工具类,StaticLayout 处理了文字换行的问题";
StaticLayout sl = new StaticLayout(text, textPaint, newBitmap.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
textPaint.setStyle(Paint.Style.FILL);
canvas.translate(0, height / 10);
sl.draw(canvas);
return newBitmap;
}
/**
* 生成二维码bitmap 要转换的地址或字符串,可以是中文
*
* @param url
* @param width
* @param height
* @return
*/
public Bitmap createQRImage(String url, final int width, final int height) {
try {
// 判断URL合法性
if (url == null || "".equals(url) || url.length() < 1) {
return null;
}
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
// 图像数据转换,使用了矩阵转换
BitMatrix bitMatrix = new QRCodeWriter().encode(url,
BarcodeFormat.QR_CODE, width, height, hints);
int[] pixels = new int[width * height];
// 下面这里按照二维码的算法,逐个生成二维码的图片,
// 两个for循环是图片横列扫描的结果
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (bitMatrix.get(x, y)) {
pixels[y * width + x] = 0xff000000;
} else {
pixels[y * width + x] = 0xffffffff;
}
}
}
// 生成二维码图片的格式,使用ARGB_8888
Bitmap bitmap = createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
三、把图片转换成POS机能打印的byte[]类型
/**
* 将图片转换成POS机能打印的byte[]类型
*
* @param bm
* @param doubleWidth
* @param doubleHeight
* @return
*/
private static byte[] genBitmapCode(Bitmap bm, boolean doubleWidth, boolean doubleHeight) {
int w = bm.getWidth();
int h = bm.getHeight();
// if(w > MAX_BIT_WIDTH)
// w = MAX_BIT_WIDTH;
int bitw = ((w + 7) / 8) * 8;
int bith = h;
int pitch = bitw / 8;
byte[] cmd = {0x1D, 0x76, 0x30, 0x00, (byte) (pitch & 0xff), (byte) ((pitch >> 8) & 0xff), (byte) (bith & 0xff), (byte) ((bith >> 8) & 0xff)};
byte[] bits = new byte[bith * pitch];
// 倍宽
if (doubleWidth) {
cmd[3] |= 0x01;
}
// 倍高
if (doubleHeight) {
cmd[3] |= 0x02;
}
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int color = bm.getPixel(x, y);
if ((color & 0xFF) < 128) {
bits[y * pitch + x / 8] |= (0x80 >> (x % 8));
}
}
}
ByteBuffer bb = ByteBuffer.allocate(cmd.length + bits.length);
bb.put(cmd);
bb.put(bits);
return bb.array();
}
四、调用打印文本方式
//生成的bitmap 显示 固定是一行 ,如果要生成多行,需要自行通过文本控制Bitmap的宽高
Bitmap newBitMap = getNewBitMap(IMAGE, 20, 300);
byte[] bytes = genBitmapCode(newBitMap, true, true);
//此方式是网络打印 通过 OutputStream 流的方式 将 byte[] 写入 到缓冲区
socketOut.write(bytes);
五、EPSON 爱普生 中打印图片的方式
//创建单行文字
Bitmap newBitMap = getNewBitMap(IMAGE, 40, 600);
//打印图片 方式 1 打印出来很漂亮
mPrinter.addImage(newBitMap, 0, 0,
newBitMap.getWidth(),
newBitMap.getHeight(),
Printer.COLOR_1,
Printer.MODE_MONO,
Printer.HALFTONE_DITHER,
Printer.PARAM_DEFAULT,
Printer.COMPRESS_AUTO);
// 方式2 打印出来 有少像素没打全
Bitmap newBitMap = getNewBitMap(IMAGE, 20, 300);
byte[] bytes = genBitmapCode(newBitMap, true, true);
mPrinter.addCommand(bytes)
六、调用打印二维码图片
Bitmap qrImage = createQRImage("qr123456", 170, 170);
byte[] bytes = genBitmapCode(qrImage, true, true);
socketOut.write(bytes);
以上代码只是作为一个参考思路, 主要是 将 String 转换 为 Bitmap ,再丢给打印机 进行打印。
不同印机应优选考虑不同的调用方式,如果是 USB 连接 EPSON 的话 其实也支持 Esc 指令 进行命令打印的。
网络打印的话,只能传递 Esc 指令集 通过流的方式传输进行打印了。
本文地址:https://blog.csdn.net/a23006239/article/details/107868456