Get Image Orientation and Rotate as Per Orientation

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 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

Image Orientation - Android

You need to account for all orientations not just 90 or 180. I am using this

    File curFile = new File("path-to-file"); // ... This is an image file from my device.
Bitmap rotatedBitmap;

try {
ExifInterface exif = new ExifInterface(curFile.getPath());
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
Matrix matrix = new Matrix();
if (rotation != 0f) {matrix.preRotate(rotationInDegrees);}
rotatedBitmap = Bitmap.createBitmap(bitmap,0,0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

}catch(IOException ex){
Log.e(TAG, "Failed to get Exif data", ex);
}

and:

 /**
* Gets the Amount of Degress of rotation using the exif integer to determine how much
* we should rotate the image.
* @param exifOrientation - the Exif data for Image Orientation
* @return - how much to rotate in degress
*/
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; }
return 0;
}

How to load image in specific orientation in Visual Studio?

As suggested in comments you can just rotate the local picture, but to do it with CSS:

Add a CSS style (place in head tag):

<style type="text/css">
.rotate90 {
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
</style>

And then

<asp:Image ID="Image1" runat="server" Height="235px" ImageUrl="~/App_Data/WP_20141225_21_42_13_Rich.jpg" Width="246px" class="rotate90" />

Reference: Rotate an image in image source in html

Orient image according to EXIF orientation before upload with PHP

Well. After a few unexplained downvotes and a very useful comment from DinoCoderSaurus this is the answer i was looking for.

I had to install and enable Imagick for PHP7.
It was not a plain simple job but there are a few guides available to google. Depending on your version / os installation notes are different so proceed with care.

My upload function (from original post) changed on the upload part.
Where it says:

if (empty($errors)){
// old code here.
}

It was changed for the following validation:

if (empty($errors)) {
// this is my new validation code.
$img = new Imagick($fileTmpName);
$orient = $img->getImageOrientation();
if($orient === 6){
// we need to rotate it 90deg
$img->rotateImage("rgba(255, 255, 255, 0.0)", 90);
}
if ($orient === 3){
// we need to rotate it 180deg
$img->rotateImage("rgba(255, 255, 255, 0.0)", 180);
}
// Note that imagick does the storage for me as well!
$img->writeImage("gallery/" . $fileName);
}
else{
$out .= "Errors on upload";
}

This fixed ALL of my issues with a reasonably good response time.
Hopefully some newbies like me will take some skill profit from this post.

As a farewell note i need to add... If you downvote a post, comment the reason why you did that, because this topic was already discussed here countless times, but after 2 days researching on SO old posts i didn't manage to find WHY it was not working!

A special thanks to DinoCoderSaurus who sent me in the right direction with around 10 words.



Related Topics



Leave a reply



Submit