简体   繁体   English

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

[英]create BITMAP image from hex String Java

I have a requirement to create a BMP image (black & white) from the hex string created through Excel Macro.我需要从通过 Excel 宏创建的十六进制字符串创建 BMP 图像(黑白)。 I have next to zero experience working on this and need some help.我在这方面的工作经验几乎为零,需要一些帮助。 Below is the Hex String, output image example of the hex, and little code snippet that I am trying:下面是十六进制字符串,output 十六进制图像示例,以及我正在尝试的小代码片段:

String :字符串

001E00FE07FE3FE03C003C003F801FFE03FE007E3E003FE03FFC0FFE0E3E0FFE3FFC3FE03E0000000FF83FFC3FFE300630063006380E180C00003E003FE03FFC0FFE0E3E0FFE3FFC3FE03E00000000003FFE3FFE3FFE01F807F01FC03FFE3FFE3FFE0000000E000E000E3FFE3FFE3FFE000E000E000E0000

Image to be created of the above string:要创建的上述字符串的图像:

在此处输入图像描述

Code Snippet:代码片段:

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();
        }
    } 

The clue here is the format of the hex/binary data .这里的线索是十六进制/二进制数据的格式 You need to know this from some kind of specification, from the device/software/service that produces the hex string.您需要从某种规范中,从产生十六进制字符串的设备/软件/服务中了解这一点。 From the data and sample image, I believe @tgdavies has correctly reverse-engineered it.从数据和样本图像来看,我相信@tgdavies 已经正确地对其进行了逆向工程。

Each pixel is one bit.每个像素是一位。 The white pixels are stored as 0, black as 1. Each column of pixels is stored as two bytes.白色像素存储为 0,黑色像素存储为 1。每像素存储为两个字节。 Each column is stored bottom-up.每列自下而上存储。

Assuming that format is correct, it's quite trivial to write code to convert it:假设格式是正确的,编写代码来转换它是非常简单的:

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());
    }
}

Result file:结果文件:

十六进制.bmp

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

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