Why does an image captured using camera intent gets rotated on some devices on Android?
Most phone cameras are landscape, meaning if you take the photo in portrait, the resulting photos will be rotated 90 degrees. In this case, the camera software should populate the Exif data with the orientation that the photo should be viewed in.
Note that the below solution depends on the camera software/device manufacturer populating the Exif data, so it will work in most cases, but it is not a 100% reliable solution.
ExifInterface ei = new ExifInterface(photoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Bitmap rotatedBitmap = null;
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotatedBitmap = rotateImage(bitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotatedBitmap = rotateImage(bitmap, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotatedBitmap = rotateImage(bitmap, 270);
break;
case ExifInterface.ORIENTATION_NORMAL:
default:
rotatedBitmap = bitmap;
}
Here is the rotateImage
method:
public static Bitmap rotateImage(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
}
How to save the correct rotated image using camerax Front Camera?
You need to read EXIF data of the image created & have to write your own custom controllers as per requirements & needs. It's very normal in most Android & iOS devices that the captured images get rotated & it must be handled accordingly. In most of the devices, the default orientation of the camera is set to landscape mode, so even if you take a pic in portrait mode it gets rotated to 90degrees.
From EXIF data, you can get the degree of the image rotated or if its mirrored & then you can handle it in the backend.
To rotate your image you can try
private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage) throws IOException
{
ExifInterface ei = new ExifInterface(selectedImage.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotateImage(img, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotateImage(img, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotateImage(img, 270);
default:
return img;
}
}
private static Bitmap rotateImage(Bitmap img, int degree)
{
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
img.recycle();
return rotatedImg;
}
For the image flipping issue you can try this
public static Bitmap flip(Bitmap src, int type)
{
// create new matrix for transformation
Matrix matrix = new Matrix();
matrix.preScale(-1.0f, 1.0f);
// return transformed image
return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
}
And then set the image to ImageView as
imgPreview.setImageBitmap(flip(bitmap));
Android camera resulted image should be rotated after the capture?
Problem is the camera orientation is a complete disaster (as is capturing an image) because OEMs do not adhere to the standard. HTC phones do things one way, Samsung phones do it a different way, the Nexus line seems to adhere no matter which vendor, CM7 based ROMs I think follow the standard no matter which hardware, but you get the idea. You sort of have to determine what to do based on the phone/ROM. See discussion here: Android camera unexplainable rotation on capture for some devices (not in EXIF)
Controlling the camera to take pictures in portrait doesn't rotate the final images
The problem is when I saved the image I didn't do well.
@Override
public void onPictureTaken(byte[] data, Camera camera) {
String timeStamp = new SimpleDateFormat( "yyyyMMdd_HHmmss").format( new Date( ));
output_file_name = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + timeStamp + ".jpeg";
File pictureFile = new File(output_file_name);
if (pictureFile.exists()) {
pictureFile.delete();
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
ExifInterface exif=new ExifInterface(pictureFile.toString());
Log.d("EXIF value", exif.getAttribute(ExifInterface.TAG_ORIENTATION));
if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6")){
realImage= rotate(realImage, 90);
} else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8")){
realImage= rotate(realImage, 270);
} else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3")){
realImage= rotate(realImage, 180);
} else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("0")){
realImage= rotate(realImage, 90);
}
boolean bo = realImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
((ImageView) findViewById(R.id.imageview)).setImageBitmap(realImage);
Log.d("Info", bo + "");
} catch (FileNotFoundException e) {
Log.d("Info", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("TAG", "Error accessing file: " + e.getMessage());
}
}
public static Bitmap rotate(Bitmap bitmap, int degree) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
// mtx.postRotate(degree);
mtx.setRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
Related Topics
Onclick Method Not Working Properly After Nestedscrollview Scrolled
How to Specify Location of Debug Keystore for Android Ant Debug Builds
How to Debug on a Real Device (Using Eclipse/Adt)
Google Map for Android My Location Custom Button
How to Setup Multiple Alarms in Android
Writing Some Characters Like '<' in an Xml File
How to Disable Viewpager Adapter on Touching Specific Views
Android Alarmmanager Setexact() Is Not Exact
How to Play an Audio File on a Voice Call in Android
Set Visibility of Progress Bar Gone on Completion of Image Loading Using Glide Library
Not Seeing Nexus7 in Eclipse's Android Devices
How to Enable Internal App Sharing for Android
How to Find Out Carrier's Name in Android
What Is Better: @Suppresslint or @Targetapi
Flutter Insecure Http Is Not Allowed by Platform
Using Espresso to Unit Test Google Maps
How to Fetch Data from a Web Server in an Android Application