Image orientation get changed after selecting - android

I want to set background image for a view using Intent.ACTION_GET_CONTENT and handled onActivityResult method as...
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
try {
InputStream inputStream =
getContentResolver().openInputStream(selectedImageUri);
Drawable drawable = Drawable.createFromStream(inputStream,
selectedImageUri.toString());
mView.setBackground(drawable);
} catch(FileNotFoundException e) {}
}
}
It works fine for some images from gallary but not for all images. Image orientation get changed after selecting some image.

Try below code:-
try {
File f = new File(imagePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix mat = new Matrix();
mat.postRotate(angle);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f),
null, options);
bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), mat, true);
ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100,
outstudentstreamOutputStream);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
} catch (OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}

Related

Why Picture Rotate after taking Pic from android:hardware:camera api

I am using android:hardware:camera API to make custom camera . i have done to make the camera but problem is that after taking picture from camera the pic save in rotated form.I am using Surface View for the Camera .
this is Camera setting function on surface-created
try {
File f = new File(imagePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix mat = new Matrix();
mat.postRotate(angle);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f),
null, options);
bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), mat, true);
ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100,
outstudentstreamOutputStream);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
} catch (OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}
try this after capture image from camera to rotate.
You can use below method to show/save image in actual orientation.
public static Bitmap setImage(String filePath, Bitmap bitmap){
File curFile = new File(filePath);
Bitmap rotatedBitmap = null;
try {
ExifInterface exif = new ExifInterface(curFile.getPath());
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
Matrix matrix = new Matrix();
if (rotation != 0.0f) {matrix.preRotate(rotationInDegrees);}
rotatedBitmap = Bitmap.createBitmap(bitmap,0,0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}catch(IOException ex){
ex.printStackTrace();
}
return rotatedBitmap;
}
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; }
return 0;
}

How to see what the orientation is for an image selected from image gallery [duplicate]

In my app, I let the user the chance to get a photo and set it as profile pic. There are 2 ways for getting the photo, from the gallery, and directly taken with the camera.
I have wrote code that works with booth methods, and I have tested on a Galaxy S5 with lollipop 5.0. When testing it with a KitKat 4.4.4, it is throwing a NPE. But is throwing this NPE just when taking the photo directly from the camera.
In booth cases, this is the structure I follow:
Get the Uri from the onActivityResult call data.
Get pic orientation value (in some cases the portrait image appears rotated in the imageview).
Decode the bitmap to downsize it mantaining the aspect ratio.
Rotate the image if it has the wrong orientation.
Save the bitmap in the internal app data.
An this is the code for the "take photo from camera" request:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PHOTO_REQUEST_FRAG:
if (resultCode == getActivity().RESULT_OK && data != null) {
Uri selectedImageUri = data.getData();
Bitmap srcBmp = null;
/*Get image orientation*/
int orientation = getImageOrientation(getActivity(), selectedImageUri);
Log.d("IMAGE_ORIENTATION", String.valueOf(orientation));
/*Downsize bitmap mantaining aspect ratio*/
srcBmp = decodeSampledBitmapFromUri(
selectedImageUri,
pic_view.getWidth(), pic_view.getHeight());
/*Rotate image if needed*/
if (orientation == 90) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
srcBmp = Bitmap.createBitmap(srcBmp, 0, 0,
srcBmp.getWidth(), srcBmp.getHeight(), matrix,
true);
}
else if (orientation == 180) {
Matrix matrix = new Matrix();
matrix.postRotate(180);
srcBmp = Bitmap.createBitmap(srcBmp, 0, 0,
srcBmp.getWidth(), srcBmp.getHeight(), matrix,
true);
}
else if (orientation == 270) {
Matrix matrix = new Matrix();
matrix.postRotate(270);
srcBmp = Bitmap.createBitmap(srcBmp, 0, 0,
srcBmp.getWidth(), srcBmp.getHeight(), matrix,
true);
}
/*Save bitmap in internal memory*/
ContextWrapper cw1 = new ContextWrapper(getActivity().getApplicationContext());
File directory1 = cw1.getDir("profile", Context.MODE_PRIVATE);
if (!directory1.exists()) {
directory1.mkdir();
}
File filepath1 = new File(directory1, "profile_pic.png");
FileOutputStream fos1 = null;
try {
fos1 = new FileOutputStream(filepath1);
srcBmp.compress(Bitmap.CompressFormat.JPEG, 90, fos1);
fos1.close();
} catch (Exception e) {
Log.e("SAVE_FULL_IMAGE", e.getMessage(), e);
}
/*Show image in imageview*/
pic_view.setImageBitmap(srcBmp);
}
break;
}
}
-
/*Downsize the bitmap from uri*/
public Bitmap decodeSampledBitmapFromUri(Uri uri, int reqWidth, int reqHeight) {
Bitmap bm = null;
try{
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(uri), null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(uri), null, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
return bm;
}
public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
-
/*Get image orientation first from Exif info*/
public int getImageOrientation(Context context, Uri photoUri) {
int orientation = getOrientationFromExif(photoUri);
if(orientation <= 0) {
orientation = getOrientationFromMediaStore(context, photoUri);
}
return orientation;
}
private int getOrientationFromExif(Uri photoUri) {
int orientation = -1;
try {
ExifInterface exif = new ExifInterface(photoUri.getPath());
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
orientation = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
orientation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
orientation = 90;
break;
case ExifInterface.ORIENTATION_NORMAL:
orientation = 0;
break;
default:
break;
}
} catch (IOException e) {
Log.e("EXIF_ORIENTATION", "Unable to get image exif orientation", e);
}
return orientation;
}
/* normal landscape: 0
* normal portrait: 90
* upside-down landscape: 180
* upside-down portrait: 270
* image not found: -1
*/
private static int getOrientationFromMediaStore(Context context, Uri photoUri) {
String[] projection = {MediaStore.Images.ImageColumns.ORIENTATION};
Cursor cursor = context.getContentResolver().query(photoUri, projection, null, null, null);
try {
if (cursor.moveToFirst()) {
return cursor.getInt(0);
} else {
return -1;
}
} finally {
cursor.close();
}
}
It is throwing the NPE in the line where I want to get the image orientation from the exif data, exactly where I get the Path from the uri:
ExifInterface exif = new ExifInterface(photoUri.getPath());
So I know that it must be something with the path. I have readed several posts about that kitkat returns the path in a diferent format. I have tried diferent custom getPath() methods, but always throws NPE when calling the Cursor.
So I know that it must be something with the path.
That's because it's not a filesystem path. A Uri is not a file, and while you are handling that properly elsewhere, you are not doing so here.
You need to switch to EXIF logic that can handle an InputStream, such as this code culled from the AOSP Mms app.

how to set camera Image orientation?

