Possiamo conoscere l'approccio generale a questo problema in this answer. Breve citazione:
La mia soluzione era di ridimensionare in primo luogo il rettangolo di selezione dell'anteprima alla dimensione dell'immagine nativa della telecamera. Quindi, ora che so quale area della risoluzione nativa contiene il contenuto che voglio, posso eseguire un'operazione simile per ridimensionare quel rettangolo sulla risoluzione nativa per l'immagine più piccola che è stata effettivamente catturata per Camera.Parameters.setPictureSize.
Ora, al codice effettivo. Il modo più semplice per eseguire il ridimensionamento è utilizzare Matrix. Ha il metodo Matrix#setRectToRect(android.graphics.RectF, android.graphics.RectF, android.graphics.Matrix.ScaleToFit) che possiamo usare in questo modo:
// 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);
Dopo tutte queste manipolazioni del resultRect
conterrà le coordinate della zona all'interno della foto scattata dalla fotocamera, che corrispondono alla esattamente la stessa immagine che hai visto nell'anteprima della tua app. È possibile tagliare quest'area dall'immagine con il metodo BitmapRegionDecoder.html#decodeRegion(android.graphics.Rect, android.graphics.BitmapFactory.Options).
E questo è tutto.
Ehi, bene, so che questa soluzione è vecchia ma forse puoi aiutarti - come posso farlo funzionare quando l'anteprima della foto è * più grande * delle dimensioni dello schermo? quindi screenWidth <= previewWidth && screenHeight <= previewHeight a seconda del dispositivo. Grazie –
Ehi. come si ottiene nativeResRect? – Dima
@aga dove dovrei inserire questo codice? Grazie – JayVDiyk