如何更改CameraSource大小,如setPreviewSize和PictureSize

时间:2017-12-05 14:41:56

标签: android api camera android-camera vision

这与google vision API有关。 CameraPreview适用于全屏。但是在框中预览相机时图像会失真。

这是我用过的代码。我的问题是预览填满了框,但预览被拉伸,我无法调整cameraPreview的大小。变量CameraPreview是SurfaceView类型。我使用CameraSource来开始预览。有没有办法改变CameraPreview(SurfaceView)的大小并使预览裁剪适合一个盒子?

  cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
            protected List<Camera.Size> mPreviewSizeList;
            protected List<Camera.Size> mPictureSizeList;
            protected Camera.Size mPreviewSize;
            protected Camera.Size mPictureSize;
            protected boolean mSurfaceChanged = false;
            private int mSurfaceChangedCallDepth = 0;
            private int mCenterPosX = -1;
            private int mCenterPosY = 0;
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(ClientIdScannerActivity.this,
                            new String[]{Manifest.permission.CAMERA}, RequestCameraPermissionId);
                    Toast.makeText(ClientIdScannerActivity.this, "The App requires this permission", Toast.LENGTH_SHORT).show();
                    return;
                }
                try {
                    cameraSource.start(cameraPreview.getHolder());
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
                mSurfaceChangedCallDepth++;

             /*   cameraSource.stop();

                Camera.Parameters cameraParams = mCamera.getParameters();

                if (!mSurfaceChanged) {
                    Camera.Size previewSize = determinePreviewSize(cameraWidth, cameraHight);
                    Camera.Size pictureSize = determinePictureSize(previewSize);
                    mPreviewSize = previewSize;
                    mPictureSize = pictureSize;
                    mSurfaceChanged = adjustSurfaceLayoutSize(previewSize,i1, i2);

                    if (mSurfaceChanged && (mSurfaceChangedCallDepth <= 1)) {
                        return;
                    }
                }

                cameraParams.setRotation(270);
                if (UtilFunctions.isTablet()) {
                } else {
                    mCamera.setDisplayOrientation(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? 270 : 90);
                }*/

//            cameraParams.setRotation(270);
//            mCamera.setDisplayOrientation(UtilFunctions.isTablet() ? 90 : 270);

              /*  cameraParams.set("orientation", "portrait");
                //  cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
                cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
                if (cameraParams.getSupportedFocusModes().contains(
                        Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                    cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                }*/

                mSurfaceChanged = false;

                try {
                    if (ActivityCompat.checkSelfPermission(ClientIdScannerActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        // here to request the missing permissions, and then overriding
                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                        //                                          int[] grantResults)
                        // to handle the case where the user grants the permission. See the documentation
                        // for ActivityCompat#requestPermissions for more details.
                        Toast.makeText(ClientIdScannerActivity.this, "App requires Camera permission to scan ID", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    cameraSource.start(cameraPreview.getHolder());
                } catch (Exception e) {
                    // Remove failed size

                    // Reconfigure
                    if (mPreviewSizeList.size() > 0) { // prevent infinite loop
                        surfaceChanged(null, 0, i1, i2);
                    } else {
//                Utils.showToast(CameraNewActivity.this, "Can't start preview", Toast.LENGTH_LONG);
                    }
                }

                mSurfaceChangedCallDepth--;
            }

            protected Camera.Size determinePreviewSize(int reqWidth, int reqHeight) {

                int reqPreviewWidth = 640;//reqHeight; // requested width in terms of camera hardware
                int reqPreviewHeight = 480;// reqWidth; // requested height in terms of camera hardware
                Camera.Size retSize = null;
                for (Camera.Size size : mPreviewSizeList) {
                    if (size.width == reqPreviewWidth && size.height == reqPreviewHeight) {
                        retSize = size;
                    }
                }
                //  retSize = mPreviewSizeList.get(mPreviewSizeList.size()-1);
                return retSize;
            }

            protected Camera.Size determinePictureSize(Camera.Size previewSize) {
                Camera.Size retSize = null;
                for (Camera.Size size : mPictureSizeList) {
                    if (size.equals(previewSize)) {
                        return size;
                    }
                }

                // if the preview size is not supported as a picture size
                float reqRatio = ((float) previewSize.width) / previewSize.height;
                float curRatio, deltaRatio;
                float deltaRatioMin = Float.MAX_VALUE;
                for (Camera.Size size : mPictureSizeList) {
                    curRatio = ((float) size.width) / size.height;
                    deltaRatio = Math.abs(reqRatio - curRatio);
                    if (deltaRatio < deltaRatioMin) {
                        deltaRatioMin = deltaRatio;
                        retSize = size;
                    }
                }

                return retSize;
            }

            protected boolean adjustSurfaceLayoutSize(Camera.Size previewSize,
                                                      int availableWidth, int availableHeight) {

                float tmpLayoutHeight = previewSize.width;
                float tmpLayoutWidth = previewSize.height;

                float factH, factW, fact;
                factH = availableHeight / tmpLayoutHeight;
                factW = availableWidth / tmpLayoutWidth;

//        if (factH < factW) {
//            fact = factH;
//        } else {
                fact = factW;
                //  }

                FrameLayout.LayoutParams layoutParams =(FrameLayout.LayoutParams) cameraPreview.getLayoutParams();
                int layoutHeight = (int) (tmpLayoutHeight * fact);
                int layoutWidth = (int) (tmpLayoutWidth * fact);

                boolean layoutChanged;
                if ((layoutWidth != cameraPreview.getWidth()) || (layoutHeight != cameraPreview.getHeight())) {
                    layoutParams.height = layoutHeight;
                    layoutParams.width = layoutWidth;
                    if (mCenterPosX >= 0) {
                        layoutParams.topMargin = mCenterPosY - (layoutHeight / 2);
                        layoutParams.leftMargin = mCenterPosX - (layoutWidth / 2);
                    }
                    cameraPreview.setLayoutParams(layoutParams); // this will trigger another surfaceChanged invocation.
                    layoutChanged = true;
                } else {
                    layoutChanged = false;
                }

                return layoutChanged;
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                cameraSource.stop();
            }
        });

1 个答案:

答案 0 :(得分:0)

请注意,'全屏'相机预览存在同样的问题。无法保证所选预览大小的宽高比​​足够接近屏幕的宽高比。请在此处查看更多详细信息: Camera Preview Stretched on Few Android Devices

您自然必须选择适合视图的最佳宽度和高度,但这还不够。您必须将预览表面的“悬挂”部分隐藏在某些非透明视图后面。例如,请参阅make a circular preview

另一个重要的事情是始终保持预览和图片尺寸同步。这并不意味着它们必须相同,但宽高比应该是。当宽高比变化以捕捉照片时,某些设备会产生奇怪的效果。