Как сделать фото того же соотношения сторон, что и в размере превью?

99,9% всех ответов на вопрос в заголовке следующие:

При поиске в List<Camera.Size>, предоставленном Camera .Parameters#getSupportedPictureSizes() попробуйте найти размер с тем же соотношением сторон, что и размер предварительного просмотра камеры, который вы установили через Camera.Parameters.html#setPreviewSize(int,int) или как можно ближе.

Это нормально, но что, если я не могу найти размер изображения то же самое соотношение сторон, что и в размере предварительного просмотра (Android не дает вам гарантии, что для каждого размера предварительного просмотра, поддерживаемого камерой, существует размер изображения с тем же соотношением сторон), а все остальные размеры изображения (которые максимально близки) просто растягивают мою фотографию, как в это и это вопросы? Как я могу сделать фотографию с точно таким же соотношением сторон, как и в предварительном просмотре, даже если размер изображения и размер предварительного просмотра установлены в Camera.Parameters имеют разные соотношения сторон?


person aga    schedule 24.06.2014    source источник


Ответы (1)


Мы можем узнать об общем подходе к этой проблеме в этом ответе. Короткая цитата:

Мое решение состояло в том, чтобы сначала масштабировать прямоугольник выбора предварительного просмотра до собственного размера изображения камеры. Затем, теперь, когда я знаю, какая область собственного разрешения содержит нужный мне контент, я могу выполнить аналогичную операцию, чтобы затем масштабировать этот прямоугольник в исходном разрешении до меньшего изображения, которое фактически было снято для 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).

Вот и все.

person aga    schedule 24.06.2014
comment
Эй, ага, я знаю, что это решение устарело, но, может быть, вы можете помочь - как я могу заставить его работать, когда предварительный просмотр фотографии больше, чем размер экрана? поэтому screenWidth ‹= previewWidth && screenHeight ‹= previewHeight в зависимости от устройства. Спасибо - person Shaked KO; 20.04.2015
comment
Привет. как получить родной ResRect? - person Dima; 25.11.2015
comment
Спасибо. это дало лучшее представление о том, что происходит во всех слоях от сенсора до jpeg. - person Vikram Rao; 14.06.2016