我一直在努力让我的自定义相机在Android上活动,但当旋转相机时,表面视图的纵横比变得混乱.

在我的oncreate for the activity中,我设置了framelayout,其中包含显示相机参数的曲面视图.

//FrameLayout that will hold the camera preview
        FrameLayout previewHolder = (FrameLayout) findViewById(R.id.camerapreview);

        //Setting camera's preview size to the best preview size
        Size optimalSize = null;
        camera = getCameraInstance();
        double aspectRatio = 0;
        if(camera != null){
            //Setting the camera's aspect ratio
            Camera.Parameters parameters = camera.getParameters();
            List<Size> sizes = parameters.getSupportedPreviewSizes();
            optimalSize = CameraPreview.getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
            aspectRatio = (float)optimalSize.width/optimalSize.height;
        }

        if(optimalSize!= null){
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int)(getResources().getDisplayMetrics().widthPixels*aspectRatio));
            previewHolder.setLayoutParams(params);
            LayoutParams surfaceParams = new LayoutParams(LayoutParams.MATCH_PARENT, (int)(getResources().getDisplayMetrics().widthPixels*aspectRatio));
            cameraPreview.setLayoutParams(surfaceParams);

        }

        cameraPreview.setCamera(camera);

        //Adding the preview to the holder
        previewHolder.addView(cameraPreview);

然后,在曲面视图中,我设置要显示的相机参数

public void setCamera(Camera camera) {
        if (mCamera == camera) { return; }

        mCamera = camera;

        if (mCamera != null) {
            requestLayout();

            try {
                mCamera.setPreviewDisplay(mHolder);
            } catch (IOException e) {
                e.printStackTrace();
            }


            if(mCamera != null){
                //Setting the camera's aspect ratio
                Camera.Parameters parameters = mCamera.getParameters();
                List<Size> sizes = parameters.getSupportedPreviewSizes();
                Size optimalSize = getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);

                parameters.setPreviewSize(optimalSize.width, optimalSize.height);
                mCamera.setParameters(parameters);
            }

            /*
              Important: Call startPreview() to start updating the preview surface. Preview must 
              be started before you can take a picture.
              */
            mCamera.startPreview();
        }

    }

在此处输入图像描述

你可以看到,当手机旋转时,乐高男会变得更高、更瘦:

How can I ensure that the aspect ratio for my camera view is correct?

推荐答案

I'm using this method -> based on API Demos to get my Preview Size:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio=(double)h / w;

        if (sizes == null) return null;

        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        for (Camera.Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

正如你所见,你必须输入屏幕的宽度和高度.此方法将根据这些值计算屏幕比率,然后从支持的预览大小列表中 Select 最适合您的.在相机对象不为空的地方,使用

mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

然后在onMeasure中,您可以获得如下最佳预览尺寸:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);

        if (mSupportedPreviewSizes != null) {
           mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        }
    }

然后(在我的faces eChanged方法代码中,就像我说的,我使用的是CameraActivity代码的API Demos struct ,您可以在Eclipse中生成它):

Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(parameters);
mCamera.startPreview();

给你一个提示,因为我做的应用和你几乎一样.相机活动的最佳做法是隐藏StatusBar.像Instagram这样的应用程序正在做这件事.它会降低屏幕高度值并更改比率值.在某些设备上获得奇怪的预览大小是可能的(您的SurfaceView将被稍微削减)


为了回答你的问题,如何判断你的预览比例是否正确?然后获取在中设置的参数的高度和宽度:

mCamera.setParameters(parameters);

你设定的比例等于高度/宽度.如果你想让摄像头在屏幕上看起来很好,那么设置为摄像头的参数的高宽比必须与屏幕的高宽比相同(减go 状态栏).

Android相关问答推荐

如何在cordova 中播放html5视频标签?

在Android应用程序上使用Room数据库时,是否可以预先填充数据

使用Kotlin的SD卡

如何解决Android Studio中的in fragment问题

推断的类型是片段,但应为上下文

有人能帮我在应用程序上使用模拟位置时避免被发现吗?我已经反编译并粘贴了一个代码,S小文件

如果我的圆形图像的顶部居中于卡片内部,我如何在其下方画一条弧线?

触发PurchasesUpdatedListener回调时,billingClient.launchBillingFlow之前设置的成员变量丢失

Kotlin为多个控件设置一个侦听器

学习Kotlin问题.无法理解Modifier参数

页面标题未显示在内容页面上

块不起作用,出现 "只有安全的 (?.)... " 错误

如何在Android Studio中删除项目

AirDroid Business 如何能够从屏幕截图中排除覆盖?

在 Compose 中停止键盘将顶部应用栏推离屏幕

在 Kotlin 中设置 startActivity() 时类型不匹配

android xml底部空间大

Android 自动分页如何与 media3 配合使用?

Kotlin 调用带参数的函数 Any is xxx ||任何 yyy 都不起作用

使用 Jetpack Compose 时,如何以简单的方式在 Color.kt 中定义 colored颜色 ?