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

[亡魂溺海] 提交于 2019-12-03 14:20:29
aga

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

My solution was to first scale the preview selection rectangle to the native camera picture size. Then, now that I know which area of the native resolution contains the content I want, I can do a similar operation to then scale that rectangle on the native resolution to the smaller picture that was actually captured per Camera.Parameters.setPictureSize.

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

// Here previewRect is a rectangle which holds the camera's preview size,
// pictureRect and nativeResRect hold the camera's 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's 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's 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 the resultRect will hold the coordinates of area inside the picture taken by the camera which correspond to the exactly the same image you've seen in the preview of your app. You can cut this area from the picture by the BitmapRegionDecoder.html#decodeRegion(android.graphics.Rect, android.graphics.BitmapFactory.Options) method.

And that's it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!