关于JCameraView 录制视频预览时图像拉伸问题

最近项目使用JCameraView录制小视频,发现预览时图像被拉伸了,无奈的我只能下源码查找了下原因了。
最终整合了下,感觉还可以用,特此记录下,希望能帮助更多人。
项目地址:
https://github.com/CJT2325/CameraView

解决方案如下:

JCameraView下

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        float widthSize = mVideoView.getMeasuredWidth();
        float heightSize = mVideoView.getMeasuredHeight();
        if (screenProp == 0) {
            screenProp = heightSize / widthSize;
        }
    }

这个方法获取了videoView的大小,我发现是10802340
当进入CameraInterface匹配分辨率时,找到的最合适的分辨率是720
1440
前者是2340/1080=2.166的比率,而后者是1440/720=2.0的比率,
最终使用2.0的比率来填充2.1的比率的手机时,就会出现拉伸现象,我的是竖屏可以,横过来就拉伸了。
结合网上的说法,参考这篇文章:
https://blog.csdn.net/u012674854/article/details/80239371
我给整合过来。
在JCameraView下新添加方法:

 private void setSuitableParams() {
        if (screenProp > 1.8) { //屏幕的宽高比大于1.8的时候处理
            float previewProp = CameraInterface.getInstance().getPrevewProp();
            if (previewProp == 0 || mVideoView == null) {   //获取的size宽高比
                return;
            }
            int measuredHeight = mVideoView.getMeasuredHeight();
            int measuredWidth = mVideoView.getMeasuredWidth();
            float clacWidth = measuredHeight / previewProp;   //计算出要显示的预览界面的宽度。
            ViewGroup.LayoutParams layoutParams = mVideoView.getLayoutParams();
            if (layoutParams == null) {
                layoutParams = new ViewGroup.LayoutParams((int) clacWidth, measuredHeight);
            }
//            if (clacWidth > 800 && Math.abs(clacWidth - measuredWidth) > clacWidth * 0.1F) {  //计算的宽度大于 800 并且和显示正常的布局的误差超过10%
            layoutParams.width = (int) clacWidth;
//            }
            final ViewGroup.LayoutParams finalLayoutParams = layoutParams;
            mVideoView.post(new Runnable() {
                @Override
                public void run() {
                    if (mVideoView != null && finalLayoutParams != null) {
                        mVideoView.setLayoutParams(finalLayoutParams);
                    }
                }
            });
        }
    }

这里的10%的误差我给屏蔽了,因为我发现,我的就是误差45像素,在10%之内。
在CameraInterface的doStartPreview方法中添加:
prevewProp = previewSize.width / previewSize.height;
获取当前比率。
最后在

@Override
    public void cameraHasOpened() {
        CameraInterface.getInstance().doStartPreview(mVideoView.getHolder(), screenProp);
        setSuitableParams();
    }

启动摄像头后重新绘制下videoView的布局。

        private float prevewProp;
        public float getPrevewProp() {
        return prevewProp;
    }
    public void doStartPreview(SurfaceHolder holder, float screenProp) {
        if (isPreviewing) {
            LogUtil.i("doStartPreview isPreviewing");
        }
        if (this.screenProp < 0) {
            this.screenProp = screenProp;
        }
        if (holder == null) {
            return;
        }
        this.mHolder = holder;
        if (mCamera != null) {
            try {
                mParams = mCamera.getParameters();
                Camera.Size previewSize = CameraParamUtil.getInstance().getPreviewSize(mParams
                        .getSupportedPreviewSizes(), 1000, screenProp);
                Camera.Size pictureSize = CameraParamUtil.getInstance().getPictureSize(mParams
                        .getSupportedPictureSizes(), 1200, screenProp);

                 prevewProp = (float) previewSize.width / (float) previewSize.height;

                mParams.setPreviewSize(previewSize.width, previewSize.height);

                preview_width = previewSize.width;
                preview_height = previewSize.height;

                mParams.setPictureSize(pictureSize.width, pictureSize.height);

                if (CameraParamUtil.getInstance().isSupportedFocusMode(
                        mParams.getSupportedFocusModes(),
                        Camera.Parameters.FOCUS_MODE_AUTO)) {
                    mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                }
                if (CameraParamUtil.getInstance().isSupportedPictureFormats(mParams.getSupportedPictureFormats(),
                        ImageFormat.JPEG)) {
                    mParams.setPictureFormat(ImageFormat.JPEG);
                    mParams.setJpegQuality(100);
                }
                mCamera.setParameters(mParams);
                mParams = mCamera.getParameters();
                mCamera.setPreviewDisplay(holder);  //SurfaceView
                mCamera.setDisplayOrientation(cameraAngle);//浏览角度
                mCamera.setPreviewCallback(this); //每一帧回调
                mCamera.startPreview();//启动浏览
                isPreviewing = true;
                Log.i(TAG, "=== Start Preview ===");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

好了,就这些,希望能帮助有用的人。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值