android-camera2相機開發【3】-解決相機預覽影象拉伸問題
簡單來說,預覽影象拉伸問題是相機的輸出尺寸和螢幕上預覽視窗的寬高比不同引起的。所以可以根據選擇的相機輸出尺寸的寬高比調整預覽視窗的寬高比,使兩者一致,從而消除影象拉伸問題。
本篇文章在上篇文章的基礎上,自定義可以設定寬高比的預覽控制元件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度,而且佈局也有問題,需要接著優化,後續文章實現。