广告
返回顶部
首页 > 资讯 > 移动开发 >Android CameraX 打开摄像头预览功能
  • 329
分享到

Android CameraX 打开摄像头预览功能

2024-04-02 19:04:59 329人浏览 八月长安
摘要

目录引入依赖权限界面开启预览运行测试增加开关小结目标很简单,用CameraX打开摄像头预览,实时显示在界面上。看看CameraX有没有Google说的那么好用。先按最简单的来,把预览

目标很简单,用CameraX打开摄像头预览,实时显示在界面上。看看CameraX有没有Google说的那么好用。先按最简单的来,把预览显示出来。

引入依赖

模块gradle的一些配置,使用的Android SDK版本为31,启用了databinding


apply plugin: 'com.android.application'
apply plugin: 'Kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 31
    buildToolsVersion "31.0.0"
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 31
    }
    dataBinding {
        enabled = true
    }
}

引入CameraX依赖(CameraX 核心库是用camera2实现的),目前主要用1.1.0-alpha11版本


dependencies {
    implementation "androidx.camera:camera-core:1.1.0-alpha11"
    implementation "androidx.camera:camera-camera2:1.1.0-alpha11"
    implementation "androidx.camera:camera-lifecycle:1.1.0-alpha11"
    implementation "androidx.camera:camera-view:1.0.0-alpha31"
    implementation "androidx.camera:camera-extensions:1.0.0-alpha31"
}

使用1.0.2版本的CameraX核心库会报错,找不到getOrCreateInstance方法。

??? bug "NoSuchMethodError getOrCreateInstance"


```log
CrashHandler: In thread: Thread[main,5,main]
    UncaughtException detected: java.lang.NoSuchMethodError: No static method getOrCreateInstance(Landroid/content/Context;)Lcom/google/common/util/concurrent/ListenableFuture; in class Landroidx/camera/core/CameraX; or its super classes (declaration of 'androidx.camera.core.CameraX' appears in /data/app/com.rustfisher.tutorial2020-1/base.apk)
    at androidx.camera.lifecycle.ProcessCameraProvider.getInstance(ProcessCameraProvider.java:149)
    at com.rustfisher.tutorial2020.camera.SimplePreviewXAct.onCreate(SimplePreviewXAct.java:36)
    at android.app.Activity.perfORMCreate(Activity.java:6161)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2507)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2640)
    at android.app.ActivityThread.access$800(ActivityThread.java:182)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1493)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5682)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:963)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)
```

权限

需要动态申请android.permission.CAMERA权限


<uses-permission android:name="android.permission.CAMERA" />

本文略过动态申请权限的地方

界面

CameraX为开发者贴心地准备了androidx.camera.view.PreviewView

把它放在一个FrameLayout里,如下的act_simple_preivew_x.layout


<?xml version="1.0" encoding="utf-8"?>
<layout>
    <FrameLayout xmlns:android="Http://schemas.android.com/apk/res/android"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.camera.view.PreviewView
            android:id="@+id/previewView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>
</layout>

开启预览

在activity中开启相机预览


// SimplePreviewXAct.java
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.LifecycleOwner;

import com.google.common.util.concurrent.ListenableFuture;
// import com.rustfisher.tutorial2020.R;
// import com.rustfisher.tutorial2020.databinding.ActSimplePreivewXBinding;

import java.util.concurrent.ExecutionException;

public class SimplePreviewXAct extends AppCompatActivity {

    private ActSimplePreivewXBinding mBinding;
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.act_simple_preivew_x);
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                // 这里不用处理
            }
        }, ContextCompat.getMainExecutor(this));
    }

    void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
        Preview preview = new Preview.Builder().build();

        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();

        preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());

        Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
    }
}

注意我们这里使用的是androidx.appcompat.app.AppCompatActivity

为了获得ProcessCameraProvider,用ProcessCameraProvider.getInstance方法拿到一个cameraProviderFuture
cameraProviderFuture完成后取出ProcessCameraProvider(cameraProvider)。

要开启预览,通过Preview.Builder构建一个Preview。用CameraSelector来选择后置摄像头。
Preview的SurfaceProvider由layout中的androidx.camera.view.PreviewView提供。

cameraProvider.bindToLifecycle绑定上后,启动摄像头预览

运行测试

运行到手机上,打开这个Activity就可以看到摄像头预览。图像宽高比正常,没有拉伸现象。

  • 荣耀 EMUI 3.1 Lite,Android 5.1 运行正常
  • Redmi 9A,MIUI 12.5.1稳定版,Android 10 运行正常
  • 一加5,H2OS 10.0.3,Android 10 运行正常

增加开关

在layout里加2个按钮,控制相机开关


<?xml version="1.0" encoding="utf-8"?>
<layout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimaryDark"
            android:gravity="center"
            android:orientation="horizontal"
            android:padding="4dp">

            <Button
                android:id="@+id/start"
                style="@style/NormalBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="打开" />

            <Button
                android:id="@+id/end"
                style="@style/NormalBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="12dp"
                android:text="关闭" />
        </LinearLayout>

        <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.camera.view.PreviewView
                android:id="@+id/previewView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </FrameLayout>

    </LinearLayout>
