Camera in Android, How to Get Best Size, Preview Size, Picture Size, View Size, Image Distorted

Camera in Android, how to get best size, preview size, picture size, view size, image distorted

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.

Camera orientation and preview size

From what I researched, you can only use supported preview sizes: stackoverflow.com/a/8051114/6286328 and stackoverflow.com/a/6952604/6286328. Perhaps your best shot is to get a similar suppored preview size (according to your required proportion) and test to see how it gets.

Android Camera Preview Stretched

I'm using this method -> based on API Demos to get my Preview Size:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;

if (sizes == null) return null;

Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;

int targetHeight = h;

for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}

if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}

As you can see you have to input width and height of your screen. This method will calculate screen ratio based on those values and then from the list of supportedPreviewSizes it will choose the best for you from avaliable ones. Get your supportedPreviewSize list in place where Camera object isn't null by using

mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

And then on in onMeasure you can get your optimal previewSize like that:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);

if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}

And then (in my code in surfaceChanged method, like I said I'm using API Demos structure of CameraActivity code, you can generate it in Eclipse):

Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(parameters);
mCamera.startPreview();

And one hint for you, because I did almost the same app like you. Good practice for Camera Activity is to hide StatusBar. Applications like Instagram are doing it. It reduces your screen height value and change your ratio value. It is possible to get strange Preview Sizes on some devices (your SurfaceView will be cut a little)


And to answer your question, how to check if your preview ratio is correct? Then get height and width of parameters that you set in:

mCamera.setParameters(parameters);

your set ratio is equal to height/width. If you want camera to look good on your screen then height/width ratio of parameters that you set to camera must be the same as height(minus status bar)/width ratio of your screen.



Related Topics



Leave a reply



Submit