当前位置: 移动技术网 > IT编程>移动开发>Android > Android camera实时预览 实时处理,人脸识别示例

Android camera实时预览 实时处理,人脸识别示例

2019年07月24日  | 移动技术网IT编程  | 我要评论

群众意见范文,人体摄影图片网,杨紫身材有料

android camera实时预览 实时处理,面部认证。

预览操作是网友共享的代码,我在继承surfaceview 的camerasurfaceview 中加入了帧监听事件,每次预览监听前五个数据帧,在处理做一个面部识别。

先看目录关系

  • 自定义控件camerasurfaceview.java
  • 自定义接口方法camerainterface.java
  • cameraactivity预览界面。

camerasurfaceview.java

package com.centaur.camera.preview;

import android.content.context;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.imageformat;
import android.graphics.matrix;
import android.graphics.pixelformat;
import android.graphics.rect;
import android.graphics.yuvimage;
import android.hardware.camera;
import android.util.attributeset;
import android.util.log;
import android.view.surfaceholder;
import android.view.surfaceview;

import com.centaur.camera.camera.camerainterface;

import java.io.bytearrayoutputstream;

/**
 * created by tianchaoxiong on 2017/1/16.
 */

public class camerasurfaceview extends surfaceview implements surfaceholder.callback, camera.previewcallback{


  private static final int facenum = 5;

  private static final string tag = "yanzi";
  camerainterface mcamerainterface;
  context mcontext;
  surfaceholder msurfaceholder;

  private boolean isfinish;
  //传输五个bitmap数组
  bitmap [] bitmaps = new bitmap[5];

  int number = 0;//作为计数器用

  onfacecollectlistener onfacecollectlistener = null;

  public camerasurfaceview(context context, attributeset attrs) {
    super(context, attrs);
    mcontext = context;
    msurfaceholder = getholder();
    msurfaceholder.setformat(pixelformat.transparent);//translucent半透明 transparent透明
    msurfaceholder.settype(surfaceholder.surface_type_push_buffers);
    msurfaceholder.addcallback(this);
  }

  @override
  public void surfacecreated(surfaceholder surfaceholder) {
    log.i(tag, "surfacecreated...");
  }

  @override
  public void surfacechanged(surfaceholder surfaceholder, int i, int i1, int i2) {
    log.i(tag, "surfacechanged...");
  }

  @override
  public void surfacedestroyed(surfaceholder surfaceholder) {
    log.i(tag, "surfacedestroyed...");
    camerainterface.getinstance().dostopcamera();
  }
  public surfaceholder getsurfaceholder(){
    return msurfaceholder;
  }

  /**
   * 收集五张图片 监听器
   */
  public static interface onfacecollectlistener {

    /**
     * 收集五张face
     * @param bitmaps 返回的五张脸的数组
     */
    void onfacecollected(bitmap[] bitmaps);

    /**
     * face重新绘制
     * @param isstart 是否重新收集
     */
    void onfacecollectstart(boolean isstart);
  }
  /**
   * 设置面部的监听器
   * @param onfacecollectlistener
   */
  public void setonfacecollectlistener(onfacecollectlistener onfacecollectlistener){

    if(onfacecollectlistener!=null){
      this.onfacecollectlistener = onfacecollectlistener;
    }
  }

  /***
   * 想在这里做一个监听处理 收五侦 传输出去
   * @param bytes
   * @param camera
   */
  @override
  public void onpreviewframe(byte[] bytes, camera camera) {
    if(number<facenum){
      //收集
      //判断监听器 开始
      if(onfacecollectlistener!=null){
        onfacecollectlistener.onfacecollectstart(true);
        //有byte数组转为bitmap
        bitmaps[number] = byte2bitmap(bytes,camera);
        log.d("ceshitian","********收集了"+number+"个************");
        number = number+1;
        if(number==5){
          log.d("ceshitian","********收集够5个************");
          //提交
          onfacecollectlistener.onfacecollected(bitmaps);
        }
      }
    }else {
      //不做操作
      onfacecollectlistener.onfacecollectstart(false);
      onfacecollectlistener.onfacecollected(null);
    }
  }

