I have a SurfaceView to display a live camera preview image in my Android app. The SurfaceView covers the whole width of the portrait screen, and a portion of the screen height.
I tried setting various preview sizes, so the preview had a distorted aspect ratio, short and fat or tall and skinny.
I printed debugs showing the actual preview display size, and the available preview camera sizes, so I could work out the aspect ratio error.
Screen size available for preview: w*h:1200*1646; Aspect ratio: 0.73
Rotation: 0; finalCameraRotation: 90; sideways: true
Supported Preview size: w*h:1080*1920: AspectRatio: 0.56: Error: -22.84%
Supported Preview size: w*h:768*1280: AspectRatio: 0.60: Error: -17.70%
...
Usually, I would pick the preview size with the lowest error in aspect ratio, but I was experimenting.
List<Camera.Size> ss = parameters.getSupportedPreviewSizes();
...
Camera.Size s = ss.get(pickOne);
parameters.setPreviewSize(s.width, s.height);
...
camera.setParameters(parameters);
...
camera.startPreview();
I measured the aspect ratio error of the preview display by pointing the camera at a white square and screenshotting it using Eclipse, then measuring the image of the white square in the screenshot using the photoshop ruler tool:.
I measured the x
and y
size of the square in screen pixels and computed 1-(y/x)
, and that should be the same as the aspect ratio error predicted in the debug log above.
I tried this on
- Alcatel 995, Android 4.0.4
- Samsung Note 2, Android 4.4.2
- Google Nexus 7, Android 4.4.4
- Google Nexus 5, Android 5.0
with various aspect ratios, as much as 25% in error from square, and in all of these, I measured aspect ratios in the preview within about 1% of that predicted. (There are errors, the camera might be not straight-on, it might be a bit out of focus...)
Except for the Google Nexus 7.
No matter what preview size I set for the Nexus 7, the measured aspect ratio was about 2% too tall, which just happens to be the best possible aspect ratio available:
Supported Preview size: w*h:768*1024: AspectRatio: 0.75: Error: 2.87%
It's as though some other program was coming and fixing the optimal preview size after I set it. I actually put in code to wait 10 seconds and read back the preview size from the camera, and it was the one I set, yet the display didn't reflect that. The display is always optimal no matter what preview size I set.
Is there something weird about preview sizes on Nexus 7?
I know that my setPreviewSize
is doing something, because I can set the preview to 144*176px and then I see odd upsampling pixellation artefacts in the display. But it still has the nearly-corrrect aspect ratio!
I've just stumbled upon this problem myself. Reportedly, this happens to some devices, when camera's picture size and preview size parameters have different aspect ratios. In my case, my Nexus 7 appeared to always use a 4:3 preview, no matter what I'd set. Also,
getPreviewSize()
reported the size I'd set, not the one really used.The solution is to find a picture size with an aspect ratio matching preview's one. So, get a list of supported picture sizes with
getSupportedPictureSizes()
, choose one with a proper width/height ratio and thensetPictureSize(int width, int height)
. It worked for me like a charm :)