赞
踩
斑马打印中文的原理是使用FNTHEX32将中文转换成图片,再转换成斑马能识别的字符串代码
但是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秒
希望对研究斑马打印机的人有所帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。