ImageIO.read()方法是否考虑EXIF方向元数据?

4

JPEG图像中有时会包含EXIF元数据,其中说明了图像应该显示的方向。

问题是,Java的ImageIO.read()在读取JPEG图像时是否考虑EXIF,并自动应用转换。

更具体地说,如果我使用Java的ImageIO将带有EXIF的JPEG图像转换为PNG图像,PNG图像的方向是否正确?或者下面的代码是否会生成一个不考虑EXIF方向指令的PNG图像?

private byte[] convertToPng(byte[] imageFileAsByteArray) {
    ByteArrayInputStream bis = new ByteArrayInputStream(imageFileAsByteArray);
    BufferedImage bi = ImageIO.read(bis);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ImageIO.write(bi, "png", bos);

    return bos.toByteArray();
}

ImageIO.read() 不会读取您的 exif。您应该使用 ImageReader 类来读取和复制图像元数据。 - Planck Constant
我不想复制任何元数据。PNG图像甚至没有任何EXIF条目。我希望根据EXIF值对图像进行转换,然后将其保存为另一种格式,忽略EXIF条目。 - SomethingSomething
1
是的,PNG格式。抱歉我忘了这个。但无论如何,您必须手动提取元数据并使用它来转换您的图像。这个库也很好:https://github.com/drewnoakes/metadata-extractor - Planck Constant
1
@Uata,你的信息来源是什么?ImageIO.read() 的作用只是为图像类型构建一个适当的 ImageReader 并调用它。因此很难看出它如何避免处理 EXIF 元数据。 - user207421
2个回答

4
简短的回答是,不幸的是,ImageIO.read(..)(默认情况下)不考虑Exif方向标签。您的PNG文件将不会相应地旋转。
然而,所有ImageIO.read(..)内部所做的就是查找适当的ImageReader插件以进行委托读取。虽然JRE捆绑的插件不考虑Exif,但可以在第三方ImageReader中添加对其的支持。不幸的是,我不知道有任何这样做的,但我正在考虑在将来添加Exif方向支持到TwelveMonkeys ImageIO JPEGImageReader
同时,您需要通过读取元数据并进行旋转来自行应用旋转。可以使用ImageIO JPEG metadata或某些第三方库来获取方向标签的值。我认为提到的metadata-extractorTwelveMonkeys ImageIO都可以用于此目的。JAI ImageIO(使用TIFF元数据)可能也可以实现此功能。
如果使用ImageIO JPEG元数据,请注意:
请注意,希望根据在javax_imageio_jpeg_image_1.0格式中给出的元数据树结构解释Exif元数据的应用程序必须检查是否存在具有指示为Exif标记段的标记的unknown标记段并包含识别其为Exif标记段的数据。

-1

我曾经为JPEG EXIF方向问题苦苦挣扎,但现在当我开始解决这些问题时,发现它们已经消失了。为了确保自己,我简化了OP的示例以便阅读。

public static void main (String [] args) throws Exception {
  java.io.File in  = new java.io.File ("in.jpg");
  java.io.File out = new java.io.File ("out.png");
  BufferedImage image  = ImageIO.read (new FileInputStream(in));
  ImageIO.write (image, "png", out);
}

in.jpg是一张带有exif方向标签8的图片,向左倾斜。当我运行示例时,out.png被创建为正确定位的png图片。因此,似乎ImageIo最近学到了一些东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接