</layout>

根layout换成LinearLayout

修改bindPreview方法,先检查传入的ProcessCameraProvider是否为空


private void bindPreview(ProcessCameraProvider cameraProvider) {
    if (cameraProvider == null) {
        Toast.makeText(getApplicationContext(), "没获取到相机", Toast.LENGTH_SHORT).show();
        return;
    }
    Preview preview = new Preview.Builder().build();

    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

    preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());

    Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
}

修改后的activity部分代码


import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;

import com.google.common.util.concurrent.ListenableFuture;
// import com.rustfisher.tutorial2020.R;
// import com.rustfisher.tutorial2020.databinding.ActSimplePreivewXBinding;

import java.util.concurrent.ExecutionException;

public class SimplePreviewXAct extends AppCompatActivity {

    private ActSimplePreivewXBinding mBinding;
    private ListenableFuture<ProcessCameraProvider> mCameraProviderFuture;
    private ProcessCameraProvider mCameraProvider;
    private boolean mRunning = false;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.act_simple_preivew_x);
        mCameraProviderFuture = ProcessCameraProvider.getInstance(this);
        mCameraProviderFuture.addListener(() -> {
            try {
                mCameraProvider = mCameraProviderFuture.get();
            } catch (ExecutionException | InterruptedException e) {
                // 这里不用处理
            }
        }, ContextCompat.getMainExecutor(this));
        mBinding.start.setOnClickListener(v -> {
            if (mCameraProvider != null && !mRunning) {
                bindPreview(mCameraProvider);
            }
        });
        mBinding.end.setOnClickListener(v -> {
            mCameraProvider.unbindAll();
            mRunning = false;
        });
    }

    private void bindPreview(ProcessCameraProvider cameraProvider) {
        if (cameraProvider == null) {
            Toast.makeText(getApplicationContext(), "没获取到相机", Toast.LENGTH_SHORT).show();
            return;
        }
        Preview preview = new Preview.Builder().build();

        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();

        preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());

        Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
        mRunning = true;
    }
}

拿到mCameraProvider后不要立刻绑定生命周期。

如果要开启预览,则调用bindPreview(mCameraProvider)。记录一下现在相机已经开启预览mRunning = true

如果要停止预览,则解绑生命周期mCameraProvider.unbindAll()。这个方法需要在主线程调用。

运行起来后,可以用按钮来控制相机预览的开关。相比之前,PreviewView的高度变小了一点(让了点位置给按钮)。
但视频宽高比例正常,没有被拉伸。默认的配置下,还有自动对焦的功能。

小结

从简单的打开相机预览来看,CameraX简化了开发者的工作。提供了PreviewView,开发者不需要自定义SurfaceView或者TextureView。实时预览中,相机能够自动对焦。本文用的是1.1.0-alpha11,而CameraX还在发展之中。

参考

camerax实现预览 - developer.android.com

https://developer.android.com/jetpack/androidx/releases/camera

NoSuchMethodError - stackoverflow

原文链接CameraX 打开摄像头预览

到此这篇关于Android CameraX 打开摄像头预览的文章就介绍到这了,更多相关Android CameraX 摄像头预览内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android CameraX 打开摄像头预览功能

