Different capture output size on certain camera resolutions in Android

Viewed 3472

I am developing a custom camera application using the Android Camera2 API where you can switch between the different camera and video resolutions available in the phone. It also offers the possibility to take squared 1:1 pictures. To take the square pictures, I take a normal 4:3 picture and then crop it to maintain the 1:1. (So 4032x3024 would be 3024x3024).

I noticed a problem when taking a 1:1 picture on certain resolutions, the output is slightly cropped (zoomed). This is the result of the same picture taken with two different resolutions:

The first picture was taken at 1944x1944

The second picture was taken at 3024x3024

My Nexus 5X supports 12MP, 8MP, 5MP and 2MP on 4:3. This problem happens when I use any resolution bigger than 5MP.

The method I use to crop the images is the following:

ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
cropSquareImageByteArray(bytes);

The cropSquareImageByteArray method:

public static byte[] cropSquareImageByteArray(byte[] bytes) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    Bitmap dst = Bitmap.createBitmap(bitmap, 0, h - w, w, w);
    dst.compress(Bitmap.CompressFormat.JPEG, 98, bos);
    return bos.toByteArray();
}

I am guessing the reason for the cropping is a 4:3 image in a 16:9 container. Because I noticed that when calling

    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

The dimensions for the generated bitmap output are 1280x960 (4:3) in 2MP, 1600x1200 (4:3) in 5MP but for bigger resolutions are 1920x1080 (16:9), so the 4:3 image is adjusted to a 16:9 bitmap, maybe causing the crop.

I am trying to figure out how to solve this. I also checked this post Android 5.0 Wrong crop regions on preview surface and captured still image but didn't find a solution there.

*edit: My ImageReader is configured like this:

public void configureImageReader(Size pictureSizeValue, ImageReader.OnImageAvailableListener listener) {

    if (mImageReader == null) {
        mImageReader = ImageReader.newInstance(pictureSizeValue.getWidth(), pictureSizeValue.getHeight(),
                ImageFormat.JPEG, 2);
    } 
    mImageReader.setOnImageAvailableListener(listener, mBackgroundHandler);

}

The value for pictureSizeValue is the output I want. So for a squared image, it is something like 3024x3024.

1 Answers
Related