代码地址如下:
http://www.demodashi.com/demo/13271.html

一、需求

最接近WeChat的全屏自定义相机(Custom Camera),拍照和预览都是全屏尺寸。使用Camera API,告别摄像头PictureSize的限制。

接触过相机开发的都知道,Camera.Parameters支持的PreviewSIze和PictureSize是不匹配的。这就导致预览和拍照的图像尺寸不一致。一般情况下PreviewSize支持的尺寸包括手机屏幕尺寸,而PictureSize包含的尺寸就古怪的多了。

这就找到了实现全屏拍照的突破口

监听预览,拿到相机预览图像数据,转成bitmap

二、程序实现

  • 清单文件添加权限
<uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

sdk 25 (android6.0) 以上记得动态获取权限

  • 在onResume()里初始化相机
Camera camera = Camera.open(cameraId);// cameraId 为0,是开启后置摄像头;1 是前置摄像头。多摄的情况不在此考虑范围内。
//将预览图像渲染到surfaceView上
mHolder = surfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
camera.setPreviewDisplay(mHolder);
  • 关键来了,设置Camera.Parameters 这里很容易出现各种问题

在相机API中可以通过setDisplayOrientation()设置相机预览方向。在默认情况下,这个值为0,与图像传感器一致。因此对于横屏应用来说,由于屏幕方向和预览方向一致,预览图像不会颠倒90度。但是对于竖屏应用,屏幕方向和预览方向垂直,所以会出现颠倒90度现象。为了得到正确的预览画面,必须通过API将相机的预览方向旋转90,保持与屏幕方向一致

camera.setDisplayOrientation(90); //横向变竖向

这是我的小米6相机支持的预览尺寸

preview-size-values parameter: 2160x1080,2048x1536,2048x1080,1920x1440,1920x1080,1920x960,1440x1080,1280x960,1280x720,1280x640,864x480,800x480,768x432,720x480,640x640,640x480,480x640,640x360,576x432,480x360,480x320

我们需要根据屏幕尺寸找到最适合的预览尺寸

private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) {int bestX = 0;int bestY = 0;int diff = Integer.MAX_VALUE;for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) {previewSize = previewSize.trim();int dimPosition = previewSize.indexOf('x');if (dimPosition < 0) {Log.w(TAG, "Bad preview-size: " + previewSize);continue;}int newX;int newY;try {newX = Integer.parseInt(previewSize.substring(0, dimPosition));newY = Integer.parseInt(previewSize.substring(dimPosition + 1));} catch (NumberFormatException nfe) {Log.w(TAG, "Bad preview-size: " + previewSize);continue;}int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y);if (newDiff == 0) {bestX = newX;bestY = newY;break;} else if (newDiff < diff) {bestX = newX;bestY = newY;diff = newDiff;}}if (bestX > 0 && bestY > 0) {return new Point(bestX, bestY);}return null;}

返回得到一个point,起名叫cameraResolution。 设置给parameters

Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y); parameters.setPreviewFormat(ImageFormat.NV21);

最后
拍照 不是调用camera.takePicture()而是设置监听PreviewCallback接口camera.setOneShotPreviewCallback(previewCallback);

在回调方法onPreviewFrame(byte[] data, Camera camera)里处理预览图像字节数组data。data是YUV格式的数据,我们需要把它转成Android支持的rgb格式

YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null);//android.graphics包下提供的将YUV转成JPEG的APIByteArrayOutputStream baos = new ByteArrayOutputStream();yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, baos);//YUV压缩成JPEGBitmapFactory.Options localOptions = new BitmapFactory.Options();localOptions.inPreferredConfig = Bitmap.Config.RGB_565;  //构造位图生成的参数,必须为565。类名+enumBitmap bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.toByteArray().length, localOptions);//转成rgb的bitmapbaos.close();

这时的bitmap还是横向的,即使相机转成竖向,那也是预览变正常了。但onPreviewFrame里拿到的数据依然是横向

//转成竖向bitmap
Matrix matrix = new Matrix();
matrix.postRotate(270);
// 创建新的图片
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,bitmap.getWidth(), bitmap.getHeight(), matrix, true);

思路流程还是很清晰的

三、项目文件结构


customcamera是自定义相机的库,方便移植到任何project中使用

四、运行效果演示

五、补充

暂时没有
最接近WeChat的全屏自定义相机(Custom Camera)

代码地址如下:
http://www.demodashi.com/demo/13271.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

