Skip to content Skip to sidebar Skip to footer

How To Rotate And Flip Bitmap In Onpicturetaken

I'm finding in onPictureTaken that the bitmap saved is mirrored about the y-axis and rotated 90 degrees clockwise even though the camera preview was not. This is on my Nexus S that

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"