having image distorted when mixing a view from OpenGL and the Android camera to get an image of both when using the takepicture method. I checked and found that the camera picture was set to 640X480 and the openGL view and the camera preview was both set to 1280x720.
so I set the camera picture size to 1280x720 and the result was perfect. however I can't set the size in code because each Android device will be different and every device the settings for both preview size and picture size have to be selected from a list of supported sizes.
what is the best way to do this considering that there are three variables here, the screen size of the activity layout, the camera preview size, and the picture size.
is it best to use a match_parent or fitXY for the FrameLayout size and only work with two variables, the preview size and picture size?
notice that several of the width and height combinations in preview sizes and picture sizes are the same. for example 1280 x 720 exists in both preview and picture, is it always the case that there will be matches in both sizes?
List<Size> previewSizes = mCamera.getParameters().getSupportedPreviewSizes();
List<Size> imageSizes = mCamera.getParameters().getSupportedPictureSizes();
// layout in the activity that the cameraView will placed in
int layoutWidth = frameLayout.getWidth();
int layoutHeight = frameLayout.getHeight();
for example in one Android tablet after measurement these are the results for the 3 variables used
size of layout viewGroup in activity as result of measurement
1280 x 736
supported picture sizes
320 x 240
640 x 480
1024 x 768
1280 x 720 << best size in my example to use
1280 x 768
1280 x 920
1600 x 1200
2048 x 1536
2560 x 1440
2560 x 1536
2560 x 1920 << native resolution of hardware camera
supported preview sizes
176 x 144
320 x 240
352 x 288
480 x 320
480 x 368
640 x 480
800 x 480
800 x 600
864 x 480
864 x 576
960 x 540
1280 x 720 << best size in my example to use
1280 x 768
1280 x 960
Most often, but not always, there is correspondence between picture aspect ratios and preview aspect ratios. You can be assured that at least some of them are classic 4:3 ratios (e.g. 640x480). Support for 16:9 is also widely available.
The screen may have different aspect ratio. To fill it with a camera image correctly, it is widely accepted to add black margins (same approach is used in YouTube). Alternatively, you may crop the camera image to fill the whole screen.
Note that the screen size (as reported in tech specs for the variety of devices) is not always actually available for your image display. For example, the system menus, and title bar, etc. may take their share of the screen real estate. The immersive mode is available on some devices, and its behavior depends on the system version. You may expect that future developments of Android, e.g. second screen support, will make the game even more interesting.
So, the answers to your specific questions:
is it best to use a match_parent or fitXY for the FrameLayout size and only work with two variables, the preview size and picture size? - no.
is it always the case that there will be matches in both sizes? - yes, but maybe this size is not optimal.
Even if your camera supports different "wide" picture sizes, 1280x720 preview and 2560x1440 picture may be the best match, both precisely at 16:9
. Usually, the quality of picture at small size is not significantly better than preview at that same size, so you may choose to save the preview frame if 1280x720
is what you really need.
If you can forgo takePicture()
, your app will be much more responsive.
I think the best way to get preview size, picture size
is the Camera was set up to support all Android devices. It means the preview size, picture size
you decide to set up is appropriate with the popular format that All Devices supported, ex. is 1280x720 etc.
As in following codes, is the ex. what I used.
// start preview with new settings
try {
// set preview size and make any resize, rotate or
// reformatting changes here
Camera.Parameters parameters = mCamera.getParameters();
for (Camera.Size size : parameters.getSupportedPictureSizes()) {
// 640 480
// 960 720
// 1024 768
// 1280 720
// 1600 1200
// 2560 1920
// 3264 2448
// 2048 1536
// 3264 1836
// 2048 1152
// 3264 2176
if (1600 <= size.width & size.width <= 1920) {
parameters.setPreviewSize(size.width, size.height);
parameters.setPictureSize(size.width, size.height);
break;
}
}
// Set parameters for camera
CustomCamera.mCamera.setParameters(parameters);
Camera.Size size = CustomCamera.mCamera.getParameters().getPictureSize();
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
Best size
depend on Camera MP. So I think should use default if using Camera.
Possible algorithm:
1) get output area aspect ratio (=width/height)
2) iterate through supported sizes:
Choose biggest one with close aspect ratio(+-5%, for example)
If nothing close or resolution too low - just make yor surface(that you draw frames to) be same aspect ratio as biggest supported size and center it in parent view
Howewer, there are preview sizes & picture sizes. If you wish them to have same aspect ratio - then better choice is to use selected picture size aspect ratio in 1) This way you'll probably have to center your surface in parent view
Hope that helps)