Camera orientation issue in Android

AndroidOrientationAndroid Camera-Intent

Android Problem Overview


I am building an application that uses camera to take pictures. Here is my source code to do this:

		File file = new File(Environment.getExternalStorageDirectory(),
			imageFileName);
	imageFilePath = file.getPath();
	Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
	//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
	intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
	startActivityForResult(intent, ACTIVITY_NATIVE_CAMERA_AQUIRE);

On onActivityResult() method, I use BitmapFactory.decodeStream() to pickup the image.

When I run my application on Nexus one, it runs well. But when I run on Samsung Galaxy S or HTC Inspire 4G, the image's direction is not correct.

  • Capture with portrait mode, the real image (save on SD card) always rotates 90 degree.

image preview after shot real image on SD card

Image preview after shot --------- Real image on SD card

  • Capture with landscape mode, all things are good.

Image preview after shot Real image on SD card

Image preview after shot --------- Real image on SD card

Android Solutions


Solution 1 - Android

There are quite a few similar topics and issues around here. Since you're not writing your own camera, I think it boils down to this:

some devices rotate the image before saving it, while others simply add the orientation tag in the photo's exif data.

I'd recommend checking the photo's exif data and looking particularly for

ExifInterface exif = new ExifInterface(SourceFileName);     //Since API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Since the photo is displaying correctly in your app, i'm not sure where the problem is, but this should definitely set you on the right path!

Solution 2 - Android

I just encountered the same issue, and used this to correct the orientation:

public void fixOrientation() {
	if (mBitmap.getWidth() > mBitmap.getHeight()) {
    	Matrix matrix = new Matrix();
    	matrix.postRotate(90);
    	mBitmap = Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
	}
}

If the width of the Bitmap is greater than the height, the returned image is in landscape, so I rotate it 90 degrees.

Hope it helps anyone else with this issue.

Solution 3 - Android

There are two things needed:

  1. Camera preview need the same as your rotation. Set this by camera.setDisplayOrientation(result);

  2. Save the picture captured as your camera preview. Do this via Camera.Parameters.

     int mRotation = getCameraDisplayOrientation();
    
     Camera.Parameters parameters = camera.getParameters();
    
     parameters.setRotation(mRotation); //set rotation to save the picture
    
     camera.setDisplayOrientation(result); //set the rotation for preview camera
    
     camera.setParameters(parameters);
    

Hope that helps.

Solution 4 - Android

            int rotate = 0;
            try {
                File imageFile = new File(sourcepath);
                ExifInterface exif = new ExifInterface(
                        imageFile.getAbsolutePath());
                int orientation = exif.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);

                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 (Exception e) {
                e.printStackTrace();
            }
            Matrix matrix = new Matrix();
	matrix.postRotate(rotate);
	bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

Solution 5 - Android

Another option is to rotate the bitmap in the result screen like this:

ImageView img=(ImageView)findViewById(R.id.ImageView01);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.refresh);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
BitmapDrawable bmd = new BitmapDrawable(rotatedBMP);

img.setImageDrawable(bmd);

Solution 6 - Android

I have also this type of same problem for some device:

private void rotateImage(final String path) {
	
	Bitmap scaledBitmap = Bitmap.createScaledBitmap(Conasants.bm1, 1000,
			700, true);
	Bitmap rotatedBitmap = null;
	try {
		ExifInterface ei = new ExifInterface(path);
		int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
				ExifInterface.ORIENTATION_NORMAL);
		Matrix matrix = new Matrix();
		switch (orientation) {
		case ExifInterface.ORIENTATION_ROTATE_90:
			matrix.postRotate(90);
			rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
					scaledBitmap.getWidth(), scaledBitmap.getHeight(),
					matrix, true);
			break;
		case ExifInterface.ORIENTATION_ROTATE_180:
			matrix.postRotate(180);
			rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
					scaledBitmap.getWidth(), scaledBitmap.getHeight(),
					matrix, true);
			break;
		case ExifInterface.ORIENTATION_ROTATE_270:
			matrix.postRotate(270);
			rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
					scaledBitmap.getWidth(), scaledBitmap.getHeight(),
					matrix, true);
			break;
		default:
			rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
					scaledBitmap.getWidth(), scaledBitmap.getHeight(),
					matrix, true);
			break;
		}
	} catch (Throwable e) {
		e.printStackTrace();
	}
	cropImage.setImageBitmap(rotatedBitmap);
	rotatedBitmap = null;
	Conasants.bm1 = null;
}

