Tuesday, March 2, 2010

Corrupt Android Camera Preview

I have been playing code to use the Camera and came across an issue which I couldn’t find a resolution for. When you run any of the various samples around the Internet they all appear to suffer from the same issue, the Camera preview is corrupt in Portrait mode. I found a fudge which switches the mode to Landscape before showing the Camera Activity but this was less than ideal because you get a short pause as the phone switches display modes. I eventually came up with the solution below in the surfaceChanged method:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

if (previewRunning) {
camera.stopPreview();
}

Camera.Parameters p = camera.getParameters();

////////////////////////////////////////////////////////////
// Check orientation and set size as w, h or h, w.
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

if(display.getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
p.setPreviewSize(h, w);
} else {
p.setPreviewSize(w, h);
}
camera.setParameters(p);

try {
camera.setPreviewDisplay(holder);
} catch(IOException e) {
e.printStackTrace();
}

camera.startPreview();
previewRunning = true;
}

The key to this solution is the order of height and width in setPreviewSize, which should be h, w when in Landscape or w,h when in Portrait.