Tengo una aplicación de procesamiento de video en tiempo real en Android que captura desde la cámara y muestra la vista previa en un TextureView.
El problema es que quiero capturar la vista previa de la cámara a 2k, pero el tamaño de la pantalla es 1080, por lo que el tamaño de TextureView es un máximo de 1080.
Quiero poder obtener TextureView.getBitmap() y obtener una imagen de 2k, pero debido a que TextureView está maximizado al tamaño de la pantalla, la imagen es solo de 1080 px.
Descubrí que podía sobrescribir el método TextureView onMeasure() para forzar el tamaño de TextureView a 2k. Esto funciona, sin embargo, debido a que la pantalla es 1080, el teléfono solo muestra la mitad de la imagen de 2k, ¿cómo mostrar la imagen completa?
Mi segundo intento, hice el tamaño de diseño de TextureView 0 para que estuviera oculto, y agregué otro ImageView al diseño, luego, desde el oyente onImageAvailable (), convierto la imagen en un mapa de bits y lo configuro en ImageView. Esto funciona, pero es muy lento, obtiene una imagen retrasada en lugar de una vista previa de la cámara en vivo.
Creo que necesito poder alejar el TextureView, o quizás tener 2 vistas de textura y copiar de una a la otra. Pero no puedo hacer que funcione como se desea.
Por favor, cualquier ayuda o sugerencia.
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); ancho = CameraConnectionFragment.MINIMUM_PREVIEW_SIZE; altura = CameraConnectionFragment.MINIMUM_PREVIEW_SIZE; setMeasuredDimension(ancho, alto); }
El código es similar a https://github.com/miyosuda/TensorFlowAndroidDemo/tree/master/app/src/main/java/org/tensorflow/demo
El código de la cámara es,
private void openCamera(final int width, final int height) {
setUpCameraOutputs(width, height);
configureTransform(width, height);
final Activity activity = getActivity();
final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
manager.openCamera(cameraId, stateCallback, backgroundHandler);
}
El código de vista previa de la cámara es,
private void createCameraPreviewSession() {
try {
final SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
// This is the output Surface we need to start preview.
final Surface surface = new Surface(texture);
// We set up a CaptureRequest.Builder with the output Surface.
previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(surface);
// Create the reader for the preview frames.
previewReader =
ImageReader.newInstance(
previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);
previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);
previewRequestBuilder.addTarget(previewReader.getSurface());
zoom(zoom, activity, false);
// Here, we create a CameraCaptureSession for camera preview.
cameraDevice.createCaptureSession(
Arrays.asList(surface, previewReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(final CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == cameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
captureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
previewRequestBuilder.set(
CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Flash is automatically enabled when necessary.
previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
if (isTorchOn) {
previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
} else {
previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
}
// Finally, we start displaying the camera preview.
previewRequest = previewRequestBuilder.build();
captureSession.setRepeatingRequest(previewRequest, captureCallback, backgroundHandler);
} catch (final CameraAccessException exception) {
LOGGER.e(exception, "Exception!");
} catch (Exception exception) {
Log.wtf("Camera preview", exception);
}
}
},
null);
} catch (final Exception e) {
LOGGER.e(e, "Exception!");
}