user2558256
user2558256

Reputation: 223

Improving android camera preview

I made an app that uses a surfaceView to display camera preview.I got many reports in developer console with errors in surfaceChanged part:

     @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {       

    Parameters parameters = mCamera.getParameters();                   //// (Line 127)

    List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();

    Camera.Size previewSize = previewSizes.get(4); //480h x 720w      /// (Line 129)

    parameters.setPreviewSize(previewSize.width, previewSize.height);
    parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

    mCamera.setParameters(parameters);

    Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    if(display.getRotation() == Surface.ROTATION_0)
    {
        parameters.setPreviewSize(height, width);                           
        mCamera.setDisplayOrientation(90);
    }

    if(display.getRotation() == Surface.ROTATION_90)
    {
        parameters.setPreviewSize(width, height);                           
    }

    if(display.getRotation() == Surface.ROTATION_180)
    {
        parameters.setPreviewSize(height, width);               
    }

    if(display.getRotation() == Surface.ROTATION_270)
    {
        parameters.setPreviewSize(width, height);
        mCamera.setDisplayOrientation(180);
    }


    mCamera.startPreview();
}

first error:

    java.lang.IndexOutOfBoundsException  (Line 129)

second error:

    java.lang.NullPointerException (Line 127)

third error:

    java.lang.RuntimeException: set display orientation failed (when rotating cam 90*)

Most of the error reports are from samsung galaxy device but the app works great on LG nexus 4. Can someone give a more stable and reliable way for surface change to avoid such errors ??

Upvotes: 0

Views: 1123

Answers (2)

CommonsWare
CommonsWare

Reputation: 1006724

java.lang.IndexOutOfBoundsException (Line 129)

Randomly choosing the fourth preview size, thinking that somehow it magically always exists and always is "480h x 720w", isn't going to work. Iterate over the preview sizes and choose the one you want.

java.lang.NullPointerException (Line 127)

mCamera is null, apparently.

java.lang.RuntimeException: set display orientation failed

Not sure what to tell you here. It might be tied to front-facing versus rear-facing cameras, as the degrees get interpreted differently. Given a degrees variable that holds 0, 90, 180, or 270 (matching the Surface.ROTATION_0, etc. values), and a Camera.Info named info, I use the following in CWAC-Camera:

if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
  displayOrientation=(info.orientation + degrees) % 360;
  displayOrientation=(360 - displayOrientation) % 360;
}
else {
  displayOrientation=(info.orientation - degrees + 360) % 360;
}

camera.setDisplayOrientation(displayOrientation);

I pulled that from the JavaDocs for setDisplayOrientation().

Upvotes: 3

Eric Ahn
Eric Ahn

Reputation: 716

I can't be 100% sure about what's causing the NullPointerException. If there was a NPE with mCamera, then line 128 should also error out. Are the errors happening at different times?

The IndexOutOfBoundsException is easily explained; there aren't 5 preview sizes to choose from on the Galaxy device, so it can't find the 5th size and throws an exception.

The RuntimeException might be related to the first.

I would suggest looking at CommonsWare's CWAC-Camera library instead, it handles many of these things for you (in general the Camera API on Android is hard to work with): https://github.com/commonsguy/cwac-camera

Upvotes: 2

Related Questions