Issues facing on Samsung, when I am capturing the image, the captured image get rotated. I am trying to rotate the image in the vertical direction 90 degree. On Back Facing the image get rotated with below code. But two images get stored on the device. Also issues facing while I am capturing the image on front face the image get rotated, how I can handle the image rotation in below code for both the front and back facing. Any ideas ?
try {
upload_bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
large_bitmap = scaleDownLargeImageWithAspectRatio(upload_bitmap);
String fileNameLarge = "myapp_" + System.currentTimeMillis() + ".jpg";
large_bitmap_path = MediaStore.Images.Media.insertImage(getContentResolver(), large_bitmap, fileNameLarge, null);
//Start change orientation
String device_name = Build.MANUFACTURER;
if(device_name.equals("samsung"))
{
int rotate=0;
try {
String realPath = getRealPathFromUri(CameraActivity.this, Uri.parse(large_bitmap_path));
exif = new ExifInterface(realPath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
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;
case ExifInterface.ORIENTATION_NORMAL:
case ExifInterface.ORIENTATION_UNDEFINED:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(90);
large_bitmap = Bitmap.createBitmap(large_bitmap, 0, 0, large_bitmap.getWidth(), large_bitmap.getHeight(), matrix, true);
horizontalList.add(large_bitmap_path);
horizontal_rv.smoothScrollBy(1000, 10);
sqLiteHelper.insertPath(large_bitmap_path, "jpg", "fileName");
}
use this library from git hub it handles all these thing related to image library link
Related
I have tried most of the code on stackoverflow but none of them are working.
I am using moto x4 for uploading picture using camera. when I use back camera it gets rotated 90 degree left and when I use front camera it gets rotated 90 degree right. but in debug mode, in both case I found the orientation = 0;
else if (requestCode == CAMERA) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
String imagePath = saveImage(thumbnail);
File imageFile = new File(imagePath);
ExifInterface exif = null;
try {
exif = new ExifInterface(imageFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
bmap = GetandSetBitmap.rotateBitmap(thumbnail,orientation);
mImageView.setBackgroundResource(0);
mImageView.setImageBitmap(bmap);
}
This probably has to do with the fact that one camera is by default in landscape and the other in reverse landscape, so orientation = 0, as the orientation is detected to be the normal one in both cases. Unfortunately, I don't have a solution that wouldn't involve manually rotating the image to cover all cases. Personally I've used a switch to cater for the cases where my photo was saved with a 90 degrees rotation:
ExifInterface exifInterface = new ExifInterface(pictureFile.getPath());
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Bitmap correctedBitmap;
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
correctedBitmap = bitmap;
capturedImageHolder.setImageBitmap(correctedBitmap);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
correctedBitmap = rotateImage(bitmap, 90);
capturedImageHolder.setImageBitmap(correctedBitmap);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
correctedBitmap = rotateImage(bitmap, 180);
capturedImageHolder.setImageBitmap(correctedBitmap);
break;
case ExifInterface.ORIENTATION_NORMAL:
default:
correctedBitmap = rotateImage(bitmap, 270);
capturedImageHolder.setImageBitmap(correctedBitmap);
break;
}
} catch (IOException e) {
}
public static Bitmap rotateImage(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
}
In your case, you would need to detect if the photo is taken from the front-facing camera or the back and adjust the values accordingly.
Hi currently I'm trying to display an image that is rotated by about 5 degrees on an imageview after I capture it and rotate the image into proper orientation (camera issues). Now the problem is after setting the image on an imageview which is rotated 5 degrees sing imageview.setRotation(5) the imageview itself becomes aliased. I'm pretty sure that the imageview is the one being aliased since my image has a padding of 5dp to have a white border on the sides but please do correct me if I'm wrong.
What solution I tried so far is this but the sample solution works for already set image on a custom view and I'm not that used to in configuring or further customizing a custom views to work based on what I need. though his problem is almost the same as mine.
I also tried this one which apply antialiasing on the fly but didn't work as well.
So far here is my code:
imageview = (ImageView) findViewById(R.id.img_preview);
imageview.setRotation(5);
Bundle extras = getIntent().getExtras();
if (extras != null) {
String img_path = extras.getString("img_path");
File image_file = new File(img_path);
try {
Bitmap captured_image = applyOrientation(BitmapFactory.decodeFile(img_path),resolveBitmapOrientation(image_file));
imageview.setImageBitmap(captured_image);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And this is the code on where I rotate my image maybe someone can help fix it from here too so here it is:
private int resolveBitmapOrientation(File bitmapFile) throws IOException {
ExifInterface exif = null;
exif = new ExifInterface(bitmapFile.getAbsolutePath());
return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}
private Bitmap applyOrientation(Bitmap bitmap, int orientation) {
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;
default:
return bitmap;
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
I am making an android app that sends pictures the user explicitly took and send it to a web server. Next, i display those pictures in a web application.
However, the pictures taken from the smartphone in portrait appear in the server rotated as if they were taken in landscape mode and vice versa.
Any idea why this is happening?
There is a property of the image, "exif tag". Which tells about the orientation of the image. You can check the value of this tag before sending the image to server.
you can use below method to get the unrotated image
public final static Bitmap getUnRotatedImage(String imahePath, Bitmap rotattedBitmap)
{
int rotate = 0;
try
{
File imageFile = new File(imahePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation)
{
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
return Bitmap.createBitmap(rotattedBitmap, 0, 0, rotattedBitmap.getWidth(), rotattedBitmap.getHeight(), matrix,
true);
}
It takes two arguments, image path and the bitmap image.
Try this method before sending the images to the server.
I have gone through some of the links to get the correct image orientation of the image selected from the default image gallery to be worked standard in all devices the exif tag always returns 0.
EXIF orientation tag value always 0 for image taken with portrait camera app android
Exif orientation tag returns 0
Exif data TAG_ORIENTATION always 0
http://mobisocial.stanford.edu/news/2011/08/rotating-images-in-android/
How to get an exact solution that will work on all devices?
If the image(photo) was taken by a program made by you, you must set Parameters.setRotation with the correct rotation value.
This, depending of camera drive, rotates the image before save or save the rotation value to exif TAG_ORIENTATION.
Therefore, if TAG_ORIENTATION is null or zero, the image are in the correct orientation, otherwise you must rotate image according the value in TAG_ORIENTATION.
CODE
Get orientation from EXIF:
ExifInterface exif = null;
try {
exif = new ExifInterface(path);
} catch (IOException e) {
e.printStackTrace();
}
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Get bitmap rotated:
Bitmap bmRotated = rotateBitmap(bitmap, orientation);
Method to rotate bitmap:
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
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;
}
}
For me ExifInterface worked quite well like this:
ExifInterface exifInterface = new ExifInterface(imagePath);
degree = Integer.parseInt(exifInterface.getAttribute(ExifInterface.TAG_ORIENTATION));
or you can try to get the details of image using MediaStore like this:
String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = managedQuery(imageUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
Similar Solution: ExifInterface always returns 1
Hope it helps.. :)
I followed last answer and I tried hard to create a system to manage pictures, rotate, resize, cache and load into ImageViews and I can tell it is a hell. Even when all it was done it crashes sometimes cause OutOfMemory in some devices. Answer is correct but it is difficult to manage Bitmaps in Android.
My point is do not reinvent the wheel, it has a perfect design. Google itself encourage you to use Glide. It works in one line, super easy to use, lightweight in size and functions number, it manage EXIF by default, and it use memory like a charm.. It is simply black magic coded ;)
I'm not sure if Picasso also manages EXIF, but there is a quick intro to both of them:
https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
My Advice: do not waste your time and use them. You can solve your problem in one line:
Glide.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
For those who come along this post, make sure to use the exifinterface from the Android Support Library that was introduced in December 2016:
compile "com.android.support:exifinterface:25.1.0" // or newer
Details about this library can be found in the according Android Developers Blog post: Introducing the ExifInterface Support Library
They also included a sample code for dealing with rotation information stored in the exif interface:
int rotation = 0;
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotation = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotation = 270;
break;
}
The solution for me was to create the ExifInterface from the input stream. Do not try to create it from a path, which maybe a content provider path and will fail to give the correct result. Convert the orientation into degrees and rotate image if required. Below is the key code for the solution when using the support library (e.g androidx.exifinterface.media.ExifInterface).
int orientation = 0;
InputStream input = mContext.getContentResolver().openInputStream(uri);
if (input != null){
ExifInterface exif = new ExifInterface(input);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
input.close();
}
Here is my full code to obtain a correctly orientated bitmap selected from the Gallery, which also takes a maxsize. If using it make sure you check for the null return case.
public Bitmap getBitmapFromGalleryUri(Context mContext, Uri uri, Double maxSize)throws IOException {
int orientation = 0;
InputStream input = mContext.getContentResolver().openInputStream(uri);
if (input != null){
ExifInterface exif = new ExifInterface(input);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
//Log.d("Utils", "rotation value = " + orientation);
input.close();
}
input = mContext.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither = true;//optional
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
try {
input.close();
} catch (NullPointerException e) {
e.printStackTrace();
}
if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) {
return null;
}
int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;
double ratio = (originalSize > maxSize) ? (originalSize / maxSize) : 1.0;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
bitmapOptions.inDither = true; //optional
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//
input = mContext.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
try {
input.close();
} catch (NullPointerException e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
//Log.d("Utils", "rotation value = " + orientation);
int rotationInDegrees = exifToDegrees(orientation);
//Log.d("Utils", "rotationInDegrees value = " + rotationInDegrees);
if (orientation != 0) {
matrix.preRotate(rotationInDegrees);
}
int bmpWidth = 0;
try {
bmpWidth = bitmap.getWidth();
} catch (NullPointerException e) {
e.printStackTrace();
}
Bitmap adjustedBitmap = bitmap;
if (bmpWidth > 0) {
adjustedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
return adjustedBitmap;
}
private static int getPowerOfTwoForSampleRatio(double ratio){
int k = Integer.highestOneBit((int)Math.floor(ratio));
if(k==0) return 1;
else return k;
}
public 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;
}
I am using commonware's camera sample to try and create an android app that takes a picture. The preview shows the camera rotated 90 degrees and I've corrected that by applying:
camera.setDisplayOrientation(90);
However, the images are still saved rotated 90 degrees the other way. How can I adjust this so that when the images are saved, they're saved in the same "aspect" as that of the viewer?
Please advise,
TIA
According to this post , this happens only in some devices and it depends on the manufacturer.
I managed to workaround this issue by detecting the orientation angle of the device and apply the rotation accordingly, like this:
ExifInterface exitInterface = new ExifInterface(imagePath);
int orientation = exitInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
int degree = 0;
switch (orientation){
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
Then I rotate my bitmap using a custom method:
public static Bitmap rotateImage(Bitmap src, float degree)
{
// create new matrix
Matrix matrix = new Matrix();
// setup rotation degree
matrix.postRotate(degree);
Bitmap bmp = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
return bmp;
}