forked from dyf/fys-Multi-tenant
可靠点阵生成工具 - 终极版
This commit is contained in:
@ -1,111 +0,0 @@
|
||||
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<Byte> 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<Byte> convertToBinary(int[][] dotMatrix) {
|
||||
List<Byte> 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;
|
||||
}
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
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 <stdint.h>\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<String> 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<String> convertToHex(int[][] dotMatrix) {
|
||||
List<String> 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;
|
||||
}
|
||||
}
|
@ -1,277 +0,0 @@
|
||||
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 <stdint.h>\n\n");
|
||||
|
||||
// 存储所有汉字的数据
|
||||
List<int[][]> hanziMatrices = new ArrayList<>();
|
||||
List<String> hanziCharacters = new ArrayList<>();
|
||||
|
||||
// 存储所有ASCII字符的数据
|
||||
List<int[][]> asciiMatrices = new ArrayList<>();
|
||||
List<String> 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<String> 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<String> 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<String> convertToHex(int[][] dotMatrix, int size) {
|
||||
List<String> 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;
|
||||
}
|
||||
}
|
@ -3,97 +3,170 @@ package com.fuyuanshen.equipment.utils.c;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发送指令显示工具
|
||||
* 可靠点阵生成工具 - 终极版
|
||||
*
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-07-1515:35
|
||||
* @date: 2025-07-15
|
||||
*/
|
||||
public class ImprovedTextToBitmap {
|
||||
public class ReliableTextToBitmap {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String unit = "中国电子集团";
|
||||
String department = "人工智能研发中心";
|
||||
String name = "张三";
|
||||
String unit = "繁體繁體繁體";
|
||||
String department = "A研B发C";
|
||||
String name = "12李34四56";
|
||||
|
||||
byte[] unitBytes = textToBitmapBytes(unit);
|
||||
byte[] deptBytes = textToBitmapBytes(department);
|
||||
byte[] nameBytes = textToBitmapBytes(name);
|
||||
|
||||
generateCFile(unitBytes, deptBytes, nameBytes, "display_data.c");
|
||||
|
||||
// 生成预览图片
|
||||
generatePreviewImage(unitBytes, "unit_image.png");
|
||||
generatePreviewImage(deptBytes, "department_image.png");
|
||||
generatePreviewImage(nameBytes, "name_image.png");
|
||||
}
|
||||
|
||||
// 专门生成预览图片的方法
|
||||
private static void generatePreviewImage(byte[] data, String filename) {
|
||||
try {
|
||||
BufferedImage image = convertByteArrayToImage(data, 12);
|
||||
ImageIO.write(image, "PNG", new File(filename));
|
||||
System.out.println("成功生成预览图片: " + filename);
|
||||
} catch (IOException e) {
|
||||
System.err.println("图片生成失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 可靠的字节数组转图像方法
|
||||
*/
|
||||
public static BufferedImage convertByteArrayToImage(byte[] data, int height) {
|
||||
if (data == null || data.length == 0) {
|
||||
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
}
|
||||
|
||||
// 计算宽度
|
||||
int width = (data.length * 8) / height;
|
||||
|
||||
// 创建RGB图像
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
// 设置白色背景
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
image.setRGB(x, y, Color.WHITE.getRGB());
|
||||
}
|
||||
}
|
||||
|
||||
// 直接设置像素点
|
||||
int bitIndex = 0;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int value = data[i] & 0xFF;
|
||||
for (int bit = 7; bit >= 0; bit--) { // 高位在前
|
||||
boolean isBlack = ((value >> bit) & 1) == 1;
|
||||
if (isBlack) {
|
||||
int x = bitIndex % width;
|
||||
int y = bitIndex / width;
|
||||
if (y < height) { // 确保不越界
|
||||
image.setRGB(x, y, Color.BLACK.getRGB());
|
||||
}
|
||||
}
|
||||
bitIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可靠的点阵生成方法
|
||||
*/
|
||||
public static byte[] textToBitmapBytes(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
// 使用更清晰的黑体字体
|
||||
Font font = new Font("黑体", Font.PLAIN, 12);
|
||||
// 1. 创建画布 - 使用RGB类型避免问题
|
||||
Font font = new Font("宋体", Font.PLAIN, 12);
|
||||
BufferedImage image = createTextImage(text, font);
|
||||
|
||||
// 2. 直接提取点阵数据
|
||||
return extractBitmapData(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文本图像 - 最可靠的方法
|
||||
*/
|
||||
private static BufferedImage createTextImage(String text, Font font) {
|
||||
// 创建临时图像获取字体度量
|
||||
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
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;
|
||||
}
|
||||
// 计算文本宽度
|
||||
int totalWidth = metrics.stringWidth(text);
|
||||
|
||||
// 宽度对齐到8的倍数
|
||||
int width = (int) Math.ceil(totalWidth / 8.0) * 8;
|
||||
int height = 12;
|
||||
|
||||
// 创建图像
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
// 创建RGB图像
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
// 设置白色背景
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, width, height);
|
||||
|
||||
// 设置黑色文本
|
||||
g.setColor(Color.BLACK);
|
||||
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();
|
||||
g.drawString(text, 0, y);
|
||||
|
||||
// 绘制文本(优化垂直对齐)
|
||||
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();
|
||||
|
||||
// 扫描像素并打包数据
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取点阵数据 - 简单可靠的方法
|
||||
*/
|
||||
private static byte[] extractBitmapData(BufferedImage image) {
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
|
||||
List<Byte> 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;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
// 获取像素颜色
|
||||
Color color = new Color(image.getRGB(x, y));
|
||||
|
||||
// 使用阈值处理(提高清晰度)
|
||||
boolean isOpaque = alpha > 64; // 阈值可调整
|
||||
// 简单阈值判断 - 灰度小于128为黑色
|
||||
int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
|
||||
boolean isBlack = gray < 128;
|
||||
|
||||
currentByte = (currentByte << 1) | (isOpaque ? 1 : 0);
|
||||
// 高位优先打包
|
||||
currentByte = (currentByte << 1) | (isBlack ? 1 : 0);
|
||||
bitCount++;
|
||||
|
||||
if (bitCount == 8) {
|
||||
@ -106,11 +179,14 @@ public class ImprovedTextToBitmap {
|
||||
|
||||
// 处理最后不满8位的部分
|
||||
if (bitCount > 0) {
|
||||
currentByte <<= (8 - bitCount); // 左移到高位
|
||||
currentByte <<= (8 - bitCount);
|
||||
byteList.add((byte) currentByte);
|
||||
}
|
||||
|
||||
// 转换结果
|
||||
return byteListToArray(byteList);
|
||||
}
|
||||
|
||||
private static byte[] byteListToArray(List<Byte> byteList) {
|
||||
byte[] result = new byte[byteList.size()];
|
||||
for (int i = 0; i < byteList.size(); i++) {
|
||||
result[i] = byteList.get(i);
|
||||
@ -121,7 +197,7 @@ public class ImprovedTextToBitmap {
|
||||
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(" * 点阵显示数据 - 可靠生成\n");
|
||||
writer.write(" * 宽度计算公式: width = (数组长度 * 8) / 12\n");
|
||||
writer.write(" */\n\n");
|
||||
writer.write("#include <stdint.h>\n\n");
|
@ -1,128 +0,0 @@
|
||||
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<Byte> 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 <stdint.h>\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 ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user