当前位置: 移动技术网 > IT编程>移动开发>Android > Android 开发随手笔记之使用摄像头拍照

Android 开发随手笔记之使用摄像头拍照

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

透视药水,魔鬼树,天书奇谈私服

在android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的camera,另一种是自己写一个摄像的界面。

      我们要添加如下权限:

<uses-permission android:name="android.permission.write_external_storage"/>
<uses-permission android:name="android.permission.camera"/>

1、调用系统camera

      调用系统自带的camera主要的步骤为:

(1)构造图片存储的路径名

(2)使用intent启动camera activity

(3)将拍摄的图片写入到文件

(4)将图片显示在mainactivity中

      首先,构造图片名:

file filepath = new file(environment.getexternalstoragedirectory(), "mycamera");
if(!filepath.exists()){
 filepath.mkdirs();
}
filename = new file(filepath, system.currenttimemillis() + ".jpg");
try{
 if(!filename.exists()){
  filename.createnewfile();
 }
}catch (exception e){
 e.printstacktrace();
}

      然后,启动camera activity:

// intent用来启动系统自带的camera
intent intent = new intent(mediastore.action_image_capture);
// 将系统camera的拍摄结果写入到文件
 intent.putextra(mediastore.extra_output, uri.fromfile(filename));
// 启动intent对应的activity,返回默认消息
 startactivityforresult(intent, activity.default_keys_dialer);

      最后,将图片显示在mainactivity内。这时,我们通过重载onactivityresult()方法来获取camera返回的消息。

@override
protected void onactivityresult(int requestcode, int resultcode, intent data){
 if(requestcode == activity.default_keys_dialer){
  // mainactivity接收camera返回的消息,然后将已经写入的图片显示在imageview内
  imageview.setimageuri(uri.fromfile(filename));
 }
}

完整代码为:

import android.app.activity;
import android.content.intent;
import android.net.uri;
import android.os.bundle;
import android.os.environment;
import android.provider.mediastore;
import android.util.log;
import android.view.view;
import android.widget.button;
import android.widget.imageview;
import java.io.file;
public class mainactivity extends activity {
 private file filename = null;
 private button button;
 private imageview imageview;
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  button = (button)findviewbyid(r.id.button);
  imageview = (imageview)findviewbyid(r.id.imageview);
  button.setonclicklistener(new view.onclicklistener() {
   @override
   public void onclick(view v) {
    file filepath = new file(environment.getexternalstoragedirectory(), "mycamera");
    if(!filepath.exists()){
     filepath.mkdirs();
    }
    filename = new file(filepath, system.currenttimemillis() + ".jpg");
    try{
     if(!filename.exists()){
      filename.createnewfile();
     }
    }catch (exception e){
     e.printstacktrace();
    }
    // intent用来启动系统自带的camera
    intent intent = new intent(mediastore.action_image_capture);
    // 将系统camera的拍摄结果写入到文件
    intent.putextra(mediastore.extra_output, uri.fromfile(filename));
    // 启动intent对应的activity,返回默认消息
    startactivityforresult(intent, activity.default_keys_dialer);
   }
  });
 }
 @override
 protected void onactivityresult(int requestcode, int resultcode, intent data){
  if(requestcode == activity.default_keys_dialer){
   // mainactivity接收camera返回的消息,然后将已经写入的图片显示在imageview内
   imageview.setimageuri(uri.fromfile(filename));
  }
 }
}

2、自己写一个摄像界面

      自己写摄像的界面,主要应用了surfaceview来显示摄像机的画面。然后通过一个button来保存当前的画面。

      同样的,我们需要添加camera和sdcard权限:

<uses-permission android:name="android.permission.write_external_storage"/>
<uses-permission android:name="android.permission.camera"/>

      首先,我们初始化这个surfaceview,为这个surfaceview添加一个对应的callback即可:

private surfaceview surfaceview;
private surfaceholder.callback callback;
surfaceview = (surfaceview)findviewbyid(r.id.surfaceview);
 callback = new surfaceholder.callback(){
  @override
  public void surfacecreated(surfaceholder holder) {
   startcamera(); // 用于启动摄像头
  }
  @override
  public void surfacechanged(surfaceholder holder, int format, int width, int height) {
  }
  @override
  public void surfacedestroyed(surfaceholder holder) {
   stopcamera(); // 用于关闭摄像头
  }
 };
 surfaceview.getholder().addcallback(callback); // 将callback绑定到surfaceview

      在启动摄像头的时候,首先打开摄像头连接,然后将其图像输出到surfaceview上,然后启动摄像头预览即可在surfaceview上显示摄像头的画面,这里的画面和实际画面相差有90度,所以我们需要将图像旋转90度之后才可以和拍摄的物体方向一致。

      在关闭摄像头时,只要停止预览,然后释放摄像头资源即可。

