通常來講拍照的時候儘可能選擇最大的輸出尺寸,以達到最好的預覽效果(和拍出的照片效果同樣)。java
在前文的基礎上進行調整,添加兩個按鈕,拍照模式、錄像模式,點擊後更新預覽窗口。android
首先,在獲取相機輸出尺寸列表時拍個序,按降序排列,方便後面的篩選。git
//獲取指定相機的輸出尺寸列表,並降序排序
outputSizes = CameraUtils.getInstance().getCameraOutputSizes(cameraId, SurfaceTexture.class);
Collections.sort(outputSizes, new Comparator<Size>() {
@Override
public int compare(Size o1, Size o2) {
return o1.getWidth() * o1.getHeight() - o2.getWidth() * o2.getHeight();
}
});
Collections.reverse(outputSizes);
複製代碼
而後設置按鈕點擊事件github
btnImageMode = view.findViewById(R.id.btn_image_mode);
btnImageMode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//拍照模式,選擇最大輸出尺寸
updateCameraPreviewWithImageMode();
}
});
btnVideoMode = view.findViewById(R.id.btn_video_mode);
btnVideoMode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//錄像模式,選擇寬高比和預覽窗口高寬比一致或最接近且的輸出尺寸
//若是該輸出尺寸太小,則選擇和預覽窗口面積最接近的輸出尺寸
updateCameraPreviewWithVideoMode();
}
});
複製代碼
拍照模式的最優輸出尺寸選擇ide
private void updateCameraPreviewWithImageMode(){
previewSize = outputSizes.get(0);
previewView.setAspectRation(previewSize.getWidth(), previewSize.getHeight());
createPreviewSession();
}
複製代碼
錄像模式下最優輸出尺寸的選擇spa
private void updateCameraPreviewWithVideoMode(){
List<Size> sizes = new ArrayList<>();
//計算預覽窗口高寬比,高寬比,高寬比
float ratio = ((float) previewView.getHeight / previewView.getWidth());
//首先選取寬高比與預覽窗口高寬比一致且最大的輸出尺寸
for (int i = 0; i < outputSizes.size(); i++){
if (((float)outputSizes.get(i).getWidth()) / outputSizes.get(i).getHeight() == ratio){
sizes.add(outputSizes.get(i));
}
}
if (sizes.size() > 0){
previewSize = Collections.max(sizes, new CompareSizesByArea());
previewView.setAspectRation(previewSize.getWidth(), previewSize.getHeight());
createPreviewSession();
return;
}
//若是不存在寬高比與預覽窗口高寬比一致的輸出尺寸,則選擇與其寬高比最接近的輸出尺寸
sizes.clear();
float detRatioMin = Float.MAX_VALUE;
for (int i = 0; i < outputSizes.size(); i++){
Size size = outputSizes.get(i);
float curRatio = ((float)size.getWidth()) / size.getHeight();
if (Math.abs(curRatio - ratio) < detRatioMin){
detRatioMin = curRatio;
previewSize = size;
}
}
if (previewSize.getWidth() * previewSize.getHeight() > PREVIEW_SIZE_MIN){
previewView.setAspectRation(previewSize.getWidth(), previewSize.getHeight());
createPreviewSession();
}
//若是寬高比最接近的輸出尺寸過小,則選擇與預覽窗口面積最接近的輸出尺寸
long area = previewView.getWidth() * previewView.getHeight();
long detAreaMin = Long.MAX_VALUE;
for (int i = 0; i < outputSizes.size(); i++){
Size size = outputSizes.get(i);
long curArea = size.getWidth() * size.getHeight();
if (Math.abs(curArea - area) < detAreaMin){
detAreaMin = curArea;
previewSize = size;
}
}
previewView.setAspectRation(previewSize.getWidth(), previewSize.getHeight());
createPreviewSession();
}
複製代碼
本文針對不一樣的使用場景,給出簡單的最優預覽輸出尺寸的選擇方法,固然還有更好,兼容性更強的方法,這裏提供一個簡單的思路。code