本文链接: https://www.lsjlt.com/news/159584.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android CameraX 打开摄像头预览功能
    目录引入依赖权限界面开启预览运行测试增加开关小结目标很简单,用CameraX打开摄像头预览,实时显示在界面上。看看CameraX有没有Google说的那么好用。先按最简单的来,把预览...
    99+
    2022-11-12
  • 怎样进行Android CameraX打开摄像头预览
    怎样进行Android CameraX打开摄像头预览,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。前言目标很简单,用CameraX打开摄像头预览,实时显示在界面上。看...
    99+
    2023-06-22
  • AndroidCameraX打开摄像头预览教程
    目录前言引入依赖权限界面开启预览运行测试增加开关小结前言 目标很简单,用CameraX打开摄像头预览,实时显示在界面上。看看CameraX有没有Google说的那么好用。先按最简单的...
    99+
    2022-11-12
  • Android实现极简打开摄像头
    很多时候忘记Android摄像头如何打开,查看google文档的话,发现太复杂(只是单纯的想打开摄像头而已,不想添加那么多设置,添加那么功能),很多博客也是对官方文档的小修小改,连方...
    99+
    2022-11-13
  • pyqt5圆形label显示打开的摄像头功能
    本博客主要谈及内容是: 如何使用pyqt5是上打开摄像头并在label上显示,以及优化成圆形label框。 本文章可能是全网首篇关于圆形label显示摄像头图像。 .在label显示...
    99+
    2022-11-12
  • win10如何开启摄像头功能
    这篇文章主要为大家展示了“win10如何开启摄像头功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“win10如何开启摄像头功能”这篇文章吧。点击打开开始菜单 - 电脑设置,打开电脑设置窗口。在...
    99+
    2023-06-28
  • 云服务器怎么用摄像头监控设备的摄像功能打开
    一、安装云服务器 要想使用摄像头监控设备的摄像功能,首先需要在云服务器上安装一个名为"MyController"的新用户。这个用户可以是个人用户或者企业用户,在登录之后,可以创建一个名为"my_view"的新视图,这个视图可以用于查看云服...
    99+
    2023-10-28
    摄像头 监控设备 功能
  • 腾讯云服务器怎么打开摄像头功能
    如果您的腾讯云服务器无法打开摄像头功能,您可以尝试以下步骤来解决问题: 检查摄像头服务是否已停止。请查看腾讯云服务提供商提供的控制台或日志文件以确定服务是否关闭。 检查摄像头服务的使用说明书是否有相关提示或警告。一些腾讯云服务器可能会禁...
    99+
    2023-10-26
    腾讯 摄像头 功能
  • Android开发实现ImageView加载摄像头拍摄的大图功能
    本文实例讲述了Android开发实现ImageView加载摄像头拍摄的大图功能。分享给大家供大家参考,具体如下:这个方法是从官方demo中摘录的,在此记录学习。权限<uses-permission android:name="andr...
    99+
    2023-05-30
    android imageview age
  • Android 使用CameraX实现预览/拍照/录制视频/图片分析/对焦/缩放/切换摄像头等操作
    1. CameraX架构 看官方文档 CameraX架构 有如下这一段话 使用CameraX,借助名为"用例"的抽象概念与设备的相机进行交互。 预览 : 接受用于显示预览的Surface,例如PreviewView图片分析 : 为分析 (例...
    99+
    2023-08-20
    android 音视频 java
  • Android 外接基于UVC协议的摄像头并实现预览
    先来一段从网上找到的理论知识,对UVC协议有初步的印象 UVC协议:USB Video Class,USB视频类,是一种为USB视频捕获设备定义的协议标准。 Android 平台支持使用即插即用的 USB 摄像头(即网络摄像头),但前提是这...
    99+
    2023-09-01
    android
  • JS如何实现打开摄像头并截图上传功能
    小编给大家分享一下JS如何实现打开摄像头并截图上传功能,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!JS打开摄像头并截图上传至后端的一个完整步骤1. 打开摄像头主要用到getUserMed...
    99+
    2022-10-19
  • Android流媒体开发之路一:Camera2采集摄像头数据并手动预览
    最近研究了一下android摄像头开发相关的技术,也看了Google提供的Camera2Basic调用示例,以及网上一部分代码,但都是在TextureView等预览基础上实现,而我想要做的是在不预览的情况下,能获取到摄像头原始数据流,并...
    99+
    2023-09-07
    android 音视频 webrtc ffmpeg C++
  • 如何实现pyqt5圆形label显示打开的摄像头功能
    这篇文章主要介绍了如何实现pyqt5圆形label显示打开的摄像头功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。.在label显示打开的摄像头原理其实在label显示图片...
    99+
    2023-06-22
  • Android 11.0 Camera2 拍照功能默认选前摄像头
    1.概述  在11.0的系统rom产品开发中,对于app调用系统api来打开摄像头拍照的功能也是常有的功能,而拍照一般是默认打开后置摄像头拍照的,由于 客户的产品特殊要求,需要打开前置摄像头拍照功能,所以需要了解拍照功能的流程,然后修改默认...
    99+
    2023-09-02
    android framework camera2 camra默认前置摄像头 默认前置摄像头
  • Android开发教程之调用摄像头功能的方法详解
    本文实例讲述了Android调用摄像头功能的方法。分享给大家供大家参考,具体如下: 我们要调用摄像头的拍照功能,显然 第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保...
    99+
    2022-06-06
    程之 调用 方法 摄像 android开发 摄像头 教程 Android
  • Android高通 8.1 老化apk打开摄像头花屏问题
    最近由于公司VR 3D系统要做双Camera老化测试apk,同时老化4小时需要轮询切换二个摄像头,保证后面camera标定精度数据更准确。 一开始我尝试用之前方案移植过去然后同时打开双摄像头 突然发现花屏 如下图所示 于是一第一时间想到是...
    99+
    2023-10-05
    android
  • Android调用手机摄像头拍照和录音功能
    本文实例为大家分享了Android调用手机摄像头拍照和录音功能的具体代码,供大家参考,具体内容如下 调用摄像头拍照: public class MainActivity extend...
    99+
    2022-11-13
  • 海康威视摄像头对接SDK实时预览功能和抓拍功能,懒癌福利,可直接CV
    海康威视摄像头完成实时预览功能和抓拍功能 背景思路、流程开发步骤1.海康的SDK,只需要在项目启动的时候初始化一次就行,所以我直接将初始化SDK和加载DLL库的代码丢到启动类中去了:2.先讲实时预览功能,我是直接通过RTSP协议取流...
    99+
    2023-08-16
    java 开发语言
  • UVCAndroid,安卓UVC相机通用开发库(支持多预览和多摄像头)
    文章目录 简介主要功能如何使用1. 添加依赖到本地工程2. 获取权限3. 初始化UVC业务类,设置UVC摄像头状态回调,设置TextureView或者SurfaceView的Surface监听回调4. 释放UVC业务类(包含取消UV...
    99+
    2023-08-17
    uvc android 安卓
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作