Java - Image BMP header



我这里有一个小问题,如果有人能帮助我,我将非常高兴。我正在尝试进行下一个操作

  1. 读取BMP图像
  2. 将图像转换为字节[]
  3. 将图像旋转90度(字节数组)
  4. 在文件夹中写入新图像
我的问题是……在那一刻,当我试图写新的图像,我有一些问题与BMP头,我不知道为什么。如果有人知道答案,请给我一些建议。

将图像转换为字节[]

private static byte[] convertAnImageToPixelsArray(File file) throws FileNotFoundException {
    FileInputStream fis = new FileInputStream(file);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buf = new byte[1024];
    try {
        for (int readNum; (readNum = fis.read(buf)) != -1; ) {
            bos.write(buf, 0, readNum);
        }
    } catch (IOException ex) {
        Logger.getLogger(ConvertImage.class.getName()).log(Level.SEVERE, null, ex);
    }
    return bos.toByteArray();
}

private static byte[] rotate(double angle, byte[] pixels, int width, int height) {
    final double radians = Math.toRadians(angle), cos = Math.cos(radians), sin = Math.sin(radians);
    final byte[] pixels2 = new byte[pixels.length];
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            final int
                    centerx = width / 2,
                    centery = height / 2,
                    m = x - centerx,
                    n = y - centery,
                    j = ((int) (m * cos + n * sin)) + centerx,
                    k = ((int) (n * cos - m * sin)) + centery;
            if (j >= 0 && j < width && k >= 0 && k < height)
                pixels2[(y * width + x)] = pixels[(k * width + j)];
        }
    }
    arraycopy(pixels2, 0, pixels, 0, pixels.length);
    return pixels2;
}

将字节[]转换为图像

private static void convertArrayPixelsIntoImage(byte[] bytes) throws IOException {
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
    Iterator<?> readers = ImageIO.getImageReadersByFormatName("bmp");
    ImageReader reader = (ImageReader) readers.next();
    Object source = bis;
    ImageInputStream iis = ImageIO.createImageInputStream(source);
    reader.setInput(iis, true);
    ImageReadParam param = reader.getDefaultReadParam();
    Image image = reader.read(0, param);
    BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = bufferedImage.createGraphics();
    g2.drawImage(image, null, null);
    File imageFile = new File("Images/Output.bmp");
    ImageIO.write(bufferedImage, "bmp", imageFile);
}
主:

public static void main(String[] args) throws IOException {
    File file = new File("Images/Input-1.bmp");
    Image img = ImageIO.read(file);
    convertArrayPixelsIntoImage(rotate(90,convertAnImageToPixelsArray(file),img.getWidth(null),img.getHeight(null)));
}

这是错误消息:

主线程javax.imageio.IIOException:无法读取图像标题。

有什么建议吗?

问题是,当您旋转图像时,您没有考虑到BMP文件的结构。

你只是从文件中读取一个byte[],就像你可以从任何文件中读取一样——它只是一个字节流。

但是在您的rotate方法中,您假设像素值为:

  • 每像素1字节;
  • 从数组的开头开始。

事实并非如此。除了每个像素几乎肯定会由多个字节编码之外,BMP文件格式以标题和其他元数据开始。

虽然你显然可以找出如何正确解码数据,但我强烈反对这样做。您已经使用ImageIO (Image img = ImageIO.read(file);)读取了图像,因此无需重新发明轮子:只需使用Java现有的图像处理功能。

您忽略了BMP图像与任何其他格式一样具有标题。当您尝试旋转图像时,您正在改变字节序列,因此标题丢失在其他地方而不是开始。尝试将前54字节提取到另一个数组,旋转其他数组,然后首先写入文件头,然后写入其他字节

最新更新