Android学习笔记 - Camera(1)

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

 背景

在APP开发中会有很多业务使用到Camera,对于一些基础的功能,调用系统的拍摄功能就可以满足要求。但是需要自定义UI界面时,例如将摄像头捕获的视图展示在页面上的时候就需要使用到Camera这个类了。

本篇会介绍哪些知识点:

  1. 什么是SurfaceView?有什么作用?何为双缓冲机制?
  2. 相机涉及到方向的概念,如何旋转到正确的方向?
  3. Camera常用的API及相关属性。
  4. Camera的调用流程。
  5. 如何设置参数,适配预览区域大小?
  6. 如何切换前后摄像头。

SurfaceView

1、为什么需要SurfaceView

Android系统默认设定的刷新频率是60FPS(每隔16.6ms底层会发出VSYNC信号重绘界面)。但是当页面绘制过于复杂,就没有办法保证60FPS,则会出现卡顿现象。其中View,ViewGroup,Animator刷新UI界面的动作都是在主线程中执行的。如果页面逻辑过于复杂时,可能出现页面卡顿,甚至可能出现ANR问题。为了解决这个问题,便引入了SurfaceView(主要用于游戏、视频等视觉效果复杂、刷新率较高的场景)。

SurfaceView的改进是引入了双缓冲机制和多线程绘制。

2、双缓冲机制

如果不用画布,直接在窗口上绘制就是无缓冲绘图。

使用一个画布,先将所有的内容绘制到画布上面,后一次性绘制到窗口上就是单缓冲绘图,其中画布是一个缓冲区。

使用两个画布,先在一个画布上面绘制所有的图像,待绘制完以后在将该画布上面所有的内容拷贝到正式绘制的画布上,这就是双缓冲绘图。

双缓冲绘图比单缓冲绘图的优势在于 拷贝比直接绘制的效率要高

在SurfaceView中,一般会开启一个新的线程,然后在新线程中通过SurfaceHolder的lockCanvas方法获取得Canvas(缓冲画布)进行绘制,绘制完以后在通过SurfaceHolder的unlockCanvasAndPost方法释放canvas并提交修改,下次刷新显示新内容即可。

3、Surface、SurfaceView、SurfaceHolder三者的关系

它们三者是典型的MVC模型。

Surface:Model层,持有缓冲画布Canvas和绘图内容相关的各种信息。

SurfaceView:View层,与用户进行交互,将Surface的内容显示给用户。

SurfaceHolder:Controller层,通过SurfaceHolder控制Surface中的数据。


相机方向

1、自然方向

人自然站立的方向。

2、设备方向

设备方向是设备与自然方向的顺时针夹角,例如手机竖着拿正对屏幕的方向是手机的自然方向,即设备方向为0°,如果手机横着拿正对屏幕且顶部在右边,则设备方向为90°。以此类推。

获取方向可以通过

int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

或者通过OrientationEventListener 监听旋转。

3、摄像头方向

手机Camera的图像数据都是来自于摄像头硬件的图像传感器(Image Sensor),摄像头的方向取决于图像传感器的安装方向。安装之后,有一个默认的取景方向,且不会被改变。但为什么手机旋转以后预览画面也会跟着旋转到自然方向呢?是因为Android系统底层根据当前手机屏幕的方向对图像Sensor采集到的数据进行了旋转处理,然后才送给显示系统。

手机后置摄像头一般都是横屏安装的。

CameraInfo.orientation 表示相机图像的方向。它的值是相机图像顺时针旋转到自然方向的角度。

android camera,ui

4、预览方向

通过setDisplayOrientation设置预览方向,默认情况是0°,即预览方向与摄像头方向一致,对于横屏应用,不需要设置预览方向。而对于竖屏应用则设置预览方向旋转90,与手机屏幕方向保持一致,这样才能得到正确的预览方向。

5、拍摄方向

相机采集图像后需要进行顺时针旋转的角度,即相机属性的orientation的值。当点击拍照时,得到的照片方向不一定与预览方向一致,因为通过setDisplayOrientation仅仅修改了预览图像的方向,不会影响到实际拍摄图像的方向,需要修改拍摄图像方向可以通过camera.setRotation实现。


适配预览区域大小

一般手机会提供多个预览和拍照尺寸,通过接口getSupportedPreviewSizes和getSupportedPictureSizes可以获得这些尺寸列表。如果previewSize比例与预览(SurfaceView)比例不一致,则看到的预览图像会变形拉伸。如何适配不同预览区大小解决拉伸问题,一般有2种方案:

一是根据previewSize比例修改SurfaceView的比例,调整预览区比例(只调整宽或高)为预览尺寸比例,从而使图像不发生变形。

二是根据SurfaceView大小固定,然后根据其比例选择最佳的(比例最接近的)预览尺寸。


切换前后摄像头

通过camera.open(int cameraId)获取camera实例时便可以通过cameraId指定摄像头。

Camera.CameraInfo.CAMERA_FACING_FRONT = 1  前置摄像头

Camera.CameraInfo.CAMERA_FACING_BACK = 0 后者摄像头

注:切换摄像头便是重新获取新的camera实例,所以在切换时需要将前一个实例释放掉。


Camera常见的API及属性

camera是Android摄像头硬件的相机类,位于硬件包"android.hardware.Camera"下,它主要用于摄像头捕获照片、启动/停止预览图片、拍照、获取视频帧等。文章来源地址https://www.toymoban.com/news/detail-772225.html

camera常见的API

  • static Camera open():打开camera,返回一个camera实例。
  • static Camera open(int cameraId):根据cameraId打开camera,返回一个camera实例。
  • final void release():释放掉camera的资源。
  • static int getNumberOfCameras():获取当前设备支持camera硬件个数。
  • Camera.Parameters getParameters():获取camera的各项参数设置类。
  • void setParameters(Camera.Parameters params):通过param将camera的各项参数写入到camera中。
  • final void setDisplayOrientation(int degrees):设置预览的旋转度。
  • final void setPreviewDisplay(SurfaceHolder holder):设置camera预览的surfaceHolder。
  • final void startPreview():开始camera的预览。
  • final void stopPreview():结束camera的预览。
  • final void autoFocus(Camera.AutoFocusCallback cb):自动对焦。
  • final takePicture(Camera.ShutterCallback shutter,Camera.PictureCallback raw,Camera.PictureCallback jpeg):拍照。
  • final void lock():锁定Camera硬件,使其他应用无法访问
  • final void unlock():解锁Camera硬件,使其他应用可以访问。

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

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

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

相关文章

  • 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日
    浏览(36)
  • Android 之 使用 Camera 拍照

    本节给大家带来的是Android中Camera的使用,简单点说就是拍照咯,无非两种: 1.调用系统自带相机拍照,然后获取拍照后的图片 2.要么自己写个拍照页面 本节我们来写两个简单的例子体验下上面的这两种情况~ 我们只需下面一席话语,即可调用系统相机,相机拍照后会返回一个

    2024年02月09日
    浏览(28)
  • Android之 Camera相机使用

    一 简介 1.1 随着信息时代的发展,相机在我们生活中使用越来越频繁,也成为手机的基本配置之一。相机可以用来拍照,拍视频,人脸识别,视频聊天,扫码支付,监控等常见领域 不管什么场景,基本原理都差不多,都要先通过相机采集原始数据,也就是二进制字节数据,我

    2024年02月15日
    浏览(28)
  • 我的NPI项目之Android Camera (二) -- 核心部件之 Camera Sensor

    说到Camera模组,我们比较关心的是用的什么样的sensor? sensor的分辨率多少,sensor的像素多大,sensor是哪家生产的等等一些问题。今天,我们就穿越时间,将sensor的历史扒一扒。 Wikipedia先看一下:history of Camera Camera的历史大体可以分为三大部分 : 核心部件Sensor : Sensor是什么

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

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

    2024年02月13日
    浏览(56)
  • Android Camera2(1)-Camera2在textureView中的预览和拍照

    解释上诉示意图,假如想要同时拍摄两张不同尺寸的图片,并且在拍摄过程中闪光灯必须亮起来。整个拍摄流程如下: 创建一个用于从 Pipeline 获取图片的 CaptureRequest。 修改 CaptureRequest 的闪光灯配置,让闪光灯在拍照过程中亮起来。 创建两个不同尺寸的 Surface 用于接收图片

    2024年02月05日
    浏览(47)
  • [Android Camera精讲]CameraServer启动流程

    代码基于Android 13,代码分支为aosp android-13.0.0_r44;调试机型为Google Pixel5。 欢迎关注微信公众号\\\"ZZH的Android\\\",关注后点击\\\"交流群\\\"菜单加入交流群。 这张图是我另一篇文章里的,直接拿过来。 cameraserver进程是承上启下的,对上是Camera Api,对应Camera App进程, 对下是CameraProvider进

    2024年01月25日
    浏览(24)
  • OpenGLES:GLSurfaceView实现Android Camera预览

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

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

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

    2024年02月16日
    浏览(41)
  • 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日
    浏览(31)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包