java实现ZEBRA斑马打印机 FNTHEX32.dll 打印图片和文字
2014-10-30 14:37
639 查看
斑马打印中文的原理是使用FNTHEX32将中文转换成图片,再转换成斑马能识别的字符串代码
但是java调用DLL是无法跨平台的,所以按照斑马的图片编码原理我写了一个java版的图片编码类,供掉坑的各苦逼程序猿参考
命令中已包含^FO和^FS 是完整的一条ZPL指令
这是掉了无数坑过后提炼出来的代码,生成速度经过测试已达到工业级标准,在0.7主频的树莓派上生成一张热敏电子面单只需要0.4-0.8秒
希望对研究斑马打印机的人有所帮助。
但是java调用DLL是无法跨平台的,所以按照斑马的图片编码原理我写了一个java版的图片编码类,供掉坑的各苦逼程序猿参考
public class Fnthex { public static BufferedImage source = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); public static Graphics2D gs = source.createGraphics(); // public static String getFontZpl(String content, int x, int y, int size, String fontName) { // return String.format("^FO%d,%d^A1N,%d,%d^FD%s^FS", x, y, size, size, content); // } public static String getFontHexWithWidth(String content, int x, int y, int width, int maxHeight, String fontName) { if (content == null || "".equals(content)) return ""; Font f = null; width = (width + 7) / 8 * 8; int size = width / content.length(); int retryFlag = 1; if (size > maxHeight) { size = maxHeight; if ("宋体".equals(fontName)) { f = new Font("simsun", Font.PLAIN, size); } else if ("黑体".equals(fontName)) { f = new Font("simhei", Font.BOLD, size); } else { f = new Font("simsun", Font.PLAIN, size); } } else { while (true) { if ("宋体".equals(fontName)) { f = new Font("simsun", Font.PLAIN, size); } else if ("黑体".equals(fontName)) { f = new Font("simhei", Font.BOLD, size); } else { f = new Font("simsun", Font.PLAIN, size); } gs.setFont(f); FontMetrics fontMetrics = gs.getFontMetrics(); Rectangle2D stringBounds = fontMetrics.getStringBounds(content, gs); int nw = (int) stringBounds.getWidth(); if (nw > width) { size--; if (retryFlag == 1) { break; } retryFlag = 0; } else { if (size >= maxHeight) break; size++; retryFlag = 1; } } } int height = size; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = image.createGraphics(); g2.setFont(f); g2.setColor(Color.BLACK); g2.drawString(content, 1, (int) (height * 0.88)); g2.dispose(); StringBuilder zpl = new StringBuilder("^FO").append(x).append(",").append(y) .append(getImage(image)).append("^FS"); return zpl.toString(); } public static String getFontHex(String content, int x, int y, int size, String fontName) { if (content == null || "".equals(content)) return ""; Font f = null; if ("宋体".equals(fontName)) { f = new Font("simsun", Font.PLAIN, size); } else if ("黑体".equals(fontName)) { f = new Font("simhei", Font.BOLD, size); } else { f = new Font("simsun", Font.PLAIN, size); } gs.setFont(f); FontMetrics fontMetrics = gs.getFontMetrics(); Rectangle2D stringBounds = fontMetrics.getStringBounds(content, gs); int width = (int) stringBounds.getWidth(); int height = size; width = (width + 7) / 8 * 8; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = image.createGraphics(); g2.setFont(f); g2.setColor(Color.BLACK); g2.drawString(content, 1, (int) (height * 0.88)); g2.dispose(); StringBuilder zpl = new StringBuilder("^FO").append(x).append(",").append(y) .append(getImage(image)).append("^FS"); return zpl.toString(); } private static final char[] HEX = "0123456789ABCDEF".toCharArray(); public static String printImage(BufferedImage image, int x, int y) { if (image.getWidth() % 8 != 0) { BufferedImage i = new BufferedImage(((image.getWidth() + 7) / 8) * 8, image.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = i.createGraphics(); g2.drawImage(image, null, 0, 0); g2.dispose(); image = i; } StringBuilder zpl = new StringBuilder("^FO").append(x).append(",").append(y) .append(getImage(image)).append("^FS"); return zpl.toString(); } private static String getImage(BufferedImage i) { int w = i.getWidth(); int h = i.getHeight(); boolean black[] = getBlackPixels(i, w, h); int hex[] = getHexValues(black); String data = ints2Hex(hex); int bytes = data.length() / 2; int perRow = bytes / h; return "^GFA," + bytes + "," + bytes + "," + perRow + "," + data; } private static String flipRows(String hex, int height) { String flipped = ""; int width = hex.length() / height; for (int i = 0; i < height; i++) { flipped += new StringBuilder(hex.substring(i * width, (i + 1) * width)).reverse() .toString(); } return flipped; } /** * Returns an array of ones or zeros. boolean is used instead of int for memory considerations. * * @param o * @return */ private static boolean[] getBlackPixels(BufferedImage bi, int w, int h) { int[] rgbPixels = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData(); int i = 0; boolean[] pixels = new boolean[rgbPixels.length]; for (int rgbpixel : rgbPixels) { pixels[i++] = isBlack(rgbpixel); } return pixels; } private static boolean isBlack(int rgbPixel) { int a = (rgbPixel & 0xFF000000) >>> 24; if (a < 127) { return false; // assume pixels that are less opaque than the luma threshold should be considered to be white } int r = (rgbPixel & 0xFF0000) >>> 16; int g = (rgbPixel & 0xFF00) >>> 8; int b = rgbPixel & 0xFF; int luma = ((r * 299) + (g * 587) + (b * 114)) / 1000; //luma formula return luma < 127; } private static int[] getHexValues(boolean[] black) { int[] hex = new int[(int) (black.length / 8)]; // Convert every eight zero's to a full byte, in decimal for (int i = 0; i < hex.length; i++) { for (int k = 0; k < 8; k++) { hex[i] += (black[8 * i + k] ? 1 : 0) << 7 - k; } } return hex; } public static String getHexString(byte[] b) throws Exception { String result = ""; for (int i = 0; i < b.length; i++) { result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1); } return result; } private static String ints2Hex(int[] ints) { char[] hexChars = new char[ints.length * 2]; for (int i = 0; i < ints.length; ++i) { hexChars[i * 2] = HEX[(ints[i] & 0xF0) >> 4]; hexChars[i * 2 + 1] = HEX[ints[i] & 0x0F]; } return new String(hexChars); } public static void main(String[] args) { System.out.println(getFontHex("你好", 10, 50, 80, "黑体")); } }
getFontHexWithWidth方法支持定宽文字自动缩小
getFontHex将图片编码成ZPL格式
printImage直接打印图片
命令中已包含^FO和^FS 是完整的一条ZPL指令
这是掉了无数坑过后提炼出来的代码,生成速度经过测试已达到工业级标准,在0.7主频的树莓派上生成一张热敏电子面单只需要0.4-0.8秒
希望对研究斑马打印机的人有所帮助。
相关文章推荐
- java实现给图片添加水印和文字
- java 操作颜色选择器和打印机实现打印功能【代码片段】
- java调用系统打印机,实现打印
- Java绘制图片并实现打印前生成图片文件进行预览
- social.framework 实现分享文字图片等到新浪微博,twitter,facebook,保存和打印。
- java实现新浪微博Oauth接口发送图片和文字的方法
- java实现给图片添加水印和文字
- java 聊天室之 传送图片文字等功能的实现
- java调用打印机打印自定义的图片
- java实现缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
- java 实现打印(图片和文本)
- java实现给图片添加水印和文字
- 重写java中JButton,实现图片下显示文字(根据图片宽度文字自动换行)
- java实现给图片添加水印和文字
- (源码实例)通过层DIV实现,当鼠标放在链接上面,显示图片及文字 - 流星絮语 JAVA学习笔记 - CSDNBlog
- Java实现在图片上添加水印图片和水印文字
- 怎么用Java实现QQ消息输入框这种能表情图片和文字混排的效果
- java调用打印机打印图片
- java--实现将文字生成二维码图片,并在中间附上logo,下方附上文字
- 用Java实现在图片上添加水印图片和水印文字