Setdisplayorientation In Camera Make Wrong Orientation When Save Image
I'm making an OCR app in Android and already installed OCR engine, and now want to create Surfaceview of Camera and have an area box on top to select capture area. I meet the probl
Solution 1:
you can use this method.
protected Bitmap decodeFileUpgaded(Bitmap bitmap) {
int orientation;
try {
if (bitmap == null) {
returnnull;
}
ExifInterfaceexif=newExifInterface(camera_pathname);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Log.e("ExifInteface .........", "rotation =" + orientation);
// exif.setAttribute(ExifInterface.ORIENTATION_ROTATE_90, 90);
Log.e("orientation", "" + orientation);
if ((orientation == ExifInterface.ORIENTATION_ROTATE_180)) {
Log.i("orientation in", "" + orientation);
bitmap = rotateImage(bitmap, 180);
//RotateBitmap rotateBitmap = new RotateBitmap(bitmap);
} elseif (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
Log.i("orientation in", "" + orientation);
bitmap = rotateImage(bitmap, 90);
//RotateBitmap rotateBitmap = new RotateBitmap(bitmap);
} elseif (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
Log.i("orientation in", "" + orientation);
bitmap = rotateImage(bitmap, 270);
//RotateBitmap rotateBitmap = new RotateBitmap(bitmap);
}
return bitmap;
} catch (Exception e) {
e.printStackTrace();
//Toast.makeText(CropImage.this,"Memory low! please try again.",Toast.LENGTH_LONG).show();returnnull;
}
}
Solution 2:
Try this class it will handle all rotation and scaling task for you :-
package com.serveroverload.cube.controller;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;
publicclassCamerHandler {
privateCamerHandler() {
getAllImages();
}
privatestatic CamerHandler camerHandler;
publicstatic CamerHandler GetCamerHandlerInstance() {
if (null == camerHandler) {
camerHandler = newCamerHandler();
}
return camerHandler;
}
privatestaticfinalStringCAM_DIRECTORY="CamDirectory";
privatestaticfinalintMAX_HEIGHT=1024;
privatestaticfinalintMAX_WIDTH=1280;
private ArrayList<File> imageURL = newArrayList<File>();
public ArrayList<File> getImageURL() {
return imageURL;
}
publicvoidsetImageURL(ArrayList<File> imageURL) {
this.imageURL = imageURL;
}
publicvoidgetAllImages() {
imageURL.clear();
Filefolder=newFile(getImageDirectory());
File[] listOfFiles = folder.listFiles();
if (null != listOfFiles && listOfFiles.length != 0) {
for (inti=0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
imageURL.add(listOfFiles[i]);
System.out.println("File " + listOfFiles[i].getName());
} elseif (listOfFiles[i].isDirectory()) {
System.out.println("Directory " + listOfFiles[i].getName());
}
}
}
}
/**
* This method is responsible for solving the rotation issue if exist. Also
* scale the images to 1024x1024 resolution
*
* @param context
* The current context
* @param selectedImage
* The Image URI
* @return Bitmap image results
* @throws IOException
*/public Bitmap handleSamplingAndRotationBitmap(Context context,
Uri selectedImage)throws IOException {
// First decode with inJustDecodeBounds=true to check dimensionsfinal BitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStreamimageStream= context.getContentResolver().openInputStream(
selectedImage);
BitmapFactory.decodeStream(imageStream, null, options);
imageStream.close();
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH,
MAX_HEIGHT);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
imageStream = context.getContentResolver().openInputStream(
selectedImage);
Bitmapimg= BitmapFactory.decodeStream(imageStream, null, options);
// img = rotateImageIfRequired(img, selectedImage);
img = rotateBitmap(context, img, selectedImage);
return img;
}
public Bitmap rotateBitmap(Context context, Bitmap bitmap, Uri selectedImage) {
ExifInterface exif;
try {
exif = newExifInterface(selectedImage.getPath());
intorientation= exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Matrixmatrix=newMatrix();
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 {BitmapbmRotated= Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
} catch (IOException e) {
e.printStackTrace();
returnnull;
} catch (OutOfMemoryError e) {
e.printStackTrace();
returnnull;
}
}
/**
* Calculate an inSampleSize for use in a {@link BitmapFactory.Options}
* object when decoding bitmaps using the decode* methods from
* {@link BitmapFactory}. This implementation calculates the closest
* inSampleSize that will result in the final decoded bitmap having a width
* and height equal to or larger than the requested width and height. This
* implementation does not ensure a power of 2 is returned for inSampleSize
* which can be faster when decoding but results in a larger bitmap which
* isn't as useful for caching purposes.
*
* @param options
* An options object with out* params already populated (run
* through a decode* method with inJustDecodeBounds==true
* @param reqWidth
* The requested width of the resulting bitmap
* @param reqHeight
* The requested height of the resulting bitmap
* @return The value to be used for inSampleSize
*/privateintcalculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of imagefinalintheight= options.outHeight;
finalintwidth= options.outWidth;
intinSampleSize=1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and// widthfinalintheightRatio= Math.round((float) height
/ (float) reqHeight);
finalintwidthRatio= Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will// guarantee a final image// with both dimensions larger than or equal to the requested height// and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
// This offers some additional logic in case the image has a strange// aspect ratio. For example, a panorama may have a much larger// width than height. In these cases the total pixels might still// end up being too large to fit comfortably in memory, so we should// be more aggressive with sample down the image (=larger// inSampleSize).finalfloattotalPixels= width * height;
// Anything more than 2x the requested pixels we'll sample down// furtherfinalfloattotalReqPixelsCap= reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
publicvoidopenGallery(Context context) {
Intentintent=newIntent(Intent.ACTION_VIEW,
Uri.parse("content://media/internal/images/media"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
privatevoidconvertToBase64(Bitmap bitmap) {
ByteArrayOutputStreambyteArrayOutputStream=newByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 30, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
Stringencoded= Base64.encodeToString(byteArray, Base64.NO_WRAP);
// bitmap.recycle();
encoded = null;
byteArray = null;
}
public String getImageDirectory() {
return createDirIfNotExists().getAbsolutePath();
}
public File createDirIfNotExists() {
FileimageDirectory=newFile(
Environment.getExternalStorageDirectory(), CAM_DIRECTORY);
if (!imageDirectory.exists()) {
if (!imageDirectory.mkdirs()) {
Log.e("imageDirectory :: ", "Problem creating Image folder");
}
}
return imageDirectory;
}
}
This class take pics & handle rotation in background task
package com.serveroverload.cube.ui;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.camtest.R;
import com.serveroverload.cube.controller.CamerHandler;
publicclassHomeActivityextendsActivity {
staticfinalintREQUEST_IMAGE_CAPTURE=1;
private ImageView previewLayout;
privatestaticfinalStringTAG="MainActivity";
staticUricapturedImageUri=null;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// Imageview to display Image
previewLayout = (ImageView) findViewById(R.id.preview);
findViewById(R.id.take_picture).setOnClickListener(
newOnClickListener() {
@OverridepublicvoidonClick(View v) {
dispatchTakePictureIntent();
}
});
}
privatevoiddispatchTakePictureIntent() {
Intentintent=newIntent("android.media.action.IMAGE_CAPTURE");
if (intent.resolveActivity(getPackageManager()) != null) {
Calendarcal= Calendar.getInstance();
// store image in new File in image directoryFilefile=newFile(CamerHandler.GetCamerHandlerInstance()
.getImageDirectory(), (cal.getTimeInMillis() + ".png"));
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Failed to make file", 500).show();
}
} else {
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Failed to make file", 500).show();
}
}
capturedImageUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
}
@SuppressLint("NewApi")@OverridepublicvoidonActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE) {
// update file in gallery
sendBroadcast(newIntent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
capturedImageUri));
// Downsample image before displaying in imageview to avoi OOM// exceptionnewLoadBitMap(previewLayout, HomeActivity.this)
.execute(capturedImageUri);
} else {
Log.e(TAG, "FAILED TO TAKE IMAGE");
}
}
}
classLoadBitMapextendsAsyncTask<Uri, Void, Void> {
publicLoadBitMap(ImageView preview, Context context) {
this.prevImageView = preview;
this.mContext = context;
}
privateBitmapbitmap=null;
private ImageView prevImageView;
private Context mContext;
@Overrideprotected Void doInBackground(Uri... params) {
try {
bitmap = CamerHandler.GetCamerHandlerInstance()
.handleSamplingAndRotationBitmap(mContext, params[0]);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
returnnull;
}
@OverrideprotectedvoidonPostExecute(Void result) {
if (null != bitmap) {
prevImageView.setBackground(newBitmapDrawable(mContext
.getResources(), bitmap));
}
super.onPostExecute(result);
}
}
Test layout file
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:fillViewport="true"android:orientation="vertical"android:background="#000"tools:context="com.serveroverload.cube.ui.HomeActivity" ><ImageViewandroid:background="#fff"android:id="@+id/preview"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@+id/take_picture"android:layout_alignParentTop="true"android:layout_margin="5dp" /><ImageViewandroid:id="@+id/take_picture"android:layout_width="50dp"android:layout_height="50dp"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_gravity="center"android:layout_margin="10dp"android:padding="5dp"android:scaleType="fitXY"android:src="@drawable/take_pic" /></RelativeLayout>
Post a Comment for "Setdisplayorientation In Camera Make Wrong Orientation When Save Image"