  private bitmap byte2bitmap(byte[] bytes, camera camera) {
    bitmap bitmap = null;

    camera.size size = camera.getparameters().getpreviewsize(); // 获取预览大小
    final int w = size.width; // 宽度
    final int h = size.height;
    final yuvimage image = new yuvimage(bytes, imageformat.nv21, w, h,
        null);
    bytearrayoutputstream os = new bytearrayoutputstream(bytes.length);
    if (!image.compresstojpeg(new rect(0, 0, w, h), 100, os)) {
      return null;
    }
    byte[] tmp = os.tobytearray();
    bitmap = bitmapfactory.decodebytearray(tmp, 0, tmp.length);

    matrix matrix = new matrix();
    matrix.setrotate(-90);
    bitmap = bitmap.createbitmap(bitmap,0,0,bitmap.getwidth(),bitmap.getheight(),matrix,true);

    return bitmap;
  }
}

camerainterface.java

package com.centaur.camera.camera;

import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.imageformat;
import android.graphics.matrix;
import android.graphics.pixelformat;
import android.graphics.rect;
import android.graphics.yuvimage;
import android.hardware.camera;
import android.util.log;
import android.view.surfaceholder;

import com.centaur.camera.util.camparautil;
import com.centaur.camera.util.imageutil;
import com.centaur.util.fileutils;

import java.io.ioexception;
import java.util.list;

/**
 * created by tianchaoxiong on 2017/1/16.
 */

public class camerainterface {
  private static final string tag = "tianchaoxiong";
  private camera mcamera;
  private camera.parameters mparams;
  private boolean ispreviewing = false;
  private float mpreviwrate = -1f;
  private static camerainterface mcamerainterface;

  public interface camopenovercallback {
    public void camerahasopened();
  }

  private camerainterface() {

  }

  public static synchronized camerainterface getinstance() {
    if (mcamerainterface == null) {
      mcamerainterface = new camerainterface();
    }
    return mcamerainterface;
  }

  /**
   * 打开camera
   *
   * @param callback
   */
  public void doopencamera(camopenovercallback callback) {
    log.i(tag, "camera open....");
    mcamera = camera.open(1);
    log.i(tag, "camera open over....");
    callback.camerahasopened();
  }

  /**
   * 开启预览
   *
   * @param holder
   * @param previewrate
   */
  public void dostartpreview(surfaceholder holder, float previewrate, camera.previewcallback previewcallback) {
    log.i(tag, "dostartpreview...");
    if (ispreviewing) {
      mcamera.stoppreview();
      return;
    }
    if (mcamera != null) {

      mparams = mcamera.getparameters();
      mparams.setpictureformat(pixelformat.jpeg);//设置拍照后存储的图片格式

      //对支持的图片的大小的一个收集
      camparautil.getinstance().printsupportpicturesize(mparams);
      camparautil.getinstance().printsupportpreviewsize(mparams);
      //设置previewsize和picturesize
      camera.size picturesize = camparautil.getinstance().getproppicturesize(
          mparams.getsupportedpicturesizes(), previewrate, 800);
      mparams.setpicturesize(picturesize.width, picturesize.height);
      camera.size previewsize = camparautil.getinstance().getproppreviewsize(
          mparams.getsupportedpreviewsizes(), previewrate, 800);
      mparams.setpreviewsize(previewsize.width, previewsize.height);

      mcamera.setdisplayorientation(90);

      camparautil.getinstance().printsupportfocusmode(mparams);
      list<string> focusmodes = mparams.getsupportedfocusmodes();
      if (focusmodes.contains("continuous-video")) {
        mparams.setfocusmode(camera.parameters.focus_mode_continuous_video);
      }
      mcamera.setparameters(mparams);  //参数设置完毕

      try {
        mcamera.setpreviewdisplay(holder);
        mcamera.setpreviewcallback(previewcallback);
        mcamera.startpreview();//开启预览
      } catch (ioexception e) {
        // todo auto-generated catch block
        e.printstacktrace();
      }

      ispreviewing = true;
      mpreviwrate = previewrate;

      mparams = mcamera.getparameters(); //重新get一次
      log.i(tag, "最终设置:previewsize--with = " + mparams.getpreviewsize().width
          + "height = " + mparams.getpreviewsize().height);
      log.i(tag, "最终设置:picturesize--with = " + mparams.getpicturesize().width
          + "height = " + mparams.getpicturesize().height);
    }
  }

