Decoded Images Some Times are Rotated by 90degree - android

hey every one I am Trying to Load Large Images to BackGround of my App Using This Code :
final Drawable drawable =new BitmapDrawable(colorResource,decodeFile(new File(LMApplication.sharedpreferences.getString(path,""))));
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
if(LMApplication.CurrentSDK < android.os.Build.VERSION_CODES.JELLY_BEAN) {
view.setBackgroundDrawable(drawable);
}else{
view.setBackground(drawable);
}
}
});
public Bitmap decodeFile(File input){
Bitmap bmpCompressed = null;
try {
//Decode image size
BitmapFactory.Options o11 = new BitmapFactory.Options();
o11.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(input),null,o11);
//The new size we want to scale to
final int REQUIRED_SIZE=500;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o11.outWidth/scale/2>=REQUIRED_SIZE && o11.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o22 = new BitmapFactory.Options();
o22.inSampleSize=scale;
BitmapFactory.decodeStream(new FileInputStream(input), null, o22);
bmpCompressed = BitmapFactory.decodeFile(input.toString(), o22);
// FileOutputStream out = null;
try {
// out = new FileOutputStream(file);
// bmpCompressed.compress(CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
// out.close();
} catch(Throwable ignore) {}
}
} catch (FileNotFoundException e) {}
return bmpCompressed;
}
But Some Images are Rotated 90 degree to the left after the decoding, is there any Problem here or is there any way i can prevent this?
UPDATE :
Changed the Code like This and now prepared for every thing :
public Bitmap decodeFile(File input){
Bitmap bmpCompressed = null;
try {
//Decode image size
BitmapFactory.Options o11 = new BitmapFactory.Options();
o11.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(input),null,o11);
//The new size we want to scale to
// final int REQUIRED_SIZE=500;
int width = getDimensions.WIDTH;
int height = getDimensions.HEIGHT;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o11.outWidth/scale/2>=width && o11.outHeight/scale/2>=height)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o22 = new BitmapFactory.Options();
o22.inSampleSize=scale;
BitmapFactory.decodeStream(new FileInputStream(input), null, o22);
bmpCompressed = BitmapFactory.decodeFile(input.toString(), o22);
ExifInterface exif = new ExifInterface(input.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
if(orientation != ExifInterface.ORIENTATION_NORMAL){
int rotatesize;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotatesize = -90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotatesize = -180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotatesize = -270;
break;
default:
break;
}
Matrix matrix = new Matrix();
matrix.postRotate(90);
bmpCompressed = Bitmap.createBitmap(bmpCompressed, 0, 0, bmpCompressed.getWidth(), bmpCompressed.getHeight(), matrix, true);
}
// FileOutputStream out = null;
try {
// out = new FileOutputStream(file);
// bmpCompressed.compress(CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
// out.close();
} catch(Throwable ignore) {}
}
} catch (IOException e) {}
return bmpCompressed;
}

Use ExifInterface for rotate like this
picturePath = getIntent().getStringExtra("path");
Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
ExifInterface exif = new ExifInterface(picturePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
break;
default:
break;
}
myImageView.setImageBitmap(bitmap);
bitmap.recycle();
Note : Here picturePath is selected Image's path from Gallery

Related

Bitmap sometimes is null

I have a problem. See, please, my code.
if(savedInstanceState==null){
mImagePath = getIntent().getStringExtra("path");
new Thread(new Runnable() {
#Override
public void run() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable=true;
ExifInterface exif;
try {
exif = new ExifInterface(new File(mImagePath).getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
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;
}
Bitmap rotatedBitmap = BitmapFactory.decodeFile(mImagePath,options);
if(rotatedBitmap==null){
Answers.getInstance().logCustom(new CustomEvent("Null 1"));
// The first place where sometimes bitmap is null
}
assert rotatedBitmap != null;
int width = rotatedBitmap.getWidth();
int height = rotatedBitmap.getHeight();
if (Math.max(width,height)>MAX_LENGTH_OF_IMAGE){
// if widht or height >1500 px then i resize the image
float factor = MAX_LENGTH_OF_IMAGE/Math.max(width,height);
width=(int)(width*factor);
height=(int)(height*factor);
mOriginalBitmap = Bitmap.createScaledBitmap(rotatedBitmap,width,height,true);
rotatedBitmap.recycle();
} else
mOriginalBitmap=rotatedBitmap;
if(rotate!=0){
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
rotattedBitmap=Bitmap.createBitmap(mOriginalBitmap, 0, 0, width, height, matrix, true);
mOriginalBitmap.recycle();
mOriginalBitmap=rotattedBitmap;
}
if(mOriginalBitmap==null){
Answers.getInstance().logCustom(new CustomEvent("Null 187"));
//I didn't receive this message
}
} catch (IOException e) {
finish();
e.printStackTrace();
}
if(mOriginalBitmap==null){
Answers.getInstance().logCustom(new CustomEvent("Null 206"));
// The second place where bitmap sometimes is null
}
mCurrentBitmap=mOriginalBitmap.copy(Bitmap.Config.ARGB_8888,true);
handler.post(new Runnable() {
#Override
public void run() {
onCreated();
}
});
}
}).start();
}
Sometimes the bitmap is null (in two places). This error occurs in 6-7 users out of 1000.
I can always check if the bitmap is null and don't perform operations with this bitmap (bitmap.copy, bitmap.getwidth and others), but what should I do to always load a bitmap?

