相機在調用過程中需要設置預覽尺寸(分辨率)(640 * 480、1920 * 1080等),同時需要設置一個控件去渲染畫面,這個控件可以是ImageView、TextureView也可以是SurfaceView。一般常見的預覽尺寸比例是4:3、16:9等,但在開發(fā)時界面上給的預覽窗口一般不會是這些比例,這時如果不做處理,預覽畫面鋪面整個窗口時就會出現(xiàn)拉伸或者縮小的情況。
這里給出兩種解決方法:
1、通過Matrix對每一幀圖片做縮放、移動等操作,然后通過Canvas繪制到渲染容器里。
偽代碼:
數(shù)據(jù)幀回調 ->{
val bitmap = 從每一幀數(shù)據(jù)中獲取Bitmap
val canvas = 從TextureView或者SurfaceView中獲取Canvas
/*bitmap的尺寸已知即初始化相機參數(shù)時設定的分辨率(640 * 480、1920 * 1080等)
*通過bitmap的寬高尺寸和控件的寬高尺寸算出bitmap的縮放比例ratio
*計算ratio根據(jù)最小寬度計算(類似于屏幕適配里的一種方案)
*最小寬度計算:以4:3出圖為例(分辨率為640 * 480),
*假如此時控件的寬度為1600px,那么按4:3的寬高比計算高度應該不低于1200px,
*如果實際高度小于了1200px,那么就應該以實際控件高度去計算出對應的寬度,
*確定了bitmap應該渲染出的寬高就算出來縮放比ratio。
*/
matrix: Matrix
if(第一幀數(shù)據(jù)){
val scaleRatio = if (viewWidth>以viewHeight和寬高比例計算出的寬度)viewHeight/bitmapHeight else viewWidth/bitmapWidth
matrix.postScale(scaleRatio,scaleRatio)//寬高等比縮放
//圖片進行了縮放,不能充滿整個渲染容器,通過位移操作將圖片置于容器中心
matrix.postTranslate(if(以寬度計算)0f else(viewWidth-(viewHeight*bitmapWidth/bitmapHeight)/2),if(以寬度計算) (viewHeight-(viewWidth*bitmapHeight/bitmapWidht)/2) else 0f)
}
canvas.drawBitmap(bitmap,matrix,paint)
}
2、自定義TextureView或者SurfaceView,通過外部設置的寬高比重新計算控件尺寸,重寫onMeasure()函數(shù)。
AspectRatioSurfaceView :SurfaceView{
setRatio(width,height){
//設置寬高比,還是以最小寬度原則去評定是以寬度計算還是高度計算
if(getWidth()>getHeight()*width/height) 以高度計算 else 以寬度計算
重繪布局
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int){
if(以高度計算)setMeasuredDimension(getHeight()*width/height,getHeight())
else setMeasuredDimension(getWidth(),getWidth()*heigth/width)
}
}
上述兩種方法只是基于設備處于一個橫豎屏不變的情況下寫的,如果有橫豎屏切換的場景,還需要獲取設備方向然后動態(tài)調整。