Solution 7 - Android

Try this way : static Uri image_uri; static Bitmap taken_image=null;

            image_uri=fileUri; // file where image has been saved

      taken_image=BitmapFactory.decodeFile(image_uri.getPath());
      try
        {
            ExifInterface exif = new ExifInterface(image_uri.getPath()); 
        
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);


            switch(orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 180);

                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 270);

                    break;
                case ExifInterface.ORIENTATION_NORMAL:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 0);

                    break;
            }

        }
        catch (OutOfMemoryError e)
        {
            Toast.makeText(getActivity(),e+"\"memory exception occured\"",Toast.LENGTH_LONG).show();


        }



public Bitmap RotateBitmap(Bitmap source, float angle) {
      Matrix matrix = new Matrix();
      matrix.postRotate(angle);

      round_Image = source;
      round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(),   source.getHeight(), matrix, true);


  return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);

}

Solution 8 - Android

No more checking the photo's exif data. Go easy with Glide.

Google introduced us an Image Loader Library for Android developed by bumptech named Glide as a library that recommended by Google. It has been used in many Google open source projects till now including Google I/O 2014 official application.

Ex : Glide.with(context).load(uri).into(imageview);

For more : https://github.com/bumptech/glide

Solution 9 - Android

public void setCameraPicOrientation(){
        int rotate = 0;
        try {
            File imageFile = new File(mCurrentPhotoPath);
            ExifInterface exif = new ExifInterface(
                    imageFile.getAbsolutePath());
            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);

            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 (Exception e) {
            e.printStackTrace();
        }
        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        int targetW = 640;
        int targetH = 640;

		/* Get the size of the image */
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

		/* Figure out which way needs to be reduced less */
        int scaleFactor = 1;
        if ((targetW > 0) || (targetH > 0)) {
            scaleFactor = Math.min(photoW/targetW, photoH/targetH);
        }

		/* Set bitmap options to scale the image decode target */
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

		/* Decode the JPEG file into a Bitmap */
        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        bitmap= Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        	/* Associate the Bitmap to the ImageView */
      imageView.setImageBitmap(bitmap);
    }

Hope this will help!! Thanks

Solution 10 - Android

	public static  int mOrientation =  1;
	
	OrientationEventListener myOrientationEventListener;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.takephoto);
		
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		
        
        myOrientationEventListener
        = new OrientationEventListener(getApplicationContext()) {
			
			@Override
			public void onOrientationChanged(int o) {
				// TODO Auto-generated method stub
				if(!isTablet(getApplicationContext()))
				{
					if(o<=285 && o>=80)
						mOrientation = 2;
					else
						mOrientation = 1;
				}
				else
				{
					if(o<=285 && o>=80)
						mOrientation = 1;
					else
						mOrientation = 2;
				}
				
			}
		};
		
		myOrientationEventListener.enable();
        
	}
	
	
	
	public static boolean isTablet(Context context) {
	    return (context.getResources().getConfiguration().screenLayout
	            & Configuration.SCREENLAYOUT_SIZE_MASK)
	            >= Configuration.SCREENLAYOUT_SIZE_LARGE;
	}
	
}

I hope this will help.Thanks!

Solution 11 - Android

Just encounter the same issue here, the code snippet below works for me:

private static final String[] CONTENT_ORIENTATION = new String[] {
        MediaStore.Images.ImageColumns.ORIENTATION
};

