赞
踩
我们有个需求,在机器上加个摄像头,定时拍照;
我到网上搜索,发现没有快速上手和简单使用的;
个人感觉,大部分博客写得很乱,或者长篇大论;
而我只想简单实现功能,并不打算学习多少理论;
下面代码是我写来测试的,大家有需要可以参考;
能快速看到效果,实际使用可在这个基础上扩展。
先看下我使用的硬件,Android板和摄像头,如图:
首先我想说一下 SurfaceView 这个东西,这个是你希望在界面上看到摄像头拍到的内容(就是所谓“预览”)时才需要,如果你不需要预览可以不用它,不用它照样可以取得摄像头数据。
下面是我主要代码,大家看下一就明白,不用解析了,如下:
- package com.wongo.test.CommCamera;
-
- import android.graphics.SurfaceTexture;
- import android.hardware.Camera;
- import android.view.SurfaceHolder;
- import java.util.List;
-
- public class WGCameraManage {
-
- Camera mCamera;
- SurfaceTexture mSurfaceTexture = new SurfaceTexture(0);
-
-
- /**
- * 打开摄像头
- * @param cameraId 如:Camera.CameraInfo.CAMERA_FACING_BACK
- * @param surfaceHolder 用于预览的SurfaceHolder,可为null
- * @param previewCallback 预览回调,可为null
- * @return 返回null表示成功,其它表示具体错误信息
- */
- public String openCamera(int cameraId, SurfaceHolder surfaceHolder, Camera.PreviewCallback previewCallback) {
- releaseCamera();
- // 判断是否存在cameraId的相机
- boolean isExistCamera = false;
- Camera.CameraInfo info = new Camera.CameraInfo();
- for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
- Camera.getCameraInfo(i, info);
- if (info.facing == cameraId) {
- isExistCamera = true;
- break;
- }
- }
- if (isExistCamera) {
- //初始化相机配置信息
- try {
- mCamera = Camera.open(cameraId);
- int width = 0;
- int height = 0;
- Camera.Parameters mParameters = mCamera.getParameters();
- List<Camera.Size> sizeList = mParameters.getSupportedPreviewSizes();
- // 找到支持的最大尺寸
- for(int i = 0; i < sizeList.size(); i++) {
- Camera.Size size = sizeList.get(i);
- if (size.width > width) {
- width = size.width;
- height = size.height;
- }
- }
- //设置预览尺寸
- mParameters.setPreviewSize(width, height);
- //设置保存图片尺寸
- mParameters.setPictureSize(width, height);
- //设置图片质量为50
- //mParameters.setJpegQuality(50);
- mCamera.setParameters(mParameters);
- // 设置预览回调
- if (previewCallback != null) {
- mCamera.setPreviewCallback(previewCallback);
- }
- } catch (Exception e) {
- return "相机初始化失败:"+e.getLocalizedMessage();
- }
- // 开始预览
- try {
- if (surfaceHolder != null) {
- mCamera.setPreviewDisplay(surfaceHolder);
- } else {
- mCamera.setPreviewTexture(mSurfaceTexture);
- }
- mCamera.startPreview();
- } catch (Exception e) {
- return "打开预览出错:"+e.getLocalizedMessage();
- }
- } else {
- return "没找到对应相机";
- }
- return null;
- }
-
-
- /**
- * 拍照
- * @param callback
- */
- public void takePicture(final takePictureCallback callback) {
- if (mCamera == null) {
- if (callback != null) { callback.onError("相机未初始化成功"); }
- return;
- }
- try {
- mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
- @Override
- public void onPictureTaken(byte[] data, Camera camera) {
- if (callback != null) {
- callback.onSuccess(data);
- }
- mCamera.startPreview();
- }
- });
- } catch (Exception e) {
- if (callback != null) {
- callback.onError(e.getLocalizedMessage());
- }
- }
- }
-
- /**
- * 释放相机
- */
- public void releaseCamera() {
- if (mCamera != null) {
- mCamera.stopPreview();
- mCamera.setPreviewCallback(null);
- mCamera.release();
- mCamera = null;
- }
- }
-
-
- /**
- * 拍照回调
- */
- public interface takePictureCallback {
- void onSuccess(byte[] data);
- void onError(String errMsg);
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
使用的话,就是创建WGCameraManage对象,调用openCamera方法,如果要保存照片就调用takePicture方法。
下面发一下,我测试使用的Activity代码,如下:
- package com.wongo.test;
-
- import android.hardware.Camera;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.widget.Toast;
-
- import com.wongo.test.CommCamera.WGCameraManage;
- import com.wongo.test.common.MyFileUtils;
-
- import java.io.File;
- import java.io.FileOutputStream;
- import java.text.SimpleDateFormat;
- import java.util.Locale;
- import java.util.Timer;
- import java.util.TimerTask;
-
- public class CameraActivity extends AppCompatActivity {
-
- WGCameraManage mCameraManage = new WGCameraManage();
- String pictureSaveRoot; // 照片保存的目录
-
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_camera);
- // 保存路径
- pictureSaveRoot = MyFileUtils.getSDCardPath("wongo/camera");
- File f = new File(pictureSaveRoot);
- if (!f.exists()) {
- f.mkdirs();
- }
- boolean isNeedPreview = true; // 是否需要预览
- if (isNeedPreview) {
- // 创建预览对象
- SurfaceView mSurfaceView = findViewById(R.id.surfaceView);
- SurfaceHolder mSurfaceHolder = mSurfaceView.getHolder();
- mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- setupCamera(holder); //注意:要在这里调用
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
- });
- } else {
- // 不需要预览,直接使用
- setupCamera(null);
- }
- }
-
-
- private void setupCamera(SurfaceHolder holder) {
- // 打开相机
- String errMsgForOpen = mCameraManage.openCamera(Camera.CameraInfo.CAMERA_FACING_BACK, holder, null);
- if (errMsgForOpen == null) {
- // 定时拍照
- Timer mTimer = new Timer();
- TimerTask mTask = new TimerTask() {
- @Override
- public void run() {
- mCameraManage.takePicture(new WGCameraManage.takePictureCallback() {
- @Override
- public void onSuccess(byte[] data) {
- savePictureToFile(data);
- }
-
- @Override
- public void onError(String errMsg) {
- alert("拍照失败:"+errMsg);
- }
- });
- }
- };
- mTimer.schedule(mTask, 10*1000, 10*1000);
- } else {
- alert(errMsgForOpen);
- }
- }
-
-
- private void savePictureToFile(byte[] data) {
- try {
- long millTime = System.currentTimeMillis();
- SimpleDateFormat dataFormat = new SimpleDateFormat("yyyyMMdd"+File.separator+"HH", Locale.getDefault());
- String saveDir = pictureSaveRoot + File.separator + dataFormat.format(millTime);
- File f = new File(saveDir);
- if (!f.exists()) {
- f.mkdirs();
- }
- SimpleDateFormat nameFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());
- String savePath = saveDir + File.separator + nameFormat.format(millTime) + ".jpg";
- FileOutputStream fos = new FileOutputStream(savePath);
- fos.write(data);
- fos.close();
- alert("保存照片完成");
- } catch (Exception e) {
- e.printStackTrace();
- alert("保存照片出错:"+e.getLocalizedMessage());
- }
- }
-
-
- private void alert(final String msg) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(CameraActivity.this, msg, Toast.LENGTH_SHORT).show();
- }
- });
- }
-
-
- @Override
- protected void onDestroy() {
- mCameraManage.releaseCamera();
- super.onDestroy();
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
还有权限声明,我这项目是测试专用的,本来就声明了各种权限,我看了下,相关的应该是下面这些:
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.CAMERA" />
-
- <uses-feature android:name="android.hardware.camera" />
- <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
----------------------------完--------------------------
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。