99,9% всех ответов на вопрос в заголовке следующие:
При поиске в List<Camera.Size>, предоставленном Camera .Parameters#getSupportedPictureSizes() попробуйте найти размер с тем же соотношением сторон, что и размер предварительного просмотра камеры, который вы установили через Camera.Parameters.html#setPreviewSize(int,int) или как можно ближе.
Это нормально, но что, если я не могу найти размер изображения то же самое соотношение сторон, что и в размере предварительного просмотра (Android не дает вам гарантии, что для каждого размера предварительного просмотра, поддерживаемого камерой, существует размер изображения с тем же соотношением сторон), а все остальные размеры изображения (которые максимально близки) просто растягивают мою фотографию, как в это и это вопросы? Как я могу сделать фотографию с точно таким же соотношением сторон, как и в предварительном просмотре, даже если размер изображения и размер предварительного просмотра установлены в Camera.Parameters имеют разные соотношения сторон?
Ответ 1 · рейтинг 11 · aga
Мы можем узнать об общем подходе к этой проблеме в этом ответе. Короткая цитата:
Мое решение состояло в том, чтобы сначала масштабировать прямоугольник выбора предварительного просмотра до собственного размера изображения камеры. Затем, теперь, когда я знаю, какая область собственного разрешения содержит нужный мне контент, я могу выполнить аналогичную операцию, чтобы затем масштабировать этот прямоугольник в исходном разрешении до меньшего изображения, которое фактически было снято для Camera.Parameters.setPictureSize.
Теперь к самому коду. Самый простой способ выполнить масштабирование - использовать Matrix. Он имеет метод Matrix#setRectToRect(android.graphics.RectF, android.graphics.RectF, android.graphics.Matrix.ScaleToFit), который мы можем использовать следующим образом:
// 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);
После всех этих манипуляций resultRect будет содержать координаты области внутри снимка, сделанного камерой, которые соответствуют точно такому же изображению, которое вы видели в превью вашего приложения. Вы можете вырезать эту область из изображения с помощью BitmapRegionDecoder.html#decodeRegion(android.graphics.Rect, android.graphics.BitmapFactory.Options).
Вот и все.