总结下个人经验,由于预览尺寸设置不当会导致Camera预览变形,经过一番折腾,发现要先获得Camera支持的尺寸在跟屏幕分辩率进行比较,把最接近尺寸设置为预览尺寸就可以了。
首先获得屏幕宽高
public void getScreenSize() { WindowManager wm = (WindowManager) getSystemService( Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); screenWidth = display.getWidth(); screenHeight = display.getHeight(); }
以下代码简写,在surfaceChanged接口中
@Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { try { //摄像头画面显示在Surface上 if (mCamera != null) { Camera.Parameters parameters = mCamera.getParameters(); List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); int[] a = new int[sizes.size()]; int[] b = new int[sizes.size()]; for (int i = 0; i < sizes.size(); i++) { int supportH = sizes.get(i).height; int supportW = sizes.get(i).width; a[i] = Math.abs(supportW - screenHeight); b[i] = Math.abs(supportH - screenWidth); Log.d(TAG,"supportW:"+supportW+"supportH:"+supportH); } int minW=0,minA=a[0]; for( int i=0; i<a.length; i++){ if(a[i]<=minA){ minW=i; minA=a[i]; } } int minH=0,minB=b[0]; for( int i=0; i<b.length; i++){ if(b[i]<minB){ minH=i; minB=b[i]; } } Log.d(TAG,"result="+sizes.get(minW).width+"x"+sizes.get(minH).height); List<Integer> list = parameters.getSupportedPreviewFrameRates(); parameters.setPreviewSize(sizes.get(minW).width,sizes.get(minH).height); // 设置预览图像大小 parameters.setPreviewFrameRate(list.get(list.size() - 1)); mCamera.setParameters(parameters); mCamera.setDisplayOrientation(90); mCamera.startPreview(); } } catch (Exception e) { if (mCamera != null) mCamera.release(); mCamera = null; } }
这里需要注意的一点是,屏幕的宽高是按照竖屏获取的,a[i] = Math.abs(supportW - screenHeight);,而获得支持的尺寸是按照横屏来说的,
所以这句后面是screenHeight,与之相反。
a、b数组是为了获得最接近屏幕分辩率的支持的尺寸的数组的下标。