虽然前文说道Android在5.0之后就推出了Camera2 API,但是各个厂家的基本未适配,导致目前市场上大部分机型使用的仍然是Camera1 API。
PS:Android 9.0 Google强制要求各个平台厂商(高通/MTK/华为等)支持Camera2,不再兼容Camera1。
Camera API是Android非常古老的API,Google在5.0推出Camera2后就再也没有更新Camera。相比于Camera2来说,Camera API使用非常简单,由于这套框架使用很久了所以稳定性和兼容性还是值得信赖的。另外Camera API只提供基本的功能,其曝光/白平衡/曝光基本无法调节,这是相对于Camera2来说比较弱的地方。
有一点需要注意的是:
Camera设备是独占,也就是说你的APP在使用Camera设备的话,其它应用就没法使用。
所以要求在APP切换到后台时需要关闭Camera设备,重入时在重新打开。
Camera可以说是底层相机设备的映射,所有对相机设备的操作都是通过Camera这个类完成。
常用方法:
保存Camera设备支持的数据,允许用户设置响应的参数(主要是图像大小、格式、预览FPS等)。
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
打开Camera比较简单,需要注意两件事:
public static final int CAMERA_FACING_BACK = 0;
public static final int CAMERA_FACING_FRONT = 1;
try {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) {
int numberOfCameras = Camera.getNumberOfCameras();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == facing) {
mDefaultCameraID = i;
mFacing = facing;
}
}
}
stopPreview();
if (mCameraDevice != null)
mCameraDevice.release();
if (mDefaultCameraID >= 0) {
mCameraDevice = Camera.open(mDefaultCameraID);
} else {
mCameraDevice = Camera.open();
mFacing = Camera.CameraInfo.CAMERA_FACING_BACK; //default: back facing
}
mRotation = setOrientationDegrees(0);
TELogUtil.d(TAG, "Camera rotation = " + mRotation);
} catch (Exception e) {
TELogUtil.e(TAG, "Open Camera Failed!");
e.printStackTrace();
mCameraDevice = null;
return false;
}
Camera打开后可以配置 Camera.Parameters:
以设置图像大小的操作顺序为例:
param = camera.getParameters();
List prevSizes = params.getSupportedPreviewSizes();
prevSize = getBestMatchSize(prevSizes, desireSize);
params.setPreviewSize(prevSize.width, prevSize.height);
camera.setParameters(params);
常用的配置项:
//图像格式
mParams.setPictureFormat(ImageFormat.NV21);
//图像分辨率
mParams.setPreviewSize(prevSz.width, prevSz.height);
//预览帧率
mParams.setPreviewFrameRate(30);
//对焦方式
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
Camera的输出支持多种方式:
下面是SurfaceTexture输出代码示例:
public synchronized void startPreview(SurfaceTexture texture) {
TELogUtil.i(TAG, "Camera startPreview...");
if (mIsPreviewing) {
TELogUtil.w(TAG, "Camera is previewing...");
// stopPreview();
return;
}
if (mCameraDevice != null) {
try {
mCameraDevice.setPreviewTexture(texture);
mCameraDevice.startPreview();
mIsPreviewing = true;
} catch (Exception e) {
e.printStackTrace();
TELogUtil.e(TAG, "startPreview: Error " + e.getMessage());
mIsPreviewing = false;
try {
mCameraDevice.release();
} catch (Exception e2) {
e2.printStackTrace();
}
mCameraDevice = null;
}
}
}
mCameraDevice.stopPreview();
mCameraDevice.close()