Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android摄像头采集选Camera1还是Camera2?

Android摄像头采集选Camera1还是Camera2?

原创
作者头像
音视频牛哥
发布于 2024-08-08 03:11:31
发布于 2024-08-08 03:11:31
3640
举报

​Camera1还是Camera2?

好多开发者纠结,Android平台采集摄像头,到底是用Camera1还是Camera2?实际上,Camera1和Camera2分别对应相机API1和相机API2。Android 5.0开始,已经弃用了Camera API1,新平台重点开发Camera API2,Camera API1 会逐渐被淘汰。Camera API2 框架为应用提供更接近底层的相机控件,包括高效的零复制连拍/视频流以及曝光、增益、白平衡增益、颜色转换、去噪、锐化等方面的每帧控件。

Camera2 相对Camera1有哪些优势?

1. 更灵活的相机控制

  • 细粒度参数调整:Camera2 API提供了更多的相机参数和配置选项,开发者可以更精确地控制相机的焦距、曝光时间、ISO感光度、白平衡等,以满足不同场景下的需求。
  • 多摄像头支持:能够同时管理和控制多个相机设备,包括前置摄像头、后置摄像头以及其他可用的摄像头,提高了系统的灵活性和扩展性。

2. 更高的性能

  • 异步操作:Camera2 API使用异步操作模式,减少了对UI线程的阻塞,提高了应用的响应速度和流畅性。
  • 并发访问:支持并发访问和操作多个相机设备,提高了相机的利用率和整体性能。

3. 更好的图像处理能力

  • RAW图像捕获:支持原生的RAW图像捕获和处理,开发者可以获取到相机传感器的原始数据,进行更高质量的图像处理和分析。
  • 实时预览和后处理:提供实时的图像预览和后处理功能,有助于开发者实现更丰富的图像效果。

4. 更好的适配性和扩展性

  • 统一的接口和架构:Camera2 API提供了更统一的接口和更清晰的架构,便于开发者进行相机功能的开发和适配。
  • 功能扩展:允许开发者通过CameraCharacteristics和CaptureRequest等接口获取和设置摄像头的各种功能和参数,支持自定义功能的开发。

5. 广泛的应用场景

  • 相机应用开发:Camera2 API提供了丰富的相机控制接口,可以用于开发各种相机应用,如拍照、录像、实时滤镜等。
  • 视频通话和实时视频应用:支持高质量的视频捕获和处理,适用于视频通话、视频会议等实时视频应用。
  • 计算机视觉和图像处理:结合OpenCV等图像处理库,可以进行实时的图像分析、特征提取、目标识别等计算机视觉任务。

如何使用Camera2进行相机操作

使用Android的Camera2 API来进行相机操作,包括预览、拍照等功能,是一个相对复杂但功能强大的过程。以下是一个基本的步骤指南,帮助你开始使用Camera2 API:

1. 添加权限

首先,你需要在AndroidManifest.xml文件中添加必要的权限,以便应用能够访问设备的相机。至少需要添加相机权限:

代码语言:java
AI代码解释
复制
<uses-permission android:name="android.permission.CAMERA"/>

如果你的应用还需要录制视频或音频,还需要添加相应的权限:

代码语言:java
AI代码解释
复制
<uses-permission android:name="android.permission.RECORD_AUDIO"/>  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
<uses-feature android:name="android.hardware.camera" android:required="true"/>  
<uses-feature android:name="android.hardware.camera.autofocus"/>

需要注意的是,从Android 6.0(API 级别 23)开始,需要在运行时请求这些权限,而不是仅仅在清单文件中声明。

2. 初始化CameraManager

在你的Activity或Fragment中,首先需要获取CameraManager的实例,这个类是用于管理设备上的相机资源:

代码语言:java
AI代码解释
复制
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

3. 获取相机ID

使用CameraManagergetCameraIdList()方法获取设备上所有可用的相机列表,并选择一个相机ID进行后续操作。通常,后置摄像头的ID是"0",前置摄像头的ID是"1",但这不是绝对的,需要根据实际情况判断:

代码语言:java
AI代码解释
复制
try {  
    String[] cameraIdList = cameraManager.getCameraIdList();  
    for (String cameraId : cameraIdList) {  
        CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);  
        // 根据需要选择合适的相机,例如选择后置摄像头  
        if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {  
            // 选择后置摄像头  
            break;  
        }  
    }  
} catch (CameraAccessException e) {  
    e.printStackTrace();  
}

4. 打开相机

使用CameraManageropenCamera()方法打开选定的相机。这个方法是异步的,并且需要一个CameraDevice.StateCallback来接收相机打开的结果:

代码语言:java
AI代码解释
复制
cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {  
    @Override  
    public void onOpened(@NonNull CameraDevice cameraDevice) {  
        // 相机打开成功,可以进行后续操作  
    }  
  
    @Override  
    public void onDisconnected(@NonNull CameraDevice cameraDevice) {  
        // 相机断开连接  
    }  
  
    @Override  
    public void onError(@NonNull CameraDevice cameraDevice, int error) {  
        // 打开相机发生错误  
    }  
}, null);

5. 创建CameraCaptureSession

一旦相机成功打开,你需要创建一个CameraCaptureSession来进行预览、拍照等操作。这个过程也是异步的,并且需要设置Surface来接收相机数据(如TextureView或SurfaceView):

代码语言:java
AI代码解释
复制
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {  
    @Override  
    public void onConfigured(@NonNull CameraCaptureSession session) {  
        // 会话创建成功,可以开始预览或拍照  
    }  
  
    @Override  
    public void onConfigureFailed(@NonNull CameraCaptureSession session) {  
        // 会话配置失败  
    }  
}, null);

6. 预览和拍照

CameraCaptureSession配置成功后,你可以通过调用setRepeatingRequest()方法来开始预览,并通过调用capture()方法来拍照。这些操作都需要CaptureRequest对象,该对象描述了捕获请求的各种参数:

代码语言:java
AI代码解释
复制
CaptureRequest.Builder previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);  
// 设置预览的参数...  
previewRequestBuilder.addTarget(surface);  
  
// 预览  
cameraCaptureSession.setRepeatingRequest(previewRequestBuilder.build(), null, null);  
  
// 拍照  
CaptureRequest.Builder captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);  
// 设置拍照的参数...  
captureRequestBuilder.addTarget(imageReader.getSurface());  
cameraCaptureSession.capture(captureRequestBuilder.build(), captureCallback, null);

7. 释放资源

当相机不再需要时,你应该及时释放相关资源,避免内存泄漏等问题。

如何从Camera1和Camera2获取原始数据?

我们在做Android平台RTMP推送、轻量级RTSP服务、实时录像和GB28181设备对接模块的时候,都需要用到摄像头采集,早期,我们提供了Camera1的采集demo,后面碎渣Camera2的优势越来越明显,高版本设备已成主流,目前一般建议采用Camera2的采集。

先说针对Camera1的采集和数据投递处理:

代码语言:java
AI代码解释
复制
/*
 * CameraPublishActivity.java
 * Author: daniusdk.com
 * WeChat: xinsheng120
 */
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
	frameCount++;
	if (frameCount % 3000 == 0) {
		Log.i("OnPre", "gc+");
		System.gc();
		Log.i("OnPre", "gc-");
	}

	if (data == null) {
		Parameters params = camera.getParameters();
		Size size = params.getPreviewSize();
		int bufferSize = (((size.width | 0x1f) + 1) * size.height * ImageFormat.getBitsPerPixel(params.getPreviewFormat())) / 8;
		camera.addCallbackBuffer(new byte[bufferSize]);
	} else {
		if (isRTSPPublisherRunning || isPushingRtmp || isRecording || isPushingRtsp) {
			if (1 == video_opt_) {
				 
				libPublisher.SmartPublisherOnCaptureVideoData(publisherHandle, data, data.length, currentCameraType, currentOrigentation);

			} else if (3 == video_opt_) {
				int w = videoWidth, h = videoHeight;
				int y_stride = videoWidth, uv_stride = videoWidth;
				int y_offset = 0, uv_offset = videoWidth * videoHeight;
				int is_vertical_flip = 0, is_horizontal_flip = 0;
				int rotation_degree = 0;

				// 镜像只用在前置摄像头场景下
				if (is_mirror && FRONT == currentCameraType) {
					// 竖屏, (垂直翻转->顺时旋转270度)等价于(顺时旋转旋转270度->水平翻转)
					if (PORTRAIT == currentOrigentation)
						is_vertical_flip = 1;
					else
						is_horizontal_flip = 1;
				}

				if (PORTRAIT == currentOrigentation) {
					if (BACK == currentCameraType)
						rotation_degree = 90;
					else
						rotation_degree = 270;
				} else if (LANDSCAPE_LEFT_HOME_KEY == currentOrigentation) {
					rotation_degree = 180;
				}

				int scale_w = 0, scale_h = 0, scale_filter_mode = 0;

				libPublisher.PostLayerImageNV21ByteArray(publisherHandle, 0, 0, 0,
						data, y_offset, y_stride, data, uv_offset, uv_stride, w, h,
						is_vertical_flip, is_horizontal_flip, scale_w, scale_h, scale_filter_mode, rotation_degree);
			}
		}

		camera.addCallbackBuffer(data);
	}
}

