Android 实现相机(CameraX)预览

这篇具有很好参考价值的文章主要介绍了Android 实现相机(CameraX)预览。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

CameraX 支持大多数常见的相机用例:
  • 预览:在屏幕上查看图片。
  • 图片分析:无缝访问缓冲区中的图片以便在算法中使用,例如将其传递到机器学习套件。
  • 图片拍摄:保存图片。
  • 视频拍摄:保存视频和音频。

这篇文章讲的是 – 实现预览

在向应用添加预览时,请使用 PreviewView,这是一种可以剪裁、缩放和旋转以确保正确显示的 View。
当相机处于活动状态时,图片预览会流式传输到 PreviewView 中的 Surface。

效果图

camera起预览,android

配置:

  • 注意:CameraX 支持的最小SDK版本是21
    camera起预览,android
  • 一、添加权限

1、清单文件中加入相机权限

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

2、动态获取相机权限

  if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.CAMERA}, 11);
            }
        } else {
            //启动相机 
        }
  • 二、在build.gradle中 添加CameraX依赖
    implementation "androidx.camera:camera-core:1.1.0-alpha10"
// CameraX Camera2 extensions[可选]拓展库可实现人像、HDR、夜间和美颜、滤镜但依赖于OEM
    implementation "androidx.camera:camera-camera2:1.1.0-alpha10"
// CameraX Lifecycle library[可选]避免手动在生命周期释放和销毁数据
    implementation "androidx.camera:camera-lifecycle:1.1.0-alpha10"
// CameraX View class[可选]最佳实践,最好用里面的PreviewView,它会自行判断用SurfaceView还是TextureView来实现
    implementation 'androidx.camera:camera-view:1.0.0-alpha23'

使用 PreviewView案例步骤:

1、(可选)配置 CameraXConfig.Provider。
2、 将 PreviewView 添加到布局。
3、 请求 ProcessCameraProvider。
4、 在创建 View 时,请检查 ProcessCameraProvider。
5、 选择相机并绑定生命周期和用例。

  • 将 PreviewView 添加到布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <FrameLayout
        android:layout_centerInParent="true"
        android:layout_width="500dp"
        android:layout_height="500dp">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </FrameLayout>
</RelativeLayout>
  • 步骤3、4、5、的处理
package com.example.myapplication;

import androidx.annotation.NonNull;
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.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.ExecutionException;


public class MainActivity extends AppCompatActivity {
    
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    private PreviewView previewView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        previewView=findViewById(R.id.previewView);//初始化
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.CAMERA}, 11);
            }
        } else {
            //启动相机
            startCamera();
        }
    }

    private void startCamera() {
        // 请求 CameraProvider
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                // No errors need to be handled for this Future.
                // This should never be reached.
            }
        }, ContextCompat.getMainExecutor(this));
    }
    //选择相机并绑定生命周期和用例
    private void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
        Preview preview = new Preview.Builder()
                .build();

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

        preview.setSurfaceProvider(previewView.getSurfaceProvider());

        Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview);
    }
}
  • 到bindPreview这一步,相机预览已经显示,请查验

如果是前后翻转

  • 解绑每个组件

cameraProvider.unbindAll();文章来源地址https://www.toymoban.com/news/detail-612418.html

camera起预览,android
  • 布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <Button
        android:onClick="btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="前置摄像头"
        />
    <Button
        android:onClick="btn2"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="后置摄像头"
        />
    <FrameLayout
        android:layout_centerInParent="true"
        android:layout_width="500dp"
        android:layout_height="500dp">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </FrameLayout>
</RelativeLayout>

  • 代码详情如下:
public class MainActivity extends AppCompatActivity {

    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    private PreviewView previewView;
    private ProcessCameraProvider cameraProvider;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        previewView=findViewById(R.id.previewView);//初始化
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.CAMERA}, 11);
            }
        } else {
            //启动相机
            startCamera(CameraSelector.LENS_FACING_BACK);
        }
    }


    private void startCamera(int state) {
        // 请求 CameraProvider
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider,state);
            } catch (ExecutionException | InterruptedException e) {
                // No errors need to be handled for this Future.
                // This should never be reached.
            }
        }, ContextCompat.getMainExecutor(this));
    }
    //选择相机并绑定生命周期和用例
    private void bindPreview(@NonNull ProcessCameraProvider cp,int state) {
        this.cameraProvider=cp;
        Preview preview = new Preview.Builder()
                .build();

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

        preview.setSurfaceProvider(previewView.getSurfaceProvider());
        cameraProvider.unbindAll();//解绑组件
        cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview);
    }

    //点击翻转到前置
    public void btn1(View view) {
        //启动相机
        bindPreview(cameraProvider,CameraSelector.LENS_FACING_FRONT);
    }
    //点击翻转到后置
    public void btn2(View view) {
        //启动相机
        bindPreview(cameraProvider,CameraSelector.LENS_FACING_BACK);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode==11){//获取权限后,开启摄像头
            //启动相机
            startCamera(CameraSelector.LENS_FACING_BACK);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cameraProvider.unbindAll();
    }
}

