预览的Nexus 5X帧转换为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();
    }
}

如您所见,我尝试使用该修复程序来捕获图像,但这无济于事,我仍然从预览中获得了一个转动图像。

如果可能的话,我想要一个解决方案,该解决方案试图更改相机的设置。我不想在通过绑定的图像范围内获得图像。

正确理解您的问题后,如果您还没有,我将尝试执行以下操作。我认为您的问题不存在于您的Previewiewcapturesession,而是在您的代码中拍摄照片。

我猜您正在使用cameradevice.template_still_capture模板使用其他caturerequest.builder。

对于此构建器,您必须设置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));

这就是我在应用程序中捕获图像的方式,并且保存的图像正确旋转了!如果这是您的操作方式,我建议您添加代码实际拍照,而不仅仅是预览会话。

希望有帮助!

最新更新