繁体   English   中英

从十六进制字符串 Java 创建 BITMAP 图像

[英]create BITMAP image from hex String Java

我需要从通过 Excel 宏创建的十六进制字符串创建 BMP 图像(黑白)。 我在这方面的工作经验几乎为零,需要一些帮助。 下面是十六进制字符串,output 十六进制图像示例,以及我正在尝试的小代码片段:

字符串

001E00FE07FE3FE03C003C003F801FFE03FE007E3E003FE03FFC0FFE0E3E0FFE3FFC3FE03E0000000FF83FFC3FFE300630063006380E180C00003E003FE03FFC0FFE0E3E0FFE3FFC3FE03E00000000003FFE3FFE3FFE01F807F01FC03FFE3FFE3FFE0000000E000E000E3FFE3FFE3FFE000E000E000E0000

要创建的上述字符串的图像:

在此处输入图像描述

代码片段:

public void createImageFromHex() throws IOException {
        String hex="001E00FE07FE3FE03C003C003F801FFE03FE007E3E003FE03FFC0FFE0E3E0FFE3FFC3FE03E0000000FF83FFC3FFE300630063006380E180C00003E003FE03FFC0FFE0E3E0FFE3FFC3FE03E00000000003FFE3FFE3FFE01F807F01FC03FFE3FFE3FFE0000000E000E000E3FFE3FFE3FFE000E000E000E0000";

        byte[] imageInByte= ByteString.decodeHex(hex).toByteArray();

        for (byte b : imageInByte) {
            System.out.println("Byte : " + b);

        }
        InputStream in = new ByteArrayInputStream(imageInByte);

        Font font = new Font("Arial", Font.PLAIN, 12);
        BufferedImage img = new BufferedImage(1, 1, BufferedImage.BITMASK);
        Graphics2D g2d = img.createGraphics();
        FontMetrics fm = g2d.getFontMetrics(font);
        g2d.dispose();

        int width = fm.stringWidth(hex);
        int height = fm.getHeight();

        img = new BufferedImage(width, height, BufferedImage.BITMASK);
        g2d = img.createGraphics();
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);
        g2d.setColor(Color.BLACK);
        g2d.setFont(font);
        g2d.drawString(hex, 0, fm.getAscent());
        g2d.dispose();

        try {
            ImageIO.write(img, "bmp", new File("Hex.bmp"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    } 

这里的线索是十六进制/二进制数据的格式 您需要从某种规范中,从产生十六进制字符串的设备/软件/服务中了解这一点。 从数据和样本图像来看,我相信@tgdavies 已经正确地对其进行了逆向工程。

每个像素是一位。 白色像素存储为 0,黑色像素存储为 1。每像素存储为两个字节。 每列自下而上存储。

假设格式是正确的,编写代码来转换它是非常简单的:

public void createImageFromHex() throws IOException {
    // Assumption: hex contains a bitmap format, where
    //   * each pair of bytes is one *column*
    //   * each column is stored "bottom-up" (LSB is bottom pixel, MSB is top pixel)
    String hex = "001E00FE07FE3FE03C003C003F801FFE03FE007E3E003FE03FFC0FFE0E3E0FFE3FFC3FE03E0000000FF83FFC3FFE300630063006380E180C00003E003FE03FFC0FFE0E3E0FFE3FFC3FE03E00000000003FFE3FFE3FFE01F807F01FC03FFE3FFE3FFE0000000E000E000E3FFE3FFE3FFE000E000E000E0000";

    // (result is 120 bytes)
    byte[] imageInByte = ByteString.decodeHex(hex).toByteArray();

    int height = 16; // 16 according to sample
    int width = imageInByte.length / 2; // 60 according to the sample, but as we know each column is 16 bits or 2 bytes, we can calculate it

    // Create a BufferedImage of correct type: For a bitmap this is TYPE_BYTE_BINARY
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);

    // Loop over pixels and insert black or white
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            int pos = height * x + y;
            int bytePos = pos / 8;
            int bitPos = 7 - (pos % 8);
            byte value = imageInByte[bytePos];

            int bit = (value >> bitPos) & 1;

            // Each pixel is either all white (0) or all black (1)
            int rgb = bit != 0 ? 0x000000 : 0xFFFFFF;
            img.setRGB(x, height - 1 - y, rgb);
        }
    }

    // Write to BMP format
    File output = new File("Hex.bmp");
    if (!ImageIO.write(img, "bmp", output)) {
        System.err.printf("Could not write %s in BMP format...%n", output.getAbsolutePath());
    }
}

结果文件:

十六进制.bmp

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM