最近开发一款自定义相机采集照片的demo,花了一个上午开发了一个在测试机上功能正常的apk连同测试机一起交付(需求方反馈没有Android设备),然而晚上被喊去说是在华为畅玩某型号上预览会变形,拍到的图片边界都移位了,只要加个班处理一下机型适配的问题。根据开发经验,防止预览图像变形的终极奥义就是保持照相机硬件支持的某个size(每个特定的手机都有其支持的camera分辨率)、屏幕宽高比、界面上SurfaceView的宽高比尽量一致,同时保持拍照图与预览图分辨率一致,拍出来的照片就和预览看到的相同。

  下面给出实现代码:

  

    private fun getOptimalPreviewSize(sizes: List<Camera.Size>?, w: Int, h: Int): Camera.Size? {
val ASPECT_TOLERANCE = 0.1
val targetRatio = h.toDouble() / w if (sizes == null) return null var optimalSize: Camera.Size? = null
var minDiff = java.lang.Double.MAX_VALUE for (size in sizes) {
val ratio = size.width.toDouble() / size.height
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue
if (Math.abs(size.height - h) < minDiff) {
optimalSize = size
minDiff = Math.abs(size.height - h).toDouble()
}
} if (optimalSize == null) {
minDiff = java.lang.Double.MAX_VALUE
for (size in sizes) {
if (Math.abs(size.height - h) < minDiff) {
optimalSize = size
minDiff = Math.abs(size.height - h).toDouble()
}
}
}
return optimalSize
}

其中第一个参数sizes是camera支持的预览size列表,第二个是View的宽,第三个是View的高,由于我这里的surfaceview是全屏的,所以传入的宽和高可以是屏幕的宽和高

下面给出完整代码:

    override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
screenWidth = ScreenUtil.getWindowWidth(this)
screenHeight = ScreenUtil.getWindowHeigh(this)
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK)
surface.holder.addCallback(this)
} override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
camera?.setPreviewDisplay(holder)
camera?.startPreview()
} override fun surfaceDestroyed(holder: SurfaceHolder?) {
} override fun surfaceCreated(holder: SurfaceHolder?) {
if (camera == null) {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK)
}
val parameters = camera?.parameters
var sizes = parameters!!.supportedPreviewSizes
var preSize = getOptimalPreviewSize(sizes, screenWidth, screenHeight)
parameters.setPreviewSize(preSize!!.width, preSize.height)
//重新给定surfaceView宽高
surface.resize(preSize.width, preSize.height)
if (parameters.supportedFocusModes!!.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
parameters.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO
}
parameters.sceneMode = Camera.Parameters.SCENE_MODE_AUTO
//保持picturesize与presize一致
parameters.setPictureSize(preSize.width, preSize.height)
parameters.previewFormat = ImageFormat.NV21
camera?.parameters = parameters
camera?.setPreviewDisplay(holder)
camera?.startPreview()
} private fun getOptimalPreviewSize(sizes: List<Camera.Size>?, w: Int, h: Int): Camera.Size? {
val ASPECT_TOLERANCE = 0.1
val targetRatio = h.toDouble() / w if (sizes == null) return null var optimalSize: Camera.Size? = null
var minDiff = java.lang.Double.MAX_VALUE for (size in sizes) {
val ratio = size.width.toDouble() / size.height
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue
if (Math.abs(size.height - h) < minDiff) {
optimalSize = size
minDiff = Math.abs(size.height - h).toDouble()
}
} if (optimalSize == null) {
minDiff = java.lang.Double.MAX_VALUE
for (size in sizes) {
if (Math.abs(size.height - h) < minDiff) {
optimalSize = size
minDiff = Math.abs(size.height - h).toDouble()
}
}
}
return optimalSize
} override fun onWindowFocusChanged(hasFocus: Boolean) {
val decorView = this@CameraActivity.window.decorView
decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
} override fun onPause() {
super.onPause()
camera?.stopPreview()
} override fun onDestroy() {
super.onDestroy()
camera?.setPreviewCallback(null)
camera?.release()
}

