一、通用方式(cpcl和zpl)
public static String convertImageToHex(Bitmap orginalImage){
StringBuffer sb = new StringBuffer();
int height = orginalImage.getHeight();
int width = orginalImage.getWidth();
int rgb, red, green, blue, index = 0;
char auxBinaryChar[] = {'0', '0', '0', '0', '0', '0', '0', '0'};
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
rgb = orginalImage.getPixel(w,h);
red = (rgb >> 16) & 0x000000FF;
green = (rgb >> 8) & 0x000000FF;
blue = (rgb) & 0x000000FF;
char auxChar = '1';
int totalColor = red + green + blue;
if (totalColor > 450) {
auxChar = '0';
}
auxBinaryChar[index] = auxChar;
index++;
if (index == 8 || w == (width - 1)) {
int decimal = Integer.parseInt(new String(auxBinaryChar), 2);
String hex = decimal > 15 ? Integer.toString(decimal, 16).toUpperCase() : "0" + Integer.toString(decimal, 16).toUpperCase();
sb.append(hex);
auxBinaryChar = new char[]{'0', '0', '0', '0', '0', '0', '0', '0'};
index = 0;
}
}
}
return sb.toString();
}
cpcl:"EG " + width + " " + height * 8 + " 0" + " 0" + " " + imgHex
zpl:"^GFA," + width * height * 8 + "," + width * height * 8 + "," + width + "," + imgHex
二、压缩方式(仅zpl)
public class ZPLBitmapUtil {
//调用此方法,可获取到完成的ZPL指令集的位图指令和数据
public byte[] getPrintImageBytes(int x, int y, int width, int height, Bitmap bitmap)
throws IOException, InterruptedException {
String charset = "GB18030";
byte[] bytes0 = String.format("^XA^PW%d^LL%d\r\n", width, height).getBytes(charset);
int imgWidth = bitmap.getWidth();
int imgHeight = bitmap.getHeight();
int widthBytes = (imgWidth + 31) / 32 * 32 / 8;
byte[] bytes1 = String.format("~DGR:PRNBUF.GRF,%d,%d,", widthBytes*imgHeight, widthBytes).getBytes(charset);
byte[] cg_image = OverImage(bitmap);
byte[] bytes3 = String.format("^FO%d,%d^XGR:PRNBUF.GRF,1,1^FS", x, y).getBytes(charset);
byte[] bytes4 = String.format("^PQ%d,,%d^XZ\r\n", 1, 1).getBytes(charset);
int totalLen = bytes0.length + bytes1.length + cg_image.length + bytes3.length + bytes4.length;
byte[] totalBytes = new byte[totalLen];
int destPos = 0;
System.arraycopy(bytes0, 0, totalBytes, destPos, bytes0.length);
destPos = bytes0.length;
System.arraycopy(bytes1, 0, totalBytes, destPos, bytes1.length);
destPos = bytes0.length + bytes1.length;
System.arraycopy(cg_image, 0, totalBytes, destPos, cg_image.length);
destPos = bytes0.length + bytes1.length + cg_image.length;
System.arraycopy(bytes3, 0, totalBytes, destPos, bytes3.length);
destPos = bytes0.length + bytes1.length + cg_image.length + bytes3.length;
System.arraycopy(bytes4, 0, totalBytes, destPos, bytes4.length);
return totalBytes;
}
//调用此方法,仅生成位图数据
private static byte[] OverImage(Bitmap cg_image) throws IOException, InterruptedException {
//参数判断
if (cg_image == null) {
throw new IllegalArgumentException();
}
int width = cg_image.getWidth();
int height = cg_image.getHeight();
int widthBytes = (width + 31) / 32 * 32 / 8;
int imageDataLen = height * widthBytes;
byte[] bitampData = new byte[imageDataLen + 62];
Arrays.fill(bitampData, (byte) 0);
byte[] compressData1 = new byte[(imageDataLen + 62) * 2];
int error_code = ImageFormatConvertPixels(cg_image, bitampData);
if (error_code < 0) {
throw new IllegalArgumentException();
}
for (int i = 0; i < bitampData.length; i++) {
bitampData[i] = (byte) ~bitampData[i];
}
int row, col;
byte[] BitMask0 = {0x7F, (byte) 0xBF, (byte) 0xDF, (byte) 0xEF, (byte) 0xF7, (byte) 0xFB,
(byte) 0xFD, (byte) 0xFE};
for (row = 0; row < height; row++) {
for (col = width; col < widthBytes * 8; col++) {
bitampData[row * widthBytes + (col / 8)] &= BitMask0[col & 0x07];
}
}
for (row = 0; row < height / 2; row++) {
byte[] temp = new byte[widthBytes];
System.arraycopy(bitampData, (height - row - 2) * widthBytes, temp, 0, widthBytes);
System.arraycopy(bitampData, row * widthBytes, bitampData, (height - row - 2) * widthBytes, widthBytes);
System.arraycopy(temp, 0, bitampData, row * widthBytes, widthBytes);
}
int destImageDataLen = GRFDataCompress(bitampData, imageDataLen, widthBytes, compressData1);
byte[] compressData2 = new byte[destImageDataLen];
System.arraycopy(compressData1, 0, compressData2, 0, destImageDataLen);
return compressData2;
}
/*********************以下为位图处理功能,无需关注************************************/
private static int ImageFormatConvertPixels(Bitmap cg_image, byte[] data_buf) {
if (cg_image == null) {
return -1;
}
int imageHSrc = cg_image.getHeight();
int imageWSrc = cg_image.getWidth();
int[] pixels = new int[imageWSrc * imageHSrc];
cg_image.getPixels(pixels, 0, imageWSrc, 0, 0, imageWSrc, imageHSrc); // int 0 代表0XFFFFFFFF,即是1.0完全不透明,0.0f完全透明。黑色完全透明。
int imageRowBytes;
int index = 0;
byte BitMask[] = {(byte) 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
for (int rowIndexSrc = imageHSrc - 1; rowIndexSrc >= 0; rowIndexSrc--) {
imageRowBytes = index;
int bit = 0;
for (int colIndexSrc = 0; colIndexSrc < imageWSrc; colIndexSrc++) {
int gray = pixels[colIndexSrc + rowIndexSrc * imageWSrc];
int grayVal = getGreyLevel(gray, (float) 1.0);
if (grayVal > 127) {
data_buf[imageRowBytes] |= BitMask[bit];
}
bit++;
if (bit >= 8) {
bit = 0;
imageRowBytes++;
}
}
index = index + (imageWSrc + 31) / 32 * 32 / 8;
}
return 0;
}
private static int getGreyLevel(int pixel, float intensity) {
float red = Color.red(pixel);
float green = Color.green(pixel);
float blue = Color.blue(pixel);
float parcial = red + green + blue;
parcial = (float) (parcial / 3.0);
int gray = (int) (parcial * intensity);
if (gray > 255) {
gray = 255;
}
return gray;
}
private static int GRFDataCompress(byte[] sourceImageData, int sourceImageDataLen, int bytesPerLine, byte[] destImageData) throws IOException, InterruptedException {
int i, j, k;
int count, num1;
byte curByte4Bits, curChar, PreChar;
int sameCount, index = 0;
int height = sourceImageDataLen / bytesPerLine;
for (i = 0; i < height; i++) {
if (i >= 1) {
for (k = 0, count = 0; k < bytesPerLine; k++) {
if (sourceImageData[i * bytesPerLine + k] == sourceImageData[(i - 1) * bytesPerLine + k]) {
count++;
continue;
}
break;
}
if (count == bytesPerLine) {
destImageData[index++] = ':';
continue;
}
}
curByte4Bits = (byte) ((sourceImageData[i * bytesPerLine] & 0xff) >> 4);
PreChar = (byte) ((curByte4Bits >= 0 && curByte4Bits <= 9) ? (curByte4Bits + '0') : ('A' + (curByte4Bits - 10)));
j = 1;
sameCount = 0;
while (j < bytesPerLine * 2) {
num1 = 0;
if (j % 2 == 0) {
for (k = j / 2; k < bytesPerLine; k++) {
if ((sourceImageData[i * bytesPerLine + k] & 0xff) == 0) {
num1++;
continue;
}
break;
}
if (num1 == bytesPerLine - (j / 2) && num1 > 1) {
if (PreChar != '0') {
if (sameCount > 0) {
sameCount++;
}
index = GRFWriteData(PreChar, sameCount, destImageData, index);
sameCount = 0;
}
destImageData[index++] = ',';
break;
}
}
if (j % 2 == 0) {
curByte4Bits = (byte) ((sourceImageData[i * bytesPerLine + (j / 2)] & 0xff) >> 4);
} else {
curByte4Bits = (byte) ((sourceImageData[i * bytesPerLine + (j / 2)] & 0xff) & 0x0f);
}
curChar = (byte) ((curByte4Bits >= 0 && curByte4Bits <= 9) ? (curByte4Bits + '0') : ('A' + (curByte4Bits - 10)));
if (curChar == PreChar) {
sameCount++;
} else if (curChar != PreChar) {
if (sameCount > 0) {
sameCount++;
}
index = GRFWriteData(PreChar, sameCount, destImageData, index);
sameCount = 0;
}
PreChar = curChar;
if (j == bytesPerLine * 2 - 1) {
if (bytesPerLine == 1 && sameCount == 1) {
if (curChar == '0') {
destImageData[index++] = ',';
} else if (curChar == '1') {
destImageData[index++] = '!';
}
} else {
if (sameCount > 0) {
sameCount++;
}
index = GRFWriteData(PreChar, sameCount, destImageData, index);
sameCount = 0;
}
}
j++;
}
destImageData[index++] = 0x0d;
destImageData[index++] = 0x0a;
}
return index;
}
private static int GRFWriteData(byte PreChar, int count, byte[] destImageData, int index) {
int n1 = count / 400;
int n2 = count % 400;
int n3 = n2 / 20;
int n4 = n2 % 20;
for (int i = 0; i < n1; i++) {
destImageData[index++] = 'z';
}
if (n3 > 0) {
destImageData[index++] = (byte) ('f' + n3);
}
if (n4 > 0) {
destImageData[index++] = (byte) ('F' + n4);
}
destImageData[index++] = PreChar;
return index;
}
}