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
How to Update Values into Appsetting.JSON
Cannot Set Some Http Headers When Using System.Net.Webrequest
Transactionscope VS Transaction in Linq to SQL
Linq Select Objects in List Where Exists in (A,B,C)
404 Error After Adding Web API to an Existing MVC Web Application
How to Compare Only Date Without Time in Datetime Types in Linq to SQL with Entity Framework
Mocking Iprincipal in ASP.NET Core
Difference Between MVC 5 Project and Web API Project
Differencebetween Bool and Boolean Types in C#
What's the Difference Between "Groups" and "Captures" in .Net Regular Expressions
Good Aes Initialization Vector Practice
What Is the Algorithm to Convert an Excel Column Letter into Its Number
Retrieving the Calling Method Name from Within a Method
Is Async Await Keyword Equivalent to a Continuewith Lambda
Differencebetween Getter-Only Auto Properties and Expression Body Properties