简单来讲,预览图像拉伸问题是相机的输出尺寸和屏幕上预览窗口的宽高比不一样引发的。因此能够根据选择的相机输出尺寸的宽高比调整预览窗口的宽高比,使二者一致,从而消除图像拉伸问题。java
本篇文章在上篇文章的基础上,自定义能够设置宽高比的预览控件 AutoFitTextureView
,解决图像拉伸的问题。android
AutoFitTextureView
继承自 TextureView
,添加一个约束宽高比的方法,设定宽高比后请求系统从新计算布局,实现预览窗口大小的调整。git
public class AutoFitTextureView extends TextureView {
private int ratioW = 0;
private int ratioH = 0;
public AutoFitTextureView(Context context) {
super(context);
}
public AutoFitTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoFitTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/** * 设置宽高比 * @param width * @param height */
public void setAspectRation(int width, int height){
if (width < 0 || height < 0){
throw new IllegalArgumentException("width or height can not be negative.");
}
//相机输出尺寸宽高默认是横向的,屏幕是竖向时须要反转
// (后续适配屏幕旋转时会有更好的方案,这里先这样)
ratioW = height;
ratioH = width;
//请求从新布局
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == ratioW || 0 == ratioH){
//未设定宽高比,使用预览窗口默认宽高
setMeasuredDimension(width, height);
}else {
//设定宽高比,调整预览窗口大小(调整后窗口大小不超过默认值)
if (width < height * ratioW / ratioH){
setMeasuredDimension(width, width * ratioH / ratioW);
}else {
setMeasuredDimension(height * ratioW / ratioH, height);
}
}
}
}
复制代码
AutoFitTextureView
的使用TextureView
替换为 AutoFitTextureView
的类全路径便可。previewSize
后添加 previewView.setAspectRation(previewSize.getWidth(), previewSize.getHeight());
通过上述改造,切换相机输出尺寸时,预览窗口会自动调整大小,保持和输出尺寸有相同的宽高比,这样就不会再出现图像拉伸的问题。github
可是,如今还有一个问题,就是若是手机未锁定方向,当手机横向放置的时候,预览窗口里的图像旋转了90度,并且布局也有问题,须要接着优化,后续文章实现。ide