簡單來說,預覽圖像拉伸問題是相機的輸出尺寸和屏幕上預覽窗口的寬高比不同引起的。所以可以根據選擇的相機輸出尺寸的寬高比調整預覽窗口的寬高比,使兩者一致,從而消除圖像拉伸問題。
本篇文章在上篇文章的基礎上,自定義可以設置寬高比的預覽控件 AutoFitTextureView
,解決圖像拉伸的問題。
1. 自定義 AutoFitTextureView
AutoFitTextureView
繼承自 TextureView
,添加一個約束寬高比的方法,設定寬高比後請求系統重新計算佈局,實現預覽窗口大小的調整。
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);
}
}
}
}
2. AutoFitTextureView
的使用
- 佈局文件:將
TextureView
替換爲AutoFitTextureView
的類全路徑即可。 - 代碼使用:在初始化界面及按鈕點擊事件更新
previewSize
後添加previewView.setAspectRation(previewSize.getWidth(), previewSize.getHeight());
3. 總結
經過上述改造,切換相機輸出尺寸時,預覽窗口會自動調整大小,保持和輸出尺寸有相同的寬高比,這樣就不會再出現圖像拉伸的問題。
但是,現在還有一個問題,就是如果手機未鎖定方向,當手機橫向放置的時候,預覽窗口裏的圖像旋轉了90度,而且佈局也有問題,需要接着優化,後續文章實現。