再说针对Camera2的数据投递处理:

代码语言:java
AI代码解释
复制
/*
 * Camera2Activity.java
 * Author: daniusdk.com
 * WeChat: xinsheng120
 */
@Override
public void onCameraImageData(Image image) {
	Image.Plane[] planes = image.getPlanes();

	int w = image.getWidth(), h = image.getHeight();
	int y_offset = 0, u_offset = 0, v_offset = 0;

	int scale_w = 0, scale_h = 0, scale_filter_mode = 0;
	scale_filter_mode = 3;

	int rotation_degree = cameraImageRotationDegree_;
	if (rotation_degree < 0) {
		Log.i(TAG, "onCameraImageData rotation_degree < 0, may need to set orientation_ to 0, 90, 180 or 270");
		return;
	}

	for (LibPublisherWrapper i : publisher_array_)
		i.PostLayerImageYUV420888ByteBuffer(0, 0, 0,
			planes[0].getBuffer(), y_offset, planes[0].getRowStride(),
			planes[1].getBuffer(), u_offset, planes[1].getRowStride(),
			planes[2].getBuffer(), v_offset, planes[2].getRowStride(), planes[1].getPixelStride(),
			w, h, 0, 0,
			scale_w, scale_h, scale_filter_mode, rotation_degree);

}

总结