  /**
   * 停止预览,释放camera
   */
  public void dostopcamera() {
    if (null != mcamera) {
      mcamera.setpreviewcallback(null);
      mcamera.stoppreview();
      ispreviewing = false;
      mpreviwrate = -1f;
      mcamera.release();
      mcamera = null;
    }
  }

  /**
   * 拍照
   */
  public void dotakepicture() {
    if (ispreviewing && (mcamera != null)) {
      log.d("fileutils", "程序运行到这里了111");
      mcamera.takepicture(mshuttercallback, null, mjpegpicturecallback);
    }
  }

  /*为了实现拍照的快门声音及拍照保存照片需要下面三个回调变量*/
  camera.shuttercallback mshuttercallback = new camera.shuttercallback()
      //快门按下的回调,在这里我们可以设置类似播放“咔嚓”声之类的操作。默认的就是咔嚓。
  {
    public void onshutter() {
      // todo auto-generated method stub
      log.i(tag, "myshuttercallback:onshutter...");
    }
  };
  /*  camera.picturecallback mrawcallback = new camera.picturecallback()
        // 拍摄的未压缩原数据的回调,可以为null
    {

      public void onpicturetaken(byte[] data, camera camera) {
        // todo auto-generated method stub
        log.i(tag, "myrawcallback:onpicturetaken...");

      }
    };*/
  camera.picturecallback mjpegpicturecallback = new camera.picturecallback()
      //对jpeg图像数据的回调,最重要的一个回调
  {
    public void onpicturetaken(byte[] data, camera camera) {
      log.d("fileutils", "程序运行到这里了222");
      // todo auto-generated method stub
      log.i(tag, "myjpegcallback:onpicturetaken...");
      bitmap b = null;
      if (null != data) {
        b = bitmapfactory.decodebytearray(data, 0, data.length);//data是字节数据,将其解析成位图
        mcamera.stoppreview();
        ispreviewing = false;
        log.d("fileutils", "程序运行到这里了333");
      }
      //保存图片到sdcard
      if (null != b) {
        log.d("fileutils", "程序运行到这里了444");
        //设置focus_mode_continuous_video)之后,myparam.set("rotation", 90)失效。
        //图片竟然不能旋转了,故这里要旋转下
        log.d("fileutils", "程序运行到这里了");
        bitmap rotabitmap = imageutil.getrotatebitmap(b, -90.0f);
        fileutils.savepaizhaobitmap(rotabitmap);
      }
    }
  };

}

cameraactivity

package com.centaur.camera.activity;

import android.content.intent;
import android.graphics.bitmap;
import android.graphics.point;
import android.os.bundle;
import android.os.environment;
import android.os.handler;
import android.support.v7.app.appcompatactivity;
import android.util.log;
import android.view.surfaceholder;
import android.view.view;
import android.view.viewgroup;
import android.widget.imagebutton;
import android.widget.textview;

import com.centaur.camera.camera.camerainterface;
import com.centaur.camera.preview.camerasurfaceview;
import com.centaur.camera.util.displayutil;
import com.centaur.testutil.r;
import com.centaur.testutil.showpic;
import com.centaur.util.detectesdk;
import com.centaur.util.detecteseeta;



public class cameraactivity extends appcompatactivity implements camerasurfaceview.onfacecollectlistener, camerainterface.camopenovercallback{
  private static final string tag = "cameraactivity";

