预览中的 Nexus 5x 帧已转为 Camera2
Nexus 5x Frames from preview are turned Camera2
我尝试在 Android 中对预览的当前帧进行一些图像处理。
对于其他所有智能手机,它都运行良好。但现在,我必须让 Nexus 5x 可以访问该应用程序。
我从预览中得到了一个 180 度旋转的图像。我该如何解决?
这是我设置相机和预览的代码:
private void resetCamera(int width, int height){
Log.d(TAG, "Reset Camera!");
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
mSensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
continue;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mImageReader = ImageReader.newInstance(width,
height,
ImageFormat.YUV_420_888,
10);
mImageReader.setOnImageAvailableListener(mOnImageAvailableTrack,
mBackgroundHandler);
mPreviewSize = getPreferredPreviewSize(map.getOutputSizes(SurfaceTexture.class), width, height);
mCameraId = cameraId;
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
预览:
private void createTrackingPreviewSession(){
try{
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
mPreviewCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewCaptureBuilder.addTarget(previewSurface);
mPreviewCaptureBuilder.addTarget(mImageReader.getSurface());
int rotation = getWindowManager().getDefaultDisplay().getRotation();
mPreviewCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION,
getOrientation(rotation));
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback(){
@Override
public void onConfigured(CameraCaptureSession session) {
if(mCameraDevice == null){
return;
}
try{
Toast.makeText(getApplicationContext(), "Create Tracking Session", Toast.LENGTH_SHORT).show();
mPreviewCapture = mPreviewCaptureBuilder.build();
mCaptureSession = session;
mCaptureSession.setRepeatingRequest(
mPreviewCapture,
mSessionCaptureCallback,
mBackgroundHandler
);
} catch(CameraAccessException e){
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Toast.makeText(
getApplicationContext(),
"create Camera session failed!",
Toast.LENGTH_SHORT
).show();
}
}, null);
} catch(CameraAccessException e){
e.printStackTrace();
}
}
如您所见,我尝试使用该修复程序来捕获图像,但它并没有帮助我仍然从预览中获得经过转换的图像。
如果可能的话,我想要一个尝试更改相机设置的解决方案。通过绑定的ImageReader获取Image后不想自己转
在正确理解您的问题后,我会尝试执行以下操作(如果您还没有这样做的话)。我认为你的问题不在于你的previewCaptureSession,而是在于你拍照的代码。
我猜你正确地使用了另一个 CaptureRequest.Builder 和 CameraDevice.TEMPLATE_STILL_CAPTURE 模板。
对于此生成器,您必须设置 JPEG 方向。正如我在评论中所说,一些相机设备有 90° 和其他 270° 旋转。
要设置正确的方向,请执行以下两个代码段。
private static SparseIntArray ORIENTATIONS = new SparseIntArray();
static{
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
private int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation){
int sensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
deviceOrientation = ORIENTATIONS.get(deviceOrientation);
return (sensorOrientation + deviceOrientation + 360) % 360;
}
或者使用你自己的逻辑/实现。
对于用于捕获图像的 captureRequestBuilder,按如下方式设置 JPEG_ORIENTATION:
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, sensorToDevice(cameraCharacteristics, rotation));
这就是我在我的应用程序中捕捉图像的方式,我保存的图像被正确旋转了!
如果您是这样做的,我建议您添加代码以实际拍照,而不仅仅是您的预览会话。
希望对您有所帮助!
我尝试在 Android 中对预览的当前帧进行一些图像处理。 对于其他所有智能手机,它都运行良好。但现在,我必须让 Nexus 5x 可以访问该应用程序。
我从预览中得到了一个 180 度旋转的图像。我该如何解决? 这是我设置相机和预览的代码:
private void resetCamera(int width, int height){
Log.d(TAG, "Reset Camera!");
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
mSensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
continue;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mImageReader = ImageReader.newInstance(width,
height,
ImageFormat.YUV_420_888,
10);
mImageReader.setOnImageAvailableListener(mOnImageAvailableTrack,
mBackgroundHandler);
mPreviewSize = getPreferredPreviewSize(map.getOutputSizes(SurfaceTexture.class), width, height);
mCameraId = cameraId;
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
预览:
private void createTrackingPreviewSession(){
try{
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
mPreviewCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewCaptureBuilder.addTarget(previewSurface);
mPreviewCaptureBuilder.addTarget(mImageReader.getSurface());
int rotation = getWindowManager().getDefaultDisplay().getRotation();
mPreviewCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION,
getOrientation(rotation));
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback(){
@Override
public void onConfigured(CameraCaptureSession session) {
if(mCameraDevice == null){
return;
}
try{
Toast.makeText(getApplicationContext(), "Create Tracking Session", Toast.LENGTH_SHORT).show();
mPreviewCapture = mPreviewCaptureBuilder.build();
mCaptureSession = session;
mCaptureSession.setRepeatingRequest(
mPreviewCapture,
mSessionCaptureCallback,
mBackgroundHandler
);
} catch(CameraAccessException e){
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Toast.makeText(
getApplicationContext(),
"create Camera session failed!",
Toast.LENGTH_SHORT
).show();
}
}, null);
} catch(CameraAccessException e){
e.printStackTrace();
}
}
如您所见,我尝试使用该修复程序来捕获图像,但它并没有帮助我仍然从预览中获得经过转换的图像。
如果可能的话,我想要一个尝试更改相机设置的解决方案。通过绑定的ImageReader获取Image后不想自己转
在正确理解您的问题后,我会尝试执行以下操作(如果您还没有这样做的话)。我认为你的问题不在于你的previewCaptureSession,而是在于你拍照的代码。
我猜你正确地使用了另一个 CaptureRequest.Builder 和 CameraDevice.TEMPLATE_STILL_CAPTURE 模板。
对于此生成器,您必须设置 JPEG 方向。正如我在评论中所说,一些相机设备有 90° 和其他 270° 旋转。
要设置正确的方向,请执行以下两个代码段。
private static SparseIntArray ORIENTATIONS = new SparseIntArray();
static{
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
private int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation){
int sensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
deviceOrientation = ORIENTATIONS.get(deviceOrientation);
return (sensorOrientation + deviceOrientation + 360) % 360;
}
或者使用你自己的逻辑/实现。
对于用于捕获图像的 captureRequestBuilder,按如下方式设置 JPEG_ORIENTATION:
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, sensorToDevice(cameraCharacteristics, rotation));
这就是我在我的应用程序中捕捉图像的方式,我保存的图像被正确旋转了! 如果您是这样做的,我建议您添加代码以实际拍照,而不仅仅是您的预览会话。
希望对您有所帮助!