最接近WeChat的全屏自定义相机(Custom Camera)相关推荐

  1. 关于html5 video全屏+自定义控制器

    最近整了台nas机,准备自己写个视频网站搭建家庭媒体服务.临时记录下h5 video全屏+自定义控制器的实现的方式,之后会针对实现完整的h5 video播放控制写一些介绍和遇到的坑. video标签中 ...

  2. iOS录屏/自定义相机

    录制屏幕参考(录制屏幕 UI元素) 使用AVFoudation https://github.com/search?l=Objective-C&q=ScreenRecoder&type ...

  3. android自定义dialog 全屏,自定义dialog全屏显示

    默认的Dialog是不能全屏的.也就是怎么设置Dialog的Layout都没用的. 下面给出实现Dialog实现全屏的两种方式: 1.代码实现.这中方法相对比较简单 首先继承Dialig,然后再构造函 ...

  4. android 自定义相机,Camera,相机遮罩层

    实现效果:      实现方法:一个自定义view实现demo 一.自定义相机Camera,无API版本限制 (1).实现接口 implements SurfaceHolder.Callback pr ...

  5. Android自定义相机

    转载请指明出处@https://blog.csdn.net/qq_41912447 版权归博主所有 /** **本文由自己搜集资料编程 如有错误请指明 **李紫洋著 */ 导引 相机成为了一个app必 ...

  6. uni-app自定义相机

    设计思路: 调用camera相机组件,用cover-view,cover-image标签添加自定义页面布局,拍完照之后将照片画到canvas里面,然后用canvasToTempFilePath方法导出 ...

  7. JavaScript网页全屏API

    在大多数的浏览器中都有实现网页全屏显示的功能,并且大部分浏览器实现全屏显示和退出全屏显示的快捷键通常是F11和Esc两个按键.如今,W3C已经制定了关于网页全屏显示的API,利用这个API 可以实现网 ...

  8. android 摄像头比例,Android摄像头是全屏预览最简单的方式.doc

    Android摄像头是全屏预览最简单的方式 Android Camera做全屏预览之最简单方法 M厂开发五部:刘 博 一.全屏预览与非全屏预览的区别 对于大多数人来说,我们看电影.玩游戏等都喜欢全屏, ...

  9. android camera 全屏,Android Camera做全屏预览之最简单方法.doc

    Android Camera做全屏预览之最简单方法 M厂开发五部:刘 博 一.全屏预览与非全屏预览的区别 对于大多数人来说,我们看电影.玩游戏等都喜欢全屏,我们之所以喜欢全屏的一个主要原因就是全屏的感 ...

最新文章

  1. oracle 判断如果有符合条件的记录则不插入_Oracle数据库AWR部分报告说明
  2. 快速编辑 Shell 命令行
  3. mysql定时器每月执行一次_MySQL定时器可以设置执行次数吗
  4. jQuery 1.11 / 2.1 beta 版发布
  5. 数据结构迷宫代码_数据结构课程设计——迷宫求解(二)
  6. Transaction marked as rollbackOnly异常处理 Duplicate entry 'xxx' for key
  7. Python中random模块生成随机数详解
  8. 线程与进程,你真的清楚吗?
  9. cifar10数据集测试有多少张图_图神经网络的ImageNet?斯坦福开源百万量级OGB基准测试数据集...
  10. 用python 画炫酷的图并讲解-Python绘制六种可视化图表详解,三维图最炫酷!你觉得呢?...
  11. 用户研究三部曲:有关用户研究的战略思考
  12. 六石管理学:切勿通过扯皮折腾别人,一句你不要管了即可
  13. atitit.提升备份文件复制速度(1) -----分析统计问题and解决方案
  14. c# 代码混淆器ConfuserEX使用
  15. educator计算机技术基础答案,计算机教育技术基础,technical basis of computer education,音标,读音,翻译,英文例句,英语词典...
  16. 拆解全笔记 | 《高阶运营:从小编到新媒体操盘手》
  17. springboot校园疫情智慧防控微信小程序毕业设计源码011133
  18. c语言表达式判断语法错误题,大连理工大学C语言模拟题机房题库单选、判断、填空(分章节_共十一章)...
  19. Squirrel脚本语言..游戏开发.
  20. DLL的远程注入技术详解

热门文章

  1. uk码对照表_这份中外衣服鞋码尺寸对照表,请收好!
  2. java xmlutil_XmlUtil工具类(toxml()和toBean())
  3. 14. GD32F103C8T6入门教程-Systick定时器
  4. 10.FreeRTOS学习笔记-中断管理
  5. QT编译boost库
  6. oracle行锁 查询等待,Oracle 的for update行锁语法
  7. linux路由内核实现分析(四)---路由缓存机制(4)
  8. linux vim文本编辑器
  9. Python-Flask构建微信小程序订餐系统-Flask打造高可用flask mvc框架-08
  10. Scala-列表操作