Android用攝像頭的那點破事

攝像頭不是全部隨便的(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

相關文章
相關標籤/搜索