Reputation: 24423
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.
Image preview after shot --------- Real image on SD card
Image preview after shot --------- Real image on SD card
Upvotes: 101
Views: 83765
Reputation: 6553
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;
}
Upvotes: -1
Reputation: 2499
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;
}
}
Upvotes: 0
Reputation: 525
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();
}
}
}
Upvotes: 0
Reputation: 309
There are two things needed:
Camera preview need the same as your rotation. Set this by camera.setDisplayOrientation(result);
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);
Upvotes: 22
Reputation:
I 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.
Upvotes: 28
Reputation: 996
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!
Upvotes: 54
Reputation: 1
//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());
}
}
Upvotes: 0
Reputation: 590
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);
Upvotes: -4
Reputation: 51
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
Upvotes: 1
Reputation: 631
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
Upvotes: 1
Reputation: 927
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;
}
Upvotes: 3
Reputation: 395
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);
Upvotes: 0
Reputation: 1091
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);
}
Upvotes: 1
Reputation: 131
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);
Upvotes: 10
Reputation: 2498
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);
Upvotes: 8