Android Camera2 API控制更灵活,性能、图像处理能力优异、适配性和扩展性也好,在版本支持的前提下,一般建议采用Camera2实现摄像头采集技术诉求,以上是Camera1和Camera2技术扫盲和技术探讨,感兴趣的开发者,可以单独跟我沟通探讨。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android Camera2 与 Camera API技术探究和RAW数据采集
Android Camera2 是 Android 系统中用于相机操作的一套高级应用程序接口(API),它取代了之前的 Camera API。以下是关于 Android Camera2 的一些主要信息:
音视频牛哥
2024/10/01
7110
如何实现RTMP推送Android Camera2数据
在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。
音视频牛哥
2020/04/05
1.6K0
Android平台如何采集摄像头数据并实现低延迟RTMP推送
2015年,我们发布了第一版的Android平台RTMP摄像头|屏幕直播推送模块,几经迭代,功能强大、性能优异,在前些年几乎已经是业内延迟体验和口碑最好的RTMP模块了(毫秒级延迟,低延迟模式下100多毫秒)。鉴于我们侧重于传统行业音视频直播方案,我们从以下几个维度,介绍下Android平台RTMP摄像头采集推送模块的使用场景。
音视频牛哥
2024/11/20
3530
Android平台GB28181设备接入模块摄像头采集方向不对怎么办?
我们在做Android平台GB28181设备接入模块的时候,有开发者提到这样的诉求:他们的智能头盔、执法记录仪等设备,采集到的图像,是旋转了90、180甚至270°的,设备本身无法针对图像做翻转或者旋转操作,问我们这种情况下需要如何处理?
音视频牛哥
2022/12/17
5420
Android平台GB28181设备接入模块摄像头采集方向不对怎么办?
Android平台实现Camera2数据推送到RTMP服务器
在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。
音视频牛哥
2021/03/02
1.4K0
如何实现Android平台GB28181设备对接Camera2数据
在写如何实现Android平台GB28181设备对接Camera2数据说明之前,我在前两年的blog就有针对camera2的RTMP直播推送模块做过技术分享:
音视频牛哥
2022/09/27
7360
如何实现Android平台GB28181设备对接Camera2数据
Android Camera2
从 Android 5.0 开始,Google 引入了一套全新的相机框架 Camera2(android.hardware.camera2)并且废弃了旧的相机框架 Camera1(android.hardware.Camera)。作为一个专门从事相机应用开发的开发者来说,这一刻我等了太久了,Camera1 那寥寥无几的 API 和极差的灵活性早已不能满足日益复杂的相机功能开发。Camera2 的出现给相机应用程序带来了巨大的变革,因为它的目的是为了给应用层提供更多的相机控制权限,从而构建出更高质量的相机应用程序。本文是 Camera2 教程的开篇作,本章将介绍以下几个内容:
ppchao
2020/12/01
2.3K0
Android Camera2
Android Camera2详解
Camera API2是Google从Android5.0开始推出的配合HAL3使用的一套新架构,相比于API1,对应用层开发者而言开放了更多的自主控制权,主要特性包括:
雪月清
2020/06/23
2.8K0
Android平台摄像头麦克风视音频采集录像之MediaRecorder还是SmartPublisher
在 Android 中录制摄像头采集的数据到 MP4 文件,我们可以用系统自带的MediaRecorder,也可以用第三方成熟的摄像头采集录制库,本文就两种方案,做个大概的梳理。
音视频牛哥
2024/11/21
2580
Android平台摄像头麦克风视音频采集录像之MediaRecorder还是SmartPublisher
Android Camera2 API 同时使用前后摄像头预览
不久前,我承担了从运行Android的设备的前后摄像头获取同步提要的任务。 像往常一样,我去了Stack Overflow,然后去了GitHub,然后去了其他博客,才意识到我可能独自一人。 难过的感觉吧?
字节流动
2022/09/26
3.4K0
Android Camera2 API 同时使用前后摄像头预览
关于Camera性能优化的一些建议
上一篇文章主要介绍Camera的基本功能,我们在做相机应用的时候,除了相机的基本功能,还有一个非常重要的点,就是性能不能查,有几个方面:预览不能卡顿、拍照速度要快、录制视频不能卡。
马上就说
2022/05/25
2.7K0
关于Camera性能优化的一些建议
Android相机应用基本功能实现
Camera2引用了管道的概念将安卓设备和摄像头之间联通起来,系统向摄像头发送 Capture 请求,而摄像头会返回 CameraMetadata。这一切建立在一个叫作 CameraCaptureSession 的会话中。
Abalone
2022/07/14
2.2K1
Android相机应用基本功能实现
Android Camera开发序列:Camera2 API 的简单描述和调用(预览、拍照、录像
Android 5.1 以后,添加了Camera2 的API,能够满足更多操纵camera的场景。当然,相对应camera1的调用,也变的复杂一点。
小驰行动派
2021/04/19
2K0
Android平台音视频RTMP推送|GB28181对接之动态水印设计
随着移动单兵、智能车载、智慧安防、智能家居、工业仿真、GB28281技术对接等行业的发展,现场已经不再限于采集到视频数据编码打包发送或对接到流媒体服务端,大多场景对视频水印的要求越来越高,从之前的固定位置静态文字水印、png水印等慢慢过渡到动态水印需求。
音视频牛哥
2022/05/25
6250
Android平台音视频RTMP推送|GB28181对接之动态水印设计
音视频直播技术--Android视频采集(Camera2)
今天为大家介绍一下如何在 Android 上进行视频采集。在 Android 系统下有两套 API 可以进行视频采集,它们是 Camera 和 Camera2 。Camera是以前老的 API ,从 Android 5.0(21)之后就已经放弃了。我今天主要给大家介绍一下如何使用 Camera2 进行视频的采集。原码可以在这里获取
音视频_李超
2020/04/02
2.2K0
一篇文章带你了解Android 最新Camera框架
这篇文章主要分下面几点来展开讲解: 1)Android 最新Camera 整体框架; 2)Android Camera2 和HAL3 的基本了解; 3)Camera2 介绍; (本文所写的内容基于Android 9.0)
小驰行动派
2021/04/01
1.9K0
2016级android在线测试15-图像 camera2
1. ImageView类用于显示各种图像,例如:图标、图片,下面对于ImageView类加载图片方法的描述错误的是()
达达前端
2022/04/29
5770
Android多媒体之Camera2的相关操作
零、前言 Android 5.0+ (API 21) Camera过时.png ---->[源码里让我们用camera2] * @deprecated We recommend using t
张风捷特烈
2019/02/25
3K0
Android多媒体之Camera2的相关操作
Android平台GB28181接入端如何对接UVC摄像头?
我们在对接Android平台GB28181接入的时候,有公司提出这样的需求,除了采集执法记录仪摄像头自带的数据外,还想通过执法记录仪采集外接UVC摄像头。
音视频牛哥
2022/11/01
8380
Android平台GB28181设备接入模块如何对接NV21、YV12、RGB、YUV等外部数据
我们在对接Android平台GB28181设备接入模块的开发者时,遇到这样的场景,除了Android设备(如执法记录仪、智能安全帽等)自带的camera或camera2前后摄像头数据外,还有些场景是需要外部编码前或编码后数据,比如对接OTG类似的外置数据源,如NV12、NV21、YV12、RGB或YUV等格式,这里做个简单的汇总。
音视频牛哥
2023/05/25
3440
Android平台GB28181设备接入模块如何对接NV21、YV12、RGB、YUV等外部数据
推荐阅读
相关推荐
Android Camera2 与 Camera API技术探究和RAW数据采集
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档