  private float reclen = 0;
  long te;
  float previewrate = -1f;
  detectesdk detectesdk;
  detecteseeta detecteseeta;

  bitmap bmp;
  bitmap bitmapfianl;

  private imagebutton shutterbtn;
  private textview textview;
  private camerasurfaceview surfaceview = null;


  @override
  protected void oncreate(bundle savedinstancestate){
    super.oncreate(savedinstancestate);
    thread openthread = new thread(){
      @override
      public void run() {
        camerainterface.getinstance().doopencamera(cameraactivity.this);
      }
    };
    openthread.start();
    te = system.currenttimemillis();
    setcontentview(r.layout.activity_camera);
    initview();
    initviewparams();
    surfaceview.setonfacecollectlistener(this);

    shutterbtn.setonclicklistener(new btnlisteners());
    timehandler.postdelayed(timerunnable, 500);
  }
  /**
   * 回调方法
   * activity中的视图和 interface中的代码实现绑定
   */
  @override
  public void camerahasopened() {
    surfaceholder holder = surfaceview.getsurfaceholder();
    camerainterface.getinstance().dostartpreview(holder, previewrate,surfaceview );
  }

  @override
  protected void ondestroy() {
    // todo auto-generated method stub
    super.ondestroy();
    camerainterface.getinstance().dostopcamera();
    log.d("runtime", "ondestroy:time:"+te);
    timehandler.removecallbacks(timerunnable);
  }
  @override
  protected void onpause() {
    // todo auto-generated method stub
    super.onpause();
    camerainterface.getinstance().dostopcamera();
    te = system.currenttimemillis()-te;
    log.d("runtime", "onpause:time:"+te);
    timehandler.removecallbacks(timerunnable);
  }

  handler timehandler = new handler();
  runnable timerunnable = new runnable() {
    @override
    public void run() {
      reclen+=500;
      textview.settext("检测时间:" + reclen/1000+"秒");
      timehandler.postdelayed(this, 500);
    }
  };


  private void initview(){
    surfaceview = (camerasurfaceview)findviewbyid(r.id.camera_surfaceview);
    shutterbtn = (imagebutton)findviewbyid(r.id.btn_shutter);
    textview = (textview) findviewbyid(r.id.time);
  }
  private void initviewparams(){
    viewgroup.layoutparams params = surfaceview.getlayoutparams();
    point p = displayutil.getscreenmetrics(this);
    params.width = p.x;
    params.height = p.y;
    previewrate = displayutil.getscreenrate(this); //默认全屏的比例预览
    surfaceview.setlayoutparams(params);
    //手动设置拍照imagebutton的大小为120dip×120dip,原图片大小是64×64
    viewgroup.layoutparams p2 = shutterbtn.getlayoutparams();
    p2.width = displayutil.dip2px(this, 80);
    p2.height = displayutil.dip2px(this, 80);
    shutterbtn.setlayoutparams(p2);

  }




  /**
   * 自建
   * @param bitmaps 返回的五张脸的数组
   */
  @override
  public void onfacecollected(bitmap[] bitmaps) {

  }

  /**
   * 自建
   * @param isstart 是否重新收集
   */
  @override
  public void onfacecollectstart(boolean isstart) {
    if(isstart){
      log.d("cameraactivity","开始收集");
    }

  }

  private class btnlisteners implements view.onclicklistener {

    @override
    public void onclick(view v) {
      // todo auto-generated method stub
      switch(v.getid()){
        case r.id.btn_shutter:
          camerainterface.getinstance().dotakepicture();
          intent intent =new intent(cameraactivity.this, showpic.class);
          // 默认一个暂存的路径 /facedetection/useso/pictures/tmp/tmp.png
          string folderpath = "/facedetection/useso/pictures/tmp/tmp.png";
          string path = environment.getexternalstoragedirectory()+folderpath;
          intent.putextra("picpath",path);
          startactivity(intent);
          finish();
          break;
        default:break;
      }
    }

  }
}

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网