Android开发中经常需要获取摄像头所支持的分辨率列表,然而获取的参数列表是List形式,而且每个分辨率并不是按大小进行排列,不方便查看和返回,所以写了一个重新排列并且格式化输出的方法。
Camera.Parameters有三个方法获取分辨率:
获取摄像头支持的视频分辨率列表
getSupportedVideoSizes();
获取摄像头支持的图像分辨率列表
getSupportedPictureSizes();
获取摄像头预览分辨率(一般是预设的推荐分辨率)
getSupportedPreviewSizes();
理论上需要获取预览分辨率和支持分辨率两个值,用来保证设置摄像头的分辨率后不会出现一些玄学概率问题(通常是摄像头推荐的分辨率和最高分辨率的冲突),在实际开发中我用getSupportedVideoSizes()和getSupportedPreviewSizes()死活获取不到值,只能通过getSupportedPictureSizes()拉取列表,获取到的分辨率也是一致的。
需要注意的是,CPU型号也会影响分辨率的获取,同一个摄像头在不同CPU上拉取到的支持分辨率是不一样的,所以还需要对不同CPU机型的摄像头分辨率进行适配。
数据定义
public static List<Camera.Size> supportedVideoSizes;
public static List<Camera.Size> previewSizes;
获取摄像头信息,然后循环取最大的width和height,(最大值一般是List的第一个元素,可以直接get(0)),但是有些摄像头拉去到的list是乱序的,所以对他们进行重新按大小排序,方便取值。width*height就是摄像头的像素,例如500百万像素。
public String getCameraInfo(){
int cameracount = 0;//摄像头数量
Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); //获取摄像头信息
cameracount = Camera.getNumberOfCameras();
Log.i("CameraTest","摄像头数量"+String.valueOf(cameracount));
for(int cameraId=0; cameraId<Camera.getNumberOfCameras(); cameraId++)
{
Camera.getCameraInfo( cameraId, cameraInfo);
Camera camera = Camera.open(cameraId); //开启摄像头获得一个Camera的实例
Camera.Parameters params = camera.getParameters(); //通过getParameters获取参数
supportedVideoSizes = params.getSupportedPictureSizes();
previewSizes = params.getSupportedPreviewSizes();
camera.release();//释放摄像头
//重新排列后设下摄像头预设分辨率在所有分辨率列表中的地址,用以选择最佳分辨率(保证适配不出错)
int index=bestVideoSize(previewSizes.get(0).width);
Log.i("CameraTest", "预览分辨率地址: " + index );
if (null != previewSizes && previewSizes.size() > 0){ //判断是否获取到值,否则会报空对象
Log.i("CameraTest", "摄像头最高分辨率宽: " + String.valueOf(supportedVideoSizes.get(0).width) ); //降序后取最高值,返回的是int类型
Log.i("CameraTest", "摄像头最高分辨率高: " + String.valueOf(supportedVideoSizes.get(0).height) );
Log.i("CameraTest", "摄像头分辨率全部: " + cameraSizeToSting( supportedVideoSizes) );
}else{
Log.i("CameraTest", "没取到值啊什么鬼" );
Log.i("CameraTest", "摄像头预览分辨率: " + String.valueOf(previewSizes.get(0).width) );
}
}
return cameraSizeToSting( supportedVideoSizes );
}
重新排列分辨率列表
//重新排列获取到的分辨率列表
public static int bestVideoSize(int _wid) {
//降序排列
Collections.sort(supportedVideoSizes, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size lhs, Camera.Size rhs) {
if (lhs.width > rhs.width) {
return -1;
} else if (lhs.width == rhs.width) {
return 0;
} else {
return 1;
}
}
});
for (int i = 0; i < supportedVideoSizes.size(); i++) {
if (supportedVideoSizes.get(i).width < _wid) {
return i;
}
}
return 0;
}
格式化输出成常见的宽x高格式
//分辨率格式化输出String值
public static String cameraSizeToSting(Iterable<Camera.Size> sizes)
{
StringBuilder s = new StringBuilder();
for (Camera.Size size : sizes)
{
if (s.length() != 0)
s.append(",\n");
s.append(size.width).append('x').append(size.height);
}
return s.toString();
}
使用完相机之后一定要记得用 Camera.release()来释放相机的实例,否则后续调用相机的请求(系统内其他app或本应用)都会失败,导致Camera.open()方法报错“Failed to connect to camera service”。所以同理,出现这种问题的时候也可以排查系统中其他apps是否正在占用摄像头没有释放。
在Android 6.0版本的摄像头开发中,使用Camera.open()方法时,需要在onCreate()方法中加入下面的权限申请,否则同样会报错"Failed to connect to camera service"
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//android6.0需要加申请权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.CAMERA}, 1);
}
}
}
运行结果如下