title: android custom camera orientation
body: <p>I have defined a custom <code>camera view</code> to take picture. The issue i am getting is, if the picture is taken with camera held in <code>portrait</code> , the image rotated in <code>90 degree</code>. I want to do same like Instagram camera does.
  What i want is, If i rotate the camera in any angle i want bitmap to be in <code>Portrait</code> and save to device.</p>
  
  <p>Please help me.</p>
  
  <p>Here is my code :</p>
  
  <pre><code> private PictureCallback mPicture = new PictureCallback() {
  
      public void onPictureTaken(byte[] data, Camera camera) {
  
          safeToTakePicture = true;
  
          File pictureFile = new File(Common.FILE_IMAGE_STORAGE, filename);
  
          if (pictureFile.exists()) {
              pictureFile.delete();
          }
  
          try {
              FileOutputStream purge = new FileOutputStream(pictureFile);
              purge.write(data);
              purge.close();
          } catch (FileNotFoundException e) {
                  } 
            catch (IOException e) {
          }
  
          if (data != null) {
  
              new AsyncBitmapCreation(filepath).execute();
          }
      }
  };
  
   class AsyncBitmapCreation extends AsyncTask&lt;Void, Void, Bitmap&gt; {
  
      byte[] data;
  
      public AsyncBitmapCreation(byte[] data) {
          this.data = data;
      }
  
      @Override
      protected Bitmap doInBackground(Void... params) {
  
          return rotateImage(data);
      }
  
      @Override
      protected void onPostExecute(Bitmap result) {
  
          bitmap = result;
  
      }
  
  }
  </code></pre>
  
  <p>Here in Rotate function i am using ExifInterface again</p>
  
  <pre><code> private Bitmap rotateImage(final byte[] data) {
      Bitmap scaledBitmap = null;
  
      try {
          BitmapFactory.Options options = new BitmapFactory.Options();
          options.inSampleSize = 3;
  
          Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length,
                  options);
  
          int actualHeight = bmp.getHeight();
          int actualWidth = bmp.getWidth();
  
          float maxHeight = 1020.0f;
          float maxWidth = 680.0f;
          float imgRatio = actualWidth / actualHeight;
          float maxRatio = maxWidth / maxHeight;
  
          if (actualHeight &gt; maxHeight || actualWidth &gt; maxWidth) {
              if (imgRatio &lt; maxRatio) {
                  imgRatio = maxHeight / actualHeight;
                  actualWidth = (int) (imgRatio * actualWidth);
                  actualHeight = (int) maxHeight;
              } else if (imgRatio &gt; maxRatio) {
                  imgRatio = maxWidth / actualWidth;
                  actualHeight = (int) (imgRatio * actualHeight);
                  actualWidth = (int) maxWidth;
              } else {
                  actualHeight = (int) maxHeight;
                  actualWidth = (int) maxWidth;
  
              }
          }
  
          options.inSampleSize = calculateInSampleSize(options, actualWidth,
                  actualHeight);
  
          // inJustDecodeBounds set to false to load the actual bitmap
          options.inJustDecodeBounds = false;
  
          options.inPurgeable = true;
          options.inInputShareable = true;
          options.inTempStorage = new byte[16 * 1024];
  
          try {
  
              Bitmap.Config conf = Bitmap.Config.ARGB_8888;
              scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,
                      conf);
  
          } catch (OutOfMemoryError exception) {
  
          }
  
          float ratioX = actualWidth / (float) options.outWidth;
          float ratioY = actualHeight / (float) options.outHeight;
          float middleX = actualWidth / 2.0f;
          float middleY = actualHeight / 2.0f;
  
          Matrix scaleMatrix = new Matrix();
          scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
  
          Canvas canvas = new Canvas(scaledBitmap);
          canvas.setMatrix(scaleMatrix);
  
          canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2,
                  middleY - bmp.getHeight() / 2, new Paint(
                          Paint.FILTER_BITMAP_FLAG));
  
          ExifInterface exif;
          try {
  
              exif = new ExifInterface(fileUri.getPath());
              Matrix matrix = new Matrix();
              if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                      .equalsIgnoreCase("6")) {
                  matrix.postRotate(90);
              } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                      .equalsIgnoreCase("8")) {
                  matrix.postRotate(270);
  
              } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                      .equalsIgnoreCase("3")) {
                  matrix.postRotate(180);
              } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                      .equalsIgnoreCase("0")) {
                  matrix.postRotate(90);
  
              }
  
              scaledBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
                      bmp.getHeight(), matrix, true);
  
          } catch (IOException e) {
  
          }
  
      } catch (Exception e) {
  
      }
  
      return scaledBitmap;
  
  }
  </code></pre>
  
  <p>Surfaceview and callback refer from this link 
  <a href="https://stackoverflow.com/questions/15130447/android-camera-setdisplayorientation-does-not-work">Android Camera setDisplayOrientation does not work</a></p>
  
  <pre><code> public class PreviewCamera extends SurfaceView implements
      SurfaceHolder.Callback {
  
  private SurfaceHolder mHolder;
  private Camera mCamera;
  
  private static boolean DEBUGGING = true;
  private static final String LOG_TAG = "CameraPreviewSample";
  private static final String CAMERA_PARAM_ORIENTATION = "orientation";
  private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
  private static final String CAMERA_PARAM_PORTRAIT = "portrait";
  protected Activity mActivity;
  
  protected List&lt;Camera.Size&gt; mPreviewSizeList;
  protected List&lt;Camera.Size&gt; mPictureSizeList;
  protected Camera.Size mPreviewSize;
  protected Camera.Size mPictureSize;
  
  public PreviewCamera(Context context, Camera camera) {
      super(context);
      mActivity = (Activity) context;
      mCamera = camera;
      mHolder = getHolder();
      mHolder.addCallback(this);
      // deprecated setting, but required on Android versions prior to 3.0
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  
  }
  
  @Override
  public void surfaceCreated(SurfaceHolder holder) {
  
      try {
          mCamera.setPreviewDisplay(holder);
          mCamera.startPreview();
      } catch (IOException e) {
          Log.d("CameraView",
                  "Error setting camera preview: " + e.getMessage());
      }
  
  }
  
  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width,
          int height) {
      if (mHolder.getSurface() == null) {
          // preview surface does not exist
          return;
      }
  
      // stop preview before making changes
      try {
          // mCamera.stopPreview();
      } catch (Exception e) {
          // ignore: tried to stop a non-existent preview
      }
  
      // set preview size and make any resize, rotate or
      // reformatting changes here
  
      // start preview with new settings
      try {
          Camera.Parameters cameraParams = mCamera.getParameters();
          boolean portrait = isPortrait();
          configureCameraParameters(cameraParams, portrait);
  
          mCamera.setPreviewDisplay(mHolder);
          mCamera.startPreview();
  
      } catch (Exception e) {
          Log.d("CameraView",
                  "Error starting camera preview: " + e.getMessage());
      }
  
  }
  
  public void onPause() {
      mCamera.release();
      mCamera = null;
  }
  
  protected void configureCameraParameters(Camera.Parameters cameraParams,
          boolean portrait) {
      if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.FROYO) { // for 2.1 and
                                                                  // before
          if (portrait) {
              cameraParams.set(CAMERA_PARAM_ORIENTATION,
                      CAMERA_PARAM_PORTRAIT);
          } else {
              cameraParams.set(CAMERA_PARAM_ORIENTATION,
                      CAMERA_PARAM_LANDSCAPE);
          }
      } else { // for 2.2 and later
          int angle;
          Display display = mActivity.getWindowManager().getDefaultDisplay();
          switch (display.getRotation()) {
          case Surface.ROTATION_0: // This is display orientation
              angle = 90; // This is camera orientation
              break;
          case Surface.ROTATION_90:
              angle = 0;
              break;
          case Surface.ROTATION_180:
              angle = 270;
              break;
          case Surface.ROTATION_270:
              angle = 180;
              break;
          default:
              angle = 90;
              break;
          }
          Log.v(LOG_TAG, "angle: " + angle);
          //mCamera.setDisplayOrientation(angle);
            mCamera.setDisplayOrientation(90);
      }
  
      cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
      cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
      if (DEBUGGING) {
          Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width
                  + ", h: " + mPreviewSize.height);
          Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width
                  + ", h: " + mPictureSize.height);
      }
  
      mCamera.setParameters(cameraParams);
  }
  
  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
      // TODO Auto-generated method stub
  
  }
  
  public boolean isPortrait() {
      return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
  }
  
  }
  </code></pre>