【问题标题】:Android Camera2 Preview is rotated 90deg while in LandscapeAndroid Camera2 Preview 在横向时旋转了 90 度
【发布时间】:2015-12-30 20:30:36
【问题描述】:

我在关注youtube tutorial,试图学习 Camera2 API。当然,我在开发自己的应用程序的同时也在学习这一点。教程和我的应用程序之间的一个不一致之处在于,教程仅在我的应用程序必须处于横向模式时才将相机设为纵向模式。

我目前能够查看相机的预览,但当我的应用处于横向或水平状态时,相机预览看起来旋转了 90 度。几乎感觉我可以旋转 TextureView,但这似乎不正确,就像我拍照时,它会旋转不正确。

下面是与图片大小有关的代码(整个代码很长)

private void setupCamera(int width, int height) {
    CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    try {
        CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(camera_id);
        StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
        mPreviewSize = getPreferredPreviewSize(map.getOutputSizes(SurfaceTexture.class), width, height);
        mCameraId = camera_id;
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}


//TODO Look for a way to make this horizontal
private Size getPreferredPreviewSize(Size[] mapSizes, int width, int height) {
    List<Size> collectorSizes = new ArrayList<>();
    for (Size option : mapSizes) {
        if (width > height) { //If the screen is in landscape
            Toast.makeText(getApplicationContext(), "Screen is Landscape", Toast.LENGTH_SHORT).show();
            if (option.getWidth() > width && option.getHeight() > height) {
                collectorSizes.add(option);
            }
        } else { //if the screen is in portrait
            Toast.makeText(getApplicationContext(), "Screen is Portrait", Toast.LENGTH_SHORT).show();
            if (option.getWidth() > height && option.getHeight() > width) {
                collectorSizes.add(option);
            }
        }
    }
    if (collectorSizes.size() > 0) {
        return Collections.min(collectorSizes, new Comparator<Size>() {
            @Override
            public int compare(Size lhs, Size rhs) {
                return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getWidth() + rhs.getHeight());
            }
        });
    }

    return mapSizes[0];
}
private void openCamera() {
    CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    try {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, null);
    } catch (CameraAccessException e){
        e.printStackTrace();
    }
}

private void createCameraPreviewSession() {
    try {
        SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
        surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        Surface previewSurface = new Surface(surfaceTexture);
        mPreviewCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        mPreviewCaptureRequestBuilder.addTarget(previewSurface);
        mCameraDevice.createCaptureSession(Arrays.asList(previewSurface),
                new CameraCaptureSession.StateCallback() {
                    @Override
                    public void onConfigured(CameraCaptureSession session) {
                        if(mCameraDevice == null){
                            return;
                        }
                        try {
                            mPreviewCaptureRequest = mPreviewCaptureRequestBuilder.build();
                            mCameraCaptureSession = session;
                            mCameraCaptureSession.setRepeatingRequest(mPreviewCaptureRequest, mSessionCaptureCallback, null);
                        } catch (CameraAccessException e){
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onConfigureFailed(CameraCaptureSession session) {
                        Toast.makeText(getApplicationContext(), "Preview Session Failed", Toast.LENGTH_SHORT).show();
                    }
                }, null);
    } catch (CameraAccessException e){
        e.printStackTrace();
    }
}

我一直在使用getPreferredPreviewSize 方法,但我并不理解它应该理解的程度。我不确定最后的compare 使用lhsrhs

我错过了一些简单的旋转吗?

【问题讨论】:

标签: android android-camera2


【解决方案1】:
private void transformImage (int width, int height)
{
    if(mPreviewSize == null || mTextureView == null)
    {
        return;
    }
    Matrix matrix = new Matrix();
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    RectF textureRectF = new RectF(0,0,width,height);
    RectF previewRectF = new RectF(0,0,mPreviewSize.getHeight(),mPreviewSize.getWidth());
    float centerX = textureRectF.centerX();
    float centery = textureRectF.centerY();

    if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270)
    {}
    else if(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270)
    {
        previewRectF.offset(centerX - previewRectF.centerX(),centery-previewRectF.centerY());
        matrix.setRectToRect(textureRectF,previewRectF,Matrix.ScaleToFit.FILL);
        float scale = Math.max((float)width / mPreviewSize.getWidth(),(float)height/ mPreviewSize.getHeight());

        matrix.postScale(scale,scale,centerX,centery);
        matrix.postRotate(90*(rotation-2),centerX,centery);
        mTextureView.setTransform(matrix );

    }

【讨论】:

  • 所以基本上你修复了显示问题,而相机仍然返回 ImageReader.OnImageAvailableListener 中旋转 90 度的字节
  • 我使用 SurfaceTexture 没有任何视图(TextureView,SurfaceTexture),那么如何为 SurfaceTexture 修复它?
  • 哇,感谢您的解决方案,我已经为此工作了几个小时!效果很好!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 2013-10-21
  • 1970-01-01
  • 2012-04-06
相关资源
最近更新 更多