I just setup a very basic camera preview that displays the camera full screen. I compared the smoothness of both my app and the android camera and figured that the android camera seems a lot smoother.
Why is that the case? Are there any special tricks to improve the camera preview performance?
PreviewView is a subclass of FrameLayout . To display the camera feed, it uses either a SurfaceView or TextureView , provides a preview surface to the camera when it's ready, tries to keep it valid as long as the camera is using it, and when released prematurely, provides a new surface if the camera is still in use.
The image must be rotated 270 degrees counterclockwise so that the preview's orientation matches the device orientation: A back-facing camera would produce an image buffer with the same orientation as the buffer above, but SENSOR_ORIENTATION is 90 degrees. As a result, the buffer is rotated 90 degrees clockwise.
Live preview is a feature that allows a digital camera's display screen to be used as a viewfinder. This provides a means of previewing framing and other exposure before taking the photograph.
I faced the same issue a time ago, and it turned out to be related with the camera resolution. Chances are that your Camera
is initializing with the maximum available resolution, which may slow down performance during preview. Try and set a lower picture size
with something like this.-
Camera.Parameters params = camera.getParameters();
params.setPictureSize(1280, 960);
camera.setParameters(params);
Notice that you'll need to set an available picture size. You can check available sizes with
camera.getParameters().getSupportedPictureSizes();
Hope it helps.
EDIT
It seems using a picture size with different aspect ratio than the default one, slows down performance as well. This is how I choose my pictureSize
.-
First off, I get the aspect ratio of the camera default pictureSize
Camera.Parameters params = camera.getParameters();
defaultCameraRatio = (float) params.getPictureSize().width / (float) params.getPictureSize().height;
And then I get a lower pictureSize
that fits the same ratio.-
private Size getPreferredPictureSize() {
Size res = null;
List<Size> sizes = camera.getParameters().getSupportedPictureSizes();
for (Size s : sizes) {
float ratio = (float) s.width / (float) s.height;
if (ratio == defaultCameraRatio && s.height <= PHOTO_HEIGHT_THRESHOLD) {
res = s;
break;
}
}
return res;
}
Where PHOTO_HEIGHT_THRESHOLD
is the max height you want to allow.
This answer is a bit late, but after struggling with the same problem, I figured I'd share what I found.
Not only was I unable to match the stock camera's "smoothness", but I was also unable to match the metering of the stock camera. My live preview was much darker compared to the stock camera, especially in low light situations.
My solution was ultimately an FPS issue, as originally proposed by Robin in an early comment.
The default preview FPS on the Nexus 5 is a static 15 FPS. The stock android app detects and sets a preview FPS that uses a dynamic range (as long as that range includes 30fps). On a nexus 5, that range is 7fps -> 30fps. In low light the camera drops to a lower FPS to keep the preview bright, while in bright conditions it jumps to a smooth 30 fps.
Relevant code from the stock android photo app:
Here's are the camera api calls to set the FPS using hard coded values (for the sake of simplicity) specific to a Nexus 5.
public void setFps(Camera camera) {
Camera.Parameters params = camera.getParameters();
params.setPreviewFpsRange(7000, 30000);
camera.setParameters(params);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With