Android CameraManager類詳解
本文實例為大家分享了Android CameraManager類的具體代碼,供大家參考,具體內(nèi)容如下
先看代碼:
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private CameraManager cameraManager;
cameraManager = new CameraManager(this);
mSurfaceView = (SurfaceView) findViewById(R.id.java_surface_view);
mSurfaceHolder = mSurfaceView.getHolder();
// mSurfaceView 不需要自己的緩沖區(qū)
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// mSurfaceView添加回調(diào)
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) { //SurfaceView創(chuàng)建
try {
cameraManager.openDriver(mSurfaceHolder);
cameraManager.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) { //SurfaceView銷毀
holder.removeCallback(this); // Camera is being used after Camera.release() was called
cameraManager.stopPreview();
cameraManager.closeDriver();
}
});
自定義一個 CameraManager 類,在關(guān)閉當(dāng)前頁面,釋放camera資源時偶爾報錯
Camera is being used after Camera.release() was called
第一次,加了一句 holder.removeCallback(this); 運行發(fā)現(xiàn)還是時不時出現(xiàn)報錯。
第二次在釋放 camera前加 camera.setPreviewCallback(null); 問題解決。
/**
* 關(guān)閉預(yù)覽
*/
public synchronized void stopPreview() {
Log.e(TAG, "stopPreview");
if (autoFocusManager != null) {
autoFocusManager.stop();
autoFocusManager = null;
}
if (camera != null && previewing) {
camera.stopPreview();
camera.setPreviewCallback(null); // Camera is being used after Camera.release() was called
previewing = false;
}
}
/**
* 關(guān)閉camera
*/
public synchronized void closeDriver() {
Log.e(TAG, "closeDriver");
if (camera != null) {
camera.release();
camera = null;
}
}
附:CameraManager類:
package com.lemoncome.facedetection;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.WindowManager;
import java.io.IOException;
import java.util.List;
/**
* User:lizhangqu(513163535@qq.com)
* Date:2015-09-05
* Time: 10:56
*/
public class CameraManager implements Camera.PreviewCallback {
private static final String TAG = CameraManager.class.getName();
private Camera camera;
private Camera.Parameters parameters;
private AutoFocusManager autoFocusManager;
private int requestedCameraId = -1;
private Context mContext;
private boolean initialized;
private boolean previewing;
/**
* 打開攝像頭
*
* @param cameraId 攝像頭id
* @return Camera
*/
public Camera open(int cameraId) {
int numCameras = Camera.getNumberOfCameras();
if (numCameras == 0) {
Log.e(TAG, "No cameras!");
return null;
}
boolean explicitRequest = cameraId >= 0;
if (!explicitRequest) {
// Select a camera if no explicit camera requested
int index = 0;
while (index < numCameras) {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(index, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
break;
}
index++;
}
cameraId = index;
}
Camera camera;
if (cameraId < numCameras) {
Log.e(TAG, "Opening camera #" + cameraId);
camera = Camera.open(cameraId);
} else {
if (explicitRequest) {
Log.e(TAG, "Requested camera does not exist: " + cameraId);
camera = null;
} else {
Log.e(TAG, "No camera facing back; returning camera #0");
camera = Camera.open(0);
}
}
int rotation = getDisplayOrientation();
camera.setDisplayOrientation(rotation);
camera.setPreviewCallback(this);
return camera;
}
public int getDisplayOrientation() {
Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
Camera.CameraInfo camInfo =
new Camera.CameraInfo();
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, camInfo);
int result = (camInfo.orientation - degrees + 360) % 360;
return result;
}
public CameraManager(Context context) {
mContext = context;
}
/**
* 打開camera
*
* @param holder SurfaceHolder
* @throws IOException IOException
*/
public synchronized void openDriver(SurfaceHolder holder)
throws IOException {
Log.e(TAG, "openDriver");
Camera theCamera = camera;
if (theCamera == null) {
theCamera = open(requestedCameraId);
if (theCamera == null) {
throw new IOException();
}
camera = theCamera;
}
theCamera.setPreviewDisplay(holder);
if (!initialized) {
initialized = true;
parameters = camera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
int w = 800;
int h = 600;
for (Camera.Size size : previewSizes) {
Log.e("TAG", "previewSizes width:" + size.width);
Log.e("TAG", "previewSizes height:" + size.height);
if (size.width - w <= 100 & size.width >= w) {
w = size.width;
h = size.height;
break;
}
}
parameters.setPreviewSize(w, h);
parameters.setPictureFormat(ImageFormat.JPEG);
parameters.setJpegQuality(100);
parameters.setPictureSize(800, 600);
theCamera.setParameters(parameters);
}
}
/**
* camera是否打開
*
* @return camera是否打開
*/
public synchronized boolean isOpen() {
return camera != null;
}
/**
* 關(guān)閉camera
*/
public synchronized void closeDriver() {
Log.e(TAG, "closeDriver");
if (camera != null) {
camera.release();
camera = null;
}
}
/**
* 開始預(yù)覽
*/
public synchronized void startPreview() {
Log.e(TAG, "startPreview");
Camera theCamera = camera;
if (theCamera != null && !previewing) {
theCamera.startPreview();
previewing = true;
autoFocusManager = new AutoFocusManager(camera);
}
}
/**
* 關(guān)閉預(yù)覽
*/
public synchronized void stopPreview() {
Log.e(TAG, "stopPreview");
if (autoFocusManager != null) {
autoFocusManager.stop();
autoFocusManager = null;
}
if (camera != null && previewing) {
camera.stopPreview();
camera.setPreviewCallback(null); // Camera is being used after Camera.release() was called
previewing = false;
}
}
public void setPreviewCallback(Camera.PreviewCallback cb) {
camera.setOneShotPreviewCallback(this);
}
/**
* 打開閃光燈
*/
public synchronized void openLight() {
Log.e(TAG, "openLight");
if (camera != null) {
parameters = camera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameters);
}
}
/**
* 關(guān)閉閃光燈
*/
public synchronized void offLight() {
Log.e(TAG, "offLight");
if (camera != null) {
parameters = camera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(parameters);
}
}
/**
* 拍照
*
* @param shutter ShutterCallback
* @param raw PictureCallback
* @param jpeg PictureCallback
*/
public synchronized void takePicture(final Camera.ShutterCallback shutter, final Camera.PictureCallback raw,
final Camera.PictureCallback jpeg) {
camera.takePicture(shutter, raw, jpeg);
}
@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
}
private Bitmap reSize(byte[] data) {
Log.i(TAG, "myJpegCallback:onPictureTaken...");
Bitmap cutMap = BitmapFactory.decodeByteArray(data, 0, data.length);//data是字節(jié)數(shù)據(jù),將其解析成位圖
//設(shè)置FOCUS_MODE_CONTINUOUS_VIDEO)之后,myParam.set("rotation", 90)失效。圖片竟然不能旋轉(zhuǎn)了,故這里要旋轉(zhuǎn)下
Matrix matrix = new Matrix();
matrix.postRotate((float) 90.0);
Bitmap rotaBitmap = Bitmap.createBitmap(cutMap, 0, 0, cutMap.getWidth(), cutMap.getHeight(), matrix, false);
//旋轉(zhuǎn)后rotaBitmap是960×1280.預(yù)覽surfaview的大小是540×800
//將960×1280縮放到540×800
Bitmap sizeBitmap = Bitmap.createScaledBitmap(rotaBitmap, 540, 800, true);
Bitmap rectBitmap = Bitmap.createBitmap(sizeBitmap, 100, 200, 300, 300);//截取
return rectBitmap;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android開發(fā)筆記之:用Enum(枚舉類型)取代整數(shù)集的應(yīng)用詳解
- android 通過向viewpage中添加listview來完成滑動效果(類似于qq滑動界面)
- Android中RecyclerView布局代替GridView實現(xiàn)類似支付寶的界面
- Android獲得當(dāng)前正在顯示的activity類名的方法
- android 類似微信的搖一搖功能實現(xiàn)思路及代碼
- Android開發(fā)之圖形圖像與動畫(一)Paint和Canvas類學(xué)習(xí)
- Android數(shù)據(jù)類型之間相互轉(zhuǎn)換系統(tǒng)介紹
- Android封裝的http請求實用工具類
- Android使用MediaRecorder類進行錄制視頻
- Android實現(xiàn)類似360,QQ管家那樣的懸浮窗
相關(guān)文章
Android如何實現(xiàn)URL轉(zhuǎn)換成二維碼
這篇文章主要為大家詳細介紹了Android實現(xiàn)URL轉(zhuǎn)換成二維碼的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
android網(wǎng)絡(luò)圖片查看器簡單實現(xiàn)代碼
這篇文章主要為大家詳細介紹了android網(wǎng)絡(luò)圖片查看器的簡單實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
Android實現(xiàn)微信側(cè)滑刪除當(dāng)前頁面
這篇文章主要為大家詳細介紹了Android實現(xiàn)微信側(cè)滑刪除當(dāng)前頁面,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12
解決android studio引用遠程倉庫下載慢(JCenter下載慢)
這篇文章主要介紹了解決android studio引用遠程倉庫下載慢(JCenter下載慢),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
Android studio實現(xiàn)簡易的計算器功能
這篇文章主要為大家詳細介紹了Android studio實現(xiàn)簡易的計算器功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05
Android Studio做超好玩的拼圖游戲 附送詳細注釋源碼
這篇文章主要介紹了用Android Studio做的一個超好玩的拼圖游戲,你是0基礎(chǔ)Android小白也能包你學(xué)會,另外附送超詳細注釋的源碼,建議收藏!2021-08-08

