Android Camera2采集摄像头原始数据并手动预览

最近研究了一下android摄像头开发相关的技术,也看了Google提供的Camera2Basic调用示例,以及网上一部分代码,但都是在TextureView等预览基础上实现,而我想要做的是在不预览的情况下,能获取到摄像头原始数据流,并由自己来决定是否绘制显示。经过一番折腾,初步实现了自己的目的——CamCap程序。

需求分析

  其实主要就是在不预览的情况下获取到摄像头原始数据,目的嘛,一是为了灵活性,方便随时开启关闭预览,二是为了以后可以直接对数据进行处理,三是为了其他程序开发做一些准备。于是实现一下几个功能:

  • 获取摄像头数据,并手动绘制图像
  • 随时开启/关闭预览
  • 随时保存当前摄像头图像,即使在关闭预览情况下

Android Camera2接口

  查阅了一些资料,Android Java层由于从API21开始,已经废弃原Camera接口,所以这里采用Camera2接口。相比Camera接口来说,第二代摄像头接口,调用复杂多了,但是灵活性也更高了,通过Google的Camera2Basic例子可以很清楚的了解到使用方式。这里把CamCap程序中的Camera2的调用顺序整理如下:

和其他程序一样,通过ImageReader来获取到CameraCaptureSession传递出来的数据,与Google例子不同的是,我取消了把TextureView的传递,改为单独以ImageReader来获取图像流,并设置为YUV_420_888格式,以拿到原始数据。

打开摄像头

摄像头打开后,创建对话

调用libyuv做RGB之间的数据转换

  获取到YUV数据之后,就可以在UI界面上进行绘制了,通过简单了解,可以通过OpenGLES来绘制,也可以转为Bitmap直接在TextureView上绘制。这里为了简单,选择了后者。然而后来发现,android.graphics.Bitmap并不支持直接将YUV数据存入,只能转为RGB数据格式,才能存入Bitmap,进而在TextureView上绘制。YUV转换RGB,之前在C++上应用过很多次了,可以把现有代码修改一下放到java里运行,不过考虑到性能问题,决定还是使用libyuv。libyuv是一款以c/c++为基础的,专做YUV与RGB格式转换的开源项目,性能非常高。

  使用libyuv,需要通过NDK交叉编译,并通过JNI来调用。libyuv编译起来也很简单,首先下载libyuv源码,代码地址是:https://chromium.googlesource.com/libyuv/libyuv 。然后确保NDK已经安装(这个直接在AndroidStudio中就能安装好),之后把NDK目录添加到环境变量。最后,进入libyuv目录,调用ndk-build即可。libyuv项目里已经写好了Android.mk,所以,直接编译就行了(我是在Windows上)。

注意!编译的时候遇到JPEG库没有指定的问题,如果不想依赖libjpeg,可以修改Android.mk,删除JPEG库相关编译项就可以解决。

在AndroidStudio上建立c++文件,封装libyuv接口,然后按照JNI规范暴露接口,同时在Java层封装类来调用native方法。

绘制图像

在绘制图像的时候,有个坑,那就是图像的旋转,这个是由于手机上的摄像头传感器的视野坐标,一般都是旋转了90度或270度的,所以,需要把摄像头采集到的画面,进行旋转,才能还原出正确的视野画面。传感器旋转方向通过以下值获得,

CameraManager.getCameraCharacteristics(camid).get(CameraCharacteristics.SENSOR_ORIENTATION)

根据这个值,构建Matrix将Bitmap进行旋转

Matrix构建代码如下:

与上面代码中类似,通过TextureView.lockCanvas(),获取到Canvas,调用drawBitmap()将图像写入,即可完成绘制。

运行截图

开启预览时的4:3画面和16:9画面

关闭预览,同时可以继续拍照

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

