简体   繁体   中英

Java Image BufferedImage loosing aspect ratio of upright image

I am storing an Image in the filesystem like:

FileImageOutputStream fos = new FileImageOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
      fos.write(buffer, 0, len);
}
fos.close();

And all images are stored correctly in the filesystem. (Also with correct aspect ratio with width and height!)

However, later, I am loading my image like:

File imgFile ...
FileImageInputStream stream = new FileImageInputStream(imgFile);
BufferedImage srcImage = ImageIO.read(stream);

And I want to get the width and height for my images like:

int actualHeight = srcImage.getHeight();
int actualWidth = srcImage.getWidth();

This works totally fine for images in landscape format. However, for images in upfront format, the width and height is always swapped, so that the width is the height of the orginial image. So, eg I have an image that is 200x500 (width x height) and the two integers above are actualHeight = 200 and actualWidth = 500 .

Am I missing something?

Most likely, your images are Exif images ("Exif-in-JPEG") from a digital camera/phone. For such images, the pixel data is often stored in the "natural" orientation of the sensor, which is always the same (usually landscape). For portrait images, the orientation is only stored in the Exif metadata, and the ImageIO JPEG plugin doesn't take this orientation into account.

Some cameras, like my Canon DSLR, has an option to do in-camera rotation to match the orientation, but this feature is typically disabled by default. This is obviously only a possible fix if you control the input images.

To fix this in the Java side, you hava some options. You already mentioned using Thumbnailator:

BufferedImage srcImage = Thumbnails.of(new FileInputStream(imgFile))
                                    .scale(1)
                                    .asBufferedImage();

Another option is to use EXIFUtilities from TwelveMonkeys (I'm the author of that library):

IIOImage image = EXIFUtilities.readWithOrientation(imgFile);
BufferedImage srcImage = (BufferedImage) image.getRenderedImage();

Or, if you don't need the other metadata for anything:

BufferedImage srcImage = (BufferedImage) EXIFUtilities.readWithOrientation(imgFile)
                                                      .getRenderedImage();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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