Quarillion
Quarillion

Reputation: 65

ImageReader on Camera2 Api android

I'm starting to use Camera2 Api instead of the deprecated Camera Api but I have a problem. I set up an ImageReader with

ImageReader.newInstance(100, 130, ImageFormat.YUV_420_888, 2);

But when I log the image dimensions in onImageAvailable:

Image img = null;
        img = imageReader.acquireLatestImage();

        if(img != null){

            Log.d("Dimen3", Integer.toString(img.getHeight()) + " " + img.getWidth());}

It says:

08-24 18:25:43.115 28363-28363/com.example.ale.camera2prova D/Dimen3: 144 176

Why the dimensions are changed?

Upvotes: 2

Views: 3049

Answers (2)

Francisco Durdin Garcia
Francisco Durdin Garcia

Reputation: 13327

You can just set in your imageReader the available sizes that your phone support. You can know it with this method:

public static Size[] previewSizes;
public static Size[] videoSizes;
public static Size[] pictureSizes;

     StreamConfigurationMap map = cameraCharacteristics.get(                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

        previewSizes = map.getOutputSizes(SurfaceTexture.class);
        videoSizes = map.getOutputSizes(MediaRecorder.class);
        pictureSizes = map.getOutputSizes(ImageFormat.JPEG);

You can just set in your imageReader the results from your pictureSizes call(also, depending from which format of ImageReader are we talking about, some devices will support some sizes in YUV or JPEG format, but not in RAW for example).

Also you can't configure multiple ImageReaders in specific sizes, it should be a problem if you are working in a Camera app with so many modes. You can read more about it in the next link: https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html

Hope that it will help you!

Upvotes: 0

Chris B
Chris B

Reputation: 411

If I understand your question correctly, you are asking why you can't use arbitrary dimensions for your ImageReader image. The answer to that is that is how they designed the ImageReader. The ImageReader is probably choosing a pre defined size which is closest to your requested size. To avoid this, choose a size from the pre defined list. I wrote a little routine which gets the list of sizes and chooses the smallest one which is equal to or bigger than the screen size:

private Size selectImageSize() {
    CameraCharacteristics cameraCharacteristics = null;
    try {
        cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
    } catch (CameraAccessException e) {
        return null;
    }

    StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
    if (streamConfigurationMap == null) {
        return null;
    }
    jpegSizes = streamConfigurationMap.getOutputSizes(ImageFormat.JPEG);

    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int screenLength = size.x;
    if (screenLength < size.y) {
        screenLength = size.y;
    }

    int index = 0;
    int finalIndex = 0;
    int finalJpegLength = Integer.MAX_VALUE;
    for (Size jpegSize : jpegSizes) {
        int jpegLength = jpegSize.getWidth();
        if (jpegLength < jpegSize.getHeight()) {
            jpegLength = jpegSize.getHeight();
        }
        if (jpegLength >= screenLength) {
            if (jpegLength < finalJpegLength) {
                finalJpegLength = jpegLength;
                finalIndex = index;
            }
        }
        index++;
    }

    Size returnSize = new Size(jpegSizes[finalIndex].getWidth(), jpegSizes[finalIndex].getHeight());
    return returnSize;
}

I am trying to get the smallest image size which is equal to or larger than the screen size because using that provides the fastest speed while providing an image which will fill the device's screen.

Upvotes: 2

Related Questions