Android摄像头preVIEW拉伸 [英] Android Camera Preview Stretched

查看:284
本文介绍了Android摄像头preVIEW拉伸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力让我的自定义相机的活动在Android上,但旋转相机时,表面视图的纵横比被搞砸了。

I've been working on making my custom camera activity on Android, but when rotating the camera, the aspect ratio of the surface view gets messed up.

在我的OnCreate的活动,我将它保存,显示相机的参数表来看的FrameLayout。

In my oncreate for the activity, I set the framelayout which holds the surface view that displays the camera's parameters.

//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);

那么,在表面来看我设置相机的参数显示

Then, in the Surface view I set the camera's parameters to be displayed

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();
        }

    }

您可以看到,乐高增长的人身高和瘦的时候,手机旋转:

You can see that the LEGO man grows taller and skinnier when the phone is rotated:

我怎样才能确保长宽比为我的相机的看法是正确的吗?

推荐答案

我用这个方法 - >基于API演示,让我的preVIEW尺寸:

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;
    }

正如你所看到的,你必须输入宽度和屏幕的高度。基于这样的价值观,然后从支持previewSizes它将从avaliable的人选择最适合你的列表中此方法计算的屏幕比例。获取地方Camera对象不为空使用您的支持previewSize列表

As you can see you have to input width and height of your screen. This method will calculate screen ratio based on those values and then from the list of supportedPreviewSizes it will choose the best for you from avaliable ones. Get your supportedPreviewSize list in place where Camera object isn't null by using

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

然后在onMeasure你可以得到你的最佳previewSize这样的:

And then on in onMeasure you can get your optimal previewSize like that:

@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);
        }
    }

然后(我的code在surfaceChanged方法,就像我说的,我使用的CameraActivity code API演示结构,你可以在Eclipse中生成它):

And then (in my code in surfaceChanged method, like I said I'm using API Demos structure of CameraActivity code, you can generate it in Eclipse):

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

和一个提示你,因为我不喜欢你几乎相同的应用程序。良好做法摄像头活动是隐藏状态栏。类似Instagram的应用程序正在这样做。它减少了屏幕高度值,并改变你的比值。这是可能得到一些奇怪的设备preVIEW尺寸(您SurfaceView将被削减一点点)

And one hint for you, because I did almost the same app like you. Good practice for Camera Activity is to hide StatusBar. Applications like Instagram are doing it. It reduces your screen height value and change your ratio value. It is possible to get strange Preview Sizes on some devices (your SurfaceView will be cut a little)

和回答你的问题,如何检查,如果你的preVIEW比例是正确的?然后得到您所设置的参数,高度和宽度:

And to answer your question, how to check if your preview ratio is correct? Then get height and width of parameters that you set in:

mCamera.setParameters(参数);

mCamera.setParameters(parameters);

您所设定的比等于高度/宽度。如果你想拍照好看屏幕上那么参数设置为摄像头的高度/宽度的比例必须是相同的高度(减去状态栏)屏幕/宽比。

your set ratio is equal to height/width. If you want camera to look good on your screen then height/width ratio of parameters that you set to camera must be the same as height(minus status bar)/width ratio of your screen.

这篇关于Android摄像头preVIEW拉伸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