当前位置:主页 > 移动开发 > Android代码 >

Android实现摄像头拍照功能

时间:2021-11-28 11:30:53 | 栏目:Android代码 | 点击:

应用场景:

在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实现摄像头拍照功能

您可能感兴趣的文章:

相关文章