最近开发一款自定义相机采集照片的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. MySql_delete同时删除多表相关联记录

    sql delete同时删除多表相关联记录 sqlserver 支持级联更新和删除oracle 只支持级联删除 删除包含主键值的行的操作,该值由其它表的现有行中的外键列引用.在级联删除中,还删除其外键 ...

  2. Oracle问题诊断过程常用SQL

    --查看临时表空间使用情况select tablespace_name ,sum(size_mb),sum(used_mb),round(sum(used_mb)/sum(size_mb),2) fr ...

  3. Linux- systemd

    systemd被设计用来改进sysvinit的缺点,它和ubuntu的upstart是竞争对手,预计会取代它们.systemd的很多概念来源于苹果的launchd.创始人Lennart是redhat员 ...

  4. EBS安装完成后,对数据库相关配置的改动

    EBS安装完成后,对数据库相关配置的改动 1.转为ASM,数据文件,控制文件,redo log,archived log从文件系统转移至ASM 2.禁用resource manager 由于发现系统的 ...

  5. delphi win64 DEBUG不能进预设断点的问题

    delphi win64 DEBUG不能进预设断点的问题  delphi win64,debug模式下运行,如果含有中文路径,不能进断点,音频跟踪.而同样的代码,DELPHI WIN32却没有这个问题 ...

  6. 约合¥1720 LG法国称G Watch将于6月开卖

    近来LG法国官方透露音讯称旗下首款智能手表G Watch将于本年6月份正式出售,预定报价为199欧元(约合¥1720). 这就意味着这款智能手表会在googleI/O大会完成之后就会开端出售,从goo ...

  7. Android图片加载框架最全解析(五),Glide强大的图片变换功能

    大家好,又到了学习Glide的时间了.前段时间由于项目开发紧张,再加上后来又生病了,所以停更了一个月,不过现在终于又可以恢复正常更新了.今天是这个系列的第五篇文章,在前面四篇文章的当中,我们已经学习了 ...

  8. 通过Web启动本地应用程序

    通过自定义协议在Web中启动本地应用程序 实例是打开本地安装的Word程序   注册自己的协议Windows Registry Editor Version 5.00 [HKEY_CLASSES_RO ...

  9. TFS WorkItem Permission Setting

    TFS非常强大,但是权限设置确实非常的恶心复杂,这貌似是一切NB又傲慢的软件的通病. 那么,在哪里设置 WorkItem 的权限呢? 第一步: 第二步: 第三步,下面你将一目了然. 第四步,Share ...

  10. 【Burnside定理】&【Pólya定理】

    Burnside & Pólya (详细内容请参阅<组合数学>或2008年cyx的论文,这里只写一些我学习的时候理解困难的几个点,觉得我SB的请轻鄙视……如果有觉得不科学的地方欢迎 ...