How to take a photo with the same aspect ratio as in the preview size?

99.9% of the answers to the question in the title:

When you look at the List<Camera.Size> provided by Camera.Parameters # getSupportedPictureSizes () , try to find the size of the same aspect as the size of the camera preview that you set via Camera.Parameters.html # setPreviewSize (int, int) or as close as possible.

This is good, but what if I cannot find the image size of the same image format as the preview size (Android does not guarantee that for every preview size supported by the camera, there is an image size of the same format), and that's it other image sizes (which are as close as possible) just stretch my photo, as in this and this question? How can I take a photo in the same format as in the preview, even if the image size and preview size set in Camera.Parameters have different proportions?

+6
android aspect-ratio android-camera
source share
1 answer

We can learn about a general approach to this problem in this answer . Short quote:

My solution was to first scale the preview rectangle to the native size of the camera image. Then, now that I know which area of ​​the native resolution contains the content that I want, I can perform a similar operation to then scale this rectangle in its own resolution to a smaller picture that was actually recorded on Camera.Parameters.setPictureSize.

Now, to the actual code. The easiest way to scale is to use Matrix . It has a Matrix # setRectToRect method (android.graphics.RectF, android.graphics.RectF, android.graphics.Matrix.ScaleToFit) , which we can use like this:

 // Here previewRect is a rectangle which holds the camera preview size, // pictureRect and nativeResRect hold the camera picture size and its // native resolution, respectively. RectF previewRect = new RectF(0, 0, 480, 800), pictureRect = new RectF(0, 0, 1080, 1920), nativeResRect = new RectF(0, 0, 1952, 2592), resultRect = new RectF(0, 0, 480, 800); final Matrix scaleMatrix = new Matrix(); // create a matrix which scales coordinates of preview size rectangle into the // camera native resolution. scaleMatrix.setRectToRect(previewRect, nativeResRect, Matrix.ScaleToFit.CENTER); // map the result rectangle to the new coordinates scaleMatrix.mapRect(resultRect); // create a matrix which scales coordinates of picture size rectangle into the // camera native resolution. scaleMatrix.setRectToRect(pictureRect, nativeResRect, Matrix.ScaleToFit.CENTER); // invert it, so that we get the matrix which downscales the rectangle from // the native resolution to the actual picture size scaleMatrix.invert(scaleMatrix); // and map the result rectangle to the coordinates in the picture size rectangle scaleMatrix.mapRect(resultRect); 

After all these manipulations, resultRect will contain the coordinates of the area inside the image taken by the camera that correspond to exactly the same image that you saw in the preview of your application. You can cut this area from the image using the BitmapRegionDecoder.html # decodeRegion (android.graphics.Rect, android.graphics.BitmapFactory.Options) method.

What is it.

+10
source share

All Articles