Android Camera多屏幕适配解决预览照片拉伸
通常,拍照预览页面的照片拉伸主要与下面两个因素有关:
1. Surfaceview的大小
2. Camera中的Preview的大小
如下图:
如图,该手机surfaceview大小为1280*720(横屏,比例为:16:9)预览尺寸大小为960*720(横屏,比例为4:3)。从上面的二维码可以看到产生了明显的拉伸。正因为surfaceview的宽高比例跟camera preview的宽高比例不一样才会产生这样的效果。
如果surfaceview尺寸比例跟预览尺寸比例相同,那便不会产生变形,如下图:
设置surfaceview大小为 1280*720(横屏,比例为:4:3)预览尺寸大小为2048*1152(横屏,比例为4:3)便不会拉伸变形。
上面只是针对一种屏幕进行设置,而且每台手机所支持的预览尺寸是不一样的,所以这样子固定死的话很可能会产生程序崩溃,而崩溃的原因是因为该手机不支持你所支持的尺寸。
那么问题就来了,怎么样才能够达到适配多台手机,界面不产生拉伸变形,而且程序又不崩溃?
思路如下:
1. 先将获取手机支持预览的尺寸列表通过方法parmeters.getSupportedPreviewSizes()来得到返回类型为List<Size>的值,
2. 先进行屏幕方向的一个判断,因为预览列表里面的尺寸都是w>h(即横屏),如果屏幕是竖屏则需要先将宽高进行调换,这样方便接下来的比较。
3. 先用for循环将预览尺寸列表每个元素宽高与surfaceview的宽高进行比较,如果存在宽高尺寸都与surfaceview宽高尺寸相同的size则将该宽高设置为预览尺寸。
4. 如果步骤2找不到相同尺寸就得进行该步骤,将尺寸列表的宽高比例和surfaceview的比例作比较,找到一个相同或相近的。(一般来说,只要surfaceview的尺寸和屏幕尺寸相同,就可以找到相同的比例)然后将该尺寸的size设置为预览尺寸。
接下来是上代码
/**
* 通过对比得到与宽高比最接近的尺寸(如果有相同尺寸,优先选择)
*
* @param surfaceWidth
* 需要被进行对比的原宽
* @param surfaceHeight
* 需要被进行对比的原高
* @param preSizeList
* 需要对比的预览尺寸列表
* @return 得到与原宽高比例最接近的尺寸
*/
protected Camera.Size getCloselyPreSize(int surfaceWidth, int surfaceHeight,
List<Size> preSizeList) { int ReqTmpWidth;
int ReqTmpHeight;
// 当屏幕为垂直的时候需要把宽高值进行调换,保证宽大于高
if (mIsPortrait) {
ReqTmpWidth = surfaceHeight;
ReqTmpHeight = surfaceWidth;
} else {
ReqTmpWidth = surfaceWidth;
ReqTmpHeight = surfaceHeight;
}
//先查找preview中是否存在与surfaceview相同宽高的尺寸
for(Camera.Size size : preSizeList){
if((size.width == ReqTmpWidth) && (size.height == ReqTmpHeight)){
return size;
}
} // 得到与传入的宽高比最接近的size
float reqRatio = ((float) ReqTmpWidth) / ReqTmpHeight;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
Camera.Size retSize = null;
for (Camera.Size size : preSizeList) {
curRatio = ((float) size.width) / size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
} return retSize;
}
其中 参数 width 和height 是 SurfaceView 的宽和高,可以在surfaceChanged方法中找到:
package com.yfqsdie.tower.preview; import com.yfqsdie.tower.util.CameraUtil; import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView; /**
* Created by renlei
* DATE: 15-11-5
* Time: 下午4:52
*/
public class MySurfacePreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder surfaceHolder;
private Handler mHandler; public MySurfacePreview(Context context, AttributeSet attrs) {
super(context, attrs);
surfaceHolder = getHolder();
surfaceHolder.setFormat(PixelFormat.TRANSPARENT);//translucent半�?�明 transparent透明
surfaceHolder.addCallback(this);
} @Override
public void surfaceCreated(SurfaceHolder holder) {
CameraUtil.getInstance().doOpenCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
} @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.print("width="+width+" height="+height+" format="+format);
// CameraUtil.getInstance().doStartPreview(surfaceHolder);
CameraUtil.getInstance().doStartPreview(surfaceHolder,width,height); //spire modify 2017-09-27 解决变形问题
if (mHandler != null) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mHandler.sendEmptyMessage(CameraUtil.PREVIEW_HAS_STARTED);
}
}, 1000);
}
} @Override
public void surfaceDestroyed(SurfaceHolder holder) {
CameraUtil.getInstance().doStopPreview();
} public void setmHandler(Handler handler) {
this.mHandler = handler;
}
}
Android Camera多屏幕适配解决预览照片拉伸的更多相关文章
- android下在屏幕适配小总结
为什么要屏幕适配?为此我就不说了,网上处理方法要么让你用几套不同分辨率的图片,要么写几套布局文件,要么就是在xml中写dip(这个还是可以的),前面两种感觉过程工作量太大了,由加载大图片的优化思想 同 ...
- Android camera调用出现错误解决方法
开发时,先是使用三星的手机测试,发现一切正常: 但是到了小米的手机的时候,发现图片很模糊,发现是设置camera.setParameters(parameters);报错导致用的是默认的最小的分辨率, ...
- Android下的屏幕适配
1080 100dp 300px720 100dp 200px 300px 1080px 比例是300/1080=0.277200px 720px
- Android 多分辨率多屏幕适配
请参见文章:http://blog.csdn.net/jiangxinyu/article/details/8598046 文章描述非常清晰.
- Android开发——自动生成Android屏幕适配的dimens.xml文件
使用dimens.xml解决屏幕适配问题是Android官方解决方案,本文主要讲述了如何自动生成Android屏幕适配的dimens.xml,减少了工作量,在维护dimens.xml文件时更加省时省力 ...
- Android 多屏幕适配 dp和px的关系 最好用dp
Android 多屏幕适配 dp和px的关系 一直以来别人经常问我,android的多屏幕适配到底是怎么弄,我也不知道如何讲解清楚,或许自己也是挺迷糊. 以下得出的结论主要是结合官方文档进行分析的ht ...
- Android 多屏幕适配 dp和px的关系
一直以来别人经常问我,android的多屏幕适配到底是怎么弄,我也不知道如何讲解清楚,或许自己也是挺迷糊. 以下得出的结论主要是结合官方文档进行分析的https://developer.android ...
- Android屏幕适配笔记
1.限定符 为了适配不同屏幕大小的android手机或android平板,有时候就需要利用限定符来为不同的屏幕设定不同的布局文件,在一般情况下我们都是在layout文件夹下为某个活动准备一个默认的布局 ...
- Android屏幕适配与切图_汇总
首先和最后,还是先看好官方文档:http://developer.android.com/guide/practices/screens_support.html 对应的翻译blog有牛人做了:And ...
随机推荐
- Angularjs 自定义指令 (下拉菜单)
为什么要自定义控件?html的select 不是可以用么?以前我就是这么想的,当我接到特殊需求时,需要我自己写一个下拉控件. 这个需求就是将图表横向放大,由于H5不能控制设备转向,所以我将图表通过cs ...
- 为啥学蛇和python10年后的变化
作者:cheng rianley链接:https://www.zhihu.com/question/22112542/answer/166053516来源:知乎著作权归作者所有.商业转载请联系作者获得 ...
- gdb 分析出错
1 创建测试代码test.php <?php function test1(){ while(true){ sleep(1); } }echo getmypid() "\r\n&quo ...
- WebDriver--定位元素的8种方式
在UI层面的自动化测试开发中,元素的定位与操作是基础,也是经常遇到的困难所在.webdriver提供了8种定位: 1. id定位:find_element_by_id("id值") ...
- ntp-redhat 同步时间配置
1. 选作一个机器作为ntp 服务端,例如 ip 为192.168.0.1 1)安装 ntp服务 yum install ntp 2) 修改ntp.conf 文件 vi /etc/ntp.conf 注 ...
- 初学Direct X(5)
初学Direct X(5) 前面学习了使用表面绘制屏幕,但这种方法与另一种比较起来,有着绘图速度颇慢以及缺乏对任何透明类型的支持,这就是前面的篮框以及炸弹会有黑色背景的原因,这种方法就是纹理.他可以绘 ...
- 【转】巫师3:狂猎(The Witcher 3: Wild Hunt )的游戏事件工作流
转自腾讯游戏开发者平台(GAD) CDPROJEKT RED的主程序.Piotr Tomsinski 在GDC2016的最后一天18号,CDPROJEKT RED的主程Piotr Tomsinski, ...
- OpenMPI源码剖析3:try_kill_peers 和 ompi_rte_abort 函数
接着上一篇的疑问,我们说道,会执行 try_kill_peers 函数,它的函数定义在 ompi_mpi_abort.c 下: // 这里注释也说到了,主要是杀死在同一个communicator的进程 ...
- pandas协助工具
pandas有时候操作很不方便,也有可能是我不熟练吧,反正就是各种别扭.下面是我写的一个简单的json数据操作工具,能够完成简单的数据分析工作,后续会不断完善的 # coding=utf-8 impo ...
- POJ 1639 Picnic Planning(最小度限制生成树)
Description The Contortion Brothers are a famous set of circus clowns, known worldwide for their inc ...