Detect which orientation a bitmap taken from the camera should be - android

I have an app that the client has asked to add rotation support.
Below is the current code that takes the image from the camera.
camera.takePicture(null, null, new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
Matrix mtx = new Matrix();
mtx.postRotate(180);
float density = Resources.getSystem().getDisplayMetrics().density;
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
Bitmap scaled = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mtx, true);
bm = Bitmap.createScaledBitmap(scaled, (int)(480*density), (int)(320*density), true); //height and width are backwards because its portrait
previewImage(bm);
}
}
});
What I am trying to work out is the quickest way to work out what orientation the captured bitmap should be in, i.e when the user takes a picture with the device in landscape we need to flip:
Bitmap.createScaledBitmap(scaled, (int)(480*density), (int)(320*density), true);
to:
Bitmap.createScaledBitmap(scaled, (int)(320*density), (int)(480*density), true);
and also change the mtx.postRotate
My issue is working out the best way to find out what rotation the image was taken in.

Try this
private Bitmap checkForRotation(String filename, Bitmap bitmap) {
Bitmap myBitmap = bitmap;
ExifInterface ei = null;
try {
ei = new ExifInterface(filename);
new ExifInterface(filename);
} catch (IOException e) {
e.printStackTrace();
}
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
//Here you get the orientation and do what ever you want to do with it as i am rotating the image
case ExifInterface.ORIENTATION_ROTATE_90:
myBitmap = rotateImage(bitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
myBitmap = rotateImage(bitmap, 180);
break;
}
return myBitmap;
}

Related

how to set captured image using android in sumsung device is portrait mode

I'm trying below code to set captured image using android in sumsung device is portrait mode, but its set to landscape mode. Below code works fine for other devices excepts for samsung and sony.
Matrix mat = new Matrix();
ExifInterface exif = new ExifInterface(yourimagepath);
String orientstring = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientstring != null ? Integer.parseInt(orientstring) : ExifInterface.ORIENTATION_NORMAL;
int rotateangle = 0;
if(orientation == ExifInterface.ORIENTATION_ROTATE_90)
rotateangle = 90;
if(orientation == ExifInterface.ORIENTATION_ROTATE_180)
rotateangle = 180;
if(orientation == ExifInterface.ORIENTATION_ROTATE_270)
rotateangle = 270;
mat.setRotate(rotateangle, (float) bmpPic.getWidth() / 2, (float) bmpPic.getHeight() / 2);
File f = new File(yourimagepath);
Bitmap bmpPic = BitmapFactory.decodeStream(new FileInputStream(f), null, null);
Bitmap bmpPic1 = Bitmap.createBitmap(bmpPic, 0, 0, bmpPic.getWidth(), bmpPic.getHeight(), mat, true);
Is there is any other solution for same? Please suggest.
use this in your manifest file in activity tag..
android:screenOrientation="portrait"
It can set portrait mode for all devices.
Use ExifInterface to check the orientation of the image as stored in the device.
int rotate = 0;
try {
File imageFile = new File(uploadFile.getPath());
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 (IOException e) {
e.printStackTrace();
}
Then using matrix rotate the bitmap to the actual portrait or landscape as stored in device.
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inDither = true;
Bitmap bmp = BitmapFactory.decodeFile(uploadFile.getPath(), options);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bmp, bmp.getWidth(), bmp.getHeight(), true);
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
rotatedBitmap is the bitmap with correct orientation.
Hope it helps.
Try this code. I was used it on different phones include samsung and it works perfectly:
public Bitmap rotateImage(Bitmap bitmap) throws IOException {
//Rotate the image to get in correct position
ExifInterface exif = new ExifInterface(mImagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 8) {
matrix.postRotate(270);
} else if (orientation == 3) {
matrix.postRotate(180);
}
Bitmap rotatedImage = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return rotatedImage;
}
Hope it helps!

Save rotated Bitmap

