【问题标题】:Convert File .bmp to binary and binary back to File .bmp in Java将文件 .bmp 转换为二进制文件并将二进制文件转换回 Java 中的文件 .bmp
【发布时间】:2020-12-23 02:41:48
【问题描述】:

我正在尝试将 Image(.bmp) 转换为二进制代码,然后对其进行处理,然后再将其转换回来。让我们把处理部分放在一边,只关注转换。

我现在如何将图像转换为二进制:

    // Image to byte[]
    File file = new File("image.bmp");
    BufferedImage bufferedImage = ImageIO.read(file);
    WritableRaster raster = bufferedImage.getRaster();
    DataBufferByte data = (DataBufferByte) raster.getDataBuffer();

   // byte[] to binary String
   String string = "";
    for (byte b : data.getData()) {
        String substring = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
        string = string.concat(substring);
    }

  // Binary string to binary LinkedList<Ingeger> - this part is optional
  LinkedList<Integer> vector = new LinkedList<>();
    for (char c : stringVector.toCharArray()) {
        if (c == '0' || c == '1') {
            vector.add((int) c - 48);

        } else {
            System.out.println("Incorrect value.");
            break;
        }
    }

此时我正在将 File(.bmp) 转换为二进制向量。我不确定它是否正确。

另一个问题是将其转换回 .bmp 文件。 我需要将我的二进制向量(或字符串)转换为 byte[] 并返回到 File 或图像。

我相信最后一步应该是这样的:

        FileOutputStream fileOutputStream = new FileOutputStream("output.bmp");
        fileOutputStream.write(byteArrayFromBinary.getBytes());

有人能帮我弄清楚吗?因为我不确定这到底有什么问题。非常感谢您的任何建议。

【问题讨论】:

  • BMP 文件不仅仅是您从光栅中获得的所有图像数据;它至少还有一个标题。所以生成的output.bmp 不会是 BMP 文件。除此之外,您正在做的事情非常令人困惑。我无法想象您为什么要将图像数据作为栅格中所有位的LinkedList&lt;Integer&gt; 进行处理。我强烈怀疑这是一个 x-y 问题,你最好解释一下你实际上想要做什么。
  • 我提到的LinkedList&lt;Intgeger&gt; 部分是可选的。对我来说使用它更容易(编码它,通过通道,解码它)。我将对图像做同样的事情,这就是为什么我需要它作为二进制文件,这就是为什么我需要将它从二进制转换回 .bmp(处理后)。但在这个线程中,我只专注于从 .bmp 转换为二进制并返回,我有点卡住了。
  • 你到底为什么要把它转换成字符串?也使用 Schlemiel the Painter 算法?而且,嗯,如果你没有注意到...... bmp is 二进制,并且鉴于它是未压缩的,它根本不是“编码”的。您实际上想通过这一切来完成什么?
  • @Nyerguds 所以是的,我做错了,现在我发布了一个非常适合我的解决方案。也许它不是最好的,但它确实对我有用。我花了一些时间,请善意地审查它:)

标签: java bitmap binary


【解决方案1】:

所以经过大量研究终于想出了一个解决方案。

将 .bmp 格式的 BufferedImage 转换为二进制:

public String imageToVector(BufferedImage image) throws Exception {
        String vectorInString = "";
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                Color color = new Color(image.getRGB(x, y), false);
            vectorInString = vectorInString.concat(decimalToBinary(color.getRed()));
            vectorInString = vectorInString.concat(decimalToBinary(color.getGreen())); 
            vectorInString = vectorInString.concat(decimalToBinary(color.getBlue())); 
            }
        }
        return vectorInString;
}

要从二进制向量转换回 .bmp 格式的 BufferedImage:

 String[] splittedString = vectorInString.split("(?<=\\G.{8})");

    int i = 0;
    for (int x = 0; x < image.getWidth(); x++) {
        for (int y = 0; y < image.getHeight(); y++) {
            int red = Integer.parseInt(splittedString[i], 2); 
            i++;
            int green = Integer.parseInt(splittedString[i], 2); 
            i++;
            int blue = Integer.parseInt(splittedString[i], 2); 
            i++;

            Color color = new Color(red, green, blue);

            image.setRGB(x, y, color.getRGB());
        }
    }

如果您有任何其他问题,请提出,我可以解释为什么我需要这个解决方案。

【讨论】:

  • 您仍在使用Schlemiel the Painter algorithm。要制作长字符串,您应该使用 StringBuilder 以避免大量减速和额外的内存使用。此外,您按 8 进行拆分,但您只处理 RGB,没有 A,因此字符串仅按 3 个字节构建。那不应该是 6,而不是 8?
  • @Nyerguds 谢谢你,会考虑你的建议并改进我的算法!至于字节数,是的,你是对的,因为另一个用例,我除以 8,但绝对应该是 6,因为我没有使用 alpha 值。您提供的链接很有帮助,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
相关资源
最近更新 更多