Android Camera相关知识

Android摄像头通常会支持两种图像格式:NV21和YV12,可通过下面方式设置

val parameters = mCamera.parameters

parameters.setPreviewFormat(ImageFormat.NV21) // ImageFormat.YV12

mCamera.parameters = parameters

比较诡异的是,Android的H264硬编码器不支持NV21和YV12格式,神奇!

6、录像时开启自动连续对焦

============================================================================

val parameters = mCamera.parameters

parameters.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO

mCamera.parameters = parameters

7、YUV图像格式转换

==========================================================================

  1. 成员变量赋值

ySize = videoWidth * videoHeight; // Y分量大小

oneFrameSize = (ySize * 3) >> 1; // 一帧画面大小

uvSize = oneFrameSize - ySize; // UV分量大小

uvHalfSize = uvSize / 2; // UV分量的一半

uvBytes = new byte[uvSize]; // 用于存放UV分量数据

maxIndex = ySize + uvHalfSize; // 最大索引

  1. YV12转I420

private void YV12ToI420(byte[] yuvDatas) {

for (i = ySize; i < maxIndex; i++) {

temp = yuvDatas[i];

yuvDatas[i] = yuvDatas[i + uvHalfSize];

yuvDatas[i + uvHalfSize] = temp;

}

}

  1. I420转NV12

private void I420ToNV12(byte[] i420Bytes) {

index = 0;

for (i = ySize; i < maxIndex; i++) {

uvBytes[index] = i420Bytes[i];

uvBytes[index + 1] = i420Bytes[i + uvHalfSize];

index += 2; // 上面已经连续存储了两个位置了,所以这里要跳2

}

System.arraycopy(uvBytes, 0, i420Bytes, ySize, uvSize);

}

  1. NV21转NV12

private void NV21ToNV12(byte[] yuvDatas) {

for (index = ySize; index < oneFrameSize; index += 2) {

temp = yuvDatas[index];

yuvDatas[index] = yuvDatas[index + 1];

yuvDatas[index + 1] = temp;

}

}

8、申请权限后摄像头不显示

============================================================================

当把SurfaceView写在布局中时,第一次运行时,先动态权限申请权限,申请到权限之后再显示摄像头,这时会发现显示不了,从打印Log可以知道surfaceCreated函数并没有执行,原因时Activity显示时,我们还没有Camera权限,此时surfaceCreated已经执行,而因为没有权限,我们的代码还没执行到给SurfaceHolder添加回调的地方,所以就看不到surfaceCreated执行。解决方案就是SurfaceView不要写死在布局中,而是在用到的时候直接new出来,然后add到布局中,这样就没问题了。

9、移除SurfaceView报异常

=================================================================================

我在项目中增加了一个关闭摄像头的按钮,点击后关闭摄像头。因为SurfaceView是new出来动态添加到主界面上的,则在关闭摄像头后应该把SurfaceView移除,但是在移除SurfaceView的过程中(container.removeView(surfaceView))会触发surfaceDestroyed函数,而我在这个函数中又调用了关闭摄像头函数,这样会导致两次调用关闭摄像头的函数,在第一次调用关闭摄像头函数时,代码还没执行完removeView的操作,surfaceDestroyed就被执行了,此时就会执行第二次的关闭摄像头函数调用,第二次就能成功把removeView操作完成,然后函数回到第一次调用的地方时就会报错,因为View已经被第二次移除掉了。解决方案:加入一个变量,确保release函数在执行完一次时才会再执行第二次,如下:

private fun releaseCamera() {

if (isReleasing) return

isReleasing = true

binding.root.findViewWithTag(TAG)?.let { binding.root.removeView(it) }

camera?.apply {

setPreviewCallback(null)

stopPreview()

release()

camera = null

}

isReleasing = false

}

最后

**一个零基础的新人,我认为坚持是最最重要的。**我的很多朋友都找我来学习过,我也很用心的教他们,可是不到一个月就坚持不下来了。我认为他们坚持不下来有两点主要原因:

他们打算入行不是因为兴趣,而是因为所谓的IT行业工资高,或者说完全对未来没有任何规划。

刚开始学的时候确实很枯燥,这确实对你是个考验,所以说坚持下来也很不容易,但是如果你有兴趣就不会认为这是累,不会认为这很枯燥,总之还是贵在坚持。

技术提升遇到瓶颈了?缺高级Android进阶视频学习提升自己吗?还有大量大厂面试题为你面试做准备!

提升自己去挑战一下BAT面试难关吧

对于很多Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些知识图谱希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

不论遇到什么困难,都不应该成为我们放弃的理由!

如果有什么疑问的可以直接私我,我尽自己最大力量帮助你!

最后祝各位新人都能坚持下来,学有所成。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 32
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值