简体   繁体   中英

Android Camera Saving Pictures in Portrait Mode

I'm trying to use a camera in my app and I want to be able to use it in landscape and portrait mode. I'm having no difficulty creating pictures in landscape mode, but I haven't found a good way to save pictures in portrait mode.

When I want to make a picture in portrait mode I need to set the displayorientation to portrait first, like this:

switch (windowManager.getDefaultDisplay().getRotation()) {
    case android.view.Surface.ROTATION_0:
        mCamera.setDisplayOrientation(90);
        break;
    case android.view.Surface.ROTATION_90:
        mCamera.setDisplayOrientation(0);
        break;
    case android.view.Surface.ROTATION_180:
        mCamera.setDisplayOrientation(270);
        break;
    case android.view.Surface.ROTATION_270:
        mCamera.setDisplayOrientation(180);
        break;
}

But then the picture is still saved in landscape mode. One solution I found was to change the rotation parameter of the camera like this:

public void onOrientationChanged(int orientation) {
    if (orientation == ORIENTATION_UNKNOWN) return;
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    orientation = (orientation + 45) / 90 * 90;
    int rotation = 0;
    if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
        rotation = (info.orientation - orientation + 360) % 360;
    } else {  // back-facing camera
        rotation = (info.orientation + orientation) % 360;
    }
    mParameters.setRotation(rotation);
}

The problem with this approach is that it may just set the orientation in the EXIF header and not actually rotate the picture (which is the case with the device I'm using).

Another approach was rotating the actual data after the picture is taken like this:

Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
bitmap=  Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
currentData = stream.toByteArray();

But this approach takes 10 seconds (which is too long) and while I could put this code in an AsyncTask, I need the data one to a few seconds later, so then I'd still need to wait.

So far I haven't found a better solution.

I have found a solution that makes me still need to wait for a second or two, but that's fast enough for me. It's a pretty simple fix, just use the Matrix.postRotate method, but change:

bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);

to:

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);

For me this is a pretty good solution, especially because everywhere else I already used .jpg images so it didn't make much sense compressing the Bitmap to a .png anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM