相机
调用系统相机
添加权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Android 6.0 以上版本,还需处理动态权限
public class PhotoTools {
public static final int REQUEST_CODE_TAKE_PICTURE = 10001;
public static Uri takePicture(Activity activity,File file){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri imgUri = null;
// 7.0以上版本,必须使用FileProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String authority = activity.getPackageName()+".fileprovider";
imgUri = FileProvider.getUriForFile(activity, authority, file);
} else {
imgUri = Uri.fromFile(file);
}
// 设置拍照后保存的路径
intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
// 设置图片保存的格式
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
activity.startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
return imgUri;
}
}
拍照
File dir = new File(Environment.getExternalStorageDirectory(),"Pictures");
if (!dir.exists()) dir.mkdir();
File image = new File(dir,System.currentTimeMillis()+".jpg");
if (!image.exists()){
try {
image.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d("PhotoTools",image.getAbsolutePath());
PhotoTools.takePicture(MainActivity.this,image);
拍照是否成功
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PhotoTools.REQUEST_CODE_TAKE_PICTURE) {
Log.d("PhotoTools","onActivityResult "+resultCode);
if (resultCode == RESULT_OK) {
Toast.makeText(this, "照片已保存", Toast.LENGTH_LONG).show();
}
}
}
关于系统相机的调用,具体可查看官方文档 拍照
注意,在API 24以上版本,不能直接使用file://型的URI,需使用FileProvider机制,具体参见 设置文件共享
FileProvider 配置文件filepaths.xml的标签:
| 标签 | 对应路径 |
|---|---|
<files-path> |
context.getFilesDir() |
<cache-path> |
context.getCacheDir() |
<external-path> |
Environment.getExternalStorageDirectory() |
<external-files-path> |
context.getExternalFilesDir() |
<external-cache-path> |
context.getExternalCacheDir() |
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external-path" path="Pictures"/>
</paths>
上例中配置的路径,即为Environment.getExternalStorageDirectory()+"/Pictures"
调用相机API

CameraManager:主要用于管理系统摄像头CameraDevice:用于代表一个摄像头。摄像头功能可被分为limit 和full 两个级别,当摄像头处于limited 级别时候,此时Camera2和早期的Camera功能相差不多。其主要承担的任务:
- 通过
CameraDevice.StateCallback监听摄像头的状态(主要包括onOpened、onClosed、onDisconnected、onErro四种状态) - 通过方法
createCaptureSession方法创建会话
- 通过
CameraCharacteristics:描述CameraDevice属性的对象,内部携带大量的相机信息,包含摄像头的正反等CaptureRequest:代表一次捕获请求,包含传感器,镜头,闪光灯等。CaptureRequest.Builder:用于CaptureRequest对象的构造。CameraCaptureSession:请求抓取相机图像帧的会话,主要会建立起一个通道。一个CameraDevice一次只能开启一个会话。 源端是摄像头,另一端是可以是Preview,也可以是ImageReader。需要注意,创建会话是一项耗时的异步操作,可能需要几百毫秒。ImageReader:用于从相机打开的通道中读取需要的格式的原始图像数据,可以设置多个ImageReader。

预览示例:
public class CameraActivity extends Activity implements EasyPermissions.PermissionCallbacks{
private CameraManager mCameraManager;
private String mCameraId;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Handler mHandler;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSurfaceView = findViewById(R.id.preview_view);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCamera();
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
}
});
try {
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
/**
* 查询本机的摄像头情况,此操作无需权限
*/
//遍历设备支持摄像头ID ,比如前置,后置等
String[] cameraIdList = mCameraManager.getCameraIdList();
for (String cameraId : cameraIdList) {
Log.d("CameraActivity", "cameraId:" + cameraId);
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
//拿到摄像头的朝向:前置,后置,或者外部的
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null) {
//后置摄像头
if (facing == CameraCharacteristics.LENS_FACING_BACK) {
mCameraId = cameraId;
} else if (facing == CameraCharacteristics.LENS_FACING_FRONT) {
//前置摄像头
}
}
//是否支持 Camera2 的高级特性
Integer level = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
/**
* 不支持 Camera2 的特性
*/
if (level == null || level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
Toast.makeText(this, "该手机不支持Camera2的高级特性", Toast.LENGTH_SHORT).show();
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void initCamera() {
HandlerThread handlerThread = new HandlerThread("Camera2");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
openCamera();
}
@SuppressLint("MissingPermission")
private void openCamera() {
try {
if (EasyPermissions.hasPermissions(CameraActivity.this, Manifest.permission.CAMERA)) {
Log.d("CameraActivity", "hasPermissions:permission.CAMERA");
mCameraManager.openCamera(mCameraId, new CameraDeviceCallback(), null);
} else {
EasyPermissions.requestPermissions(CameraActivity.this, "该测试需要相机权限", 1, Manifest.permission.CAMERA);
}
} catch (CameraAccessException e) {
Log.e("CameraActivity", "open camera failed." + e.getMessage());
}
}
private void createCameraCaptureSession(CameraDevice device) throws CameraAccessException {
final CaptureRequest.Builder requestBuilder =
device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 添加surface容器,用于预览显示
requestBuilder.addTarget(mSurfaceHolder.getSurface());
device.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface()),
new CameraCaptureSession.StateCallback() {
// 会话开始处理捕获请求
@Override
public void onConfigured(CameraCaptureSession session) {
try {
//设置自动聚焦
requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
//设置自动曝光
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 请求不断重复捕获图像,以此来实现预览
session.setRepeatingRequest(requestBuilder.build(), null, mHandler);
} catch (CameraAccessException e) {
Log.e("CameraActivity", "set preview builder failed." + e.getMessage());
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Toast.makeText(CameraActivity.this, "配置失败", Toast.LENGTH_SHORT).show();
}
}, mHandler);
}
class CameraDeviceCallback extends CameraDevice.StateCallback{
//此时摄像头已打开,可以预览了
@Override
public void onOpened(@NonNull CameraDevice camera) {
try {
createCameraCaptureSession(camera);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
// 摄像头关闭
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
camera.close();
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
camera.close();
}
}
// 动态权限处理。这里调用第三方库EasyPermissions来处理
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
// 授权成功
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
openCamera();
}
// 授权失败
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
/**
* 若是在权限弹窗中,用户选择拒绝权限。并且勾选了'不在提示'
* 这时候,需要跳转到设置界面去,让用户手动开启权限
*/
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this).build().show();
}
}
}
相机预览的基本步骤:
- 获取相机设备信息(
CameraManager) - 创建用于预览的显示区域(
SurfaceView或TextureView) - 打开相机(
openCamera,6.0以上版本需检查动态权限) - 创建Capture会话(
createCaptureSession) - 创建CaptureRequest,并设置条件
- 开始预览(
setRepeatingRequest) - 关闭相机
增加拍照处理的逻辑
// 拍照
private void takePicture() {
if (mCameraDevice == null) return;
// 创建拍照需要的CaptureRequest
final CaptureRequest.Builder captureBuilder;
try {
captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// 将imageReader的surface作为CaptureRequest.Builder的目标
captureBuilder.addTarget(mImageReader.getSurface());
// 自动聚焦、曝光
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 根据设备方向计算设置照片的方向
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getDisplayRotation());
// 先停止预览
mCameraCaptureSession.stopRepeating();
//拍照
CaptureRequest request = captureBuilder.build();
mCameraCaptureSession.capture(request, null, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private int getDisplayRotation(){
// 获取手机方向
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch (rotation){
case Surface.ROTATION_0:
rotation = 0;
break;
case Surface.ROTATION_90:
rotation = 90;
break;
case Surface.ROTATION_180:
rotation = 180;
break;
case Surface.ROTATION_270:
rotation = 270;
break;
}
return (mSensorOrientation - rotation + 360) % 360;
}
// 保存照片
private void saveImage(File file){
FileOutputStream fos = null;
Image image = null;
try {
fos = new FileOutputStream(file);
//获取捕获的照片数据
image = mImageReader.acquireLatestImage();
//拿到所有的 Plane 数组
Image.Plane[] planes = image.getPlanes();
//由于是 JPEG ,数组只有一个元素
ByteBuffer buffer = planes[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.flush();
}catch (Exception e){
Log.e("CameraActivity", ""+e.toString());
}finally {
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (image != null) {
image.close();
}
}
}
修改之前预览的代码
在initCamera方法中增加ImageReader的创建
private void initCamera() {
mHandlerThread = new HandlerThread("Camera2");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mImageReader = ImageReader.newInstance(mSurfaceView.getWidth(), mSurfaceView.getHeight(),
ImageFormat.JPEG, 2);
// 当有图像数据生成时,回调OnImageAvailableListener的onImageAvailable方法
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
File file = new File(Environment.getExternalStorageDirectory(), "take.jpg");
Log.d("CameraActivity", file.getAbsolutePath());
saveImage(file);
}
}, mHandler);
openCamera();
}
此外需注意,在createCameraCaptureSession方法中,增加mImageReader.getSurface()
device.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(),mImageReader.getSurface()),
在查询摄像头信息时,增加摄像头方向的查询代码
mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
拍照时,有一个问题需要特别注意,即设置照片的方向。当我们使用 TextureView 或者 SurfaceView 进行画面预览时,系统会根据设备自然方向、摄像头方向和显示方向自动矫正预览画面的方向,但该矫正规则只适用于显示方向和和设备自然方向一致的情况。而当我们拍照时,则需要手动去处理照片方向的问题。