Camera 预览变形问题解决的更多相关文章

  1. opencv-android笔记1:android studio 2.3 + opencv-android-sdk 实现 camera预览

    Android studio环境配置不再赘述,可以参照我的其他博客. Android应用程序开发环境搭建:http://blog.csdn.net/ja33son/article/details/61 ...

  2. Android Camera 预览图像被拉伸变形的解决方法【转】

    问题描述: 预览图像被拉伸变形 问题原因: 由于预览图像大小跟SurfaceView 大小不一致引起 解决方法: 获取系统支持的所有预览尺寸[getSupportedPictureSizes],然后再 ...

  3. 圆形Camera预览实现

    需求 最近有个需求要求界面上使用圆形相机预览进行面部检测 , 具体需求如下图 关于Camera之前接触得比较多 , 主要就是通过SurfaceView显示预览视图 , 因此需要展示圆形预览界面, 只需 ...

  4. Android手势识别 Camera 预览界面上显示文字 布局注意事项(merge布局)

    通常在Surfaceview作为预览视频帧的载体,有时需在上面显示提示文字.曾经我弄的都好好的.今天忽然发现叠加的TextView不管咋弄都出不来文字了,跟Surfaceview一起放在FrameLa ...

  5. vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决:

    //预览<div class="htmlViewBox"> <p v-html="activity_html_defaultMsg" v-sh ...

  6. android camera 摄像头预览画面变形

    问题:最近在处理一下camera的问题,发现在竖屏时预览图像会变形,而横屏时正常.但有的手机则是横竖屏都会变形. 结果:解决了预览变形的问题,同时支持前后摄像头,预览无变形,拍照生成的jpg照片方向正 ...

  7. 玩转Android Camera开发(四):预览界面四周暗中间亮,仅仅拍摄矩形区域图片(附完整源代码)

    杂家前文曾写过一篇关于仅仅拍摄特定区域图片的demo.仅仅是比較简陋.在坐标的换算上不是非常严谨,并且没有完毕预览界面四周暗中间亮的效果,深以为憾.今天把这个补齐了. 在上代码之前首先交代下,这里面存 ...

  8. Android开发实践:掌握Camera的预览方向和拍照方向

    http://ticktick.blog.51cto.com/823160/1592267?utm_source=tuicool&utm_medium=referral Android的Cam ...

  9. OV5640全景模式预览倒180度,拍照正常的问题

    此方法基本上适用于所有android平台上全景模式预览倒180度,拍照正常的问题. 首先说明的是,影响camera方向的有三个地方,分别是系统方向,内核camera方向和驱动镜像.全景模式预览只跟系统 ...

随机推荐

  1. 使用命令行编译和运行 c、Java和python程序

    集成开发环境已经非常方便,从编写程序到执行程序看到结果,让我们不用关心中间的过程.但是使用原始的.命令的方式来将程序编译运行有的时候可能有些用,比如写个简答的程序,或者是身边没有集成工具的时候. C语 ...

  2. C#设计模式泛型注入

    TSFac注入方式: 泛型接口工厂: public class SFac<TInterface, TClass> where TInterface : class where TClass ...

  3. CentOS 7挂载磁盘提示: mount: unknown filesystem type 'LVM2_member'

    说明:CentOS 7采用新的分区格式xfs以及LVM的模式,造成挂载硬盘的方式有变化. 解决: 使用lvdisplay命令查看LVM最终的卷路径,然后再进行挂载. 比如: mount /dev/Vo ...

  4. InvalidateRect(转)

    ///===================该段是自己总结的一个小结================================= InvalidateRect()函数的作用是设置一个无效区域,并 ...

  5. systemtap 用户态调试2

    [root@localhost ~]# cat user.stpprobe process(@1).function(@2){print_ubacktrace();exit();} session 1 ...

  6. Android项目文件夹结构分析

    项目结构例如以下图所看到的,使用不同sdk版本号建立的项目项目结构有所不同,整体同样,高版本号添加了一些包结构 1.src 和java项目一样src存放项目源码 2.gen 自己主动生成,当中R.ja ...

  7. hybrid App h5二级页面返回的时候保持与一级页面浏览的位置一致

    最近在开发公司hybrid app的时候,需要将原本原生的配置中心模块统一变更为H5,做完之后从测试那里反馈回来这样一个问题,当滑到页面底部或中部的时候进入子页面进行设置,返回的时候页面应该定位到离开 ...

  8. 浅用block 转

    block是一门有用的大后期学问.现在我只是列出一点基本用法. 1.快速枚举(Enumeration) 通常是和NSArray, NSDictionary, NSSet, NSIndexSet放在一起 ...

  9. Unity3.x游戏开发经典教程 书例 100%完毕~

    大家都公布自己的作品,作为一个新人,我也发点什么.刚刚做完了Unity3.x游戏开发经典教程书例不久,假如有同学想学这本书入门U3D,我的作品也能让新人參考一下...脚本都是C#写的.以下附上链接~ ...

  10. 算法:哈希表格(Hash Table)

    背景 Java 和 .Net 平台都有一个所有引用类型都会间接或直接继承的类型:Object,这个类型提供最基本的相等性比较算法和哈希算法,很多书上都给出了在重写这两个算法的时候的主意事项,其中大多数 ...