首页 > 解决方案 > 为什么 Google Appengine 的图像 API 提供的图像方向不正确?

问题描述

如果您使用 AppEngine图像 API创建图像, 则输出图像没有 Exif。如果源图像在 Exif 中设置了方向标志,则不会将其保留到输出图像中,因此会在用户看来是旋转的。

有没有办法告诉将ImagesServiceFactoryExif 传递给输出图像?

标签: javagoogle-app-engineexif

解决方案


到目前为止,我发现的最好方法是使用java Exif parser简单地读取 Orientation 标志,然后对生成的图像应用旋转变换,以便实际旋转像素。这是一个简化的示例:

byte[] sourceImage = yourCode();

int orientation = 1;
try {
    Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(sourceImage));
    orientation = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class).getInt(ExifIFD0Directory.TAG_ORIENTATION);
} catch (Throwable t) {
    log.log(Level.INFO, "Failed to extract orientation", t);
}

Image destinationImage = ImagesServiceFactory.makeImage(sourceImage);
Transform rotate;

switch (orientation) {
    case (EXIF_ORIENTATION_90): {
        rotate = ImagesServiceFactory.makeRotate(90);
        break;
    }
    case (EXIF_ORIENTATION_180): {
        rotate = ImagesServiceFactory.makeRotate(180);
        break;
    }
    case (EXIF_ORIENTATION_270): {
        rotate = ImagesServiceFactory.makeRotate(270);
        break;
    }
    default:
        rotate = ImagesServiceFactory.makeRotate(0); // anything else, no rotate
}
destinationImage = ImagesServiceFactory.getImagesService().applyTransform(rotate, destinationImage);

final byte[] destinationImageData = destinationImage.getImageData();

这应该足以让你继续前进。可能的 Exif 方向值(如果存在)是:

1 = Horizontal (normal) 
2 = Mirror horizontal 
3 = Rotate 180 
4 = Mirror vertical 
5 = Mirror horizontal and rotate 270 CW 
6 = Rotate 90 CW 
7 = Mirror horizontal and rotate 90 CW 
8 = Rotate 270 CW

我宁愿不必这样做,因为它需要不必要的转换和额外的 Exif 解析步骤。欢迎更好的解决方案:)


推荐阅读