英文:
Print Image to Printer Thermal but the result give weird character Android
问题
我为Google Chrome浏览器构建了打印服务。从技术上讲,我将PDF转换为图像,然后将其转换为字节数组,然后进行打印。但在某些设备上,结果会出现奇怪的字符。以下是代码:
PrintService.class
byte[] image = bitmapToBytes(rescaledBitmap, false);
byte[][] bytesToPrint = convertGSv0ToEscAsterisk(image);
timestamp = new Timestamp(System.currentTimeMillis());
for (byte[] bytes : bytesToPrint) {
this.mOutputStream.write(bytes);
this.mOutputStream.flush();
}
String endLine = "\n\n\n\n\n";
this.mOutputStream.write(endLine.getBytes());
....
....
public static byte[] bitmapToBytes(Bitmap bitmap, boolean gradient) {
// 省略部分代码
return imageBytes;
}
public static byte[][] convertGSv0ToEscAsterisk(byte[] bytes) {
// 省略部分代码
return returnedBytes;
}
在某些设备上,结果如下所示:
但在某些设备上,结果也是正常的。我陷入了修复这个问题几天了。是否有其他将位图转换为字节数组以供热敏打印机打印的方法?非常感谢任何建议。
英文:
I build print service for Google Chrome browser. technically I convert the PDF into image then convert it to byte array then do print. But on some device give the weird character on result. Here is the code :
PrintService.class
byte[] image = bitmapToBytes(rescaledBitmap, false);
byte[][] bytesToPrint = convertGSv0ToEscAsterisk(image);
timestamp = new Timestamp(System.currentTimeMillis());
for (byte[] bytes : bytesToPrint) {
this.mOutputStream.write(bytes);
this.mOutputStream.flush();
}
String endLine = "\n\n\n\n\n";
this.mOutputStream.write(endLine.getBytes());
....
....
public static byte[] bitmapToBytes(Bitmap bitmap, boolean gradient) {
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
int bytesByLine = (bitmapWidth + 7) / 8;
byte[] imageBytes = new byte[bytesByLine * bitmapHeight + 8];
int i = 8;
int greyscaleCoefficientInit = 0;
int gradientStep = 6;
double colorLevelStep = 765.0 / (15 * gradientStep + gradientStep - 1);
for (int posY = 0; posY < bitmapHeight; posY++) {
int greyscaleCoefficient = greyscaleCoefficientInit;
int greyscaleLine = posY % gradientStep;
for (int j = 0; j < bitmapWidth; j += 8) {
int b = 0;
for (int k = 0; k < 8; k++) {
int posX = j + k;
if (posX < bitmapWidth) {
int color = bitmap.getPixel(posX, posY);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
if ((gradient && (red + green + blue) < ((greyscaleCoefficient * gradientStep + greyscaleLine) * colorLevelStep))
|| (!gradient && (red < 160 || green < 160 || blue < 160))) {
b |= 1 << (7 - k);
}
greyscaleCoefficient += 5;
if (greyscaleCoefficient > 15) {
greyscaleCoefficient -= 16;
}
}
}
imageBytes[i++] = (byte) b;
}
greyscaleCoefficientInit += 2;
if (greyscaleCoefficientInit > 15) {
greyscaleCoefficientInit = 0;
}
}
imageBytes[4] = (byte) (bytesByLine & 0xFF);
imageBytes[5] = (byte) ((bytesByLine >> 8) & 0xFF);
imageBytes[6] = (byte) (bitmapHeight & 0xFF);
imageBytes[7] = (byte) ((bitmapHeight >> 8) & 0xFF);
return imageBytes;
}
public static byte[][] convertGSv0ToEscAsterisk(byte[] bytes) {
final byte LF = 0x0A;
final byte[] LINE_SPACING_30 = {0x1b, 0x33, 0x1e};
final byte[] LINE_SPACING_24 = {0x1b, 0x33, 0x18};
int
xL = bytes[4] & 0xFF,
xH = bytes[5] & 0xFF,
yL = bytes[6] & 0xFF,
yH = bytes[7] & 0xFF,
bytesByLine = xH * 256 + xL,
dotsByLine = bytesByLine * 8,
nH = dotsByLine / 256,
nL = dotsByLine % 256,
imageHeight = yH * 256 + yL,
imageLineHeightCount = (int) Math.ceil((double) imageHeight / 24.0),
imageBytesSize = 6 + bytesByLine * 24;
byte[][] returnedBytes = new byte[imageLineHeightCount + 2][];
returnedBytes[0] = LINE_SPACING_24;
for (int i = 0; i < imageLineHeightCount; ++i) {
int pxBaseRow = i * 24;
byte[] imageBytes = new byte[imageBytesSize];
imageBytes[0] = 0x1B;
imageBytes[1] = 0x2A;
imageBytes[2] = 0x21;
imageBytes[3] = (byte) nL;
imageBytes[4] = (byte) nH;
for (int j = 5; j < imageBytes.length; ++j) {
int
imgByte = j - 5,
byteRow = imgByte % 3,
pxColumn = imgByte / 3,
bitColumn = 1 << (7 - pxColumn % 8),
pxRow = pxBaseRow + byteRow * 8;
for (int k = 0; k < 8; ++k) {
int indexBytes = bytesByLine * (pxRow + k) + pxColumn / 8 + 8;
if (indexBytes >= bytes.length) {
break;
}
boolean isBlack = (bytes[indexBytes] & bitColumn) == bitColumn;
if (isBlack) {
imageBytes[j] |= 1 << 7 - k;
}
}
}
imageBytes[imageBytes.length - 1] = LF;
returnedBytes[i + 1] = imageBytes;
}
returnedBytes[returnedBytes.length - 1] = LINE_SPACING_30;
return returnedBytes;
}
On some device, result is like below below :
But on some device the result is normal too. I stuck fixing this for couple days. Is there another method to convert bitmap to byte array for printing to thermal printer? I really appreciate any suggestion.
答案1
得分: 0
这个问题发生是因为打印处理仍在运行,但套接字已关闭。所以奇怪的字符是之前进程的一部分。但这个问题只在一些打印机设备上发生(具有相同长度的字节)。所以我添加了一些用户界面(以秒为单位)来定义在打印后关闭套接字的时间(默认为0)。
for (byte[] bytes : bytesToPrint) {
this.mOutputStream.write(bytes);
this.mOutputStream.flush();
}
String endLine = "\n\n\n\n\n";
this.mOutputStream.write(endLine.getBytes());
Handler handler = new Handler();
handler.postDelayed(() -> {
try {
closeBTPrinter();
} catch (IOException e) {
e.printStackTrace();
}
}, socketTimeOut);
英文:
This problem occur because print processing still running but the socket was close. So the weird character is part of previous process. But this problem only occur in some printer devices (with same length bytes). So I add some UI (time in second) for user to define time to close socket after printing (by default still is 0).
for (byte[] bytes : bytesToPrint) {
this.mOutputStream.write(bytes);
this.mOutputStream.flush();
}
String endLine = "\n\n\n\n\n";
this.mOutputStream.write(endLine.getBytes());
Handler handler = new Handler();
handler.postDelayed(() -> {
try {
closeBTPrinter();
} catch (IOException e) {
e.printStackTrace();
}
}, socketTimeOut);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论