摄像头不是所有随便的(w, h)都能够认识的,所以呢,我们有了下面这样的增强版:
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?!如果确实想老版本上也用的话,怎么办??
有鉴于有软件可以达成,所以肯定是有方法的!得这么写:
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;
}
}
}
啊啊~,リフレクションなんか、大嫌い然后还要用类似这样的方法调用~
@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 )。但是据说不是所有的机器都可以的