diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ChineseDotMatrixExtractor.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ChineseDotMatrixExtractor.java new file mode 100644 index 0000000..b0cd04f --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ChineseDotMatrixExtractor.java @@ -0,0 +1,111 @@ +package com.fuyuanshen.equipment.utils.c; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; + +/** + * @author: 默苍璃 + * @date: 2025-07-1508:52 + */ + +public class ChineseDotMatrixExtractor { + + public static void main(String[] args) { + String chineseChar = "汉"; // 要提取的汉字 + int size = 12; // 点阵尺寸 + + // 生成点阵数据 + int[][] dotMatrix = generateDotMatrix(chineseChar, size); + + // 打印点阵 + printDotMatrix(dotMatrix); + + // 获取二进制数据(可选) + List binaryData = convertToBinary(dotMatrix); + System.out.println("\nBinary data: " + binaryData); + } + + /** + * 生成汉字点阵 + * @param character 单个汉字字符 + * @param size 点阵尺寸 + * @return 二维点阵数组(1表示点亮,0表示熄灭) + */ + public static int[][] generateDotMatrix(String character, int size) { + // 创建12x12灰度图像 + BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_BYTE_GRAY); + Graphics2D g = image.createGraphics(); + + try { + // 设置白色背景 + g.setColor(Color.RED); + g.fillRect(0, 0, size, size); + + // 设置黑色字体(使用支持中文的字体) + g.setColor(java.awt.Color.BLACK); + g.setFont(new Font("宋体", Font.PLAIN, size)); + + // 居中绘制文字(调整y坐标使字符垂直居中) + g.drawString(character, 0, size - 2); + } finally { + g.dispose(); + } + + // 分析像素生成点阵 + int[][] dotMatrix = new int[size][size]; + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + // 获取像素灰度值(0-255) + int rgb = image.getRGB(x, y) & 0xFF; + // 灰度小于128视为有效像素(黑色区域) + dotMatrix[y][x] = (rgb < 128) ? 1 : 0; + } + } + return dotMatrix; + } + + /** + * 打印点阵到控制台 + * @param dotMatrix 点阵数据 + */ + public static void printDotMatrix(int[][] dotMatrix) { + for (int[] row : dotMatrix) { + for (int pixel : row) { + System.out.print(pixel == 1 ? "■ " : "□ "); + } + System.out.println(); + } + } + + /** + * 将点阵转换为二进制数据(每行两个字节) + * @param dotMatrix 点阵数据 + * @return 二进制数据列表(每个元素代表一行) + */ + public static List convertToBinary(int[][] dotMatrix) { + List binaryData = new ArrayList<>(); + for (int[] row : dotMatrix) { + byte highByte = 0; + byte lowByte = 0; + + // 处理每行前8位 + for (int i = 0; i < 8; i++) { + if (i < row.length && row[i] == 1) { + highByte |= (1 << (7 - i)); + } + } + + // 处理每行后4位(12x12点阵的特殊处理) + for (int i = 8; i < 12; i++) { + if (i < row.length && row[i] == 1) { + lowByte |= (1 << (15 - i)); // 放在第二个字节的高4位 + } + } + binaryData.add(highByte); + binaryData.add(lowByte); + } + return binaryData; + } +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ChineseDotMatrixToC.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ChineseDotMatrixToC.java new file mode 100644 index 0000000..d1e5508 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ChineseDotMatrixToC.java @@ -0,0 +1,193 @@ +package com.fuyuanshen.equipment.utils.c; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author: 默苍璃 + * @date: 2025-07-1509:06 + */ +public class ChineseDotMatrixToC { + + public static void main(String[] args) { + // 要转换的汉字列表 + String[] characters = {"汉", "字", "点", "阵", "显", "示", "屏", "登", "记", "信", "息"}; + + // 输出C文件名 + String outputFileName = "chinese_font_12x12.c"; + + // 生成C文件 + generateCFontFile(characters, 12, outputFileName); + + System.out.println("C文件已生成: " + outputFileName); + } + + /** + * 生成C字体文件 + * @param characters 汉字数组 + * @param size 点阵尺寸 + * @param fileName 输出文件名 + */ + public static void generateCFontFile(String[] characters, int size, String fileName) { + try (FileWriter writer = new FileWriter(fileName)) { + // 写入文件头部 + writer.write("/*\n"); + writer.write(" * 12×12 汉字点阵数据(高位在前)\n"); + writer.write(" * 格式:每行16位(2字节),实际使用前12位\n"); + writer.write(" * 存储:每个汉字24字节(12行×2字节)\n"); + writer.write(" * 生成时间: " + new java.util.Date() + "\n"); + writer.write(" */\n\n"); + + writer.write("#include \n\n"); + + // 主数组声明 + writer.write("const uint8_t FONT_12X12[] = {\n"); + + // 存储所有汉字的数据 + for (int i = 0; i < characters.length; i++) { + String character = characters[i]; + int unicode = (int)character.charAt(0); + + // 生成点阵数据 + int[][] dotMatrix = generateDotMatrix(character, size); + + // 转换为十六进制数组 + List hexData = convertToHex(dotMatrix); + + // 写入注释(汉字和Unicode) + writer.write(String.format(" /* '%s' (U+%04X) */\n", character, unicode)); + + // 写入数据(每8个字节一行) + for (int j = 0; j < hexData.size(); j += 8) { + writer.write(" "); + for (int k = j; k < Math.min(j + 8, hexData.size()); k++) { + writer.write(hexData.get(k)); + if (k < hexData.size() - 1) { + writer.write(", "); + } + } + writer.write("\n"); + } + + // 最后一个汉字后不加逗号 + if (i < characters.length - 1) { + writer.write(",\n"); + } + } + + writer.write("};\n\n"); + + // 添加获取点阵的函数 + writer.write("// 获取汉字点阵数据\n"); + writer.write("const uint8_t* get_font_data(uint16_t unicode) {\n"); + writer.write(" switch(unicode) {\n"); + + int offset = 0; + for (String character : characters) { + int unicode = (int)character.charAt(0); + writer.write(String.format(" case 0x%04X: // '%s'\n", unicode, character)); + writer.write(String.format(" return &FONT_12X12[%d];\n", offset)); + offset += 24; // 每个汉字24字节 + } + + writer.write(" default:\n"); + writer.write(" return NULL;\n"); + writer.write(" }\n"); + writer.write("}\n"); + + System.out.println("成功生成 " + characters.length + " 个汉字的点阵数据"); + } catch (IOException e) { + System.err.println("文件写入错误: " + e.getMessage()); + } + } + + /** + * 生成汉字点阵 + * @param character 单个汉字字符 + * @param size 点阵尺寸 + * @return 二维点阵数组(1表示点亮,0表示熄灭) + */ + private static int[][] generateDotMatrix(String character, int size) { + // 创建12x12灰度图像 + BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_BYTE_GRAY); + Graphics2D g = image.createGraphics(); + + try { + // 设置白色背景 + g.setColor(Color.WHITE); + g.fillRect(0, 0, size, size); + + // 设置黑色字体(使用支持中文的字体) + g.setColor(Color.BLACK); + + // 尝试加载系统字体(优先使用宋体) + Font font; + try { + font = new Font("宋体", Font.PLAIN, size); + } catch (Exception e) { + font = new Font(Font.SANS_SERIF, Font.PLAIN, size); + } + g.setFont(font); + + // 调整绘制位置(居中显示) + FontMetrics metrics = g.getFontMetrics(); + int x = (size - metrics.charWidth(character.charAt(0))) / 2; + int y = ((size - metrics.getHeight()) / 2) + metrics.getAscent(); + + // 绘制文字 + g.drawString(character, x, y); + } finally { + g.dispose(); + } + + // 分析像素生成点阵 + int[][] dotMatrix = new int[size][size]; + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + // 获取像素灰度值(0-255) + int rgb = image.getRGB(x, y) & 0xFF; + // 灰度小于128视为有效像素(黑色区域) + dotMatrix[y][x] = (rgb < 180) ? 1 : 0; // 使用稍高阈值确保清晰度 + } + } + return dotMatrix; + } + + /** + * 将点阵转换为十六进制字符串(高位在前) + * @param dotMatrix 点阵数据 + * @return 十六进制字符串列表(每个元素是一个字节的十六进制表示) + */ + private static List convertToHex(int[][] dotMatrix) { + List hexData = new ArrayList<>(); + + for (int[] row : dotMatrix) { + int highByte = 0; + int lowByte = 0; + + // 处理前8位(高位在前) + for (int i = 0; i < 8; i++) { + if (i < row.length && row[i] == 1) { + highByte |= (1 << (7 - i)); + } + } + + // 处理后4位(放在第二个字节的高4位) + for (int i = 8; i < 12; i++) { + if (i < row.length && row[i] == 1) { + lowByte |= (1 << (15 - i)); + } + } + + // 添加到结果列表 + hexData.add(String.format("0X%02X", highByte)); + hexData.add(String.format("0X%02X", lowByte)); + } + + return hexData; + } +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/DotMatrixGenerator.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/DotMatrixGenerator.java new file mode 100644 index 0000000..7ba70bd --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/DotMatrixGenerator.java @@ -0,0 +1,277 @@ +package com.fuyuanshen.equipment.utils.c; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class DotMatrixGenerator { + + public static void main(String[] args) { + // 要转换的字符列表(汉字+字母+数字) + String[] characters = { + "登", "记", "信", "息", + "A", "B", "C", + "0", "1", "2" + }; + + // 输出C文件名 + String outputFileName = "display_fonts.c"; + + // 生成C文件 + generateCFontFile(characters, outputFileName); + + System.out.println("C字体文件已生成: " + outputFileName); + } + + /** + * 生成C字体文件 + * @param characters 字符数组 + * @param fileName 输出文件名 + */ + public static void generateCFontFile(String[] characters, String fileName) { + try (FileWriter writer = new FileWriter(fileName)) { + // 写入文件头部 + writer.write("/*\n"); + writer.write(" * 显示屏点阵数据\n"); + writer.write(" * 生成时间: " + new java.util.Date() + "\n"); + writer.write(" * 格式说明:\n"); + writer.write(" * - 汉字: 12×12点阵 (24字节/字符)\n"); + writer.write(" * - 字母数字: 8×12点阵 (12字节/字符)\n"); + writer.write(" * 所有数据均采用高位在前(MSB first)格式\n"); + writer.write(" */\n\n"); + + writer.write("#include \n\n"); + + // 存储所有汉字的数据 + List hanziMatrices = new ArrayList<>(); + List hanziCharacters = new ArrayList<>(); + + // 存储所有ASCII字符的数据 + List asciiMatrices = new ArrayList<>(); + List asciiCharacters = new ArrayList<>(); + + // 分离汉字和ASCII字符 + for (String character : characters) { + char c = character.charAt(0); + if (isHanzi(c)) { + hanziMatrices.add(generateDotMatrix(character, 12)); + hanziCharacters.add(character); + } else if (isAscii(c)) { + asciiMatrices.add(generateDotMatrix(character, 8)); + asciiCharacters.add(character); + } + } + + // 汉字点阵数组 + if (!hanziMatrices.isEmpty()) { + writer.write("/* 12×12 汉字点阵数据 */\n"); + writer.write("const uint8_t HANZI_FONT_12X12[] = {\n"); + + for (int i = 0; i < hanziMatrices.size(); i++) { + String character = hanziCharacters.get(i); + int[][] dotMatrix = hanziMatrices.get(i); + List hexData = convertToHex(dotMatrix, 12); + + // 写入注释(汉字和Unicode) + writer.write(String.format(" /* '%s' (U+%04X) */\n", + character, (int)character.charAt(0))); + + // 写入数据(每8个字节一行) + for (int j = 0; j < hexData.size(); j += 8) { + writer.write(" "); + for (int k = j; k < Math.min(j + 8, hexData.size()); k++) { + writer.write(hexData.get(k)); + if (k < hexData.size() - 1) { + writer.write(", "); + } + } + writer.write("\n"); + } + + // 最后一个汉字后不加逗号 + if (i < hanziMatrices.size() - 1) { + writer.write(",\n"); + } + } + writer.write("};\n\n"); + } + + // ASCII点阵数组 + if (!asciiMatrices.isEmpty()) { + writer.write("/* 8×12 字母数字点阵数据 */\n"); + writer.write("const uint8_t ASCII_FONT_8X12[] = {\n"); + + for (int i = 0; i < asciiMatrices.size(); i++) { + String character = asciiCharacters.get(i); + int[][] dotMatrix = asciiMatrices.get(i); + List hexData = convertToHex(dotMatrix, 8); + + // 写入注释(字符和ASCII码) + writer.write(String.format(" /* '%c' (0x%02X) */ ", + character.charAt(0), (int)character.charAt(0))); + + // 写入数据(每行12字节) + for (int j = 0; j < hexData.size(); j++) { + writer.write(hexData.get(j)); + if (j < hexData.size() - 1) { + writer.write(", "); + } + } + writer.write("\n"); + } + writer.write("};\n\n"); + } + + // 添加获取点阵的函数 + writer.write("/* 获取点阵数据函数 */\n"); + writer.write("const uint8_t* get_font_data(uint16_t code) {\n"); + + // 汉字处理 + if (!hanziCharacters.isEmpty()) { + writer.write(" // 汉字处理\n"); + writer.write(" switch(code) {\n"); + + int offset = 0; + for (int i = 0; i < hanziCharacters.size(); i++) { + String character = hanziCharacters.get(i); + writer.write(String.format(" case 0x%04X: // '%s'\n", + (int)character.charAt(0), character)); + writer.write(String.format(" return &HANZI_FONT_12X12[%d];\n", offset)); + offset += 24; // 每个汉字24字节 + } + + writer.write(" }\n"); + } + + // ASCII字符处理 + if (!asciiCharacters.isEmpty()) { + writer.write(" // ASCII字符处理\n"); + writer.write(" switch(code) {\n"); + + int offset = 0; + for (int i = 0; i < asciiCharacters.size(); i++) { + String character = asciiCharacters.get(i); + writer.write(String.format(" case 0x%02X: // '%c'\n", + (int)character.charAt(0), character.charAt(0))); + writer.write(String.format(" return &ASCII_FONT_8X12[%d];\n", offset)); + offset += 12; // 每个ASCII字符12字节 + } + + writer.write(" }\n"); + } + + writer.write(" return NULL; // 未找到对应字符\n"); + writer.write("}\n"); + + System.out.println("成功生成字符点阵数据"); + System.out.println(" - 汉字: " + hanziCharacters.size() + " 个"); + System.out.println(" - 字母数字: " + asciiCharacters.size() + " 个"); + + } catch (IOException e) { + System.err.println("文件写入错误: " + e.getMessage()); + } + } + + /** + * 判断是否是汉字 + */ + private static boolean isHanzi(char c) { + // 基本汉字Unicode范围: 4E00-9FFF + return c >= 0x4E00 && c <= 0x9FFF; + } + + /** + * 判断是否是ASCII字符 + */ + private static boolean isAscii(char c) { + return c < 128; + } + + /** + * 生成点阵 + * @param character 字符 + * @param size 点阵尺寸 + * @return 二维点阵数组 + */ + private static int[][] generateDotMatrix(String character, int size) { + // 创建图像 + BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_BYTE_GRAY); + Graphics2D g = image.createGraphics(); + + try { + // 设置白色背景 + g.setColor(Color.WHITE); + g.fillRect(0, 0, size, size); + + // 设置黑色字体 + g.setColor(Color.BLACK); + + // 选择合适的字体 + Font font; + if (isHanzi(character.charAt(0))) { + font = new Font("宋体", Font.PLAIN, size); + } else { + font = new Font("Courier New", Font.PLAIN, size); + } + g.setFont(font); + + // 调整绘制位置(居中显示) + FontMetrics metrics = g.getFontMetrics(); + int x = (size - metrics.charWidth(character.charAt(0))) / 2; + int y = ((size - metrics.getHeight()) / 2) + metrics.getAscent(); + + // 绘制文字 + g.drawString(character, x, y); + } finally { + g.dispose(); + } + + // 分析像素生成点阵 + int[][] dotMatrix = new int[size][size]; + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + // 获取像素灰度值 + int rgb = image.getRGB(x, y) & 0xFF; + // 灰度小于180视为有效像素 + dotMatrix[y][x] = (rgb < 180) ? 1 : 0; + } + } + return dotMatrix; + } + + /** + * 将点阵转换为十六进制字符串 + * @param dotMatrix 点阵数据 + * @param size 点阵尺寸 + * @return 十六进制字符串列表 + */ + private static List convertToHex(int[][] dotMatrix, int size) { + List hexData = new ArrayList<>(); + + for (int[] row : dotMatrix) { + int value = 0; + + // 高位在前处理 + for (int i = 0; i < size; i++) { + if (i < row.length && row[i] == 1) { + value |= (1 << (size - 1 - i)); + } + } + + // 根据尺寸拆分字节 + if (size == 12) { + // 12×12点阵:每行拆分为2字节 + hexData.add(String.format("0X%02X", (value >> 8) & 0xFF)); + hexData.add(String.format("0X%02X", value & 0xFF)); + } else { + // 8×12点阵:每行1字节 + hexData.add(String.format("0X%02X", value & 0xFF)); + } + } + + return hexData; + } +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ImprovedTextToBitmap.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ImprovedTextToBitmap.java new file mode 100644 index 0000000..08ec8e9 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ImprovedTextToBitmap.java @@ -0,0 +1,163 @@ +package com.fuyuanshen.equipment.utils.c; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 发送指令显示工具 + * + * @author: 默苍璃 + * @date: 2025-07-1515:35 + */ +public class ImprovedTextToBitmap { + + public static void main(String[] args) throws IOException { + String unit = "中国电子集团"; + String department = "人工智能研发中心"; + String name = "张三"; + + byte[] unitBytes = textToBitmapBytes(unit); + byte[] deptBytes = textToBitmapBytes(department); + byte[] nameBytes = textToBitmapBytes(name); + + generateCFile(unitBytes, deptBytes, nameBytes, "display_data.c"); + } + + public static byte[] textToBitmapBytes(String text) { + if (text == null || text.isEmpty()) { + return new byte[0]; + } + + // 使用更清晰的黑体字体 + Font font = new Font("黑体", Font.PLAIN, 12); + + // 创建临时图像获取字体度量 + BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + Graphics2D tempG = tempImage.createGraphics(); + tempG.setFont(font); + FontMetrics metrics = tempG.getFontMetrics(); + + // 添加字符间距(防止汉字粘连) + int charSpacing = 1; + int totalWidth = 0; + for (char c : text.toCharArray()) { + totalWidth += metrics.charWidth(c) + charSpacing; + } + + // 宽度对齐到8的倍数 + int width = (int) Math.ceil(totalWidth / 8.0) * 8; + int height = 12; + + // 创建图像 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setFont(font); + + // 设置渲染参数 - 关闭抗锯齿(提高小字清晰度) + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + + // 透明背景 + g.setComposite(AlphaComposite.Clear); + g.fillRect(0, 0, width, height); + g.setComposite(AlphaComposite.Src); + g.setColor(Color.BLACK); + + // 绘制文本(优化垂直对齐) + int y = (height - metrics.getHeight()) / 2 + metrics.getAscent() - 1; + int x = 0; + for (char c : text.toCharArray()) { + g.drawString(String.valueOf(c), x, y); + x += metrics.charWidth(c) + charSpacing; + } + g.dispose(); + tempG.dispose(); + + // 扫描像素并打包数据 + List byteList = new ArrayList<>(); + int currentByte = 0; + int bitCount = 0; + + for (int yPos = 0; yPos < height; yPos++) { + for (int xPos = 0; xPos < width; xPos++) { + int pixel = image.getRGB(xPos, yPos); + int alpha = (pixel >> 24) & 0xFF; + + // 使用阈值处理(提高清晰度) + boolean isOpaque = alpha > 64; // 阈值可调整 + + currentByte = (currentByte << 1) | (isOpaque ? 1 : 0); + bitCount++; + + if (bitCount == 8) { + byteList.add((byte) currentByte); + currentByte = 0; + bitCount = 0; + } + } + } + + // 处理最后不满8位的部分 + if (bitCount > 0) { + currentByte <<= (8 - bitCount); // 左移到高位 + byteList.add((byte) currentByte); + } + + // 转换结果 + byte[] result = new byte[byteList.size()]; + for (int i = 0; i < byteList.size(); i++) { + result[i] = byteList.get(i); + } + return result; + } + + public static void generateCFile(byte[] unit, byte[] department, byte[] name, String filename) throws IOException { + try (FileWriter writer = new FileWriter(filename)) { + writer.write("/**\n"); + writer.write(" * 点阵显示数据 - 自动生成\n"); + writer.write(" * 宽度计算公式: width = (数组长度 * 8) / 12\n"); + writer.write(" */\n\n"); + writer.write("#include \n\n"); + + // 单位数据 + writer.write(String.format("// 单位: %d 字节, 宽度: %d 像素\n", + unit.length, (unit.length * 8) / 12)); + writer.write("const uint8_t unit[] = {\n "); + writeByteArray(writer, unit); + writer.write("\n};\n\n"); + + // 部门数据 + writer.write(String.format("// 部门: %d 字节, 宽度: %d 像素\n", + department.length, (department.length * 8) / 12)); + writer.write("const uint8_t department[] = {\n "); + writeByteArray(writer, department); + writer.write("\n};\n\n"); + + // 姓名数据 + writer.write(String.format("// 姓名: %d 字节, 宽度: %d 像素\n", + name.length, (name.length * 8) / 12)); + writer.write("const uint8_t name[] = {\n "); + writeByteArray(writer, name); + writer.write("\n};\n"); + } + } + + private static void writeByteArray(FileWriter writer, byte[] data) throws IOException { + for (int i = 0; i < data.length; i++) { + int value = data[i] & 0xFF; + writer.write(String.format("0x%02X", value)); + + if (i < data.length - 1) { + writer.write(", "); + if ((i + 1) % 12 == 0) writer.write("\n "); + } + } + } +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/TextToBitmapConverter.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/TextToBitmapConverter.java new file mode 100644 index 0000000..f5dfba9 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/TextToBitmapConverter.java @@ -0,0 +1,128 @@ +package com.fuyuanshen.equipment.utils.c; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author: 默苍璃 + * @date: 2025-07-1515:14 + */ +public class TextToBitmapConverter { + // 主函数:输入文字并生成C文件 + public static void main(String[] args) throws IOException { + String unit = "单位名称"; + String department = "部门名称"; + String name = "姓名"; + + byte[] unitBytes = textToBitmapBytes(unit); + byte[] deptBytes = textToBitmapBytes(department); + byte[] nameBytes = textToBitmapBytes(name); + + generateCFile(unitBytes, deptBytes, nameBytes, "output.c"); + } + + // 将文本转换为点阵字节数组 + public static byte[] textToBitmapBytes(String text) { + // 1. 创建虚拟画布 + Font font = new Font("SansSerif", Font.PLAIN, 12); + FontMetrics metrics = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB) + .getGraphics().getFontMetrics(font); + + // 计算文本宽度并调整为8的倍数 + int textWidth = metrics.stringWidth(text); + int width = (int) Math.ceil(textWidth / 8.0) * 8; + int height = 12; + + // 创建带透明通道的图像 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setFont(font); + + // 设置渲染参数 + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.setComposite(AlphaComposite.Clear); + g.fillRect(0, 0, width, height); + g.setComposite(AlphaComposite.Src); + g.setColor(Color.BLACK); + + // 绘制文本(垂直居中) + int y = (height - metrics.getHeight()) / 2 + metrics.getAscent(); + g.drawString(text, 0, y); + g.dispose(); + + // 2. 扫描像素并打包数据 + List byteList = new ArrayList<>(); + int currentByte = 0; + int bitCount = 0; + + for (int yPos = 0; yPos < height; yPos++) { + for (int xPos = 0; xPos < width; xPos++) { + // 检查像素透明度 + int pixel = image.getRGB(xPos, yPos); + boolean isOpaque = ((pixel >> 24) & 0xFF) > 0; + + // 打包位数据(高位在前) + currentByte = (currentByte << 1) | (isOpaque ? 1 : 0); + bitCount++; + + // 每8位打包为一个字节 + if (bitCount == 8) { + byteList.add((byte) currentByte); + currentByte = 0; + bitCount = 0; + } + } + } + + // 转换结果 + byte[] result = new byte[byteList.size()]; + for (int i = 0; i < byteList.size(); i++) { + result[i] = byteList.get(i); + } + return result; + } + + // 生成C文件 + public static void generateCFile(byte[] unit, byte[] department, byte[] name, String filename) throws IOException { + try (FileWriter writer = new FileWriter(filename)) { + // 写入文件头 + writer.write("#include \n\n"); + + // 写入单位数据 + writer.write("const uint8_t unit[] = {\n "); + writeByteArray(writer, unit); + writer.write("\n};\n\n"); + + // 写入部门数据 + writer.write("const uint8_t department[] = {\n "); + writeByteArray(writer, department); + writer.write("\n};\n\n"); + + // 写入姓名数据 + writer.write("const uint8_t name[] = {\n "); + writeByteArray(writer, name); + writer.write("\n};\n"); + } + } + + // 辅助方法:格式化字节数组输出 + private static void writeByteArray(FileWriter writer, byte[] data) throws IOException { + for (int i = 0; i < data.length; i++) { + // 将字节转换为无符号整数 + int value = data[i] & 0xFF; + writer.write(String.format("0x%02X", value)); + + // 添加逗号(最后一个元素除外) + if (i < data.length - 1) { + writer.write(", "); + // 每16个元素换行 + if ((i + 1) % 16 == 0) writer.write("\n "); + } + } + } +}