到了这里,关于Android 实现相机(CameraX)预览的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android OpenGLES + Camera1 相机预览

    if (isCreate) { return; } onCreatePre(); onClearColor(); onInitBlend(); onInitVertexBuffer(); onInitCoordinateBuffer(); onInitVbo(); onInitProgram(); onCreateAfter(); isCreate = true; } @Override public void onChange(int width, int height) { if (isChange) { return; } onChangePre(); setWidth(width); setHeight(height); onViewport(); onInitFbo(); onChangeAfter(

    2024年04月12日
    浏览(40)
  • Android OpenGLES + Camera1 相机预览(2)

    private void checkRenderThreadState() { if (mGLThread != null) { throw new IllegalStateException( “setRenderer has already been called for this instance.”); } } 也就是说,设置了 Renderer 后,就不能更换了,那么如果有需求:本来是渲染一个灰度滤镜的,当想变换其他滤镜的时候,又不能重新设置 Renderer ,此

    2024年04月25日
    浏览(40)
  • Android Camera开发入门(3):CameraX的使用

    CameraX API简介 在前两篇博客中,我们介绍了Camera基础知识和Camera2 API的使用。为了进一步简化相机应用开发,Google推出了CameraX API,它提供了一个更加简洁、易于使用的接口,帮助开发者快速实现高质量的相机功能。本篇博客将带领你了解CameraX的使用方法,并提供相应的示例

    2024年02月11日
    浏览(37)
  • android camera系列(Camera1、Camera2、CameraX)的使用以及输出的图像格式

    1.1.1、布局 1.1.2、实现预览 Camera.open() 打开摄像头 setPreviewDisplay 设置预览展示的控件 startPreview 开始预览 发现预览是横着的,需要使用 setDisplayOrientation 调整预览图像的方向 1.1.3、获取摄像头的原始数据 setPreviewCallback 设置预览数据的回调 2560*1440 默认返回图像的分辨率 Image

    2024年02月21日
    浏览(50)
  • OpenGLES:GLSurfaceView实现Android Camera预览

    前几篇博文对OpenGL做了一些讲解,虽然只是一些基础的知识,但也足够玩出很多有趣的东东了 之前讲过OpenGL本身只是一个开源的图形渲染标准协议,所以OpenGL的学习应注重实战实操,多动手写代码才更有助于巩固所学知识 OpenGLES是OpenGL适配移动端嵌入式设备的版本,裁剪了

    2024年02月04日
    浏览(46)
  • 十分钟实现 Android Camera2 相机拍照

    因为工作中要使用 Android Camera2 API ,但因为 Camera2 比较复杂,网上资料也比较乱,有一定入门门槛,所以花了几天时间系统研究了下,并在 CSDN 上记录了下,希望能帮助到更多的小伙伴。 上篇文章 我们使用 Camera2 实现了相机预览的功能,这篇文章我们接着上文,来实现 Cam

    2024年02月11日
    浏览(60)
  • 使用 CameraX 在 Jetpack Compose 中构建相机 Android 应用程序

    CameraX 是一个 Jetpack 库,旨在帮助简化相机应用程序的开发。 [camerax官方文档] https://developer.android.com/training/camerax CameraX的几个用例: Image Capture Video Capture Preview Image analyze 具体如何使用相关用例,请查看上面的官方链接。 下面仅就视频录制用例来叙述相关实现流程。 添加

    2024年02月06日
    浏览(65)
  • Android相机调用-CameraX【外接摄像头】【USB摄像头】

    Android相机调用有原生的Camera和Camera2,我觉得调用代码都太复杂了,CameraX调用代码简洁很多。 说明文档:https://developer.android.com/jetpack/androidx/releases/camera?hl=zh-cn 现有查到的调用资料都不够新,对于外接摄像头(USB摄像头)这类非前置也非后置摄像头的设备调用,都说是没有实

    2024年02月09日
    浏览(51)
  • Android Camera预览画面变形问题

    csdn 安卓camera1在预览时,预览画面看起来被拉伸了. 如图,圆形的盖子,变成椭圆形了. 默认流程,如下为大致的打开摄像头并进行预览显示的代码 网上大部分的解决方法(实测不一定有效) 原理是遍历摄像头分辨率,找到与当前屏幕契合的分辨率,并设置为预览大小. 如下

    2024年02月13日
    浏览(70)
  • Android Camera2-预览、拍照、录像流程

    一、Camera2实现预览、拍照、录像三大基础功能的流程框架图 Camera2关键几个类: CameraManager 管理手机上的所有摄像头设备。管理手机上的所有摄像头设备,它的作用主要是获取摄像头列表和打开(openCamera)指定的摄像头。 它其实是一个系统服务,通过getSystemService(Context.CAM

    2024年02月16日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包