public void startcamera(){
 camera = camera.open();
 try {
  camera.setpreviewdisplay(surfaceview.getholder());
  camera.setdisplayorientation(90);
  camera.startpreview();
 } catch (ioexception e) {
  e.printstacktrace();
 }
}
public void stopcamera(){
 camera.stoppreview();
 camera.release();
 camera = null;
}

      最后,是将拍摄到的图片保存到sdcard,我们单击button来拍摄图片,调用camera.takepicture()方法,其原型为:

/**
  * equivalent to takepicture(shutter, raw, null, jpeg).
  *
  * @see #takepicture(shuttercallback, picturecallback, picturecallback, picturecallback)
  */
 public final void takepicture(shuttercallback shutter, picturecallback raw,
   picturecallback jpeg) {
  takepicture(shutter, raw, null, jpeg);
 }

      其中,shutter为按快门瞬间的回调,就是说按快门瞬间会调用shuttercallback.onshutter()方法。raw是未压缩的图像的回调,即处理图像原始数据的时候会调用picturecallback.onpicturetaken()方法。jpeg为处理jpeg图片时候的回调,即我们需要将图像数据按照jpg格式保存的时候会调用这个方法,picturecallback.onpicturetaken()。这里我们就调用了这个方法,从而将jpg图片存储到sdcard上。

button.setonclicklistener(new view.onclicklistener() {
  @override
  public void onclick(view v) {
   camera.takepicture(null, null, new camera.picturecallback() {
    @override
    public void onpicturetaken(byte[] data, camera camera) {
     try {
      file filepath = new file(environment.getexternalstoragedirectory(), "mycamera");
      if(!filepath.exists()) {
       filepath.mkdirs();
      }
      file filename = new file(filepath, system.currenttimemillis() + ".jpg");
      filename.createnewfile();
      fileoutputstream fos = new fileoutputstream(filename);
      fos.write(data);
      fos.flush();
      fos.close();
     } catch (ioexception e) {
      e.printstacktrace();
     }
    }
   });
  }
 });

      这样,我们便实现了用surfaceview预览摄像头画面,点击button将当前预览保存到sdcard中。

完整代码如下:

import android.app.activity;
import android.hardware.camera;
import android.os.bundle;
import android.os.environment;
import android.view.surfaceholder;
import android.view.surfaceview;
import android.view.view;
import android.widget.button;
import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
public class mainactivity extends activity {
 private camera camera;
 private button button;
 private surfaceview surfaceview;
 private surfaceholder.callback callback;
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  button = (button)findviewbyid(r.id.button);
  surfaceview = (surfaceview)findviewbyid(r.id.surfaceview);
  callback = new surfaceholder.callback(){
   @override
   public void surfacecreated(surfaceholder holder) {
    startcamera();
   }
   @override
   public void surfacechanged(surfaceholder holder, int format, int width, int height) {
   }
   @override
   public void surfacedestroyed(surfaceholder holder) {
    stopcamera();
   }
  };
  surfaceview.getholder().addcallback(callback);
  button.setonclicklistener(new view.onclicklistener() {
   @override
   public void onclick(view v) {
    camera.takepicture(null, null, new camera.picturecallback() {
     @override
     public void onpicturetaken(byte[] data, camera camera) {
      try {
       file filepath = new file(environment.getexternalstoragedirectory(), "mycamera");
       if(!filepath.exists()) {
        filepath.mkdirs();
       }
       file filename = new file(filepath, system.currenttimemillis() + ".jpg");
       filename.createnewfile();
       fileoutputstream fos = new fileoutputstream(filename);
       fos.write(data);
       fos.flush();
       fos.close();
      } catch (ioexception e) {
       e.printstacktrace();
      }
     }
    });
   }
  });
 }
 public void startcamera(){
  camera = camera.open();
  try {
   camera.setpreviewdisplay(surfaceview.getholder());
   camera.setdisplayorientation(90);
   camera.startpreview();
  } catch (ioexception e) {
   e.printstacktrace();
  }
 }
 public void stopcamera(){
  camera.stoppreview();
  camera.release();
  camera = null;
 }
}

以上所述是本文给大家介绍的关于android 开发随手笔记之使用摄像头拍照的全部内容,希望大家喜欢。

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

相关文章:

验证码:
移动技术网