Jetpack CameraX

2024-01-11 20:44
文章标签 jetpack camerax

本文主要是介绍Jetpack CameraX,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • Jetpack CameraX
    • 概述
    • 添加依赖库
    • 使用
      • 预览
      • 拍照
      • 录视频
    • 代码下载
    • 文档

Jetpack CameraX

概述

CameraX 是一个 Jetpack 库,旨在帮助您更轻松地开发相机应用。如果您要开发新应用,我们建议您从 CameraX 开始。它提供了一个一致且易于使用的 API,该 API 适用于绝大多数 Android 设备,并向后兼容 Android 5.0(API 级别 21)。

添加依赖库

// CameraX core library using the camera2 implementation
def camerax_version = "1.2.0-alpha02" //1.2.0-alpha02
// The following line is optional, as the core library is included indirectly by camera-camera2
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
// If you want to additionally use the CameraX Lifecycle library
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
// If you want to additionally use the CameraX VideoCapture library
implementation "androidx.camera:camera-video:${camerax_version}"
// If you want to additionally use the CameraX View class
implementation "androidx.camera:camera-view:${camerax_version}"
// If you want to additionally add CameraX ML Kit Vision Integration
implementation "androidx.camera:camera-mlkit-vision:${camerax_version}"
// If you want to additionally use the CameraX Extensions library
implementation "androidx.camera:camera-extensions:${camerax_version}"

使用

预览

class PictureActivity : BaseActivity() {private lateinit var mBinding: ActivityPictureBindingprivate lateinit var mPreview: Previewprivate lateinit var mCamera: Cameraprivate lateinit var mCameraProvider: ProcessCameraProviderprivate var singleTapDetector: GestureDetector? = nullprivate val mExecutor: Executor by lazy {ContextCompat.getMainExecutor(this)}private var isBack = trueoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)mBinding = ActivityPictureBinding.inflate(layoutInflater)setContentView(mBinding.root)mBinding.root.post {initCameraX()}}private fun initCameraX() {// 请求CameraProviderval cameraProviderFuture = ProcessCameraProvider.getInstance(this)cameraProviderFuture.addListener({mCameraProvider = cameraProviderFuture.get()bindPreview(mCameraProvider, mBinding.previewView)listenGesture()}, mExecutor)}private fun bindPreview(cameraProvider: ProcessCameraProvider, previewView: PreviewView) {// 切换前后摄像头val cameraSelector =if (isBack) CameraSelector.DEFAULT_BACK_CAMERA else CameraSelector.DEFAULT_FRONT_CAMERA// 创建PreviewmPreview = Preview.Builder().build()      // 绑定前确保解除了所有绑定,防止CameraProvider重复绑定到Lifecycle发生异常cameraProvider.unbindAll()// 绑定生命周期mCamera = cameraProvider.bindToLifecycle(this,cameraSelector,mPreview)// 将Preview连接到PreviewViewmPreview.setSurfaceProvider(previewView.surfaceProvider)}/*** 监听手势*/private fun listenGesture() {mBinding.previewView.setOnTouchListener { view, event ->singleTapForFocus(event)true}focusOnPosition((mBinding.previewView.width / 2).toFloat(),(mBinding.previewView.height / 2).toFloat(),)}/*** 根据坐标聚焦*/private fun focusOnPosition(x: Float, y: Float, isShowTapView: Boolean = false) {logE("position: $x - $y")logE("width: ${mBinding.previewView.width}  height: ${mBinding.previewView.height}")val action = FocusMeteringAction.Builder(mBinding.previewView.meteringPointFactory.createPoint(x, y)).build()if (isShowTapView) {showTapView(x.toInt(), y.toInt())}mCamera.cameraControl.startFocusAndMetering(action)}/*** 显示聚焦的图标*/private fun showTapView(x: Int, y: Int) {val imageView = ImageView(this).apply {setImageResource(R.drawable.ic_focus_view)}val popupWindow = PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT).apply {contentView = imageView}val offset = dp2px(50)popupWindow.showAsDropDown(mBinding.previewView, x - offset / 2, y - offset / 2)mBinding.previewView.postDelayed({ popupWindow.dismiss() }, 500L)}/*** 单击聚焦*/private fun singleTapForFocus(event: MotionEvent) {if (singleTapDetector == null) {singleTapDetector = GestureDetector(this@PictureActivity,object : GestureDetector.SimpleOnGestureListener() {override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {focusOnPosition(event.x, event.y, true)return super.onSingleTapConfirmed(e)}})}singleTapDetector!!.onTouchEvent(event)}/*** 前后摄像头切换*/private fun changeCamera() {isBack = !isBackbindPreview(mCameraProvider, mBinding.previewView)}  
}

