在 Jetpack Compose 中使用 CameraX示例

在使用Jetpack Compose开发安卓应用,当在学习使用CameraX组件时发现官方提供的教程不是Compose的。教程地址如下:
https://developer.android.com/codelabs/camerax-getting-started?hl=zh-cn#1
与是我就记录一下,简单的示例。

内容参考:
https://medium.com/@deepugeorge2007travel/mastering-camerax-in-jetpack-compose-a-comprehensive-guide-for-android-developers-92ec3591a189
在这里插入图片描述

依赖

build.gradle中增加以下内容:

dependencies {// Camerax implementationdef cameraxVersion = "1.3.1"implementation ("androidx.camera:camera-core:${cameraxVersion}")implementation ("androidx.camera:camera-camera2:${cameraxVersion}")implementation ("androidx.camera:camera-view:${cameraxVersion}")implementation ("androidx.camera:camera-lifecycle:$cameraxVersion")// Camerax implementation
}

权限

修改文件CmrXTutorial/app/src/main/AndroidManifest.xml
增加以下内容:

<uses-featureandroid:name="android.hardware.camera"android:required="false" />
<uses-permission android:name="android.permission.CAMERA"/>

修改完以后形如:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><uses-featureandroid:name="android.hardware.camera"android:required="false" /><uses-permission android:name="android.permission.CAMERA"/><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"...略...</application>
</manifest>

cmrxtutorial/composables/Camerax.kt

代码如下:

package com.android.example.cmrxtutorial.composablesimport android.content.ContentValues
import android.content.Context
import android.os.Build
import android.provider.MediaStore
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine@Composable
fun CameraPreviewScreen() {val lensFacing = CameraSelector.LENS_FACING_BACKval lifecycleOwner = LocalLifecycleOwner.currentval context = LocalContext.currentval preview = Preview.Builder().build()val previewView = remember {PreviewView(context)}val cameraxSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()val imageCapture = remember {ImageCapture.Builder().build()}LaunchedEffect(lensFacing) {val cameraProvider = context.getCameraProvider()cameraProvider.unbindAll()cameraProvider.bindToLifecycle(lifecycleOwner, cameraxSelector, preview, imageCapture)preview.setSurfaceProvider(previewView.surfaceProvider)}Box(contentAlignment = Alignment.BottomCenter, modifier = Modifier.fillMaxSize()) {AndroidView({ previewView }, modifier = Modifier.fillMaxSize())Button(onClick = { captureImage(imageCapture, context) }) {Text(text = "Capture Image")}}
}private fun captureImage(imageCapture: ImageCapture, context: Context) {val name = "CameraxImage.jpeg"val contentValues = ContentValues().apply {put(MediaStore.MediaColumns.DISPLAY_NAME, name)put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX-Image")}}val outputOptions = ImageCapture.OutputFileOptions.Builder(context.contentResolver,MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues).build()imageCapture.takePicture(outputOptions,ContextCompat.getMainExecutor(context),object : ImageCapture.OnImageSavedCallback {override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {println("Successs")}override fun onError(exception: ImageCaptureException) {println("Failed $exception")}})
}private suspend fun Context.getCameraProvider(): ProcessCameraProvider =suspendCoroutine { continuation ->ProcessCameraProvider.getInstance(this).also { cameraProvider ->cameraProvider.addListener({continuation.resume(cameraProvider.get())}, ContextCompat.getMainExecutor(this))}}

cmrxtutorial/MainActivity.kt

代码如下:

package com.android.example.cmrxtutorialimport android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.content.ContextCompat
import com.android.example.cmrxtutorial.composables.CameraPreviewScreen
import com.android.example.cmrxtutorial.ui.theme.CmrXTutorialThemeclass MainActivity : ComponentActivity() {private val cameraPermissionRequest =registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->if (isGranted) {setCameraPreview()} else {// Camera permission denied}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)when (PackageManager.PERMISSION_GRANTED) {ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA) -> {setCameraPreview()}else -> {cameraPermissionRequest.launch(Manifest.permission.CAMERA)}}}private fun setCameraPreview() {setContent {CmrXTutorialTheme {// A surface container using the 'background' color from the themeSurface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background) {CameraPreviewScreen()}}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3269727.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

吴恩达的TranslationAgent学习

TranslationAgent构成 整个[TranslationAgent (github.com)]在流程上分为短文本的一次性翻译和长文本的分chunk翻译&#xff08;按照Token进行划分&#xff09;。 但是不论长文本翻译还是短文本翻译&#xff0c;总体流程遵循执行、纠正再执行的逻辑循环实现。 这种按照自省思路…

基于JSP的电子商城系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSPJavaB/S架构 工具&#xff1a;Eclipse、Tomcat 系统展示 首页 管理员功能界面 用户功能界面 医…

Kylin 入门教程

Apache Kylin 是一个开源的分布式数据仓库和 OLAP(在线分析处理)引擎,旨在提供亚秒级查询响应时间,即使在处理超大规模数据集时也是如此。Kylin 可以有效地将原始数据预计算为多维数据立方体(Cube),并利用这些预计算结果来提供快速查询。本文将带你从基础知识到操作实践…

项目管理工具-Maven-创建一个mavenweb项目

文章目录 IDEA开发maven项目依赖范围 IDEA开发maven项目 点击NewProject&#xff0c;填写项目名字Name为javaWeb-maven&#xff0c;填写项目的存储地址&#xff0c;选择Archetype为org.apache.maven.archetypes:maven-archetype-webapp&#xff0c;然后再点击Create&#xff0…

Android WebViewClient 的 `shouldOverrideUrlLoading` 方法

简介 在Android开发中&#xff0c;WebView是一个强大的工具&#xff0c;可以在你的应用中显示网页内容。了解 WebViewClient 中的 shouldOverrideUrlLoading 方法是至关重要的&#xff0c;因为这个方法允许你控制 URL 在 WebView 中的处理方式。 在本文中&#xff0c;我们将详…

基于FFmpeg和SDL的音视频解码播放的实现过程与相关细节

目录 1、视频播放器原理 2、FFMPEG解码 2.1 FFMPEG库 2.2、数据类型 2.3、解码 2.3.1、接口函数 2.3.2、解码流程 3、SDL播放 3.1、接口函数 3.2、视频播放 3.3、音频播放 4、音视频的同步 4.1、获取音频的播放时间戳 4.2、获取当前视频帧时间戳 4.3、获取视…

OZON打开哈萨克斯坦市场,OZON测试开通哈萨克斯坦市场中国产品

在全球化日益深入的今天&#xff0c;跨境电商成为了连接不同国家和地区消费者的重要桥梁。2024年7月26日&#xff0c;Ozon Global宣布了一项重大扩展计划&#xff0c;正式将中国卖家的销售版图拓展至哈萨克斯坦市场&#xff0c;为中国企业打开了新的增长机遇之门。 OZON哈萨克斯…

实现共模噪声电流相互抵消的方法

共模传导路径中噪声电流相互抵消&#xff0c;从而使总的共模电流减小&#xff0c; 终达到降噪的目的。目前为实现共模噪声电流相互抵消&#xff0c;主要是采用动点电容抵消法。 动点电容抵消法原理 动点电容抵消法就是选取合适的动点&#xff0c;添加原副边跨接电容&#xff0c…

【Leetcode】二十、记忆化搜索:零钱兑换

文章目录 1、记忆化搜索2、leetcode509&#xff1a;斐波那契数列3、leetcode322&#xff1a;零钱兑换 1、记忆化搜索 也叫备忘录&#xff0c;即把已经计算过的结果存下来&#xff0c;下次再遇到&#xff0c;就直接取&#xff0c;不用重新计算。目的是以减少重复计算。 以前面提…

深度强化学习 ②(DRL)

参考视频&#xff1a;&#x1f4fa;王树森教授深度强化学习 前言&#xff1a; 最近在学习深度强化学习&#xff0c;学的一知半解&#x1f622;&#x1f622;&#x1f622;&#xff0c;这是我的笔记&#xff0c;欢迎和我一起学习交流~ 这篇博客目前还相对比较乱&#xff0c;后面…

【算法刷题】【力扣】| 最长回文子串|

给你一个字符串 s&#xff0c;找到 s 中最长的 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#xff1a;"bab" 解释&#xff1a;"aba" 同样是符合题意的答案。示例 2&#xff1a; 输入&#xff1a;s "cbbd" 输出&#x…

全网最最实用--模型高效推理:量化基础

文章目录 一、量化基础--计算机中数的表示1. 原码&#xff08;Sign-Magnitude&#xff09;2. 反码&#xff08;Ones Complement&#xff09;3. 补码&#xff08;Twos Complement&#xff09;4. 浮点数&#xff08;Floating Point&#xff09;a.常用的浮点数标准--IEEE 754(FP32…

如何利用业余时间做副业,在家里赚钱,来增加收入

人一生每个阶段都会有压力和烦恼&#xff0c;中年人更是如此。 上有老下有小&#xff0c;生活的重担都在一个人身上&#xff0c;压得人喘不过气&#xff0c;这些都需要钱&#xff0c;仅靠工资已经很难维持一家人的开支了。 所以很多人打算利用业余时间做副业&#xff0c;来增加…

几个小创新模型,Transformer与SVM、LSTM、BiLSTM、Adaboost的结合,MATLAB分类全家桶再更新!...

截止到本期MATLAB机器学习分类全家桶&#xff0c;一共发了5篇&#xff0c;参考文章如下&#xff1a; 1.机器学习分类全家桶&#xff0c;模式识别&#xff0c;故障诊断的看这一篇绝对够了&#xff01;MATLAB代码 2. 再更新&#xff0c;机器学习分类全家桶&#xff0c;模式识别&a…

Linux基础复习(三)

前言 接Linux基础复习二 一、常用命令及其解释 Tab补全 在上一篇文章配置了IP然后通过远程SSH连接软件控制主机&#xff0c;在配置过程中会发现有些命令过于长&#xff0c;那么&#xff0c;Tab键补全就可以很好的帮助我们去快速的敲出命令&#xff0c;同时如果有些命令有遗…

【Leetcode】十九、贪心算法:玩筹码 + 跳跃游戏

文章目录 1、贪心算法2、leetcode1217&#xff1a;玩筹码3、leetcode55&#xff1a;跳跃游戏 1、贪心算法 关于贪心算法中&#xff0c;“每一步都是最好的选择"的理解”。以零钱兑换为例&#xff0c;现在有1分、2分、5分的硬币&#xff0c;现在要凑出11分&#xff0c;且要…

API资源对象CRD、认识Operator-理论知识和认识Operator-初次上手(2024-07-17)

一、API资源对象CRD Kubernetes 自定义资源定义&#xff08;Custom Resource Definition&#xff0c;简称 CRD&#xff09;是一种强大的 Kubernetes API 扩展机制&#xff0c;允许你定义和创建自己的资源类型&#xff0c;以满足您的应用程序或基础设施需求。 CRD 的核心思想是…

RAG优化技巧 | 7大挑战与解決方式 | 提高你的LLM: 下篇

RAG优化技巧 | 7大挑战与解决方式 | 提高你的LLM&#xff1a;下篇 在当今快速发展的人工智能领域&#xff0c;大型语言模型&#xff08;LLM&#xff09;已经成为无处不在的技术&#xff0c;它们不仅改变了我们与机器交流的方式&#xff0c;还在各行各业中发挥着革命性的影响。…

实时多模态大模型

1、GPT4o 不开源 2、Moshi 开源模型来自法国一个仅有 8 人的非营利性 AI 研究机构 ——Kyutai&#xff0c;模型名为 Moshi&#xff0c;具备听、说、看的多模态功能。图灵奖得主 Yann LeCun 转发说道&#xff1a;「Moshi 能听懂带有法国口音的英语。」据悉&#xff0c;该团队开…

C++序列化Cereal库的使用

目录 一、什么是序列化二、Cereal序列化库三、下载与编译四、使用 一、什么是序列化 序列化在编程中有以下几个重要的原因&#xff1a; 数据存储&#xff1a;将数据对象序列化为一种持久化的格式&#xff0c;可以将其存储在文件、数据库或其他存储介质中。这样可以在程序的不同…