haibindev.cnblogs.com,合作请联系QQ。(转载请注明作者和出处~)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Android流媒体开发之路一:Camera2采集摄像头原始数据并手动预览的更多相关文章

  1. Android Camera2采集摄像头原始数据并手动预览

    Android Camera2采集摄像头原始数据并手动预览 最近研究了一下android摄像头开发相关的技术,也看了Google提供的Camera2Basic调用示例,以及网上一部分代码,但都是在Te ...

  2. Android流媒体开发之路二:NDK开发Android端RTMP直播推流程序

    NDK开发Android端RTMP直播推流程序 经过一番折腾,成功把RTMP直播推流代码,通过NDK交叉编译的方式,移植到了Android下,从而实现了Android端采集摄像头和麦克缝数据,然后进行 ...

  3. Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器

    基于NDK开发Android平台RTSP播放器 最近做了不少android端的开发,有推流.播放.直播.对讲等各种应用,做了RTMP.RTSP.HTTP-FLV.自定义等各种协议,还是有不少收获和心得 ...

  4. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  5. Android中直播视频技术探究之---采集摄像头Camera视频源数据进行推流(采用金山云SDK)

    一.前言 在之前已经详细介绍了Android中的一种视频数据源:Camera,不了解的同学可以点击进入:Android中Camera使用详解 ,在这篇文章中我们介绍了如何采集摄像头的每一帧数据,然后进 ...

  6. iOS RTMP 视频直播开发笔记(1) – 采集摄像头图像

    1. 采集硬件(摄像头)视频图像 这里简单说下 iOS 的摄像头采集. 首先初始化AVCaptureSession,说到Session,有没有人想到AVAudioSession呢? // 初始化 AV ...

  7. 网站开发进阶(十二)JS实现打印功能(包括打印预览、打印设置等)

    JS实现打印功能(包括打印预览.打印设置等) 绪 最近在进行项目开发时,需要实现后台管理端打印功能,遂在网上一阵搜索,搜到了很多相关的文章.其中绝大部分文章都是使用的Lodop5.0(Web打印和套打 ...

  8. vue开发中vue-resource + canvas 图片压缩、上传、预览

    1.使用vue-resource上传,也可以自定义ajax上传: 2.使用<input type="file" @change="submit()" na ...

  9. Android相机开发那些坑

    版权声明:本文由王梓原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/168 来源:腾云阁 https://www.qclou ...

随机推荐

  1. Kubernetes 网络改进的三项实践分享

    自研CNI IPAM插件 解决K8s功能问题 首先,在功能方面,Kubernetes 网络模型由于IP不固定,无法对IP资源进行精细管控,无法使用基于IP的监控和基于IP的安全策略,此外,一些IP发现 ...

  2. 让sublime可以和visual studio一样自动在运算符前后添加空格的插件

    用过vs的人都知道,vs会自动在代码中运算符的前后加空格,比如 i=1; 换行后会自动变成i = 1; 开始觉得这个挺烦的,后来习惯了,发现这个功能还是挺好的,然代码更清晰. 最近换了sublimet ...

  3. elasticsearch 安装 windows linux macOS

    导读 在上一章节我们介绍Elasticsearch基本概念,今天我们继续进行本章内容,Elasticsearch在各种环境下安装,下面将逐一讲解在各种操作系统或不同安装在不同环境中注意事项. 安装 E ...

  4. 51Nod 算法马拉松12 移数博弈

    点进去发现并不是博弈QAQ 一开始考虑单调队列什么乱七八糟的发现根本做不出来 (没错我一直在想枚举最大值求次大值QAQ 不妨换个思路: 我们考虑枚举次大值求最大值 设当前为now, 设now之前第一个 ...

  5. ORA-12801/ORA-12853: insufficient memory for PX buffers: current 274880K, max needed 19722240K/ORA-04031解决方法

    近日,现场一台服务器在运行时出现下列异常: ORA-12801: error signaled in parallel query server P139 ORA-12853: insufficien ...

  6. 剑指offer(36)两个链表中的第一个公共节点

    题目描述 输入两个链表,找出它们的第一个公共结点. 题目分析 我发现关于链表的题都涉及双指针,大家做的时候记得用双指针. 题目理解了就很好做了,比较简单,先在长的链表上跑,知道长的和短的一样长,再一起 ...

  7. Loj 6036 「雅礼集训 2017 Day4」编码 - 2-sat

    题目传送门 唯一的传送门 题目大意 给定$n$个串,每个串只包含 ' .问是否可能任意两个不同的串不满足一个是另一个的前缀. 2-sat的是显然的. 枚举每个通配符填0还是1,然后插入Trie树. 对 ...

  8. 关闭vs的编译警告

    现象:出现warning cxxxx.. 解决:项目,属性,C/C++,高级,禁用特定警告,把xxxx输入

  9. Linux——入门命令

    授课内容: 0.linux系统由来 linux各种常用命令以及对命令参数选项的熟悉: 1.目录操作命令([跳转:查看自己当下的位置-绝对路径:查看任何路径下的目录内容]pwd(Print Workin ...

  10. DataTable与List的相互转换

    List转DataTable: public static DataTable ToDataTable<T>(IEnumerable<T> collection) { var ...