Photo Rotated from Camera (Samsung Device)

Photo rotated from camera (SAMSUNG device)

UPD 29.08.2018 I found that this method doesn't work with Samsung device based on Android 8+. I don't have Samsung s8 (for example) and can't understand why this again does not work there. If someone can test and check why this not work - let's try to fix this together.


I found how to fix: well it's really stupid and very hard for me.

First step get activity result

 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {

String _path = Environment.getExternalStorageDirectory() + File.separator + "TakenFromCamera.jpg";
String p1 = Environment.getExternalStorageDirectory().toString();
String fName = "/TakenFromCamera.jpg";
final int rotation = getImageOrientation(_path);
File file = resaveBitmap(p1, fName, rotation);
Bitmap mBitmap = BitmapFactory.decodeFile(_path);

Main steps it's getImageOrientation before changes in file.

  1. getImageOrientation (by path)
  2. resave file (if need send to server, if you need only for preview we can skip this step)
  3. get correct bitmap from file

For preview it's enough to perform only steps 1 and 3, and using this function - just rotate bitmap.

private Bitmap checkRotationFromCamera(Bitmap bitmap, String pathToFile, int rotate) {
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return rotatedBitmap;
}

getImageOrientation

public static int getImageOrientation(String imagePath) {
int rotate = 0;
try {
ExifInterface exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return rotate;
}

and resaveBitmap if need

private File resaveBitmap(String path, String filename, int rotation) { //help for fix landscape photos
String extStorageDirectory = path;
OutputStream outStream = null;
File file = new File(filename);
if (file.exists()) {
file.delete();
file = new File(extStorageDirectory, filename);
}
try {
// make a new bitmap from your file
Bitmap bitmap = BitmapFactory.decodeFile(path + filename);
bitmap = checkRotationFromCamera(bitmap, path + filename, rotation);
bitmap = Bitmap.createScaledBitmap(bitmap, (int) ((float) bitmap.getWidth() * 0.3f), (int) ((float) bitmap.getHeight() * 0.3f), false);
bitmap = Utils.getCircleImage(bitmap);
outStream = new FileOutputStream(path + filename);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}

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);
}

Capture photo rotate 90 degree in samsung mobile

Some device rotate image according to device orientation .

here i have write one common method to get orientation and get image in right scale

    public  Bitmap decodeFile(String path) {//you can provide file path here 
int orientation;
try {
if (path == null) {
return null;
}
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 0;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale++;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bm = BitmapFactory.decodeFile(path, o2);
Bitmap bitmap = bm;

ExifInterface exif = new ExifInterface(path);

orientation = exif
.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

Log.e("ExifInteface .........", "rotation ="+orientation);

// exif.setAttribute(ExifInterface.ORIENTATION_ROTATE_90, 90);

Log.e("orientation", "" + orientation);
Matrix m = new Matrix();

if ((orientation == ExifInterface.ORIENTATION_ROTATE_180)) {
m.postRotate(180);
// m.postScale((float) bm.getWidth(), (float) bm.getHeight());
// if(m.preRotate(90)){
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
return bitmap;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
m.postRotate(90);
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
return bitmap;
}
else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
m.postRotate(270);
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
return bitmap;
}
return bitmap;
} catch (Exception e) {
return null;
}

}

EDIT:

This code is not optimized , i just show the logic code from my one of the test project.

Choosing Images on a Samsung Galaxy Device rotates

Duplicate Question, see Android image selected from gallery Orientation is always 0 : Exif TAG

Check answer of MKJParekh. What you have to do:
1.) Retrieve orientation of the bitmap media store
2.) Rotate the bitmap according the orientation if necessary

Android rotates pictures by 90 degrees (taken by camera)

This is a bug based on different manufacturers settings. Some phones rotate them, some don't. see the link, it's issue #1193

http://code.google.com/p/android/issues/detail?id=1193

Also answers available to correct it - Why does an image captured using camera intent gets rotated on some devices on Android?

Samsung Galaxy S7 show device photos rotated

If you use an image-loading library, and you care about EXIF orientation headers, choose an image-loading library that applies those headers for you (e.g., Picasso, at least for local images). This may require some sort of an opt-in call (e.g., considerExifParams(true), per your comment).

Not all images will have an EXIF orientation header. It depends on whether it is a photo, what sort of camera hardware took the photo, whether the camera app that took the photo rotated the image for you, etc.



Related Topics



Leave a reply



Submit