In my application I have added feature of image uploading,It works fine with all the Images except camera image,whenever I browse camera image from gallery and portrait image rotate in 90 degree..following is my snippet code..can anyone help me?I followed so many tutorials but all of them work well in kikat..but when same tutorial does not work with ics,jellybean etc..
public class MainActivity extends Activity {
private Button browse;
private String selectedImagePath="";
private ImageView img;
private TextView messageText;
private static int SELECT_PICTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = (ImageView)findViewById(R.id.imagevw);
browse=(Button)findViewById(R.id.browseimg);
messageText = (TextView)findViewById(R.id.messageText);
browse.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
/*String filePath = getRealPathFromURI(getActivity(), selectedImageUri );
messageText.setText(filePath );
Picasso.with(getActivity())
.load(new File(filePath ))
.centerCrop()
.resize(60, 60).into( img);*/
selectedImagePath = getPath(selectedImageUri);
messageText.setText(selectedImagePath);
System.out.println(requestCode);
System.out.println("Image Path : " + selectedImagePath);
img.setImageURI(selectedImageUri);
}
}
}
#SuppressWarnings("deprecation")
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
just include this code
public void rotateImage(String file) throws IOException{
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
int rotationAngle = getCameraPhotoOrientation(getActivity(), Uri.fromFile(file1), file1.toString());
Matrix matrix = new Matrix();
matrix.postRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
FileOutputStream fos=new FileOutputStream(file);
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
}
public static int getCameraPhotoOrientation(Context context, Uri imageUri, String imagePath){
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
rotate = 0;
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();
}
return rotate;
}
There are several methods, but the simplest I found is by using Picasso library. As this is an uploading case, we will get the orientation correct and also can make adjustment in image bitmap size.
String filePath = getRealPathFromURI(getActivity(), selectedImageUri );
messageText.setText(filePath );
Picasso.with(getActivity())
.load(new File(filePath ))
.centerCrop()
.resize(60, 60).into( img);
I solved the image rotation problem with following code
public Bitmap rotateImageIfRequired(String imagePath) {
int degrees = 0;
try {
ExifInterface exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degrees = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degrees = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degrees = 270;
break;
}
} catch (IOException e) {
Log.e("ImageError", "Error in reading Exif data of " + imagePath, e);
}
BitmapFactory.Options decodeBounds = new BitmapFactory.Options();
decodeBounds.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, decodeBounds);
int numPixels = decodeBounds.outWidth * decodeBounds.outHeight;
int maxPixels = 2048 * 1536; // requires 12 MB heap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (numPixels > maxPixels) ? 2 : 1;
bitmap = BitmapFactory.decodeFile(imagePath, options);
if (bitmap == null) {
return null;
}
Matrix matrix = new Matrix();
matrix.setRotate(degrees);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
return bitmap;
}

Android camera image randomly rotated

I've found a very interesting problem. After taking a camera picture (I hold the device in portrait mode, and not rotating), the given photo is sometimes rotated, but not always. I know, some device give always rotated photo, but it can be rotated with exif or mediastore information. But in this case, exif and mediastore says orientation is 0, but the image is rotated. The most frustrating thing this comes totally randomly. The code is very simple:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, currentFileUri);
startActivityForResult(intent, RequestCodeCollection.CAMERA_IMAGE_CAPTURE);
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
oldImageExifInterface = new ExifInterface(currentFileUri.getPath());
}
}
Have anybody seen this problem? I experienced on Galaxy Nexus after OS update (4.1.1)
Try this.
try {
File f = new File(imagePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix mat = new Matrix();
mat.postRotate(angle);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f),
null, options);
bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), mat, true);
ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100,
outstudentstreamOutputStream);
imageView.setImageBitmap(correctBmp);
} catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
} catch (OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}

Photo rotate 90 degree while capture in some phones

Photo is rotating 90 degree while capturing from camera in samsung mobile rest of other mobiles its working fine. Please help me for this.
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, IMAGE_CAPTURE);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try
{
if (requestCode == IMAGE_CAPTURE) {
if (resultCode == RESULT_OK){
Uri contentUri = data.getData();
if(contentUri!=null)
{
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
imageUri = Uri.parse(cursor.getString(column_index));
}
tempBitmap = (Bitmap) data.getExtras().get("data");
mainImageView.setImageBitmap(tempBitmap);
isCaptureFromCamera = true;
}
}
This happens to be a bug in earlier versions of Android.
I solved this issue just getting the orientation angle and rotate the bitmap accordingly.
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;
}
}
Also query the MediaStore.Images.Media.ORIENTATION value to get the rotation angle. Then you can rotate the image by yourself or whatever.
What I am doing :
first check the orientation of image taken by camera using its meta data information , and If we found this in portrait then we have to rotate the image by 90 and display otherwise only display.
For getting the Information about orientation of image we can use ExifInterface.
That's It!

Categories

Resources