I have a real-time video processing app in Android that captures from camera and display the preview to a TextureView.
The issue is that I want to capture the camera preview at 2k, but screen size is 1080, so TextureView size is max of 1080.
I want to be able to get, TextureView.getBitmap() and get a 2k image, but because TextureView is maxed to the screen size the image is only 1080px.
I found that I could overwrite the TextureView onMeasure() method to force the TextureView size to 2k. This works, however because the screen is 1080, the phone only shows the middle of the 2k image, how to display the whole image?
My 2nd attempt I made the layout size of the TextureView 0 so it was hidden, and added another ImageView to the layout, then from the listener onImageAvailable() I convert the Image to a Bitmap and set it in the ImageView. This works, but is very slow, get a delayed image instead of live camera preview.
I think I need to be able to zoom out the TextureView, or perhaps have 2 texture views and copy from one to the other. But can't get it to work as desired.
Please, any help or suggestions.
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = CameraConnectionFragment.MINIMUM_PREVIEW_SIZE; height = CameraConnectionFragment.MINIMUM_PREVIEW_SIZE; setMeasuredDimension(width, height); }
The code is similar to, https://github.com/miyosuda/TensorFlowAndroidDemo/tree/master/app/src/main/java/org/tensorflow/demo
The camera code is,
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);
}
Camera preview code is,
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!");
}