How to Rotate Jpeg Images Based on the Orientation Metadata

How to rotate JPEG images based on the orientation metadata?

If you want to rotate your images, I would suggest to use the metadata extractor library http://code.google.com/p/metadata-extractor/. You can get the image information with the following code:

// Inner class containing image information
public static class ImageInformation {
public final int orientation;
public final int width;
public final int height;

public ImageInformation(int orientation, int width, int height) {
this.orientation = orientation;
this.width = width;
this.height = height;
}

public String toString() {
return String.format("%dx%d,%d", this.width, this.height, this.orientation);
}
}

public static ImageInformation readImageInformation(File imageFile) throws IOException, MetadataException, ImageProcessingException {
Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
JpegDirectory jpegDirectory = metadata.getFirstDirectoryOfType(JpegDirectory.class);

int orientation = 1;
try {
orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
} catch (MetadataException me) {
logger.warn("Could not get orientation");
}
int width = jpegDirectory.getImageWidth();
int height = jpegDirectory.getImageHeight();

return new ImageInformation(orientation, width, height);
}

Then given the orientation you retrieve, you can rotate and/or flip the image to the right orientation. The Affine transform for the EXIF orientation is given by the following method:

// Look at http://chunter.tistory.com/143 for information
public static AffineTransform getExifTransformation(ImageInformation info) {

AffineTransform t = new AffineTransform();

switch (info.orientation) {
case 1:
break;
case 2: // Flip X
t.scale(-1.0, 1.0);
t.translate(-info.width, 0);
break;
case 3: // PI rotation
t.translate(info.width, info.height);
t.rotate(Math.PI);
break;
case 4: // Flip Y
t.scale(1.0, -1.0);
t.translate(0, -info.height);
break;
case 5: // - PI/2 and Flip X
t.rotate(-Math.PI / 2);
t.scale(-1.0, 1.0);
break;
case 6: // -PI/2 and -width
t.translate(info.height, 0);
t.rotate(Math.PI / 2);
break;
case 7: // PI/2 and Flip
t.scale(-1.0, 1.0);
t.translate(-info.height, 0);
t.translate(0, info.width);
t.rotate( 3 * Math.PI / 2);
break;
case 8: // PI / 2
t.translate(0, info.width);
t.rotate( 3 * Math.PI / 2);
break;
}

return t;
}

The rotation of the image would be done by the following method:

public static BufferedImage transformImage(BufferedImage image, AffineTransform transform) throws Exception {

AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);

BufferedImage destinationImage = op.createCompatibleDestImage(image, (image.getType() == BufferedImage.TYPE_BYTE_GRAY) ? image.getColorModel() : null );
Graphics2D g = destinationImage.createGraphics();
g.setBackground(Color.WHITE);
g.clearRect(0, 0, destinationImage.getWidth(), destinationImage.getHeight());
destinationImage = op.filter(image, destinationImage);
return destinationImage;
}

In a server environment, don't forget to run with -Djava.awt.headless=true

JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images

The github project JavaScript-Load-Image provides a complete solution to the EXIF orientation problem, correctly rotating/mirroring images for all 8 exif orientations. See the online demo of javascript exif orientation

The image is drawn onto an HTML5 canvas. Its correct rendering is implemented in js/load-image-orientation.js through canvas operations.

Hope this saves somebody else some time, and teaches the search engines about this open source gem :)

How to fix EXIF orientation data in JPG files

As you say, there is orientation data in Exif. It defines how the raw pixel data should be transformed before being displayed (rotation, but also potentially flipping on either axis).

For a JPEG image with Exif, the 'easy' way to rotate the image is just to update the Exif info. Of course this requires the viewer to honour that rotation information.

The more expensive way (and potentially lossy) is to physically rotate the image data. I suspect that this is what you need to do to satisfy your photo frame.

In .NET you can do this with System.Windows.Drawing, for example. The Image.RotateFlip method would be a good place to start.

To extract the orientation data from your image, may I humbly suggest using my MetadataExtractor library?

var orientation = ImageMetadataReader.ReadMetadata(myImagePath)
.OfType<ExifIfd0Directory>()
.FirstOrDefault()
?.GetObject(ExifIfd0Directory.TagOrientation);

That'll give you an int?, the values of which are:

  1. Top, left side (Horizontal / normal)
  2. Top, right side (Mirror horizontal)
  3. Bottom, right side (Rotate 180)", "Bottom, left side (Mirror vertical)
  4. Left side, top (Mirror horizontal and rotate 270 CW)
  5. Right side, top (Rotate 90 CW)
  6. Right side, bottom (Mirror horizontal and rotate 90 CW)
  7. Left side, bottom (Rotate 270 CW)

An aside here, mostly because it's interesting: JPEG images are encoded as a grid of 16x16 pixel 'blocks'. If your image is not exactly a multiple of 16 pixels in both directions, then rotation can potentially shift the alignment of this grid which will result in decoding and re-encoding of the images, which will lose information. If the original JPEG has low compression then you probably won't be able to perceive this loss, so it may be academic to point it out, but it will still be there.

Different rotation of image on PC and through input type file

There are two main metadata tags for specifying image orientation:

Orientation: [TopLeft, BottomRight, RightTop, LeftBottom]

and

exif:Orientation: [1, 3, 6, 8]

I suspect your image was taken by a device, which uses exif:Orientation meta tag. Ubuntu default image viewer supports exif:Orientation and thus it displays the image correctly. Browsers, however, do not support this tag (for backward compatibility reasons) and they have to fall back to the default orientation which is rotated 90 deg to right in your case.

You could solve your issue by supplementing your images with the Orientation meta tag. This could be done with most image viewing software by simply rotating your image and saving it in place (in Ubuntu you will see the image rotated properly, so simply rotate it in any direction and rotate it back and save).



Related Topics



Leave a reply



Submit