CameraView這個自定義View源自《AS開發(fā)實戰(zhàn)從零基礎到App上線》-歐陽粲著的第9章利虫。
Camera類和SurfaceView如何建立聯(lián)系
CameraView extends SurfaceView
// 聲明一個相機對象
private Camera mCamera;
// 獲取表面視圖的表面持有者
SurfaceHolder holder = getHolder();
// 設置相機的預覽界面
mCamera.setPreviewDisplay(holder);
// 開始預覽畫面
mCamera.startPreview();
CameraView完整代碼
public class CameraView extends SurfaceView {
private static final String TAG = "CameraView";
private Context mContext; // 聲明一個上下文對象
private Camera mCamera; // 聲明一個相機對象
private boolean isPreviewing = false; // 是否正在預覽
private Point mCameraSize; // 相機畫面的尺寸
private int mCameraType = CAMERA_BEHIND; // 攝像頭類型
public static int CAMERA_BEHIND = 0; // 后置攝像頭
public static int CAMERA_FRONT = 1; // 前置攝像頭
public CameraView(Context context) {
this(context, null);
}
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
// 獲取表面視圖的表面持有者
SurfaceHolder holder = getHolder();
// 給表面持有者添加表面變更監(jiān)聽器
holder.addCallback(mSurfaceCallback);
// 去除黑色背景。TRANSLUCENT半透明腋颠;TRANSPARENT透明
holder.setFormat(PixelFormat.TRANSPARENT);
}
// 獲取攝像頭的類型
public int getCameraType() {
return mCameraType;
}
// 設置攝像頭的類型
public void setCameraType(int CameraType) {
mCameraType = CameraType;
}
// 下面是單拍的代碼
// 執(zhí)行拍照動作。外部調(diào)用該方法完成拍照
public void doTakePicture() {
if (isPreviewing && mCamera != null) {
// 命令相機拍攝一張照片
mCamera.takePicture(mShutterCallback, null, mPictureCallback);
}
}
private String mPhotoPath; // 照片的保存路徑
// 獲取照片的保存路徑搞疗。外部調(diào)用該方法獲得相片文件的路徑
public String getPhotoPath() {
return mPhotoPath;
}
// 定義一個快門按下的回調(diào)監(jiān)聽器爱葵〈砦可在此設置類似播放“咔嚓”聲之類的操作敷待,默認就是咔嚓场仲。
private ShutterCallback mShutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter...");
}
};
// 定義一個獲得拍照結(jié)果的回調(diào)監(jiān)聽器和悦。可在此保存圖片
private PictureCallback mPictureCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken...");
Bitmap raw = null;
if (null != data) {
// 原始圖像數(shù)據(jù)data是字節(jié)數(shù)組渠缕,需要將其解析成位圖
raw = BitmapFactory.decodeByteArray(data, 0, data.length);
// 停止預覽畫面
mCamera.stopPreview();
isPreviewing = false;
}
// 旋轉(zhuǎn)位圖
Bitmap bitmap = BitmapUtil.getRotateBitmap(raw,
(mCameraType == CAMERA_BEHIND) ? 90 : -90);
// 獲取本次拍攝的照片保存路徑
mPhotoPath = String.format("%s%s.jpg", BitmapUtil.getCachePath(mContext),
DateUtil.getNowDateTime());
// 保存照片文件
BitmapUtil.saveBitmap(mPhotoPath, bitmap, "jpg", 80);
Log.d(TAG, "bitmap.size=" + (bitmap.getByteCount() / 1024) + "K" + ", path=" + mPhotoPath);
try {
Thread.sleep(1000); // 保存文件需要時間
} catch (InterruptedException e) {
e.printStackTrace();
}
// 再次進入預覽畫面
mCamera.startPreview();
isPreviewing = true;
}
};
// 預覽畫面狀態(tài)變更時的回調(diào)監(jiān)聽器
private SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() {
// 在表面視圖創(chuàng)建時觸發(fā)
public void surfaceCreated(SurfaceHolder holder) {
// 打開攝像頭
mCamera = Camera.open(mCameraType);
try {
// 設置相機的預覽界面
mCamera.setPreviewDisplay(holder);
// 獲得相機畫面的尺寸
mCameraSize = CameraUtil.getCameraSize(mCamera.getParameters(),
CameraUtil.getSize(mContext));
Log.d(TAG, "width=" + mCameraSize.x + ", height=" + mCameraSize.y);
// 獲取相機的參數(shù)信息
Camera.Parameters parameters = mCamera.getParameters();
// 設置預覽界面的尺寸
parameters.setPreviewSize(mCameraSize.x, mCameraSize.y);
// 設置圖片的分辨率
parameters.setPictureSize(mCameraSize.x, mCameraSize.y);
// 如果想得到最大分辨率的圖片鸽素,可使用下面兩行代碼設置最大的圖片尺寸
//Camera.Size maxSize = CameraUtil.getMaxPictureSize(mCamera.getParameters());
//parameters.setPictureSize(maxSize.width, maxSize.height);
// 設置圖片的格式
parameters.setPictureFormat(ImageFormat.JPEG);
// 設置對焦模式為自動對焦。前置攝像頭似乎無法自動對焦
if (mCameraType == CameraView.CAMERA_BEHIND) {
//parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// FOCUS_MODE_AUTO只會自動對焦一次亦鳞,若想連續(xù)對焦則需用下面的FOCUS_MODE_CONTINUOUS_PICTURE
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
// 設置相機的參數(shù)信息
mCamera.setParameters(parameters);
} catch (Exception e) {
e.printStackTrace();
mCamera.release(); // 遇到異常要釋放相機資源
mCamera = null;
}
}
// 在表面視圖變更時觸發(fā)
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// 設置相機的展示角度
mCamera.setDisplayOrientation(90);
// 開始預覽畫面
mCamera.startPreview();
isPreviewing = true;
// 開始自動對焦
mCamera.autoFocus(null);
}
// 在表面視圖銷毀時觸發(fā)
public void surfaceDestroyed(SurfaceHolder holder) {
// 將預覽監(jiān)聽器置空
mCamera.setPreviewCallback(null);
// 停止預覽畫面
mCamera.stopPreview();
// 釋放相機資源
mCamera.release();
mCamera = null;
}
};
}