Cámara2 con un SurfaceView

Estoy tratando de obtener el nuevo Camera2 trabajando con un simple SurfaceView y estoy teniendo algunos problemas con la vista previa en vivo. En algunos dispositivos, la imagen se estira de proporciones mientras se ve bien en otros.

He configurado un SurfaceView que programo ajustar para caber el tamaño del tamaño de la secuencia de vista previa.

En Nexus 5 esto se ve bien, pero uno de los dispositivos de Samsung está lejos. También los dispositivos Samsung tienen un borde negro en la parte derecha de la vista previa.

¿Realmente no es posible trabajar con SurfaceView o es el momento de cambiar a TextureView?

Sí, ciertamente es posible. Tenga en cuenta que el SurfaceView y su Surface asociada son dos cosas diferentes, y cada uno puede / debe tener asignado un tamaño.

La Surface es el búfer de memoria real que mantendrá la salida de la cámara, y por lo tanto la configuración de su tamaño dicta el tamaño de la imagen real que obtendrá de cada marco. Para cada formato disponible de la cámara, hay un pequeño conjunto de posibles tamaños (exactos) que puede hacer este búfer.

SurfaceView es lo que hace la visualización de esta imagen cuando está disponible, y básicamente puede ser de cualquier tamaño en su diseño. Estirará sus datos de imagen asociados subyacentes para adaptarse a cualquier tamaño de diseño, pero tenga en cuenta que este tamaño de pantalla es diferente del tamaño de los datos: Android cambiará el tamaño de los datos de la imagen para que se muestren automáticamente. Esto es lo que probablemente está causando su estiramiento.

Por ejemplo, puede crear una SurfaceView de SurfaceView basada en SurfaceView similar a AutoFitTextureView de la camera2basic de la siguiente manera (esto es lo que uso):

 import android.content.Context; import android.util.AttributeSet; import android.view.SurfaceView; public class AutoFitSurfaceView extends SurfaceView { private int mRatioWidth = 0; private int mRatioHeight = 0; public AutoFitSurfaceView(Context context) { this(context, null); } public AutoFitSurfaceView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoFitSurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio * calculated from the parameters. Note that the actual sizes of parameters don't matter, that * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result. * * @param width Relative horizontal size * @param height Relative vertical size */ public void setAspectRatio(int width, int height) { if (width < 0 || height < 0) { throw new IllegalArgumentException("Size cannot be negative."); } mRatioWidth = width; mRatioHeight = height; requestLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (0 == mRatioWidth || 0 == mRatioHeight) { setMeasuredDimension(width, height); } else { if (width < height * mRatioWidth / mRatioHeight) { setMeasuredDimension(width, width * mRatioHeight / mRatioWidth); } else { setMeasuredDimension(height * mRatioWidth / mRatioHeight, height); } } } } 

En los documentos para createCaptureSession se dice

Para dibujar a un SurfaceView: Una vez que se crea la Superfície de SurfaceView, defina el tamaño de Surface con setFixedSize (int, int) como uno de los tamaños devueltos por getOutputSizes (SurfaceHolder.class)

Nunca he trabajado con Camera2 (pero muy interesante en la nueva tecnología) y todo lo que puedo sugerir es seguir las muestras. Y si lo comprueba con cuidado, el ejemplo utiliza un TextureView personalizado, debe intentar copiarlo en su proyecto:

http://developer.android.com/samples/Camera2Basic/src/com.example.android.camera2basic/AutoFitTextureView.html

 /** * A {@link TextureView} that can be adjusted to a specified aspect ratio. */ public class AutoFitTextureView extends TextureView { 

También teniendo en cuenta que entre SurfaceView y TextureView (teóricamente) es sólo que se puede usar como una vista normal en el diseño y el otro "golpea un todo" a través de la jerarquía de vista, y que Camera2 sólo está disponible en API21 + … debería haber No daña la migración a TextureView

  • Se ha abandonado BufferQueue: Al reproducir vídeo con TextureView
  • TextureView vs GLSurfaceView o Cómo utilizar GLSurfaceView con EGL14
  • ¿Cuándo está cerrado el "Consumer Side" de un TextureView?
  • El video de TextureView que se reproduce se vuelve negro después de onPause
  • ¿Es esto posible tener la opinión de la textura para la cámara en forma circular para el androide?
  • ¿Cómo aplicar efectos de video (filtros como sepia, vintage, etc.) en TextureView en android?
  • TextureView con vista previa de la cámara
  • Android SurfaceTexture.detachFromGLContext Error durante detachFromGLContext
  • Escena de OpenGL con fondo transparente + widgets nativos por debajo y por encima
  • ¿Cómo utilizo las clases de "superficie" de Android?
  • Android - Cómo recortar la previsualización de la cámara con TextureView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.