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 ...
随机推荐
- R tutorial
http://www.clemson.edu/economics/faculty/wilson/R-tutorial/Introduction.html https://www.youtube.com ...
- Java设计模式(7)——结构型模式之适配器模式(Adapter)
一.概述 概念 其实,举个生活中的例子的话,适配器模式可以类比转接头,比如typeC和USB的转接头,把原本只能接typeC的接口,拓展为可以接普通USB:这里的转接头一方面需要查在typeC上,一方 ...
- Caliburn.Micro 杰的入门教程1(翻译)
Caliburn.Micro 杰的入门教程1(原创翻译)Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(翻译)Caliburn.Micro 杰的入门教程 ...
- 【转】Odoo:基本字段类型
class Stage(models.Model): _name = 'todo.task.stage' _order = 'sequence,name' # String fields: name ...
- Hough变换-理解篇
Hough变换-理解篇 霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体.该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符 ...
- 4946: [Noi2017]蔬菜
4946: [Noi2017]蔬菜 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 分析: 贪心. 首先可以将一个蔬菜拆成两个,一个是有加成 ...
- gitlab改root密码
1. ~$ sudo gitlab-rails console production 2.查询要改的用户 irb(main)::> u = User.where().first => #& ...
- selenium自动化测试资源整理
1. 所有版本chrome下载 是不是很难找到老版本的chrome?博主收集了几个下载chrome老版本的网站,其中哪个下载的是原版的就不得而知了. http://www.slimjet.com/ch ...
- leetcode-二叉树的层次遍历(Java)
给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如:给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其层 ...
- Redis 数据结构服务器
Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久 ...