Camera preview in portrait mode

I am creating one app which uses camera. camera is perfectly working in both landscape and portrait. But the Result Image is perfectly set with in the frame at the landscape mode. but in portrait , the result image set in the frame at 90 degree orientaion.how to fix this problem?
public void createImageInImageCenter() {
Bitmap backgroundBitmap = DgCamActivity.photo;
backgroundBitmap = backgroundBitmap.createScaledBitmap(
backgroundBitmap, 900, 700, true);
Bitmap bitmapToDrawInTheCenter = null;
File f = new File(FrameGridView.selected_img);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
try {
bitmapToDrawInTheCenter = BitmapFactory.decodeStream(
new FileInputStream(f), null, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmapToDrawInTheCenter = bitmapToDrawInTheCenter.createScaledBitmap(
bitmapToDrawInTheCenter, 900, 700, true);
resultBitmap = Bitmap.createBitmap(backgroundBitmap.getWidth(),
backgroundBitmap.getHeight(), backgroundBitmap.getConfig());
Canvas canvas = new Canvas(resultBitmap);
canvas.drawBitmap(backgroundBitmap, new Matrix(), null);
canvas.drawBitmap(bitmapToDrawInTheCenter, 0, 0, new Paint());
ImageView image = (ImageView) findViewById(R.id.final_img);
image.setImageBitmap(resultBitmap);
}
Please try below code it's helpful to you for handle image rotation.
public class CaptureImage extends Activity {
private static final int PICK_CAMERA_IMAGE = 2;
ImageView img;
Button btn;
double d = 1.2;
private Uri mImageCaptureUri;
public static String userPicPath;
File file;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_capture_image);
img = (ImageView) findViewById(R.id.activity_capture_image_img);
btn = (Button) findViewById(R.id.button1);
btn.setText(String.valueOf(d));
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SimpleDateFormat dateFormatter = new SimpleDateFormat(
"yyyyMMdd_HHmmss", Locale.US);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
file = new File(Environment.getExternalStorageDirectory()
+ "/MyImage", "img_"
+ dateFormatter.format(new Date()).toString() + ".png");
userPicPath = file.getPath();
mImageCaptureUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
startActivityForResult(intent, PICK_CAMERA_IMAGE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_CAMERA_IMAGE && resultCode == RESULT_OK) {
Log.d("CaptureImage", mImageCaptureUri.toString());
Bitmap bitmapProfile = getBitmap(userPicPath, this);
img.setImageBitmap(rotatedBitmap(file, bitmapProfile));
}
}
public static Bitmap rotatedBitmap(File imageFile, Bitmap source) {
try {
int rotate = 0;
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;
}
Log.v("Capture Image", "Exif orientation: " + orientation + ":"
+ String.valueOf(rotate));
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, false);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Bitmap getBitmap(String path, Context context) {
Uri uri = Uri.fromFile(new File(path));
InputStream in = null;
ContentResolver mContentResolver = context.getContentResolver();
try {
// final int IMAGE_MAX_SIZE = 2048;
final int IMAGE_MAX_SIZE = 1024;
in = mContentResolver.openInputStream(uri);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(
2,
(int) Math.round(Math.log(IMAGE_MAX_SIZE
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5)));
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
in = mContentResolver.openInputStream(uri);
Bitmap b = BitmapFactory.decodeStream(in, null, o2);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 25, stream);
in.close();
return b;
} catch (FileNotFoundException e) {
Log.e("CaptureImage", "file " + path + " not found");
} catch (IOException e) {
Log.e("CaptureImage", "file " + path + " not found");
}
return null;
}
}
and layout file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Capture Image" />
<ImageView
android:id="#+id/activity_capture_image_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="#drawable/ic_launcher" />
I came across the same problem. Before Android API 13, the retrived image from the camera was the same that the preview one, but after API 13 they have inverted the Y axis from the preview. It is the "real" view from the point of the camera. Apply this function to your bitmap :
public Bitmap rotateBitmap(Bitmap source) {
orientation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
Matrix matrix = new Matrix();
if(android.os.Build.VERSION.SDK_INT > 13) {
float[] mirrorY = {-1, 0, 0, 0, 1, 0, 0, 0, 1};
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
matrix.postConcat(matrixMirrorY);
}
switch (orientation) {
case Surface.ROTATION_0:
if(android.os.Build.VERSION.SDK_INT > 13) {
matrix.postRotate(90);
} else {
matrix.postRotate(270);
}
break;
case Surface.ROTATION_90:
matrix.postRotate(0);
break;
case Surface.ROTATION_180:
if(android.os.Build.VERSION.SDK_INT > 13) {
matrix.postRotate(270);
} else {
matrix.postRotate(90);
}
break;
case Surface.ROTATION_270:
matrix.postRotate(180);
break;
}
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
This is for processing the image or saving it to the sdcard for example. But if the rotation problem occurs in your preview, use this rotation in your "surfaceChanged" method :
Camera.Parameters parameters = mCamera.getParameters();
orientation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
switch (orientation) {
case Surface.ROTATION_0:
mCamera.setDisplayOrientation(90);
break;
case Surface.ROTATION_90:
mCamera.setDisplayOrientation(0);
break;
case Surface.ROTATION_180:
mCamera.setDisplayOrientation(270);
break;
case Surface.ROTATION_270:
mCamera.setDisplayOrientation(180);
break;
}
Tested and working on Android 4.x (AOSP, Cyanogen, and FirePhone).

Android: Get Bitmap Orientation from Uri

After opening an image picker using:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "choose image", 1);
The recommended way to get a Bitmap from the selected Uri is using the following code:
InputStream input = cxt.getContentResolver().openInputStream(fileUri);
Bitmap bmp = BitmapFactory.decodeStream(input);
But this method does not automatically rotate an image taken in portrait mode with the camera.
How can I get the Bitmap orientation using just the Uri? (taking into account the Uri may be from Google Drive or other locations that may not translate into a real file on the disk)
I use this class:
The src is the string of the selected image and the bitmap is the bitmap extracted from the image.
public class ExifUtils {
public static Bitmap rotateBitmap(String src, Bitmap bitmap) {
try {
int orientation = getExifOrientation(src);
if (orientation == 1) {
return bitmap;
}
Matrix matrix = new Matrix();
switch (orientation) {
case 2:
matrix.setScale(-1, 1);
break;
case 3:
matrix.setRotate(180);
break;
case 4:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case 5:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case 6:
matrix.setRotate(90);
break;
case 7:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case 8:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return oriented;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
private static int getExifOrientation(String src) throws IOException {
int orientation = 1;
try {
/**
* if your are targeting only api level >= 5 ExifInterface exif =
* new ExifInterface(src); orientation =
* exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
*/
if (Build.VERSION.SDK_INT >= 5) {
Class<?> exifClass = Class
.forName("android.media.ExifInterface");
Constructor<?> exifConstructor = exifClass
.getConstructor(new Class[] { String.class });
Object exifInstance = exifConstructor
.newInstance(new Object[] { src });
Method getAttributeInt = exifClass.getMethod("getAttributeInt",
new Class[] { String.class, int.class });
java.lang.reflect.Field tagOrientationField = exifClass
.getField("TAG_ORIENTATION");
String tagOrientation = (String) tagOrientationField.get(null);
orientation = (Integer) getAttributeInt.invoke(exifInstance,
new Object[] { tagOrientation, 1 });
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return orientation;
}
}
In the part where you need to upload an image. This is how to use it:
ExifUtils.rotateBitmap(path, decodeSampledBitmap(file, 400, 400)));
The decodeSampledBitmap is :
public Bitmap decodeSampledBitmap(File res, int reqWidth, int reqHeight) {
if (res != null) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
FileInputStream stream2 = new FileInputStream(res);
BitmapFactory.decodeStream(stream2, null, options);
stream2.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Calculate inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
o2.inJustDecodeBounds = false;
FileInputStream stream = null;
try {
stream = new FileInputStream(res);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, o2);
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
} else
return null;
}
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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
There is alo a method to retrieve the bytes from bitmaps if you are uploading them. This method also compresses the bitmap size:
public byte[] getBytesFromBitmap(Bitmap bitmap) {
if (bitmap != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
return stream.toByteArray();
} else
return null;
}

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

Image rotate 90 degree using camera intent

Hello I am working on one android app where I need to capture the image using camera intent and set the bitmap in the imageview but here bitmap is rotated by 90 degree. I have checked many threads of stackoverflow like Photo rotate 90 degree while capture in some phones but did not work for me.
Here when I am executing this exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); then it is returning 0 ORIENTATION_UNDEFINED and in my getImage function no condition is satisfying.
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
capturedPhotoName = System.currentTimeMillis() + ".png";
File photo = new File(Environment.getExternalStorageDirectory(),
capturedPhotoName);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
startActivityForResult(cameraIntent, CAMERA_INTENT_REQUEST);
onActivityResult
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr,
selectedImage);
bitmap = Util.getImage(bitmap, selectedImage.toString());
mPictureImageView.setImageBitmap(bitmap);
} catch (Exception e) {
Log.e("New Issue Activity", e.toString());
}
/**
* Get the image orientation
*
* #param imagePath
* #return orietation angle
* #throws IOException
*/
public static Bitmap getImage(Bitmap bitmap, String path) throws IOException {
Matrix m = new Matrix();
ExifInterface exif = new ExifInterface(path);
int orientation = exif
.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
if ((orientation == ExifInterface.ORIENTATION_ROTATE_180)) {
m.postRotate(180);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
m.postRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
m.postRotate(270);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
}
return bitmap;
}
I implemented one photo take activity which you can take the photo and set the orientation of the photo. It is supported by every device I tested including Samsung galaxy series, tablets, sony xperia series, tablets.
You can check out my accepted answer about rotation of images on this topic:
Camera capture orientation on samsung devices in android
If you also need to save and use that image that you have rotated, saving and using the photo functions additional to my answer I gave above:
savePhoto function:
public void savePhoto(Bitmap bmp) {
imageFileFolder = new File(Environment.getExternalStorageDirectory(),
cc.getDirectoryName());
imageFileFolder.mkdir();
FileOutputStream out = null;
Calendar c = Calendar.getInstance();
String date = fromInt(c.get(Calendar.MONTH))
+ fromInt(c.get(Calendar.DAY_OF_MONTH))
+ fromInt(c.get(Calendar.YEAR))
+ fromInt(c.get(Calendar.HOUR_OF_DAY))
+ fromInt(c.get(Calendar.MINUTE))
+ fromInt(c.get(Calendar.SECOND));
imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
try {
out = new FileOutputStream(imageFileName);
bmp.compress(Bitmap.CompressFormat.JPEG, 70, out);
out.flush();
out.close();
scanPhoto(imageFileName.toString());
out = null;
} catch (Exception e) {
e.printStackTrace();
}
}
scanPhoto function:
public void scanPhoto(final String imageFileName) {
geniusPath = imageFileName;
msConn = new MediaScannerConnection(MyClass.this,
new MediaScannerConnectionClient() {
public void onMediaScannerConnected() {
msConn.scanFile(imageFileName, null);
}
#Override
public void onScanCompleted(String path, Uri uri) {
msConn.disconnect();
}
});
msConn.connect();
}
SavePhotoTask class:
class SavePhotoTask extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... jpeg) {
File photo = new File(Environment.getExternalStorageDirectory(),
"photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
} catch (java.io.IOException e) {
}
return (null);
}
}
Try below code:-
Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));
ExifInterface exif = new ExifInterface(imageFile.toString());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Bitmap bitmap = Utility.getOrientationFromExif(new Utility().compressImage1(imageFile.toString(),((Activity)context)),orientation);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG , 50 , bos);
Utility.java
public class Utility
{
public Bitmap compressImage1(String imageUri, Activity act)
{
String filePath = getRealPathFromURI(imageUri, act);
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not
// loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
// Bitmap bmp = decodeBitmap(Uri.parse(imageUri), 612, 816, act);
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
// setting inSampleSize value allows to load a scaled down version of
// the original image
options.inSampleSize = calculateInSampleSize(options, 612, 816);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low
// on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(filePath, options);
return bmp;
}
public static 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)
{
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
{
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap getOrientationFromExif(Bitmap bitmap, int orientation)
{
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int newWidth = 612;
int newHeight = 816;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
switch (orientation)
{
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
// matrix.setScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
// matrix.postScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
// matrix.postScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
// matrix.postScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try
{
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e)
{
e.printStackTrace();
return null;
}
}
}
This function worked for me, try your luck.
public static Bitmap rotateImage(Bitmap bmp, String imageUrl) {
if (bmp != null) {
ExifInterface ei;
int orientation = 0;
try {
ei = new ExifInterface(imageUrl);
orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
default:
break;
// etc.
}
Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0, bmpWidth,
bmpHeight, matrix, true);
return resizedBitmap;
} else {
return bmp;
}
}

Categories

Resources