Camera Preview Is in Portrait Mode But Image Captured Is Rotated

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



Leave a reply



Submit