今天在使用手持终端上自定义照相机的时候发现预览界面会变形
先找一下问题所在:
当我调整预览界面的方向时发现旋转90°能改变这个问题,但是预览界面整体也会横过来,对于页面自定义开发就会变得困难,而且也不是最终把问题解决了,只是绕过去了而已
解决问题:
然后我从网上找了很多相关的资料,最终得到的结果因为设备预览角度和相机宽高与该设备不兼容从而导致的
所以就从这方面下手,最终还是成功了,不多说上代码
解决方法:
首先想初始化SurfaceView
//初始化SurfaceView public void initSurfaceView() { //有一些可以改变相机方向的属性,但是我这里指标不治本 // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//surfaceview不维护自己的缓冲区,等待屏幕渲染引擎将内容推送到用户面前 mSurfaceHolder.addCallback(this); }
监听事件,也是比较简单没有做复杂的逻辑
//创建完成后 @Override public void surfaceCreated(SurfaceHolder holder) { //打开照相机 mPresenter.openCamera(mContext); } //改变完成后 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mSurfaceHolder = holder; } //销毁后 @Override public void surfaceDestroyed(SurfaceHolder holder) { //释放内存 mPresenter.releaseCamera(); }
注意接下来就是重点所在了
//打开照相机 @Override public void openCamera(Context context, SurfaceHolder mSurfaceHolder, SurfaceView mSurfaceView) { mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); try { mCamera.setPreviewDisplay(mSurfaceHolder); } catch (IOException e) { e.printStackTrace(); } // 为了适配部分手机setparams失败的问题,失败则不设置 try { Camera.Parameters parameters = mCamera.getParameters(); Point bestPreviewSizeValue1 = findBestPreviewSizeValue(parameters.getSupportedPreviewSizes()); parameters.setPreviewSize(bestPreviewSizeValue1.x, bestPreviewSizeValue1.y); mCamera.setParameters(parameters); } catch (Exception e) { Log.d("wangc", "set parameters fail"); } //进行横竖屏判断然后对图像进行校正 //如果是竖屏 if (context.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { mCamera.setDisplayOrientation(90); } else {//如果是横屏 mCamera.setDisplayOrientation(0); } //开启预览 mCamera.startPreview(); //如果要实现连续的自动对焦,这一句必须加 mCamera.cancelAutoFocus(); }
得到相应的尺寸
/** * 通过对比得到与宽高比最接近的尺寸(如果有相同尺寸,优先选择) * @return 得到与原宽高比例最接近的尺寸 */ private static Point findBestPreviewSizeValue(List<Camera.Size> sizeList){ int bestX = 0; int bestY = 0; int size = 0; for (Camera.Size nowSize : sizeList){ int newX = nowSize.width; int newY = nowSize.height; int newSize = Math.abs(newX * newX) + Math.abs(newY * newY); float ratio = (float) (newY * 1.0 / newX); if(newSize >= size && ratio != 0.75){//确保图片是16:9 bestX = newX; bestY = newY; size = newSize; }else if(newSize < size){ continue; } } if(bestX > 0 && bestY > 0){ return new Point(bestX,bestY); } return null; }
接下来让我们愉快的开发把
//拍照 @Override public void takePic() { mCamera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { } }); }