static int getExifOrientation(ContentResolver contentResolver, Uri uri) {
    Cursor cursor = null;

    try {
        cursor = contentResolver.query(uri, CONTENT_ORIENTATION, null, null, null);
        if (cursor == null || !cursor.moveToFirst()) {
            return 0;
        }
        return cursor.getInt(0);
    } catch (RuntimeException ignored) {
        // If the orientation column doesn't exist, assume no rotation.
        return 0;
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

hope this does help :)

Solution 12 - Android

Try this in surfaceChanged callback:

Camera.Parameters parameters=mCamera.getParameters();
if(this.getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
    parameters.setRotation(90);
}else{
    parameters.setRotation(0);
}
mCamera.setParameters(parameters);

Solution 13 - Android

//button click

btnCamera.setOnClickListener( new View.OnClickListener() {
        @Override
        public void onClick(View view) {

                try {
                    ContentValues values;
                    values = new ContentValues();
                    values.put(MediaStore.Images.Media.TITLE, "New Picture");
                    values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera");
                    imageUri = context.getContentResolver().insert(
                            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                    startActivityForResult(intent, CAMERA_REQUEST);
                }catch (Exception e){}

            });

//onActivityResult method

   if (requestCode==CAMERA_REQUEST){
        try {
            if (imageUri!=null) {
                path = String.valueOf(new File(FilePath.getPath(context, imageUri)));
                   }  
        }catch (Exception e){
            toast("please try again "+e.getMessage());
            Log.e("image error",e.getMessage());
        }
    }

//create a class filepath

public class FilePath {

public static String getPath(final Context context, final Uri uri) {

    // check here to KITKAT or new version
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/"
                        + split[1];
            }
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"),
                    Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] { split[1] };

            return getDataColumn(context, contentUri, selection,
                    selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context
 *            The context.
 * @param uri
 *            The Uri to query.
 * @param selection
 *            (Optional) Filter used in the query.
 * @param selectionArgs
 *            (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public static String getDataColumn(Context context, Uri uri,
                                   String selection, String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = { column };

    try {
        cursor = context.getContentResolver().query(uri, projection,
                selection, selectionArgs, null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri
            .getAuthority());
}

/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri
            .getAuthority());
}

/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri
            .getAuthority());
}

/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri
            .getAuthority());
}

}

Solution 14 - Android

The code is functionally for landscape and portrait @frontCameraID = variable got it the method classic for show camera wanted

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
    if(holder.getSurface() == null) {
        return;
    }
    try{
        camera.stopPreview();
    } catch (Exception e){
    }

    try{

        int orientation = getDisplayOrientation(frontCameraID);

        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }

        parameters.setRotation(rotationPicture);
        camera.setParameters(parameters);
        camera.setDisplayOrientation(orientation);
        camera.startPreview();

    } catch (Exception e) {
        Log.i("ERROR", "Camera error changed: " + e.getMessage());
    }
}

Method for get orientation y rotation to save picture and display orientation @result = orientation on the preview view of camera @rotationPicture = rotation necessary to save picture correctly

private int getDisplayOrientation(int cameraId) {

    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = ((Activity) context).getWindowManager().getDefaultDisplay().getRotation();
    int degrees = 0;
    switch (rotation) {
        case Surface.ROTATION_0: degrees = 0; break;
        case Surface.ROTATION_90: degrees = 90; break;
        case Surface.ROTATION_180: degrees = 180; break;
        case Surface.ROTATION_270: degrees = 270; break;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360;
        rotationPicture = (360 - result) % 360;
    } else {
        result = (info.orientation - degrees + 360) % 360;
        rotationPicture = result;
    }

    return result;
}

Someone question about code, please tell me.

Solution 15 - Android

two One line solutions using Picasso and glide library

After spending a lot of time with a lot of solutions for image rotation problem I finally found two simple solutions. We don't need to do any additional works. Picasso and Glide are a very powerful library for handling images in your app includes. It will read image EXIF data and auto-rotates the images.

Using glide library https://github.com/bumptech/glide

Glide.with(this).load("http url or sdcard url").into(imgageView);

Using Picasso library https://github.com/square/picasso

Picasso.with(context).load("http url or sdcard url").into(imageView);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNguyen Minh BinhView Question on Stackoverflow
Solution 1 - AndroidramzView Answer on Stackoverflow
Solution 2 - Androiduser901309View Answer on Stackoverflow
Solution 3 - AndroidTran Khanh TungView Answer on Stackoverflow
Solution 4 - Androidvineet palView Answer on Stackoverflow
Solution 5 - AndroidPakitoVView Answer on Stackoverflow
Solution 6 - Androidpatel135View Answer on Stackoverflow
Solution 7 - AndroidsherinView Answer on Stackoverflow
Solution 8 - AndroidS.PrapagornView Answer on Stackoverflow
Solution 9 - AndroidDear SView Answer on Stackoverflow
Solution 10 - AndroidJagdishView Answer on Stackoverflow
Solution 11 - AndroidCloud ChenView Answer on Stackoverflow
Solution 12 - AndroidManavendherView Answer on Stackoverflow
Solution 13 - AndroidPramila RawatView Answer on Stackoverflow
Solution 14 - AndroidAlex ZaraosView Answer on Stackoverflow
Solution 15 - AndroidVigneswaran AView Answer on Stackoverflow