Przekształć dane wyjściowe

W przypadku zastosowania AparatuX dane wyjściowe są dwukierunkowe: bufor i transformacja. informacje. Bufor to tablica bajtów, a informacje o przekształceniu określają sposób powinny zostać przycięte i obrócone przed wyświetleniem użytkownikom. Jak zastosować zależy od formatu bufora.

Robienie zdjęć

W przypadku użycia funkcji ImageCapture przed zapisaniem jest stosowany bufor prostokątny przycinania na dysk, a rotacja zostanie zapisana w danych Exif. Nie ma żadnych dodatkowych wymagane działanie w aplikacji.

Podgląd

W przypadku użycia funkcji Preview informacje o przekształceniu możesz uzyskać przez połączenia SurfaceRequest.setTransformationInfoListener() Po każdej aktualizacji przekształcenia element wywołujący otrzymuje nowy komunikat SurfaceRequest.TransformationInfo obiektu.

Sposób zastosowania informacji o przekształceniu zależy od źródła Surface. Zwykle jest to proste. Jeśli celem jest po prostu wyświetlanie podglądu, użyj PreviewView. PreviewView to widok niestandardowy, który automatycznie obsługuje przekształcenie. Do zaawansowanych zastosowań, gdy trzeba edytować podgląd tak jak w przypadku trybu OpenGL, spójrz na przykładowy kod w podstawowym teście usługi CameraX

Przekształć współrzędne

Innym typowym zadaniem jest praca ze współrzędnymi zamiast z bufora, na przykład jak rysowanie ramki wokół wykrytej twarzy na podglądzie. W takich przypadkach konieczne jest przekształcenie współrzędnych wykrytej twarzy z analizy obrazu na podgląd.

Ten fragment kodu tworzy macierz, która jest mapowana na podstawie analizy obrazu do współrzędnych PreviewView. Aby przekształcić współrzędne (x, y) Matrix, zobacz Matrix.mapPoints()

Kotlin

fun getCorrectionMatrix(imageProxy: ImageProxy, previewView: PreviewView) : Matrix {
   val cropRect = imageProxy.cropRect
   val rotationDegrees = imageProxy.imageInfo.rotationDegrees
   val matrix = Matrix()

   // A float array of the source vertices (crop rect) in clockwise order.
   val source = floatArrayOf(
       cropRect.left.toFloat(),
       cropRect.top.toFloat(),
       cropRect.right.toFloat(),
       cropRect.top.toFloat(),
       cropRect.right.toFloat(),
       cropRect.bottom.toFloat(),
       cropRect.left.toFloat(),
       cropRect.bottom.toFloat()
   )

   // A float array of the destination vertices in clockwise order.
   val destination = floatArrayOf(
       0f,
       0f,
       previewView.width.toFloat(),
       0f,
       previewView.width.toFloat(),
       previewView.height.toFloat(),
       0f,
       previewView.height.toFloat()
   )

   // The destination vertexes need to be shifted based on rotation degrees. The
   // rotation degree represents the clockwise rotation needed to correct the image.

   // Each vertex is represented by 2 float numbers in the vertices array.
   val vertexSize = 2
   // The destination needs to be shifted 1 vertex for every 90° rotation.
   val shiftOffset = rotationDegrees / 90 * vertexSize;
   val tempArray = destination.clone()
   for (toIndex in source.indices) {
       val fromIndex = (toIndex + shiftOffset) % source.size
       destination[toIndex] = tempArray[fromIndex]
   }
   matrix.setPolyToPoly(source, 0, destination, 0, 4)
   return matrix
}

Java

Matrix getMappingMatrix(ImageProxy imageProxy, PreviewView previewView) {
   Rect cropRect = imageProxy.getCropRect();
   int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();
   Matrix matrix = new Matrix();

   // A float array of the source vertices (crop rect) in clockwise order.
   float[] source = {
       cropRect.left,
       cropRect.top,
       cropRect.right,
       cropRect.top,
       cropRect.right,
       cropRect.bottom,
       cropRect.left,
       cropRect.bottom
   };

   // A float array of the destination vertices in clockwise order.
   float[] destination = {
       0f,
       0f,
       previewView.getWidth(),
       0f,
       previewView.getWidth(),
       previewView.getHeight(),
       0f,
       previewView.getHeight()
   };

   // The destination vertexes need to be shifted based on rotation degrees.
   // The rotation degree represents the clockwise rotation needed to correct
   // the image.

   // Each vertex is represented by 2 float numbers in the vertices array.
   int vertexSize = 2;
   // The destination needs to be shifted 1 vertex for every 90° rotation.
   int shiftOffset = rotationDegrees / 90 * vertexSize;
   float[] tempArray = destination.clone();
   for (int toIndex = 0; toIndex < source.length; toIndex++) {
       int fromIndex = (toIndex + shiftOffset) % source.length;
       destination[toIndex] = tempArray[fromIndex];
   }
   matrix.setPolyToPoly(source, 0, destination, 0, 4);
   return matrix;
}