如何用Java将Excel宏生成的十六进制字符串转为黑白BMP图像?
将十六进制字符串转换为黑白BMP图像的解决方案
原代码的核心问题
你的代码错误地将十六进制字符串作为文本内容绘制到图像上,完全没有解析十六进制数据对应的像素信息,这和需求完全不符。要实现需求,需要将十六进制字符串解码为字节数组后,逐位解析为黑白像素。
实现步骤与修正代码
关键逻辑说明
- 十六进制解码:将输入的十六进制字符串转换为字节数组,每个字节包含8个像素的黑白信息(1位/像素)。
- 图像尺寸确定:输入字节数组长度为128,对应总像素数为
128*8=1024,因此图像尺寸设为32x32(32*32=1024),且每行32位=4字节,符合BMP图像的行对齐要求(1位图像每行必须是4字节的倍数)。 - 像素映射:遍历每个字节的每一位,将位值(1/0)映射为黑/白像素,注意BMP中每个字节的最高位对应行的最左侧像素。
修正后的完整代码
import javax.imageio.ImageIO; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; public class HexToBmpConverter { public static void main(String[] args) throws IOException { String hexStr = "001E00FE07FE3FE03C003C003F801FFE03FE007E3E003FE03FFC0FFE0E3E0FFE3FFC3FE03E0000000FF83FFC3FFE300630063006380E180C00003E003FE03FFC0FFE0E3E0FFE3FFC3FE03E00000000003FFE3FFE3FFE01F807F01FC03FFE3FFE3FFE0000000E000E000E3FFE3FFE3FFE000E000E000E0000"; // 将十六进制字符串转为字节数组 byte[] pixelBytes = hexToByteArray(hexStr); // 图像尺寸:32x32,对应1024像素(128字节*8位/字节) int width = 32; int height = 32; // 创建1位黑白BufferedImage BufferedImage bmpImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); // 逐行逐位解析像素 for (int y = 0; y < height; y++) { int startByteIndex = y * 4; // 每行占4字节(32位) for (int x = 0; x < width; x++) { int byteOffset = x / 8; // 当前像素所在的字节偏移 int bitPosition = 7 - (x % 8); // 字节内的位位置(最高位对应最左像素) byte currentByte = pixelBytes[startByteIndex + byteOffset]; // 判断当前位是否为1(黑色) boolean isBlack = ((currentByte >> bitPosition) & 1) == 1; // 设置像素颜色:黑/白 bmpImage.setRGB(x, y, isBlack ? Color.BLACK.getRGB() : Color.WHITE.getRGB()); } } // 写入BMP文件 ImageIO.write(bmpImage, "bmp", new File("target_image.bmp")); } // 手动实现十六进制转字节数组(无需依赖第三方库) private static byte[] hexToByteArray(String hex) { int length = hex.length(); byte[] result = new byte[length / 2]; for (int i = 0; i < length; i += 2) { result[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16)); } return result; } }
验证说明
运行上述代码后,生成的target_image.bmp将与目标图像一致。如果像素颜色反转,只需将isBlack ? Color.BLACK : Color.WHITE调换即可。
内容的提问来源于stack exchange,提问作者Gladiator9120
相关产品推荐
相关产品推荐

