Android中的拍照camera和camera2
在android我们可以调用系统的相机来进行照相,当然也可以设计自己的照相页面,通过surface进行预览,通过camera api来进行拍照即可。
在Android 5.0之后google推荐使用的Camera2 Api,但是由于兼容问题我们大部分还在使用Camera Api。这里我们一起简单介绍一下,仅仅是预览拍照,至于细节的设置,比如图像大小比例、对焦、图像旋转等就不一一细说了。
首先我们需要在布局中加入一个SurfaceView
Camera Api
var camera: Camera? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)//为surfaceholder添加监听surface.holder.addCallback(object : SurfaceHolder.Callback{override fun surfaceChanged(p0: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {}override fun surfaceDestroyed(p0: SurfaceHolder?) {}override fun surfaceCreated(p0: SurfaceHolder?) {//当surface创建完成初始化相机initCamera1()}})take.setOnClickListener {//拍照takePicture1()}}fun initCamera1(){//打开相机,开启预览camera = Camera.open()camera?.setPreviewDisplay(surface.holder)camera?.startPreview()}fun takePicture1(){//拍照,通过回调获取图片数据camera?.takePicture({},{bytes, camera ->if(bytes == null){return@takePicture}var b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)imageView.setImageBitmap(b)},{bytes, camera ->if(bytes == null){return@takePicture}var b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)imageView2.setImageBitmap(b)})}
可以看到使用Camera比较简单,打开相机开启预览,拍照在回调中处理即可。
Camera2 Api
Camera2的Api相比Camera要复杂很多
var mCameraDevice : CameraDevice? = nullvar mCameraCaptureSession : CameraCaptureSession? = nullvar childHandler : Handler? = null@SuppressLint("NewApi")var imageReader : ImageReader? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)//为surfaceholder添加监听surface.holder.addCallback(object : SurfaceHolder.Callback{override fun surfaceChanged(p0: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {}override fun surfaceDestroyed(p0: SurfaceHolder?) {}override fun surfaceCreated(p0: SurfaceHolder?) {//当surface创建完成初始化相机initCamera2()}})take.setOnClickListener {//拍照takePicture2()}}fun initCamera2(){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//因为处理图片比较耗时,所以这里新建一个线程的handler来处理var handlerThread = HandlerThread("camera")handlerThread.start()childHandler = Handler(handlerThread.looper)//创建一个ImageReader,后面会通过这个获取拍照的图片imageReader = ImageReader.newInstance(500, 500, ImageFormat.JPEG,2)//为ImageReader添加回调,这里使用我们新建的线程的handler处理图片imageReader?.setOnImageAvailableListener(object : ImageReader.OnImageAvailableListener{override fun onImageAvailable(imageReader: ImageReader) {//得到图片后,关闭相机,从ImageReader中获取图片数据mCameraDevice?.close()var image = imageReader.acquireNextImage()var buffer = image.planes[0].buffervar bytes = ByteArray(buffer.remaining())buffer.get(bytes)var bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)//由于这部分是在子线程中处理的,所以对ui操作要放到主线程中runOnUiThread {imageView.setImageBitmap(bitmap)}}}, childHandler)//通过CameraManager打开相机,注意这里的handler是主线程的。var cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManagercameraManager.openCamera(CameraCharacteristics.LENS_FACING_FRONT.toString(), object : CameraDevice.StateCallback() {override fun onOpened(cameraDevice: CameraDevice) {//相机打开后,得到CameraDevice并开启预览mCameraDevice = cameraDevicecamera2Preview()}override fun onDisconnected(p0: CameraDevice) {}override fun onError(p0: CameraDevice, p1: Int) {}}, Handler(Looper.getMainLooper()))}}fun camera2Preview(){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {mCameraDevice?.let {//新建一个PRIVIEW的CaptureRequest,将surface添加进去var builder = it.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)builder.addTarget(surface.holder.surface)//通过CameraDevice新建一个CaptureSession事务,在回调中开启预览it.createCaptureSession(Arrays.asList(surface.holder.surface, imageReader?.surface), object : CameraCaptureSession.StateCallback() {override fun onConfigureFailed(p0: CameraCaptureSession) {}override fun onConfigured(cameraCaptureSession: CameraCaptureSession) {//获得对应的CaptureSession事务,并设置预览的request开始预览mCameraCaptureSession = cameraCaptureSessionvar previewRequest = builder.build()mCameraCaptureSession?.setRepeatingRequest(previewRequest, null ,childHandler)}}, childHandler)}}}//拍照fun takePicture2(){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {mCameraDevice?.let {//新建一个拍照请求,并添加之前创建的ImageReader的surfacevar builder = it.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)builder.addTarget(imageReader!!.surface)var previewRequest = builder.build()//通过预览是获取的CaptureSession事务,执行拍照请求,结果会通过之前设置的ImageReader的回调返回mCameraCaptureSession?.setRepeatingRequest(previewRequest, null ,childHandler)}}}
使用Camera2 Api的流程基本与Camera一样,但是代码复杂很多,主要是需要通过事务CaptureSession来处理预览及拍照,而且为了处理图片还需要一个新建子线程,同时拍照结果也是通过ImageReader封装起来的。
Android中的拍照camera和camera2相关推荐
- android中的照相机机拍照程序(含连续拍照)
最近用到了android中的照相机功能,android中实现拍照的方式有两种,一种是调用系统自带的照相机进行拍照,此种方法较为简单,因为是android本身就已经实现了的:另一种就是自己来实现一个拍照 ...
- android camera(6)---camera2 拍照流程
android camera2 拍照流程 正文 camera2 API 的加入是从AndroidV5.0(21)开始的,因此我们使用Camera2应该是在Android 5.0(含5.0)之后.同时, ...
- android开发自动拍照,Android:Camera2开发详解(上):实现预览、拍照、保存照片等功能...
android.jpg 前言 在前几篇文章中介绍了如何调用系统相机拍照和使用Camera1的实现自定义相机拍照.人脸检测等功能 文章传送门: 接下来的几篇文章中,我将给大家介绍如何使用Camera2实 ...
- android中的多媒体应用camera
MainActivity.java 代码 package com.amaker.ch11.app; import java.io.File; import java.io.FileOutputStre ...
- Java乔晓松-android中调用系统拍照功能并显示拍照的图片
android中调用系统拍照功能并显示拍照的图片 如果你是拍照完,利用onActivityResult获取data数据,把data数据转换成Bitmap数据,这样获取到的图片,是拍照的照片的缩略图 代 ...
- Android 中拍照、相册选择、裁剪照片
一个多月没总结知识点了,差点连博客账号都忘了...好了,步入正题,在 Android 中调用摄像头拍照获取图片或者是从相册中选取图片是很常见的功能,比如某些 APP 上传头像的功能就是一个例子. ** ...
- Android拍照录像框架Camera2使用简介
Android拍照录像框架Camera2使用简介 在Android 21时Google更新了以往的摄像头类库Camera,取而代之的是Camera2.作为更新版本,Camera2具有更强功能的同时也增 ...
- Android机型适配问题——Camera拍照时快门咔嚓声
文/腾讯优测 吴宇焕 现在Android手机一般都会带有照相功能,有很多朋友就发现手机照相时快门声音很响,想关又关不掉.....不过话说回来,静音拍照你想做啥? 来到主题上,因为网络上有很多关于&qu ...
- android opencv 数码变焦,Android开发(53) 摄像头自动对焦。在OpenCV图像识别中连续拍照时自动对焦和拍照。......
概述 对焦,这里所说的"焦"是指"焦距".在拍照时,一定是需要调焦的.一般会在目标位置最清晰的时候会停止对焦.最近在处理OpenCV进行图像识别时,需要连续的调 ...
最新文章
- b360装服务器系统,B365主板能不能安装Win7系统 B365和B360主板区别对比介绍
- html5混合编写,Html5混合开发环境的搭建
- win7一直提示格式化磁盘_win10磁盘分区操作步骤
- java第一阶段知识_坚持:学习Java后台的第一阶段,我学习了那些知识
- python爬虫编码转换_Python 爬虫遇到形如 小说 的编码如何转换为中文? - SegmentFault 思否...
- jquery - 正则表达式
- python何时用list,dict,set
- 数学连乘和累加运算符号_期中复习:小学数学各年级知识点和重点、难点大全!...
- 评分9.7! 这本Python神作,火爆编程圈!网友:太香!
- 检验学习笔记-寄生虫
- 使Window注册表更改立刻生效的命令行命令
- 遇见逆水寒服务器维护时间,《遇见逆水寒》7月23日更新公告
- 乐趣国学—品读“富润屋,德润身。”中的智慧
- vSphere web client 虚拟机生成模板快速部署
- ipad上html语言编辑,在 iPad 上键入和编辑文本的小技巧
- 对View的onMeasure方法理解
- loaded the xxx nib but the view outlet was not set 错误的解决办法。
- HTML+CSS flex弹性布局
- VirtualBox打开虚拟机失败,Not in a hypervisor partition(HPV=0)(VERR_NEM_NOT_AVAILABLE) ,但是没有virtualization选项
- 第七十一篇:从ADAS到自动驾驶(四):车辆检测
热门文章
- /usr/bin/ld: cannot find -lltdl collect2: ld returned 1 exit status make: *** [sapi/cgi/php-cgi] Err
- TcpSocket编程与Event编写学习的好例子
- Android中的Notification
- [EffectiveC++]item22:Declare data members private
- vue-element-admin使用常见问题
- lintcode-415-有效回文串
- android 布局之scrollview
- log4cxx编译过程–linux
- IOS学习之UINavigationController详解与使用(一)添加UIBarButtonItem
- 汉字转拼音(VB版)