首页 > 系统 > Android > 正文

Android实现摄像头拍照功能

2019-10-22 18:12:22
字体:
来源:转载
供稿:网友

应用场景:

Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用。

知识点介绍:

使用权限:调用手机自身设备功能(摄像头拍照功能),应该确保已经在AndroidManifest.xml中正确声明了对摄像头的使用及其它相关的feature。

<!--摄像头权限 -->  <uses-permission android:name="android.permission.CAMERA" />  <!--存储权限  SD卡读写权限 -->  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  <!--Camera Feature 声明对camera feature的使用 -->  <uses-feature android:name="android.hardware.camera" />  <uses-feature  android:name="android.hardware.camera.autofocus"  android:required="false" />  <!--视频、录音权限  请求音频捕获权限 -->  <uses-permission android:name="android.permission.RECORD_VIDEO"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> 

Class类:

1、 SurfaceView
视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
2、 SurfaceHolder
SurfaceHolder是控制surface的一个抽象接口,你可以通过SurfaceHolder来控制surface的尺寸和格式,或者修改surface的像素,监视surface的变化等等,SurfaceHolder是SurfaceView的典型接口。
3、 SurfaceHolder.Callback
用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时,  它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。设置Callback的方法是SurfaceHolder.addCallback。

使用方式:

第一步:新建一个Android项目CameraTest,包含两个Activity: MainActivity、CameraActivity。

第二步:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:background="#FFFFFF"  android:layout_height="match_parent"  tools:context=".MainActivity" >  <LinearLayout android:layout_height="wrap_content"  android:layout_width="match_parent">  <ImageView  android:id="@+id/main_image"  android:layout_height="wrap_content"  android:src="@drawable/ic_launcher"  android:layout_width="match_parent"/>  </LinearLayout>  <LinearLayout  android:layout_height="wrap_content"  android:layout_width="match_parent"  android:layout_alignParentBottom="true"  android:layout_marginBottom="20dp"  android:orientation="horizontal">  <Button android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_weight="1"  android:id="@+id/main_camera"  android:text="拍照"/>  <Button android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_weight="1"  android:text="退出"  android:id="@+id/main_quit"/>  </LinearLayout> </RelativeLayout> 

