攝像頭不是全部隨便的(w, h)都可以認識的,因此呢,咱們有了下面這樣的加強版: java
List<Size> mSupportedPreviewSizes; mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.1; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (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); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; }
後來的Sample裏有了這段代碼,看起來強大了很多。然而很是不幸的,首先getSupportedPreviewSizes()這個函數在2.1以後纔有,我一開始是打算用1.6開發的……好吧我改,這個先不說,本身的手機已經刷到2.1了,這個函數的返回值竟然是null?!若是確實想老版本上也用的話,怎麼辦?? ide
有鑑於有軟件能夠達成,因此確定是有方法的!得這麼寫: 函數
public class SupportedSizesReflect { private static Method Parameters_getSupportedPreviewSizes = null; private static Method Parameters_getSupportedPictureSizes = null; static { initCompatibility(); }; private static void initCompatibility() { try { Parameters_getSupportedPreviewSizes = Camera.Parameters.class.getMethod( "getSupportedPreviewSizes", new Class[] {}); Parameters_getSupportedPictureSizes = Camera.Parameters.class.getMethod( "getSupportedPictureSizes", new Class[] {}); } catch (NoSuchMethodException nsme) { nsme.printStackTrace(); Parameters_getSupportedPreviewSizes = Parameters_getSupportedPictureSizes = null; } } /** * Android 2.1以後有效 * @param p * @return Android1.x返回null */ public static List<Size> getSupportedPreviewSizes(Camera.Parameters p) { return getSupportedSizes(p, Parameters_getSupportedPreviewSizes); } public static List<Size> getSupportedPictureSizes(Camera.Parameters p){ return getSupportedSizes(p, Parameters_getSupportedPictureSizes); } @SuppressWarnings("unchecked") private static List<Size> getSupportedSizes(Camera.Parameters p, Method method){ try { if (method != null) { return (List<Size>) method.invoke(p); } else { return null; } } catch (InvocationTargetException ite) { Throwable cause = ite.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else if (cause instanceof Error) { throw (Error) cause; } else { throw new RuntimeException(ite); } } catch (IllegalAccessException ie) { return null; } } }
啊啊~,リフレクションなんか、大嫌い……而後還要用相似這樣的方法調用~ ui
@Override public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { Camera.Parameters params = camera.getParameters(); List<Size> supportedPictureSizes = SupportedSizesReflect.getSupportedPictureSizes(params); List<Size> supportedPreviewSizes = SupportedSizesReflect.getSupportedPreviewSizes(params); if ( supportedPictureSizes != null && supportedPreviewSizes != null && supportedPictureSizes.size() > 0 && supportedPreviewSizes.size() > 0) { //2.x pictureSize = supportedPictureSizes.get(0); int maxSize = 1280; if(maxSize > 0){ for(Size size : supportedPictureSizes){ if(maxSize >= Math.max(size.width,size.height)){ pictureSize = size; break; } } } WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); DisplayMetrics displayMetrics = new DisplayMetrics(); display.getMetrics(displayMetrics); previewSize = getOptimalPreviewSize( supportedPreviewSizes, display.getWidth(), display.getHeight()); params.setPictureSize(pictureSize.width, pictureSize.height); params.setPreviewSize(previewSize.width, previewSize.height); } this.camera.setParameters(params); try { this.camera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } this.camera.startPreview(); }
預覽畫面90°的,2.X後能夠用parameters.set(「rotation」, 「90″),以前的話得寫成parameters.set(「orientation」, 「portrait」)。可是聽說不是全部的機器均可以的…… this