Android摄像头预览拉伸

文章标签: android
2015-1-1 9:44:41     人阅读    

android操作相机,我自定义了android 相机,当时当手机旋转后摄像机的宽度和高度比例出现问题,错乱了

我在oncreate活动,主要是设置布局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();
 
        }



    }

您可以看到,在旋转的时候 LEGO man 越来越高和苗条

我怎样才能确保我的相机视图的长宽比是正确的吗?

处理方法


我以前使用这个方法

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


正如你所看到的,你必须输入你的屏幕的宽度和高度。 该方法将基于这些值,然后计算屏幕比例从supportedPreviewSizes列表中它会为你选择最好的。 让你supportedPreviewSize列表中使用相机对象不为空
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();


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

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


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

Camera.Parameters parameters = mCamera.getParameters();

parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

mCamera.setParameters(parameters);

mCamera.startPreview();


给你一个提示,你是想法对的,我做过和你这个一模一样的应用程序。 隐藏状态栏才能在最好的展示摄像效果。 应用程序像Instagram这样做。 它能减少你的屏幕高度值和改变你的比例值。 可以得到一些设备上的奇怪的预览大小(SurfaceView将减少一点)

回答你的问题,如何检查如果你预览比率是正确的吗? 然后得到高度和宽度的参数设置:
mCamera.setParameters(参数);


原文地址:http://www.itmmd.com/201501/423.html
该文章由 萌萌的IT人 整理发布,转载须标明出处。

是什么好:@SuppressLint还是@TargetApi ?   上一篇
下一篇  试图从DCIM中获取图片时候出现的奇怪问题
精彩回复
我要追加问题,请求站长解决!
姓名:       

《程序员app》专门为程序员量身定做!