拍照

// 设置图片拍摄
mImageCapture = ImageCapture.Builder().setTargetRotation(previewView.display.rotation)
//            .setCaptureMode() // 设置拍摄模式
//            .setFlashMode() // 设置闪光模式.build()// 设置图片质量
mImageAnalysis = ImageAnalysis.Builder().setTargetRotation(previewView.display.rotation).setTargetResolution(Size(720, 1440)).setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build()// 绑定生命周期
mCamera = cameraProvider.bindToLifecycle(this,cameraSelector,mPreview,mImageCapture,mImageAnalysis
)
// 拍照
val contentValues = ContentValues().apply {put(MediaStore.MediaColumns.DISPLAY_NAME,"my_capture_${System.currentTimeMillis()}")put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")}
val outputFileOptions = ImageCapture.OutputFileOptions.Builder(contentResolver,MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues
).build()
mImageCapture.takePicture(outputFileOptions,mExecutor,object : ImageCapture.OnImageSavedCallback {override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {val uri = outputFileResults.savedUri ?: returnshowPicture(uri)}override fun onError(exception: ImageCaptureException) {logE("onError: ${exception.imageCaptureError}")}})

录视频

class VideoActivity : BaseActivity() {private lateinit var mBinding: ActivityVideoBindingprivate lateinit var mPreview: Previewprivate lateinit var mCamera: Cameraprivate lateinit var mCameraProvider: ProcessCameraProviderprivate lateinit var mVideoCapture: VideoCaptureprivate val mExecutor: Executor by lazy {ContextCompat.getMainExecutor(mContext)}private var isRecording = falseoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)mBinding = ActivityVideoBinding.inflate(layoutInflater)setContentView(mBinding.root)mBinding.root.post {initCameraX()}mBinding.ivVideo.setOnClickListener {if (!isRecording) startRecordVideo() else stopRecordVideo()}}private fun initCameraX() {val listenableFuture = ProcessCameraProvider.getInstance(this)listenableFuture.addListener({mCameraProvider = listenableFuture.get()bindPreview(mCameraProvider, mBinding.previewView)}, mExecutor)}private fun bindPreview(cameraProvider: ProcessCameraProvider, previewView: PreviewView) {// 设置摄像头val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA// 创建PreviewmPreview = Preview.Builder().build()mVideoCapture = VideoCapture.Builder().setTargetRotation(previewView.display.rotation).setVideoFrameRate(25).setBitRate(3 * 1024 * 1024).build()// 绑定前确保解除了所有绑定,防止CameraProvider重复绑定到Lifecycle发生异常cameraProvider.unbindAll()// 绑定生命周期mCamera = cameraProvider.bindToLifecycle(this,cameraSelector,mPreview,mVideoCapture)// 将Preview连接到PreviewViewmPreview.setSurfaceProvider(previewView.surfaceProvider)}private fun startRecordVideo() {isRecording = truemBinding.tvVideo.text = "停止录制"val contentValues = ContentValues().apply {put(MediaStore.MediaColumns.DISPLAY_NAME, "my_video" + "_" + System.currentTimeMillis())put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4")}val options = VideoCapture.OutputFileOptions.Builder(contentResolver,MediaStore.Video.Media.EXTERNAL_CONTENT_URI,contentValues).build()if (ActivityCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {return}mVideoCapture.startRecording(options,mExecutor,object : VideoCapture.OnVideoSavedCallback {override fun onVideoSaved(outputFileResults: VideoCapture.OutputFileResults) {val uri = outputFileResults.savedUriuri?.let {val path = it.pathpath?.let {showToast("视频保存在:$path")logE("视频保存在:$path")}}}override fun onError(videoCaptureError: Int, message: String, cause: Throwable?) {showToast("保存失败:$message")logE("保存失败:$message")}})}private fun stopRecordVideo() {isRecording = falsemBinding.tvVideo.text = "开始录制"mVideoCapture.stopRecording()}
}

