How To Rotate And Flip Bitmap In Onpicturetaken
Solution 1:
I have put a lot of work into this and thought, I'd share my solution. It is tested on a Motorola Devy, Samsung Xcover 1 and Samsung XCover 2.
As I work with a custom camera preview, the solution basically has two parts. 1. Take care of the camera preview and set rotation of the preview according to device rotation. 2. Once a picture is taken, that is the 'onPictureTaken' callback is invoked rotate the picture by the correct angle, such that it shows what the preview just showed.
1
privatevoidinitPreview(int width, int height) {
if (camera != null && holder.getSurface() != null) {
try {
camera.setPreviewDisplay(holder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(getContext(), t.getMessage(),
Toast.LENGTH_LONG).show();
}
try {
Camera.Parameters parameters=camera.getParameters();
Camera.Size size=getBestPreviewSize(width, height, parameters);
Camera.Size pictureSize=getSmallestPictureSize(parameters);
Display display = windowManager.getDefaultDisplay();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and beforeif (isPortrait(display)) {
parameters.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
} else {
parameters.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
}
} else { // for 2.2 and laterswitch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientationif (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(90);
break;
case Surface.ROTATION_90:
if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(0);
break;
case Surface.ROTATION_180:
if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(270);
break;
case Surface.ROTATION_270:
if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(180);
break;
}
}
parameters.setPictureSize(pictureSize.width, pictureSize.height);
//parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Your 'surfaceChanged' method, in your camera preview (SurfaceView), you should look like this:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
stopPreview();
initPreview(w, h);
startPreview();
}
where
stopPreview:
privatevoidstopPreview() {
if (camera != null) {
camera.stopPreview();
}
}
startPreview:
privatevoidstartPreview() {
if (camera != null) {
camera.startPreview();
}
}
2
In your 'onPictureTaken' callback rotate the picture, using the following code:
Displaydisplay= getWindowManager().getDefaultDisplay();
introtation=0;
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
rotation = 90;
break;
case Surface.ROTATION_90:
rotation = 0;
break;
case Surface.ROTATION_180:
rotation = 270;
break;
case Surface.ROTATION_270:
rotation = 180;
break;
}
Bitmapbitmap= BitmapTools.toBitmap(data);
bitmap = BitmapTools.rotate(bitmap, rotation);
BitmapTools.java
publicclassBitmapTools {
publicstatic Bitmap toBitmap(byte[] data) {
return BitmapFactory.decodeByteArray(data , 0, data.length);
}
publicstatic Bitmap rotate(Bitmap in, int angle) {
Matrixmat=newMatrix();
mat.postRotate(angle);
return Bitmap.createBitmap(in, 0, 0, in.getWidth(), in.getHeight(), mat, true);
}
}
Solution 2:
here you go check this out, save the picture and maybe this will work and remember if(bitmap.getWidth > bitmap.getHeight()) as another check
publicstaticint getExifRotation(String imgPath)
{
try
{
ExifInterface exif = new ExifInterface(imgPath);
String rotationAmount = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
if (!TextUtils.isEmpty(rotationAmount))
{
int rotationParam = Integer.parseInt(rotationAmount);
switch (rotationParam)
{
case ExifInterface.ORIENTATION_NORMAL:
return0;
case ExifInterface.ORIENTATION_ROTATE_90:
return90;
case ExifInterface.ORIENTATION_ROTATE_180:
return180;
case ExifInterface.ORIENTATION_ROTATE_270:
return270;
default:
return0;
}
}
else
{
return0;
}
}
catch (Exception ex)
{
return0;
}
}
Solution 3:
you must read about ExifInterface to resolve this issue.
i have this function in my application to check weather weather image taken from camera needs to be rotateed or not.
if(ExifNeedsRotate(GetPathFromUri(context, selectedImage))){
// Rotate your bitmap using the Matrix
}
publicstaticbooleanExifNeedsRotate(String paramString){
if (android.os.Build.VERSION.SDK_INT >= 5){
try
{
Class localClass = Class.forName("android.media.ExifInterface");
Class[] arrayOfClass1 = newClass[1];
arrayOfClass1[0] = String.class;
Constructor localConstructor = localClass.getConstructor(arrayOfClass1);
Class[] arrayOfClass2 = newClass[1];
arrayOfClass2[0] = String.class;
Method localMethod = localClass.getMethod("getAttribute", arrayOfClass2);
Object[] arrayOfObject1 = newObject[1];
arrayOfObject1[0] = paramString;
Object localObject1 = localConstructor.newInstance(arrayOfObject1);
Object[] arrayOfObject2 = newObject[1];
arrayOfObject2[0] = "Orientation";
Object localObject2 = localMethod.invoke(localObject1, arrayOfObject2);
if (localObject2 != null){
boolean bool = localObject2.equals("6");
if (bool)
returntrue;
}
}
catch (Exception localException){
returnfalse;
}
}
returnfalse;
}
Pass the path of the ImageUri as a input.
publicstaticString GetPathFromUri(Context paramContext, Uri paramUri)
{
String str;
try
{
if (paramUri.toString().startsWith("file:")){
str = paramUri.getPath();
}
else
{
str = null;
String[] arrayOfString = newString[1];
arrayOfString[0] = "_data";
Cursor localCursor = paramContext.getContentResolver().query(paramUri, arrayOfString, null, null, null);
if (localCursor != null)
{
localCursor.moveToFirst();
int i = localCursor.getColumnIndex(arrayOfString[0]);
if ((localCursor.getCount() >= 1) && (localCursor.getColumnCount() >= i + 1))
str = localCursor.getString(i);
localCursor.close();
}
}
}
catch (Exception localException){
str = null;
}
return str;
}
Solution 4:
Instead of rotating the picture explicitly in the picture taken callback, you can configure the camera to have picture rotated for you when the picture is taken.
camera.SetDisplayOrientation(degrees) //sets the orientation in the preview
while
cameraParameters.SetRotation(degress) //rotates the actual captured image
Post a Comment for "How To Rotate And Flip Bitmap In Onpicturetaken"