上一篇文章中介紹了相機(jī)預(yù)覽的基本實(shí)現(xiàn)隙袁,只固定的顯示了一個(gè)輸出尺寸花履, android 設(shè)備相機(jī)實(shí)際可以支持輸出很多尺寸的圖像鸽粉,不同的設(shè)備具體尺寸數(shù)值不同状原,通過(guò)系統(tǒng)提供的方法可以獲取設(shè)備支持的輸出尺寸聋呢,具體的操作可以參考上一篇文章中的相關(guān)內(nèi)容。
本文在上一篇文章的基礎(chǔ)上進(jìn)行調(diào)整颠区,實(shí)現(xiàn)的效果是削锰,添加一個(gè)按鈕,點(diǎn)擊的時(shí)候切換相機(jī)輸出尺寸毕莱,更新預(yù)覽界面器贩。
1. 簡(jiǎn)單的工具類
將一些簡(jiǎn)單的相機(jī)的操作封裝程一個(gè)工具類,能獲取指定的相機(jī)朋截,相機(jī)輸出尺寸列表蛹稍,釋放相機(jī)資源,具體代碼如下部服。
public class CameraUtils {
private static CameraUtils ourInstance = new CameraUtils();
private static Context appContext;
private static CameraManager cameraManager;
public static void init(Context context){
if (appContext == null) {
appContext = context.getApplicationContext();
cameraManager = (CameraManager) appContext.getSystemService(Context.CAMERA_SERVICE);
}
}
public static CameraUtils getInstance() {
return ourInstance;
}
private CameraUtils() {
}
public CameraManager getCameraManager(){
return cameraManager;
}
public String getFrontCameraId(){
return getCameraId(true);
}
public String getBackCameraId(){
return getCameraId(false);
}
/**
* 獲取相機(jī)id
* @param useFront 是否使用前置相機(jī)
* @return
*/
public String getCameraId(boolean useFront){
try {
for (String cameraId : cameraManager.getCameraIdList()){
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
int cameraFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (useFront){
if (cameraFacing == CameraCharacteristics.LENS_FACING_FRONT){
return cameraId;
}
}else {
if (cameraFacing == CameraCharacteristics.LENS_FACING_BACK){
return cameraId;
}
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
return null;
}
/**
* 根據(jù)輸出類獲取指定相機(jī)的輸出尺寸列表
* @param cameraId 相機(jī)id
* @param clz 輸出類
* @return
*/
public List<Size> getCameraOutputSizes(String cameraId, Class clz){
try {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
return Arrays.asList(configs.getOutputSizes(clz));
} catch (CameraAccessException e) {
e.printStackTrace();
}
return null;
}
/**
* 根據(jù)輸出格式獲取指定相機(jī)的輸出尺寸列表
* @param cameraId 相機(jī)id
* @param format 輸出格式
* @return
*/
public List<Size> getCameraOutputSizes(String cameraId, int format){
try {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
return Arrays.asList(configs.getOutputSizes(format));
} catch (CameraAccessException e) {
e.printStackTrace();
}
return null;
}
/**
* 釋放相機(jī)資源
* @param cameraDevice
*/
public void releaseCamera(CameraDevice cameraDevice){
if (cameraDevice != null){
cameraDevice.close();
cameraDevice = null;
}
}
}
2. 初始化相機(jī)
使用工具類唆姐,初始化一些相機(jī)相關(guān)的參數(shù),后面打開(kāi)相機(jī)的時(shí)候直接使用即可饲宿,省去了上一篇文章 configCamera()
配置相機(jī)的步驟厦酬。
private void initCamera(){
cameraManager = CameraUtils.getInstance().getCameraManager();
cameraId = CameraUtils.getInstance().getCameraId(false);//默認(rèn)使用后置相機(jī)
//獲取指定相機(jī)的輸出尺寸列表
outputSizes = CameraUtils.getInstance().getCameraOutputSizes(cameraId, SurfaceTexture.class);
//初始化預(yù)覽尺寸
previewSize = outputSizes.get(0);
}
3. 點(diǎn)擊按鈕切換輸出尺寸,更新預(yù)覽界面
點(diǎn)擊按鈕時(shí)瘫想,在相機(jī)輸出尺寸列表中進(jìn)行循環(huán)仗阅,依次使用選定的尺寸構(gòu)造預(yù)覽界面。
btnChangePreviewSize.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//切換預(yù)覽分辨率
updateCameraPreview();
setButtonText();
}
});
private void updateCameraPreview(){
if (sizeIndex + 1 < outputSizes.size()){
sizeIndex++;
}else {
sizeIndex = 0;
}
previewSize = outputSizes.get(sizeIndex);
//重新創(chuàng)建會(huì)話
createPreviewSession();
}
private void setButtonText(){
btnChangePreviewSize.setText(previewSize.getWidth() + "-" + previewSize.getHeight());
}
總結(jié)
經(jīng)過(guò)上面的步驟国夜,點(diǎn)擊按鈕時(shí)就可以預(yù)覽不同輸出尺寸的圖像减噪。
可以發(fā)現(xiàn),不同的預(yù)覽尺寸由于和預(yù)覽窗口寬高比不同车吹,造成不同程度的圖像拉伸筹裕,需要進(jìn)一步優(yōu)化,后續(xù)文章進(jìn)行實(shí)現(xiàn)窄驹。