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 ...
随机推荐
- linux驱动动态与静态加载
在Linux中驱动的加载方式有动态加载和静态加载.动态加载,即驱动不添加到内核中,在内核启动完成后,仅在用到这一驱动时才会进行加载静态加载,驱动编译进内核中,随内核的启动而完成驱动的加载.添加字符驱动 ...
- P2P通讯
转载: http://www.cnblogs.com/pannengzhi/p/4800526.html http://blog.csdn.net/lee353086/article/details/ ...
- 状压搜索 洛谷T47092 作业
TYM 有 nn 本作业,编号为 1,\dots,n1,…,n. 由于 \mathrm{TYM}TYM 很喜欢偷懒,而且不喜欢消耗脑细胞,所以他选择跳着完成这 nn 本作业.此外,如果将做作业的顺序转 ...
- web项目由简入繁
1.MVC--[javaBean+接口+jdbc+servlet+jsp] 用javaBean做数据模型, 数据操作放到DAO层 前端页面展示由JSP完成 页面跳转由servlet完成,页面数据传递用 ...
- 成都Uber优步司机奖励政策(4月1日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- SpringBoot-01:什么是SpringBoot?
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- SpringBoot: Spring Boot可以轻松创建独立的,生产级的基于Spring的应用程序,您可以“ ...
- fastjson处理json
返回主页 你是风儿 博客园首页新随笔联系订阅管理 随笔 - 29 文章 - 0 评论 - 23 FastJson对于JSON格式字符串.JSON对象及JavaBean之间的相互转换 fastJson对 ...
- XenServer master主机的作用
https://wenku.baidu.com/view/a2d3f0a333d4b14e852468c9.html###
- editText设置最大长度
xml中可以设置为: <EditText android:layout_width = "fill_parent" android:layout_height = " ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 第3章.Servlet应用
第3章.Servlet应用 转发与重定向 转发:浏览器发送资源请求到ServletA后,ServletA传递请求给ServletB,ServletB生成响应后返回给浏览器. 请求转发:forward: ...