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).
Related
I am trying to let users select a profile picture from gallery. My issue is that some pictures come as rotated to the right.
I start the image picker like so:
Intent photoPickerIntent = new Intent();
photoPickerIntent.setType("image/*");
photoPickerIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(photoPickerIntent, "Select profile picture"), Global.CODE_SELECT_PICTURE);
I get the image from onActivityResult like so:
Uri selectedPicture = data.getData();
profilePic = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), selectedPicture);
How can i make have images not to be rotated?
UPDATE:
Following some of the helpful answers i have received, i managed to come up with the following working solution (It's just a working code, not well written). I would love to get your feedback on how i can improve it!
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == Global.CODE_SELECT_PICTURE) {
// Get selected gallery image
Uri selectedPicture = data.getData();
// Get and resize profile image
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = activity.getContentResolver().query(selectedPicture, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath);
ExifInterface exif = null;
try {
File pictureFile = new File(picturePath);
exif = new ExifInterface(pictureFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
int orientation = ExifInterface.ORIENTATION_NORMAL;
if (exif != null)
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
loadedBitmap = rotateBitmap(loadedBitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
loadedBitmap = rotateBitmap(loadedBitmap, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
loadedBitmap = rotateBitmap(loadedBitmap, 270);
break;
}
}
}
public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
You could use ExifInterface to modify the orientation:
public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
ExifInterface ei = new ExifInterface(image_absolute_path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotate(bitmap, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotate(bitmap, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotate(bitmap, 270);
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
return flip(bitmap, true, false);
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
return flip(bitmap, false, true);
default:
return bitmap;
}
}
public static Bitmap rotate(Bitmap bitmap, float degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
Matrix matrix = new Matrix();
matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
In order to get absolute path of your images from their uri, check this answer
2 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.
Using Picasso library https://github.com/square/picasso
Picasso.with(context).load("http url or sdcard url").into(imageView);
Using glide library https://github.com/bumptech/glide
Glide.with(this).load("http url or sdcard url").into(imgageView);
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.
I use these static methods. The first determines the orientation and the second rotates the image shrinking it as needed.
public static int getOrientation(Context context, Uri photoUri) {
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor == null || cursor.getCount() != 1) {
return 90; //Assuming it was taken portrait
}
cursor.moveToFirst();
return cursor.getInt(0);
}
/**
* Rotates and shrinks as needed
*/
public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri, int maxWidth)
throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);
if (orientation == 90 || orientation == 270) {
Log.d("ImageUtil", "Will be rotated");
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
Log.d("ImageUtil", String.format("rotatedWidth=%s, rotatedHeight=%s, maxWidth=%s",
rotatedWidth, rotatedHeight, maxWidth));
if (rotatedWidth > maxWidth || rotatedHeight > maxWidth) {
float widthRatio = ((float) rotatedWidth) / ((float) maxWidth);
float heightRatio = ((float) rotatedHeight) / ((float) maxWidth);
float maxRatio = Math.max(widthRatio, heightRatio);
Log.d("ImageUtil", String.format("Shrinking. maxRatio=%s",
maxRatio));
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
Log.d("ImageUtil", String.format("No need for Shrinking. maxRatio=%s",
1));
srcBitmap = BitmapFactory.decodeStream(is);
Log.d("ImageUtil", String.format("Decoded bitmap successful"));
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
srcBitmap.getHeight(), matrix, true);
}
return srcBitmap;
}
I do it this way:
public void browseClick(View view) {
view.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.button_animation));
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
And the result where the orientation is checked will interest you most:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath);
Matrix matrix = new Matrix();
Bitmap scaledBitmap;
if (loadedBitmap.getWidth() >= loadedBitmap.getHeight()){
matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 400, 300), Matrix.ScaleToFit.CENTER);
scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true);
} else{
matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 300, 400), Matrix.ScaleToFit.CENTER);
scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true);
}
File file = new File(getExternalCacheDir(), "image.jpg");
try {
FileOutputStream out = new FileOutputStream(file);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
Log.e("Image", "Convert");
}
imageView.setImageBitmap(scaledBitmap);
}
}
Here is the ExifInterface approach written in Kotlin:
fun modifyOrientation(bitmap: Bitmap, image_absolute_path: String): Bitmap {
val ei = ExifInterface(image_absolute_path)
val orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
return when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(bitmap, 90f)
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(bitmap, 180f)
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(bitmap, 270f)
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> flipImage(bitmap, true, false)
ExifInterface.ORIENTATION_FLIP_VERTICAL -> flipImage(bitmap, false, true)
else -> bitmap
}
}
private fun rotateImage(bitmap: Bitmap, degrees: Float): Bitmap {
val matrix = Matrix()
matrix.postRotate(degrees)
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
private fun flipImage(bitmap: Bitmap, horizontal: Boolean, vertical: Boolean): Bitmap {
val matrix = Matrix()
matrix.preScale((if (horizontal) -1 else 1).toFloat(), (if (vertical) -1 else 1).toFloat())
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
Using Picasso:
Picasso
.get()
.load("Your image path")
.into(imageView);
Picasso.with(this) is now replaced with Picasso.get()
Picasso library: https://github.com/square/picasso
Add : implementation 'com.squareup.picasso:picasso:2.71828' in build.gradle file.
Picasso will take care of image auto-rotation.
I have tried to capture image with Back camera in some android devices, it works fine(Not rotated) with postRotate(90). when i trying to capture image with Samsung Galaxy S5 Front camera, it shows rotate/angled image
Here is my code:
private static final int PICK_FROM_CAMERA = 1;
private static final int PICK_FROM_FILE = 2;
private Uri mImageCaptureUri;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mImageCaptureUri = Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "Img"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK)
return;
Drawable drawable = null;
switch (requestCode) {
case PICK_FROM_CAMERA:
if (resultCode == Activity.RESULT_OK) {
if (mImageCaptureUri != null) {
drawable = getDrawableImage(this,
mImageCaptureUri.toString(), true);
}
}
break;
}
public static Drawable getDrawableImage(Context context, String path,
boolean isCamera) {
if (path == null || path.length() == 0)
return null;
else
try {
InputStream is = (InputStream) new URL(path).getContent();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap oBitmap = BitmapFactory.decodeStream(is, null, options);
int width_tmp = options.outWidth;
int height_tmp = options.outHeight;
WindowManager wm = ((WindowManager) context
.getSystemService(Context.WINDOW_SERVICE));
Display display = wm.getDefaultDisplay();
int heightRatio = (height_tmp / display.getHeight());
int widthRatio = (width_tmp / display.getWidth());
int s = 1;
if (heightRatio > 1 || widthRatio > 1) {
if (heightRatio > widthRatio) {
s = heightRatio;
} else {
s = widthRatio;
}
}
Drawable drawable;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = s;
Bitmap bitmap = BitmapFactory.decodeStream(
(InputStream) new URL(path).getContent(), null, o2);
if (isCamera) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int rotate = 0;
Matrix mat = new Matrix();
try {
ExifInterface exif = new ExifInterface(path);
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();
}
mat.postRotate(rotate);
/*if (w > h)
mat.postRotate(90);*/
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mat, true);
}
drawable = new BitmapDrawable(bitmap);
return drawable;
} catch (Exception e) {
return null;
}
}
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;
}
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
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;
}
}