由于手机摄像头的方向和手机自然方向是不同的,通常相差90度,因此我们拍出的照片就需要进行旋转矫正。总结规律,我们可以归纳出一个计算公式
后置摄像头:
矫正角度 = (摄像头方向 - 手机方向 + 360) % 360
前置摄像头:
矫正角度 = (360 - (摄像头方向 + 手机方向) % 360) % 360
我们在拍照时停止了预览,可以设置监听器,在完成后重新开启预览
mCameraCaptureSession.capture(request, new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
try {
//拍完之后,继续预览
CaptureRequest.Builder request1 = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
request1.addTarget(mSurfaceHolder.getSurface());
mCameraCaptureSession.setRepeatingRequest(request1.build(),null,mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}, mHandler);
最后,还有一个问题需要来探讨一下,即预览、拍照的最佳尺寸选择。
当摄像头获取的图像宽高比与预览区域的宽高比不一致时,画面会变形

解决这种变形问题,无外乎两种方式,一种是让预览区域的TextureView的宽高比和摄像头采集的画面宽高比保持一致,这就要重新调整TextureView的宽高,调用TextureView的setDefaultBufferSize方法设置;另一种则是修改画面绘制在 TextureView 上的方式,类似于剪裁,调用TextureView的setTransform()。(注意,SurfaceView没有这些方法,只能通过布局调整它的宽高)
摄像头采集的画面会包含多组宽高尺寸,这里我们先选出最佳尺寸
// 获取预览最佳尺寸
// 注意surface的宽高和获取的Size的宽高是反过来的
private Size getBestPreviewSize(CameraCharacteristics characteristics,int surfaceWidth, int surfaceHeight) {
Size bestSize = null;
// 获取摄像头支持的所有输出尺寸
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizeArray = map.getOutputSizes(SurfaceHolder.class);
for (Size size : sizeArray) {
Log.d("CameraActivity", "Size: " + size.getWidth()+" - "+size.getHeight());
// 寻找宽高比相等的尺寸
if ((size.getWidth() * surfaceWidth/surfaceHeight) == size.getHeight()) {
bestSize = size;
break;
}
}
if (bestSize == null){
// 寻找宽高差值最小的尺寸
int diffs = Integer.MAX_VALUE;
for (Size s : sizeArray) {
int newDiffs = Math.abs(s.getHeight() - surfaceWidth) + Math.abs(s.getWidth() - surfaceHeight);
if (newDiffs <= diffs) {
bestSize = s;
diffs = newDiffs;
}
}
}
return bestSize;
}
// 然后调用setDefaultBufferSize,设置上述方法返回的Size
// Size bestSize = getBestPreviewSize()
textureView.setDefaultBufferSize(bestSize.getWidth(), bestSize.getHeight());
关于拍照的尺寸,我们可以选择最大分辨率,以获取最佳质量
// 设置图片尺寸,选择最大的分辨率即可
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizes = map.getOutputSizes(ImageFormat.JPEG);
// 自定义一个比较器,选出sizes数组的最大值
Size largest = Collections.max(Arrays.asList(sizes),new CompareSizesByArea());
//设置ImageReader
mImageReader = ImageReader.newInstance(largest.getWidth(),largest.getHeight(),
ImageFormat.JPEG,1);
class CompareSizesByArea implements Comparator<Size> {
@Override
public int compare(Size lhs, Size rhs) {
// 比较Size对象的大小,这里以面积大小来比较
return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
}
}
相机相关参数
createCaptureRequest:该方法需要传入一个模版类型,六种类型如下TEMPLATE_PREVIEW: 配置预览的模板TEMPLATE_STILL_CAPTURE: 用于拍照的模板,图像质量优先于帧速率TEMPLATE_RECORD: 用于视频录制的模板TEMPLATE_VIDEO_SNAPSHOT: 用于视频录制时截图的模板TEMPLATE_ZERO_SHUTTER_LAG: 用于零快门延迟的请求。(在不影响预览帧率的情况下最大化图像质量)TEMPLATE_MANUAL: 手动配置参数的模板,请求中所有的自动控制都是禁用的(自动曝光,自动白平衡、自动焦点)
CameraCharacteristics.get():获取相机的各种参数CaptureRequest.Builder.set():设置指定的参数
CameraCharacteristics 常用的Key值属性:
CameraCharacteristics.LENS_FACING: 获取摄像头方向。前置摄像头(LENS_FACING_FRONT)、后置摄像头(LENS_FACING_BACK)或外置摄像头(LENS_FACING_EXTERNAL)CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL: 获取当前设备支持的相机特性CameraCharacteristics.SENSOR_ORIENTATION: 获取摄像头方向CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP: 获取 StreamConfigurationMap,它是管理摄像头支持的所有输出格式和尺寸CameraCharacteristics.FLASH_INFO_AVAILABLE: 是否支持闪光灯CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT: 同时检测到人脸的数量CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES: 相机支持的人脸检测模式
CaptureRequest 常用设置的属性字段
- 自动对焦
requestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTUR) - 闪光灯
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH) - 拍照时对照片进行旋转
requestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mCameraSensorOrientation) - 人脸检测模式
requestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,CameraCharacteristics.STATISTICS_FACE_DETECT_MODE_SIMPLE)
这里还需要注意,CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL属性用于查询硬件层面支持的Camera2功能的等级,主要分为五个等级:
INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
向后兼容模式, 基本没有额外功能,相当于Camera API接口
INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
除了基本的功能, 还支持一些额外的高级功能, 这些高级功能是LEVEL_FULL的子集
INFO_SUPPORTED_HARDWARE_LEVEL_FULL
支持对每一帧数据进行控制,还支持高速率的图片拍摄
INFO_SUPPORTED_HARDWARE_LEVEL_3
支持YUV后处理和Raw格式图片拍摄, 还支持额外的输出流配置
INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL
API28中加入,对应的是外接摄像头,功能类似LIMITED等级
支持的功能多少排序为:LEGACY < LIMITED < FULL < LEVEL_3
更多属性,可查看官方文档 CameraCharacteristics 或者查看以下附录内容
相机API的使用,可参考Google的2个Java写的Demo工程
附录:
CameraCharacteristics 属性
| 返回值 | 字段名 | 解释 |
|---|---|---|
| int[] | COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES | 异常校正模式 |
| int[] | CONTROL_AE_AVAILABLE_ANTIBANDING_MODES | 自动曝光反带模式列表 |
| int[] | CONTROL_AE_AVAILABLE_MODES | 在自动曝光模式列表 |
| Range | CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES | 帧速率范围表 |
| Rational | CONTROL_AE_COMPENSATION_STEP | 最小的一步,可以改变曝光补偿。 |
| int[] | CONTROL_AF_AVAILABLE_MODES | 自动对焦(AF)列表 |
| int[] | CONTROL_AVAILABLE_EFFECTS | 色彩效果列表 |
| int[] | CONTROL_AVAILABLE_MODES | 控制模式列表 |
| int[] | CONTROL_AVAILABLE_SCENE_MODES | 场景列表模式 |
| int[] | CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES | 视频稳定模式列表 |
| int[] | CONTROL_AWB_AVAILABLE_MODES | 白平衡模式列表 |
| Boolean | CONTROL_AWB_LOCK_AVAILABLE | 相机设备支持MANUAL_POST_PROCESSING或BURST_CAPTURE则为true |
| Integer | CONTROL_MAX_REGIONS_AE | 自动曝光(AE)例程可使用的最大计量区域数。 |
| Integer | CONTROL_MAX_REGIONS_AF | 自动对焦(AF)例程可使用的最大计量区域数。 |
| Integer | CONTROL_MAX_REGIONS_AWB | 自动白平衡(AWB)例程可使用的最大计量区域数。 |
| Range | CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE | 范围的增加 |
| Boolean | DEPTH_DEPTH_IS_EXCLUSIVE | 表示捕获请求是否可以同时针对DEPTH16/depthpointcloud输出,以及正常的颜色输出(例如yuv420888、JPEG或RAW)。 |
| int[] | EDGE_AVAILABLE_EDGE_MODES | 边缘增强模式列表 |
| Boolean | FLASH_INFO_AVAILABLE | 相机是否有闪光灯单元 |
| int[] | HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES | 热像素校正模式列表 |
| Integer | INFO_SUPPORTED_HARDWARE_LEVEL | 相机设备功能的整体分类 |
| Size[] | JPEG_AVAILABLE_THUMBNAIL_SIZES | JPEG缩略图的列表 |
| Integer | LENS_FACING | 摄像机相对于设备屏幕的方向 |
| float[] | LENS_INFO_AVAILABLE_APERTURES | 孔径尺寸值表 |
| float[] | LENS_INFO_AVAILABLE_FILTER_DENSITIES | 中性密度滤波器值表 |
| float[] | LENS_INFO_AVAILABLE_FOCAL_LENGTHS | 焦距列表 |
| int[] | LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION | 光学图像稳定(OIS)模式列表 |
| Integer | LENS_INFO_FOCUS_DISTANCE_CALIBRATION | 镜头聚焦距离校准质量。 |
| Float | LENS_INFO_HYPERFOCAL_DISTANCE | 这个镜头的超焦距。 |
| Float | LENS_INFO_MINIMUM_FOCUS_DISTANCE | 在镜头前的最短距离,可以把焦点集中在镜头的最前面。 |
| float[] | LENS_INTRINSIC_CALIBRATION | 该相机设备的固有校正参数。 |
| float[] | LENS_POSE_ROTATION | 传感器坐标系统的方向。 |
| float[] | LENS_POSE_TRANSLATION | 照相机光学中心的位置。 |
| float[] | LENS_RADIAL_DISTORTION | 修正了该相机装置的径向和切向透镜畸变的校正系数。 |
| int[] | NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES | 噪声抑制方式表 |
| Integer | REPROCESS_MAX_CAPTURE_STALL | 通过重新处理捕获请求引入的最大摄相机捕获管道(在帧数单元中)。 |
| int[] | REQUEST_AVAILABLE_CAPABILITIES | 这个相机设备所宣传的功能是完全支持的。 |
| Integer | REQUEST_MAX_NUM_INPUT_STREAMS | 任何类型的输入流的最大数量,可以同时被摄像机设备配置和使用。 |
| Integer | REQUEST_MAX_NUM_OUTPUT_PROC | 不同类型的输出流的最大数量,可以同时配置和使用一个摄像机设备来处理任何处理的(但不是停滞的)格式。 |
| Integer | REQUEST_MAX_NUM_OUTPUT_PROC_STALLING | 可以对任意处理(和停止)格式的摄像机设备同时配置和使用的不同类型的输出流的最大数量。 |
| Integer | REQUEST_MAX_NUM_OUTPUT_RAW | 不同类型的输出流的最大数量,可以同时配置和使用任何原始格式的摄像机设备。 |
| Integer | REQUEST_PARTIAL_RESULT_COUNT | 定义一个结果将由多少子组件组成。 |
| Byte | REQUEST_PIPELINE_MAX_DEPTH | 指定一个框架必须经历的最大管道阶段的数量,当它暴露在框架下的时候。 |
| Float | SCALER_AVAILABLE_MAX_DIGITAL_ZOOM | 活动区域宽度和作物区域宽度、活动区高度和作物区高度之间的最大比率, |
| Integer | SCALER_CROPPING_TYPE | 这个相机设备所支持的裁剪类型。 |
| StreamConfigurationMap | SCALER_STREAM_CONFIGURATION_MAP | 这个相机设备支持的可用的流配置;还包括最小帧持续时间和每个格式/大小组合的停顿时间。 |
| int[] | SENSOR_AVAILABLE_TEST_PATTERN_MODES | 传感器测试模式模式列表 |
| BlackLevelPattern | SENSOR_BLACK_LEVEL_PATTERN | 每一种颜色过滤装置(CFA)马赛克通道都有固定的黑色电平。 |
| ColorSpaceTransform | SENSOR_CALIBRATION_TRANSFORM1 | 每个设备的校准转换矩阵,从参考传感器的色彩空间映射到实际的设备传感器的色彩空间。 |
| ColorSpaceTransform | SENSOR_CALIBRATION_TRANSFORM2 | 每个设备的校准转换矩阵,从参考传感器的色彩空间映射到实际的设备传感器的色彩空间(这是原始缓冲区数据的色彩空间)。 |
| ColorSpaceTransform | SENSOR_COLOR_TRANSFORM1 | 一个矩阵,它将颜色值从CIE XYZ颜色空间转换为参考传感器颜色空间。 |
| ColorSpaceTransform | SENSOR_COLOR_TRANSFORM2 | 一个矩阵,它将颜色值从CIE XYZ颜色空间转换为参考传感器颜色空间。 |
| ColorSpaceTransform | SENSOR_FORWARD_MATRIX1 | 一个矩阵,它将白色平衡摄像机的颜色从参考传感器的色彩空间转换为带有D50白色点的CIE XYZ颜色空间。 |
| ColorSpaceTransform | SENSOR_FORWARD_MATRIX2 | 一个矩阵,它将白色平衡摄像机的颜色从参考传感器的色彩空间转换为带有D50白色点的CIE XYZ颜色空间。 |
| Size | SENSOR_INFO_PIXEL_ARRAY_SIZE | 全像素数组的尺寸,可能包括黑色校准像素 |
| Rect | SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE | 在应用任何几何畸变校正之前,图像传感器的区域与活动的像素相对应。 |
| Range | SENSOR_INFO_SENSITIVITY_RANGE | 敏感的范围 |
| Integer | SENSOR_INFO_TIMESTAMP_SOURCE | 传感器捕获的时间基准源开始时间戳。 |
| Integer | SENSOR_INFO_WHITE_LEVEL | 传感器的最大原始值输出。 |
| Integer | SENSOR_MAX_ANALOG_SENSITIVITY | 最大灵敏度是通过模拟增益实现的。 |
| Integer | SENSOR_OPTICAL_BLACK_REGIONS | 显示传感器光学屏蔽黑色像素区域的分离矩形的列表。 |
| Rect[] | SENSOR_OPTICAL_BLACK_REGIONS | 显示传感器光学屏蔽黑色像素区域的分离矩形的列表。 |
| Integer | SENSOR_ORIENTATION | 顺时针方向的角度,在设备屏幕上,输出图像需要旋转以保持在本机定位上。 |
| Integer | SENSOR_REFERENCE_ILLUMINANT1 | 标准参考光源用作场景光源 |
| Byte | SENSOR_REFERENCE_ILLUMINANT2 | |
| int[] | SHADING_AVAILABLE_MODES | 透镜阴影模式列表 |
| int[] | STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES | 人脸检测方式 |
| boolean[] | STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES | 热像素映射输出模式列表 |
| int[] | STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES | 镜头阴影贴图输出模式列表 |
| Integer | STATISTICS_INFO_MAX_FACE_COUNT | 同时可检测到的人脸的最大数量。 |
| Integer | SYNC_MAX_LATENCY | 提交请求后(不同于之前的)的最大帧数被提交,并且在结果的状态变为同步之前。 |
| int[] | TONEMAP_AVAILABLE_TONE_MAP_MODES | tonemapping列表模式 |
| Integer | TONEMAP_MAX_CURVE_POINTS |
CaptureRequest 和 CaptureResult 属性
| 返回值 | 字段名 | 解释 |
|---|---|---|
| Boolean | BLACK_LEVEL_LOCK | 黑等级的补偿是否被锁定在当前的值上,或者是自由的变化。 |
| Integer | COLOR_CORRECTION_ABERRATION_MODE | 色差 |
| RggbChannelVector | COLOR_CORRECTION_GAINS | 获得白平衡Bayer的raw color频道 |
| Integer | COLOR_CORRECTION_MODE | 模式控制选择如何将图像数据从传感器的本机颜色转换为线性sRGB颜色。 |
| ColorSpaceTransform | COLOR_CORRECTION_TRANSFORM | 一种颜色变换矩阵,用于从传感器RGB颜色空间转换为输出线性sRGB色彩空间 |
| Integer | CONTROL_AE_ANTIBANDING_MODE | 相机设备的自动曝光算法的反带补偿的理想设置。 |
| Integer | CONTROL_AE_EXPOSURE_COMPENSATION | 调整自动曝光(AE)目标图像亮度。 |
| Integer | CONTROL_AE_LOCK | 是否自动曝光(AE)目前被锁定在最新的计算值上。 |
| Integer | CONTROL_AE_MODE | 相机设备的自动曝光程序所需的模式。 |
| Integer | CONTROL_AE_PRECAPTURE_TRIGGER | 当它处理这个请求时,摄像机设备是否会触发一个预捕获的测量序列。 |
| MeteringRectangle[] | CONTROL_AE_REGIONS | 用于自动曝光调整的计量区域表。 |
| Boolean | CONTROL_AWB_LOCK | 自动白平衡(AWB)是否被锁定在最新的计算值上。 |
| Integer | CONTROL_AWB_MODE | 自动白平衡(AWB)是否正在设置颜色转换字段,以及它的照明目标是什么。 |
| MeteringRectangle[] | CONTROL_AWB_REGIONS | 用于自动平衡光源估计的计量区域的列表。 |
| Integer | CONTROL_CAPTURE_INTENT | 信息到相机设备3A(自动曝光,自动对焦,自动平衡)例程,以帮助相机设备决定最优的3A策略。 |
| Integer | CONTROL_EFFECT_MODE | 一种特殊的颜色效果。 |
| Boolean | CONTROL_ENABLE_ZSL | 允许相机设备为android.control.captureIntent == STILL_CAPTURE 的请求启用零树/延迟模式 |
| Integer | CONTROL_MODE | 3A的整体模式(自动曝光,自动平衡,自动对焦)控制例程。 |
| Integer | CONTROL_POST_RAW_SENSITIVITY_BOOST | 在获取原始传感器数据后,应用于输出图像的额外灵敏度增加。 |
| Integer | CONTROL_SCENE_MODE | 控制哪个场景模式当前是活跃的。 |
| Integer | CONTROL_VIDEO_STABILIZATION_MODE | 视频稳定是否活跃。 |
| Integer | EDGE_MODE | 边缘增强的操作模式。 |
| Integer | FLASH_MODE | 闪存模式 |
| Integer | HOT_PIXEL_MODE | 热像素校正的操作模式。 |
| Location | JPEG_GPS_LOCATION | 在生成图像GPS元数据时使用的位置对象。 |
| Integer | JPEG_ORIENTATION | 一个JPEG图像的朝向。 |
| Byte | JPEG_QUALITY | 最终JPEG图像的压缩质量 |
| Size | JPEG_THUMBNAIL_SIZE | 嵌入的JPEG缩略图的解析。 |
| Float | LENS_APERTURE | 所需的镜头光圈大小,作为透镜焦距与有效孔径的比值。 |
| Float | LENS_FILTER_DENSITY | 镜头中性密度滤光片(s)所需的设置。 |
| Float | LENS_FOCAL_LENGTH | 想要的镜头焦距;用于光学变焦。 |
| Float | LENS_FOCUS_DISTANCE | 从镜头的最前表面测量到最尖锐焦点的距离。 |
| Integer | LENS_OPTICAL_STABILIZATION_MODE | 设置相机设备在拍摄图像时是否使用光学图像稳定(OIS)。 |
| Integer | NOISE_REDUCTION_MODE | 降噪算法的操作模式。 |
| Float | REPROCESS_EFFECTIVE_EXPOSURE_FACTOR | 在进行再加工前,应用处理的应用程序处理的暴露时间增加了。 |
| Rect | SCALER_CROP_REGION | 传感器所需要的区域来读取这个捕获(拍某个形状的设置) |
| Long | SENSOR_EXPOSURE_TIME | 持续每一个像素都暴露在光中。 |
| Long | SENSOR_FRAME_DURATION | 从帧曝光开始到下一个帧曝光的持续时间。 |
| Integer | SENSOR_SENSITIVITY | 处理前的传感器数据的增益。 |
| int[] | SENSOR_TEST_PATTERN_DATA | 当android.sensor.testPatternMode是 SOLID_COLOR,一个pixel[R, G_even, G_odd, B]提供测试模式的像素 |
| Integer | SENSOR_TEST_PATTERN_MODE | 当启用时,传感器会发送一个测试模式,而不是从摄像机中进行真实的曝光。 |
| Integer | SHADING_MODE | 镜头阴影校正的质量应用于图像数据。 |
| Integer | STATISTICS_FACE_DETECT_MODE | 人脸检测装置的工作模式。 |
| Boolean | STATISTICS_HOT_PIXEL_MAP_MODE | 热像素映射生成的操作模式。 |
| Integer | STATISTICS_LENS_SHADING_MAP_MODE | 摄像机设备是否会输出结果元数据中的镜头着色图。 |
| TonemapCurve | TONEMAP_CURVE | 当android.tonemap.mode 是CONTRAST_CURVE时,使用音调/对比度/伽玛曲线 |
| Float | ONEMAP_GAMMA | android.tonemap.mode 是GAMMA_VALUE时,使用Tonemapping曲线。tonemap曲线将定义如下公式:OUT=pow(在1.0/gamma中)输入的像素值被缩放到范围0.0,1.0,pow是能量函数,而伽玛是这个键所指定的伽马值。 |
| Integer | TONEMAP_MODE | 高级全球对比/γ/ tonemapping控制。 |
| Integer | TONEMAP_PRESET_CURVE | android.tonemap.mode 是 PRESET_CURVE时,使用Tonemapping曲线。tonemap曲线将由指定的标准定义。 |
公众号“编程之路从0到1”