代码下载

文档

https://juejin.cn/post/7267840969605382198

https://juejin.cn/post/6951017751457005576

https://blog.csdn.net/EthanCo/article/details/125603671

https://developer.android.google.cn/media/camera/camerax?hl=zh-cn

这篇关于Jetpack CameraX的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/595650

相关文章

Android JetPack ViewModel 源码解析

是什么? ViewModel 用来存储页面相关的数据,当页面销毁的时候,存储数据也会清楚。但是当页面发生旋转的时候,并不会清楚数据。 怎么用? UserViewModel userViewModel = new ViewModelProvider(this).get(UserViewModel.class); UserViewModel 是自己写的ViewModel,就可以

Android JetPack Lifecycle源码解析

是什么? JetPack Lifecycle是一个页面(Activity/Fragment)生命周期的组件,当你想监听生命周期,那么就可以使用这个组件。 怎么用? 第一种: getLifecycle().addObserver(new LifecycleObserver() {@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)publi

Jetpack架构组件_ViewModel组件_1.简介和示例

1.简介        ViewModel是我们MVVM中的VM层,ViewModel类似于MVP中的P层,它是我们View层和Model层之间的一个桥梁。 1.1 和MVP的P层的主要区别是: (1)ViewModel是与我们Android系统挂钩的,是官方的一个类,MV之间的一个桥梁。 (2)ViewModel还保持数据。 1.2 Android为什么要引入ViewModel?

Android经典实战之CameraX 库性能优化的策略

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 CameraX 库在处理不同分辨率和帧率的视频拍摄时,有哪些性能优化的策略 在使用 CameraX 库处理不同分辨率和帧率的视频拍摄时,性能优化的策略主要包括以下几个方面: 1、 选择合适的分辨率和帧率:在创建 VideoCapture 对象时,可以通过设置分辨率和帧

安卓开发中的Jetpack Compose

本文内容总结自郭神的jetpack compose专栏 ,整理自学,未完持续... 一、了解Jetpack Compose         Compose是一个由Google Android团队官方推出的声明式UI框架,Compose也是属于AndroidX的一部分,它的本质就是用来编写界面以及处理与用户交互相关的逻辑的,来代替传统的View用xml来定义UI的方法。         传统

使用OpenGL预览CameraX摄像头数据

前言 CameraX 是一个 Jetpack 支持库,旨在帮助您简化相机应用的开发工作。笔者看了下网上关于CameraX的资料虽然很多,但是很多基本上都是官网资料的翻版,学习的价值很没有直接看官网的高。 也有些博客介绍了CameraX结合OpenGL渲染的的例子,但好像都建立在Preview类的setOnPreviewOutputUpdateListener这个方法中进行处理,但是笔者更新Ca

jetpack compose的@Preview和自定义主题

1.@Preview @Preview可以在 Android Studio 的预览窗口中实时查看和调试 UI 组件。 基本使用 import androidx.compose.foundation.layout.fillMaxSizeimport androidx.compose.material.MaterialThemeimport androidx.compose.material

jetpack compose 在两个页面间切换

jetpack compose 在两个页面间切换: 创建两个Compose页面:定义两个简单的Composable函数,分别代表两个页面。 import androidx.compose.foundation.layout.Arrangementimport androidx.compose.foundation.layout.Columnimport androidx.compose.

Android开发系列(五)Jetpack Compose之Icon Image

Icon是用于在界面上显示矢量图标的组件。它提供了很多内置的矢量图标,也支持自定义图标。要使用Icon组件,可以通过指定图标资源的名称或引用来创建一个Icon对象。例如,使用Icons.Default.Home来创建一个默认风格的首页图标。可以通过设置图标的大小、颜色、和点击事件等属性来自定义Icon的外观和行为。     Image是用于在界面上显示位图图像的组件。它支持从本地资源、网络

【ai】tx2-nx 查看 jetpack 版本信息及对应的tritonserver

3 jtop nvidia@tx2-nx:~$ jtop[WARN] Board missing UNKNOWN (press CTRL + Click)nvidia@tx2-nx:~$ 点击info 可以看到 jetpack是4.6opencv 是4.1.1 5.1.2 的不适合我 tritonserver2.35.0-jetpack5.1.2-update-2.tgz