Controlling the camera to take pictures in portrait doesn't rotate the final images Controlling the camera to take pictures in portrait doesn't rotate the final images android android

Controlling the camera to take pictures in portrait doesn't rotate the final images


The problem is when I saved the image I didn't do well.

@Overridepublic void onPictureTaken(byte[] data, Camera camera) {    String timeStamp = new SimpleDateFormat( "yyyyMMdd_HHmmss").format( new Date( ));    output_file_name = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + timeStamp + ".jpeg";    File pictureFile = new File(output_file_name);    if (pictureFile.exists()) {        pictureFile.delete();    }    try {        FileOutputStream fos = new FileOutputStream(pictureFile);        Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);        ExifInterface exif=new ExifInterface(pictureFile.toString());        Log.d("EXIF value", exif.getAttribute(ExifInterface.TAG_ORIENTATION));        if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6")){            realImage= rotate(realImage, 90);        } else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8")){            realImage= rotate(realImage, 270);        } else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3")){            realImage= rotate(realImage, 180);        } else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("0")){            realImage= rotate(realImage, 90);        }        boolean bo = realImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);        fos.close();        ((ImageView) findViewById(R.id.imageview)).setImageBitmap(realImage);        Log.d("Info", bo + "");    } catch (FileNotFoundException e) {        Log.d("Info", "File not found: " + e.getMessage());    } catch (IOException e) {        Log.d("TAG", "Error accessing file: " + e.getMessage());    }}public static Bitmap rotate(Bitmap bitmap, int degree) {    int w = bitmap.getWidth();    int h = bitmap.getHeight();    Matrix mtx = new Matrix();   //       mtx.postRotate(degree);    mtx.setRotate(degree);    return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);}


The setCameraDisplayOrientation() method lets you change how the preview is displayed without affecting how the image is recorded (source).

In order to change the actual recorded image you need to set the rotation parameter of the Camera. You do it like this:

//STEP #1: Get rotation degreesCamera.CameraInfo info = new Camera.CameraInfo();Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();int degrees = 0;switch (rotation) {    case Surface.ROTATION_0: degrees = 0; break; //Natural orientation        case Surface.ROTATION_90: degrees = 90; break; //Landscape left        case Surface.ROTATION_180: degrees = 180; break;//Upside down        case Surface.ROTATION_270: degrees = 270; break;//Landscape right    }int rotate = (info.orientation - degrees + 360) % 360;//STEP #2: Set the 'rotation' parameterCamera.Parameters params = mCamera.getParameters();params.setRotation(rotate); mCamera.setParameters(params);

Your solution is kind of a workaround since you modify the image AFTER it was already recorded. This solution is cleaner and doesn't require all these 'if' statements before saving the image.


You can use the method below to generate preview correctly when your using front camera.

This code goes into surfaceChanged Method of your camera preview

@Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {     int angleToRotate=CommonMethods.getRoatationAngle(mActivity, Camera.CameraInfo.CAMERA_FACING_FRONT);     mCamera.setDisplayOrientation(angleToRotate);}

This code can be put into a static class

 /**     * Get Rotation Angle     *      * @param mContext     * @param cameraId     *            probably front cam     * @return angel to rotate     */    public static int getRoatationAngle(Activity mContext, int cameraId) {        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();        android.hardware.Camera.getCameraInfo(cameraId, info);        int rotation = mContext.getWindowManager().getDefaultDisplay().getRotation();        int degrees = 0;        switch (rotation) {        case Surface.ROTATION_0:            degrees = 0;            break;        case Surface.ROTATION_90:            degrees = 90;            break;        case Surface.ROTATION_180:            degrees = 180;            break;        case Surface.ROTATION_270:            degrees = 270;            break;        }        int result;        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {            result = (info.orientation + degrees) % 360;            result = (360 - result) % 360; // compensate the mirror        } else { // back-facing            result = (info.orientation - degrees + 360) % 360;        }        return result;    }

You can Rotate image this way.This is used only when image is taken and we are about to save the image

public static Bitmap rotate(Bitmap bitmap, int degree) {        int w = bitmap.getWidth();        int h = bitmap.getHeight();        Matrix mtx = new Matrix();        mtx.postRotate(degree);        return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);    }

The Method that will be used for taking picture

  @Override    public void onPictureTaken(byte[] data, Camera camera) {        int angleToRotate = getRoatationAngle(MainActivity.this, Camera.CameraInfo.CAMERA_FACING_FRONT);        // Solve image inverting problem        angleToRotate = angleToRotate + 180;        Bitmap orignalImage = BitmapFactory.decodeByteArray(data, 0, data.length);        Bitmap bitmapImage = rotate(orignalImage, angleToRotate);    }

The bitmapImage contains the correct image.