package com.icil.elsa.label.common.utils;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import com.icil.elsa.label.service.client.UpLoadS3Thread;
import lombok.extern.slf4j.Slf4j;
/***********************************************************************
*<PRE>
*
* File Name :
*
* Creation Date : 19-9-4
*
* Author :
*
* Purpose :
*
* History :
*
*</PRE>
***************************************************************************/
@Slf4j
public class ZPLConveterUtils {
private int blackLimit = 380;
private int total;
private int widthBytes;
private boolean compressHex = false;
private static Map<Integer, String> mapCode = new HashMap<Integer, String>();
{
mapCode.put(1, "G");
mapCode.put(2, "H");
mapCode.put(3, "I");
mapCode.put(4, "J");
mapCode.put(5, "K");
mapCode.put(6, "L");
mapCode.put(7, "M");
mapCode.put(8, "N");
mapCode.put(9, "O");
mapCode.put(10, "P");
mapCode.put(11, "Q");
mapCode.put(12, "R");
mapCode.put(13, "S");
mapCode.put(14, "T");
mapCode.put(15, "U");
mapCode.put(16, "V");
mapCode.put(17, "W");
mapCode.put(18, "X");
mapCode.put(19, "Y");
mapCode.put(20, "g");
mapCode.put(40, "h");
mapCode.put(60, "i");
mapCode.put(80, "j");
mapCode.put(100, "k");
mapCode.put(120, "l");
mapCode.put(140, "m");
mapCode.put(160, "n");
mapCode.put(180, "o");
mapCode.put(200, "p");
mapCode.put(220, "q");
mapCode.put(240, "r");
mapCode.put(260, "s");
mapCode.put(280, "t");
mapCode.put(300, "u");
mapCode.put(320, "v");
mapCode.put(340, "w");
mapCode.put(360, "x");
mapCode.put(380, "y");
mapCode.put(400, "z");
}
public void setCompressHex(boolean compressHex) {
this.compressHex = compressHex;
}
public void setBlacknessLimitPercentage(int percentage) {
this.blackLimit = (percentage * 768 / 100);
}
private String headDoc() {
String str = "^XA " + "^FO0,0^GFA," + total + "," + total + "," + widthBytes + ", ";
return str;
}
private String footDoc() {
String str = "^FS" + "^XZ";
return str;
}
/**
* Image to zpi string data.
*
* @param image
* @return
* @throws IOException
*/
public String convertfromImg(BufferedImage image) throws IOException {
String cuerpo = createBody(image);
if (compressHex) {
cuerpo = encodeHexAscii(cuerpo,20);
}
return headDoc() + cuerpo + footDoc();
}
/**
* the BufferedImage to String
*
* @param orginalImage
* @return
* @throws IOException
*/
private String createBody(BufferedImage orginalImage) throws IOException {
StringBuffer sb = new StringBuffer();
Graphics2D graphics = orginalImage.createGraphics();
graphics.drawImage(orginalImage, 0, 0, null);
int height = orginalImage.getHeight();
int width = orginalImage.getWidth();
// int newWidth = width + 200;
int rgb, red, green, blue, index = 0;
char auxBinaryChar[] = {'0', '0', '0', '0', '0', '0', '0', '0'};
// widthBytes = width / 16 ;
// widthBytes = width % 8 > 0 ? (((int) (width / 8)) + 1) : width / 8;
widthBytes = width % 8 > 0 ? (((int) (width / 8)) + 1) : width / 8;
this.total = widthBytes * height;
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
rgb = orginalImage.getRGB(w, h);
red = (rgb >> 16) & 0x000000FF;
green = (rgb >> 8) & 0x000000FF;
blue = (rgb) & 0x000000FF;
char auxChar = '1';
int totalColor = red + green + blue;
if (totalColor > blackLimit) {
auxChar = '0';
}
auxBinaryChar[index] = auxChar;
index++;
if (index == 8 || w == (width - 1)) {
sb.append(fourByteBinary(new String(auxBinaryChar)));
auxBinaryChar = new char[]{'0', '0', '0', '0', '0', '0', '0', '0'};
index = 0;
}
}
sb.append("\n");
}
return sb.toString();
}
/**
* @param binaryStr
* @return
*/
private String fourByteBinary(String binaryStr) {
int decimal = Integer.parseInt(binaryStr, 2);
return decimal > 15 ? Integer.toString(decimal, 16).toUpperCase() : "0" + Integer.toString(decimal, 16).toUpperCase();
}
/**
* @param code
* @return
*/
private String encodeHexAscii(String code) {
int maxlinea = widthBytes * 2;
StringBuffer sbCode = new StringBuffer();
StringBuffer sbLinea = new StringBuffer();
String previousLine = null;
int counter = 1;
char aux = code.charAt(0);
boolean firstChar = false;
for (int i = 1; i < code.length(); i++) {
if (firstChar) {
aux = code.charAt(i);
firstChar = false;
continue;
}
if (code.charAt(i) == '\n') {
if (counter >= maxlinea && aux == '0') {
sbLinea.append(",");
} else if (counter >= maxlinea && aux == 'F') {
sbLinea.append("!");
} else if (counter > 20) {
int multi20 = (counter / 20) * 20;
int resto20 = (counter % 20);
sbLinea.append(mapCode.get(multi20));
if (resto20 != 0) {
sbLinea.append(mapCode.get(resto20) + aux);
} else {
sbLinea.append(aux);
}
} else {
sbLinea.append(mapCode.get(counter) + aux);
if (mapCode.get(counter) == null) {
}
}
counter = 1;
firstChar = true;
if (sbLinea.toString().equals(previousLine)) {
sbCode.append(":");
} else {
sbCode.append(sbLinea.toString());
}
previousLine = sbLinea.toString();
sbLinea.setLength(0);
continue;
}
if (aux == code.charAt(i)) {
counter++;
} else {
if (counter > 20) {
int multi20 = (counter / 20) * 20;
int resto20 = (counter % 20);
sbLinea.append(mapCode.get(multi20));
if (resto20 != 0) {
sbLinea.append(mapCode.get(resto20) + aux);
} else {
sbLinea.append(aux);
}
} else {
sbLinea.append(mapCode.get(counter) + aux);
}
counter = 1;
aux = code.charAt(i);
}
}
return sbCode.toString();
}
private String encodeHexAscii(String code,int number) {
int maxlinea = widthBytes * 2;
StringBuffer sbCode = new StringBuffer();
StringBuffer sbLinea = new StringBuffer();
String previousLine = null;
int counter = 1;
char aux = code.charAt(0);
boolean firstChar = false;
for (int i = 1; i < code.length(); i++) {
if (firstChar) {
aux = code.charAt(i);
firstChar = false;
continue;
}
if (code.charAt(i) == '\n') {
if (counter >= maxlinea && aux == '0') {
sbLinea.append(",");
} else if (counter >= maxlinea && aux == 'F') {
sbLinea.append("!");
} else if (counter > number) {
int multi20 = (counter / number) * number;
int resto20 = (counter % number);
sbLinea.append(mapCode.get(multi20));
if (resto20 != 0) {
sbLinea.append(mapCode.get(resto20) + aux);
} else {
sbLinea.append(aux);
}
} else {
sbLinea.append(mapCode.get(counter) + aux);
if (mapCode.get(counter) == null) {
}
}
counter = 1;
firstChar = true;
if (sbLinea.toString().equals(previousLine)) {
sbCode.append(":");
} else {
sbCode.append(sbLinea.toString());
}
previousLine = sbLinea.toString();
sbLinea.setLength(0);
continue;
}
if (aux == code.charAt(i)) {
counter++;
} else {
if (counter > number) {
int multi20 = (counter / number) * number;
int resto20 = (counter % number);
sbLinea.append(mapCode.get(multi20));
if (resto20 != 0) {
sbLinea.append(mapCode.get(resto20) + aux);
} else {
sbLinea.append(aux);
}
} else {
sbLinea.append(mapCode.get(counter) + aux);
}
counter = 1;
aux = code.charAt(i);
}
}
return sbCode.toString();
}
public static String convertPDFToZPL(String pdfPath, boolean isRotate) {
File sourceFile = new File(pdfPath);
// File destinationFile = new File(destinationDir);
PDDocument document = null;
FileWriter fw = null;
BufferedWriter bw = null;
try {
if (sourceFile.exists()) {
// System.out.println("Images copied to Folder Location: "+
// destinationFile.getAbsolutePath());
document = PDDocument.load(sourceFile);
// PDPage page = document.getDocumentCatalog().getPages().get(0);
/*
* PDPageContentStream cs = new PDPageContentStream(document, page,
* PDPageContentStream.AppendMode.PREPEND, false, false); PDRectangle cropBox =
* page.getCropBox(); float tx = (cropBox.getLowerLeftX() +
* cropBox.getUpperRightX()) / 2; float ty = (cropBox.getLowerLeftY() +
* cropBox.getUpperRightY()) / 2; cs.transform(Matrix.getTranslateInstance(tx,
* ty)); cs.transform(Matrix.getRotateInstance(Math.toRadians(90), 0, 0));
* cs.transform(Matrix.getTranslateInstance(-tx, -ty)); cs.close(); File file =
* new File(JasperService.class.getResource("/").getPath()+ "file/",
* "IRJET_Copy_Right_form-rotated-center-scale.pdf"); if(!file.exists()) {
* //file.createNewFile(); } document.save(new File(
* "/home/peterwong/svn/Microservices/labelService/trunk/main_body/src_codes/src/elsa-label-service/target/classes/files",
* "IRJET_Copy_Right_form-rotated-center-scale.pdf"));
*/
PDFRenderer pdfRenderer = new PDFRenderer(document);
int numberOfPages = document.getNumberOfPages();
//log.info("Total files to be converting -> " + numberOfPages);
String fileName = sourceFile.getName();
/*
* 600 dpi give good image clarity but size of each image is 2x times of 300
* dpi. Ex: 1. For 300dpi 04-Request-Headers_2.png expected size is 797 KB 2.
* For 600dpi 04-Request-Headers_2.png expected size is 2.42 MB
*/
int dpi = 203;// use less dpi for to save more space in harddisk. For professional usage you
// can use more than 300dpi
// for (int i = 0; i < numberOfPages; ++i) {
File imageFile = new File( pdfPath.replace("pdf", "png"));
//
BufferedImage bImage = pdfRenderer.renderImageWithDPI(0, dpi, ImageType.RGB);
if (isRotate) {
// 旋转图片90度
bImage = RotateImage.Rotate(bImage, 90);
}
// ImageIO.write(des1, fileExtension, imageFile);
ZPLConveterUtils zplConveterUtils = new ZPLConveterUtils();
String zplStr = zplConveterUtils.convertfromImg(bImage);
zplStr = zplStr.replace("\n", "");
log.info("zpl is {}",zplStr);
String zplFilePath = pdfPath.replace("pdf", "txt");
FileUtils.writeToFile(zplStr, zplFilePath);
// }
// System.out.println("convertfromiMg "+ convertfromImg);
//是否将数据发送到打印机,ULHKG_LP4X1 是label 打印机
//ServerPrintService.print("ULHKG_LP4X1", zplStr, null,null);
// ImageIO.write(bImage, fileExtension, outPutFile);
/*
* Base64 base64 = new Base64();
*
* // Decode encoded ZPL to a normal format String convertedZPL = new
* String(base64.decode(zpl.getBytes()));
*/
// System.out.println(convertedZPL);
return zplStr;
} else {
log.error("generate pdf failed");
}
} catch (Exception e) {
log.error("e is {}", e);
} finally {
try {
if (document != null) {
document.close();
}
} catch (IOException e) {
log.error("close stram failed,the exception is {}", e);
}
}
return "";
}
}
//test
import org.junit.Test;
import com.icil.elsa.label.common.utils.FileUtils;
import com.icil.elsa.label.common.utils.ZPLConveterUtils;
public class ZPLUtils {
@Test
public void test() {
String pdfPath = "/home/zhangsan/Pictures/API_test_label.pdf";
String fileDataString = ZPLConveterUtils.convertPDFToZPL(pdfPath, false);
FileUtils.writeToFile(fileDataString, "/home/zhangsan/Pictures/API_test_label.txt");
}
}