Android Camera2采集摄像头原始数据并手动预览
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采集摄像头原始数据并手动预览的更多相关文章
- Android流媒体开发之路一:Camera2采集摄像头原始数据并手动预览
Android Camera2采集摄像头原始数据并手动预览 最近研究了一下android摄像头开发相关的技术,也看了Google提供的Camera2Basic调用示例,以及网上一部分代码,但都是在Te ...
- Android开发实践:掌握Camera的预览方向和拍照方向
http://ticktick.blog.51cto.com/823160/1592267?utm_source=tuicool&utm_medium=referral Android的Cam ...
- opencv-android笔记1:android studio 2.3 + opencv-android-sdk 实现 camera预览
Android studio环境配置不再赘述,可以参照我的其他博客. Android应用程序开发环境搭建:http://blog.csdn.net/ja33son/article/details/61 ...
- 【android学习3】解决Android界面布局添加EditView之后无法预览问题
在设计登陆界面时,拖入一个EditView之后发现界面无法预览 问题分析: 进入xml源文件里发现一个警告,提示添加inputType或者hint元素,添加后界面仍然无法预览... 仔细查看了当前使用 ...
- Android Camera开发:使用TextureView和SurfaceTexture预览Camera 基础拍照demo
Google自Android4.0出了TextureView,为什么推出呢?就是为了弥补Surfaceview的不足,另外一方面也是为了平衡GlSurfaceView,当然这是本人揣度的.关于Text ...
- Android Studio xml文件中的布局预览视图
操作系统:Windows 10 x64 IDE:Android Studio 3.3.1 更新了Android Studio之后,xml文件中的布局预览视图变得如此简洁! 原因是没有勾选Show La ...
- Android 使用Gallery组件实现图片播放预览
Gallery(画廊)扩展了LayoutParams,以此提供可以容纳当前的转换信息和先前的位置转换信息的场所. Activity package com.app.test01; import com ...
- Android Camera2 预览,拍照,人脸检测并实时展现
https://www.jianshu.com/p/5414ba2b5508 背景 最近需要做一个人脸检测并实时预览的功能.就是边检测人脸,边在预览界面上框出来. 当然本人并不是专门做 ...
- Android使用Camera2获取预览数据
一.Camera2简介 Camera2是Google在Android 5.0后推出的一个全新的相机API,Camera2和Camera没有继承关系,是完全重新设计的,且Camera2支持的功能也更加丰 ...
随机推荐
- sql servel 报错:将 expression 转换为数据类型 int 时出现算术溢出错误。
执行sql语句:SELECT AVG( DATEDIFF(s,s.CreatedDate,s.SendDate) ) AS submitTime FROM dbo.SmsSend AS s ...
- JSP执行过程分析
概述 在java领域,表现层技术主要有三种:jsp.freemarker.velocity.jsp是由sun公司倡导的官方标准,freemarker和velocity是第三方的模板. jsp是大家最熟 ...
- [Haskell] 为什么列表操作++很昂贵?
博主是haskell新手.学习haskll的时候遇到了一些问题,在寻求答案的过程中产生了一些思考,可能理解存在偏差,希望各位不吝赐教. 提出问题 <Learn you a haskell for ...
- Java入门篇(一)——如何编写一个简单的Java程序
最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...
- BZOJ1258: [CQOI2007]三角形tri
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1258 如果最后一位是4,那就改成123就好了. 然后最后一位不是4的话,至多三个答案,然后可以 ...
- 51 Nod 1119
机器人走方格 V2 M * N的方格,一个机器人从左上走到右下,只能向右或向下走.有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果. Input 第1行,2个数M,N ...
- find the nth digit(二分查找)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1597 find the nth digit Time Limit: 1000/1000 MS (Jav ...
- JAVA虚拟机之对象探秘
上一章主要写到了JVM中运行时数据区域各个部分的功能及其作用.上一章说到了对象是分配在堆上面的,所以接下来我们写到对象在堆内存中是如何创建.如何布局.如何访问.1. 对象的创建 在java程序中对象的 ...
- 【老司机经验】CC2530&STM8S105二合一嵌入式学习板设计思路与经验分享
CC2530&STM8S105二合一嵌入式学习板设计思路与经验分享 1.缘起 这些年来一直在其他公司的实验箱和别人的开发板上进行教学与开发工作,总是觉得功能设计不那么合意.心里突然冒出个 ...
- Linux 用户组及用户管理
查看所有组的信息:(信息保存在/etc/group文件中) 其中每段信息用:分割 ,每段的含义如下: 用户名组名:密码:用户组的id:用户组所包含的用户(多个用户用,分割) 查看所有的用户信息:(信息 ...