Sergi Juanola
Sergi Juanola

Reputation: 6647

Camera preview always returns a 320x240 Bitmap

I am creating an image preview and I wished to get a very high picture resolution. However, and I don't know why, despite Galaxy Nexus supports a wide range of resolutions (I think the largest one is 1920x1080, but I can't remember if those are the exact values), when I save the picture, it says the info coming from the preview is of 320x240.

pixels.mCamera = getCameraInstance();
Camera.Parameters params = mCamera.getParameters();
List<Size> sizes = params.getSupportedPreviewSizes();
Size biggestSize = sizes.get(0);
double biggestPixels = biggestSize.width + biggestSize.height;
for (Size size : sizes) {
    double pixels = size.width * size.height;
    if (pixels > biggestPixels) {
        biggestSize = size;
        biggestPixels = pixels;
    }
}
// At this point, biggestSize is 1920x1080
float ratio = ((float) biggestSize.width)
                    / ((float) biggestSize.height);
params.setPreviewSize(biggestSize.width, biggestSize.height);
mCamera.setParameters(params);
setCameraDisplayOrientation(this, 0, mCamera);
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
LinearLayout innerWrapper = (LinearLayout) findViewById(R.id.innerWrapper);
LayoutParams layoutParams = (LayoutParams) innerWrapper
                    .getLayoutParams();
layoutParams.height = (int) (layoutParams.height * ratio);
innerWrapper.setLayoutParams(layoutParams);
preview.addView(mPreview);

That innerWrapper stuff is to show a square picture. setCameraOrientation turns the image to align with the ratio. When taking the picture I use autofocus and then...

mCamera.autoFocus(new AutoFocusCallback() {

    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        mCamera.takePicture(null, null, new PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 1;
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                                            data.length, options);
                Bitmap finalBitmap;
                float ow = bitmap.getWidth();
                float oh = bitmap.getHeight();
                // At this point, ow and oh are 320 and 240
                float ratio = ow / oh;
                int fw, fh, x, y, angle;
                //It continues, but irrelevant
                ...

Is this anything related to the layout dimensions of the FrameLayout I use to hold the preview? Because I defined it to be of 350x350 dp, and this the preview should be bigger.

Upvotes: 1

Views: 719

Answers (1)

Sergi Juanola
Sergi Juanola

Reputation: 6647

Silly me. The problem is that my PictureCallback is implemented as the jpeg parameter, not the raw one. Where, quoting the documentation:

The raw callback occurs when the raw image data is available (NOTE: the data will be null if there is no raw image callback buffer available or the raw image callback buffer is not large enough to hold the raw image). The postview callback occurs when a scaled, fully processed postview image is available (NOTE: not all hardware supports this). The jpeg callback occurs when the compressed image is available.

Moving the whole PictureCallback to the second parameter of mCamera.takePicture instead of the third would be on the path to solve the issue. However, you'd need a CallbackBuffer to do so and change the code to adapt to the use of buffers. So for the first version I'll stick to low quality pictures.

Upvotes: 1

Related Questions