MainActivity.java

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException;  import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView;  public class MainActivity extends Activity {   private Button cameraButton; //拍照按钮  private Button quitButton; //退出按钮  private ImageView imageView; //图片显示   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  initViews();  }   private void initViews() {  imageView = (ImageView) findViewById(R.id.main_image); // 从本地取图片(在sdcard中获取文件)  Bitmap bitmap = getLoacalBitmap("/sdcard/mhc.jpg");  Log.e("msgTag", new File("/sdcard/mhc.jpg").exists()+"==========");  imageView .setImageBitmap(bitmap); //设置Bitmap  cameraButton = (Button) findViewById(R.id.main_camera);  quitButton = (Button) findViewById(R.id.main_quit);  MainOnClickListener mainOnClickListener = new MainOnClickListener();  cameraButton.setOnClickListener(mainOnClickListener);  quitButton.setOnClickListener(mainOnClickListener);  }   private class MainOnClickListener implements OnClickListener{   @Override  public void onClick(View v) {  switch (v.getId()) {  case R.id.main_camera:  startActivity(new Intent(MainActivity.this, CameraActivity.class));  break;  case R.id.main_quit:  MainActivity.this.finish();  break;  default:  break;  }  }  }   /**  * 根据文件路径获取所需要文件,并将该文件封装成Bitmap对象返回  * @param fileUrl  * @return  */  public static Bitmap getLoacalBitmap(String fileUrl) {  try {  FileInputStream fis = new FileInputStream(fileUrl);  return BitmapFactory.decodeStream(fis); ///把流转化为Bitmap图片  } catch (FileNotFoundException e) {  e.printStackTrace();  return null;  }  } } 

activity_camera.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="#FFFFFF"  tools:context=".CameraActivity" >   <LinearLayout  android:layout_width="match_parent"  android:layout_height="match_parent" >  <SurfaceView  android:id="@+id/camera_preview"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:layout_gravity="center_vertical|center_horizontal" />  </LinearLayout>  <LinearLayout  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_alignParentBottom="true">  <Button  android:id="@+id/camera_save"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:text="拍照" />  </LinearLayout> </RelativeLayout> 

CameraActivity.java

import java.io.File; import java.io.FileOutputStream; import java.io.IOException;  import android.graphics.ImageFormat; import android.hardware.Camera; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;  public class CameraActivity extends Activity {  private String tag ="CameraActivity";  private SurfaceView surfaceView;  //Surface的控制器  private SurfaceHolder surfaceHolder;  private Camera camera;  private Button saveButton;  //拍照的回调接口  private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {  public void onPictureTaken(byte[] data, Camera camera) {  new SavePictureTask().execute(data);  camera.startPreview();  }  };   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_camera);  initViews();  }   private void initViews() {  saveButton = (Button) findViewById(R.id.camera_save);  surfaceView = (SurfaceView) findViewById(R.id.camera_preview);  surfaceHolder = surfaceView.getHolder();  // 给SurfaceView当前的持有者 SurfaceHolder 一个回调对象。  //用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时,  //它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。  //设置Callback的方法是SurfaceHolder.addCallback.  //实现过程一般继承SurfaceView并实现SurfaceHolder.Callback接口  surfaceHolder.addCallback(surfaceCallback);  // 设置surface不需要自己的维护缓存区  surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  saveButton.setOnClickListener(new OnClickListener() {   @Override  public void onClick(View v) {  camera.takePicture(null, null, pictureCallback); // Camera.takePicture(shutterCallback,rawCallback,pictureCallback ); // private ShutterCallback shutterCallback = new ShutterCallback(){ //  public void onShutter(){ //  /* 按快门瞬间会执行这里的代码 */ //  } //  }; // private PictureCallback rawCallback = new PictureCallback(){ //  public void onPictureTaken(byte[] _data, Camera _camera){ //  /* 如需要处理 raw 则在这里 写代码 */ //  } //  }; //  //当拍照后 存储JPG文件到 sd卡 //  PictureCallback pictureCallback=new PictureCallback(){ //  public void onPictureTaken(byte[] data,Camera camera) { //  FileOutputStream outSteam=null; //  try{ //  SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss"); //  String times=format.format((new Date())); //  outSteam=new FileOutputStream("/sdcard/"+times+"mhc.jpg"); //  outSteam.write(data); //  outSteam.close(); //  }catch(FileNotFoundException e){ //  Log.d("Camera", "row"); //  } catch (IOException e) { //  e.printStackTrace(); //  } //  }; //  };  }  });  }    //SurfaceView当前的持有者的回调接口的实现  SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {   @Override  public void surfaceCreated(SurfaceHolder holder) {  camera = Camera.open();  Log.e(tag, "摄像头Open完成");  try {  camera.setPreviewDisplay(holder);  } catch (IOException e) {  camera.release();  camera = null;  }  }   @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width,  int height) {  Camera.Parameters parameters = camera.getParameters();  parameters.setPictureFormat(ImageFormat.JPEG);  camera.setDisplayOrientation(0);  camera.setParameters(parameters);  camera.startPreview();  }   @Override  public void surfaceDestroyed(SurfaceHolder holder) {  camera.stopPreview();  camera.release();  camera = null;  }  };   class SavePictureTask extends AsyncTask<byte[], String, String> {  @Override  protected String doInBackground(byte[]... params) {  File picture = new File("/sdcard/mhc.jpg");  try {  FileOutputStream fos = new FileOutputStream(picture.getPath());  fos.write(params[0]);  fos.close();  } catch (Exception e) {  e.printStackTrace();  }  Log.e(tag, "照片保存完成");  CameraActivity.this.finish();  return null;  }  } } 

下载地址:Android实现摄像头拍照功能

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


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表