Android CameraManager类详解

本文实例为大家分享了Android CameraManager类的具体代码,供大家参考,具体内容如下

先看代码:

  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 不需要自己的缓冲区
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    // mSurfaceView添加回调
    mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
      @Override
      public void surfaceCreated(SurfaceHolder holder) { //SurfaceView创建
        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 类,在关闭当前页面,释放camera资源时偶尔报错

Camera is being used after Camera.release() was called

第一次,加了一句 holder.removeCallback(this); 运行发现还是时不时出现报错。

第二次在释放 camera前加  camera.setPreviewCallback(null); 问题解决。

  /**
   * 关闭预览
   */
  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;
    }
  }

  /**
   * 关闭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;
  }

  /**
   * 关闭camera
   */
  public synchronized void closeDriver() {
    Log.e(TAG, "closeDriver");
    if (camera != null) {
      camera.release();
      camera = null;
    }
  }

  /**
   * 开始预览
   */
  public synchronized void startPreview() {
    Log.e(TAG, "startPreview");
    Camera theCamera = camera;
    if (theCamera != null && !previewing) {
      theCamera.startPreview();
      previewing = true;
      autoFocusManager = new AutoFocusManager(camera);
    }
  }

  /**
   * 关闭预览
   */
  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);
    }
  }

  /**
   * 关闭闪光灯
   */
  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是字节数据,将其解析成位图
    //设置FOCUS_MODE_CONTINUOUS_VIDEO)之后,myParam.set("rotation", 90)失效。图片竟然不能旋转了,故这里要旋转下
    Matrix matrix = new Matrix();
    matrix.postRotate((float) 90.0);
    Bitmap rotaBitmap = Bitmap.createBitmap(cutMap, 0, 0, cutMap.getWidth(), cutMap.getHeight(), matrix, false);

    //旋转后rotaBitmap是960×1280.预览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;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android开发之图形图像与动画(一)Paint和Canvas类学习

    Paint类 *Paint类代表画笔,用来描述图形的颜色和风格,如线宽,颜色,透明度和填充效果等信息. *使用Paint类时,需要先创建该类的对象,可以通过该类的构造函数实现.通常情况的实现代码是: *Paintpaint=newPaint(); *创建完Paint对象后,可以通过该对象提供的方法对画笔的默认设置进行改变 Canvas *Canvas类代表画布,通过该类提供的构造方法,可以绘制各种图形. *通常情况下,要在Android中绘图,需要先创建一个继承自View类的视图,并且在该类中重

  • Android获得当前正在显示的activity类名的方法

    本文实例讲述了Android获得当前正在显示的activity类名的方法.分享给大家供大家参考.具体实现方法如下: 首先需要加一个权限: 复制代码 代码如下: <uses-permission android:name="android.permission.GET_TASKS"/> Java代码如下: 复制代码 代码如下: ActivityManager manager = (ActivityManager)   getSystemService(Context.ACTI

  • Android封装的http请求实用工具类

    复制代码 代码如下: import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.URLEncoder;import java.security.KeyStore;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Map.Entry; import org.apache.http

  • android 通过向viewpage中添加listview来完成滑动效果(类似于qq滑动界面)

    文件名:page.xml 复制代码 代码如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="fill_parent"    android:layout_height="fill

  • android 类似微信的摇一摇功能实现思路及代码

    复制代码 代码如下: package com.eboy.testyaoyiyao; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import

  • Android中RecyclerView布局代替GridView实现类似支付宝的界面

    单纯使用GridView 通用的两种给GridView 添加分割线的方法:http://stackoverflow.com/questions/7132030/android-gridview-draw-dividers 给Gridview 添加分割线,也就是实现网格布局,不清楚谷歌为什么没有给Gridview 添加一个类似 ListView 的Divider 属性,因此就需要我们自己去添加分割线, 目前两种方法,第一种是 利用GridView 的  android:horizontalSpac

  • Android开发笔记之:用Enum(枚举类型)取代整数集的应用详解

    在Android的API中可以发现有很多用整数集来作为参数的地方,先来看一下实例.LinearLayout是大家所熟知的一个UI基本元素,它里面有一个方向的属性,可以通过以下方法来设置: 复制代码 代码如下: LinearLayout.setOrientation(int); 使用的时候,通常都是这样: 复制代码 代码如下: LinearLayout.setOrientation(LinearLayout.HORIZONTAL);LinearLayout.setOrientation(Linea

  • Android使用MediaRecorder类进行录制视频

    我们提醒大家使用MediaRecorder录音录像的设置代码步骤一定要按照API指定的顺序来设置,否则报错 步骤为: 1.设置视频源,音频源,即输入源 2.设置输出格式 3.设置音视频的编码格式 一.首先看布局文件,这里有一个SurfaceView,这是一个绘制容器,可以直接从内存或者DMA等硬件接口取得图像数据, <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tool

  • Android数据类型之间相互转换系统介绍

    一些初学Android的朋友可能会遇到JAVA的数据类型之间转换的苦恼,例如,整数和float,double型之间的转换,整数和String类型之间的转换,以及处理.显示时间方面的问题等.下面笔者就开发中的一些体会介绍给大家. 我们知道,android的数据类型分为三大类,即布尔型.字符型和数值型,而其中数值型又分为整型和浮点型:相对于数据类型,Java的变量类型为布尔型 boolean:字符型char:整型byte.short.int.long:浮点型float.double.其中四种整型变量

  • Android实现类似360,QQ管家那样的悬浮窗

    一.前言: 我手机从来不装这些东西,不过,有次看到同事的android手机上,有个QQ管家在桌面上浮着,同事拖动管家时,管家就变成一只鸟,桌面下方还有个弹弓,桌面顶部有只乌鸦,把管家也就是鸟拖动到弹弓那,然后,松手,鸟就飞出去.这个过程是动画过程,做的事,实际上是清楚内存. 二:原理: 其实,没什么原理,用到的就是WindowManager以及WindowManager.LayoutParams,对这个LayoutParams做文章,当设置为属性后,然后,创建一个View,将这个View添加到W

随机推荐