itI take a picture from the camera and I simply want to save it with the correct orientation.
I know their is quite a few post about that subject but even after reading all the answers I got stuck to save my rotated Bitmap.
So here si my code:
Bitmap bitmap = BitmapFactory.decodeFile(pictureFile
.getAbsolutePath());
Matrix matrix = new Matrix();
matrix.postRotate(finalOrientation);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
findViewById(R.id.image_preview).setVisibility(View.VISIBLE);
((ImageView) findViewById(R.id.image_preview)).setImageBitmap(rotatedBitmap);
findViewById(R.id.surfaceView).setVisibility(View.GONE);
if(outputStream != null)
{
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
As you can see I show up my Bitmap image in an image view to be sure it's in the correct orientation and it is. But it's only when I save (compress) it that it returns to her original state.
Thank you in advance!
This is not an answer, but I want to post some code that might shed light on what is going on, and it does not fit into a comment:
ExifInterface exif;
int rotate = 0;
try {
exif = new ExifInterface (file.getAbsolutePath());
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90: rotate = 1 /*90*/; break;
case ExifInterface.ORIENTATION_ROTATE_180: rotate = 2 /*180*/; break;
case ExifInterface.ORIENTATION_ROTATE_270: rotate = 3 /*270*/; break;
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.d(TAG,"~~~~~~ exifOrientation: rotate="+rotate);

How to strip EXIF data from Android Camera image

I need to upload photo from camera to server in my app. It works great on most of the devices. But a few devices are causing image to rotate by 90' which is not my desired behavior. After research, I came to know that its due to EXIF data attached with image. To strip EXIF data from the image bitmap, I tried various things like re-sizing image etc but none of them worked for me. Anybody please suggest a way to perform this task.
Try this,
public static Bitmap getImage(Context context, Uri uri)
throws FileNotFoundException, IOException {
InputStream input = context.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);
input.close();
if ((onlyBoundsOptions.outWidth == -1)
|| (onlyBoundsOptions.outHeight == -1))
return null;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inDither = true;
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// optional
input = context.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
ExifInterface ei = new ExifInterface(uri.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
bitmap = rotateImage(bitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
bitmap = rotateImage(bitmap, 180);
break;
}
return bitmap;
}
here uri is the uri of image taken from camera.
For understanding exif orienatation: goto http://www.impulseadventure.com/photo/exif-orientation.html
Here we use the ExifInterface object to read tags in a JPEG file and fetch the orientation attribute of image e.g.
// Variable to store the corrected bitmap.
Bitmap correctedBitMap = null;
ExifInterface exifInterface = new ExifInterface(<PATH OF YOUR PHOTO>);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Now the integer variable orientation has the info about how much is the image rotated by, which is then checked against ExifInterface constant value & respectively the changes are made.
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
correctedBitMap = rotateImage(<YOUR BITMAP OBJECT>, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
correctedBitMap = rotateImage(<YOUR BITMAP OBJECT>, 180);
break;
}
Here is the code for rotateImage method:
private Bitmap rotateImage(Bitmap source, float angle) {
Bitmap bitmap = null;
Matrix matrix = new Matrix();
matrix.postRotate(angle);
try {
bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
return bitmap;
}

Image oriention issue capture from camera

I was facing a problem image capture from camera it was showing image in landscape even though i capture that image in portrait then i found code online. But i think there is some problem with this code it sometimes didn't work (show image in landscape). So what's wrong there
private void adjustImageOrientation()
{
ExifInterface exif;
int rotate = 0;
try
{
exif = new ExifInterface(filepath);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0)
{
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
try
{
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
catch(OutOfMemoryError e)
{
e.printStackTrace();
//image = Bitmap.createBitmap(image, 0, 0, w/2, h/2, mtx, false);
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
// return image.copy(Bitmap.Config.ARGB_8888, true);
}

Rotating of large image causes OutOfMemoryError

I'm trying to rotate the image taken from camera and save it without scaling down without showing in an view, but when I try to load it like this
Bitmap bmp = BitmapFactory.decodeFile(tmpImageFilePath);
I get OutOfMemoryError. There is no problem for me to rotate image but how to load it and save with original size? I've already googled some techniques in order to solve this problem but none of them fits me.
And when I try this variant:
File f = new File(tmpImageFilePath);
long filesize = f.length();
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 = 8;
Bitmap bmp = BitmapFactory.decodeFile(tmpImageFilePath, options);
Bitmap correctBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
bmp.recycle();
try {
FileOutputStream out = new FileOutputStream(f);
correctBmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
I get lesser image.

Categories

Resources