控制摄像头拍照

现在的智能手机和平板电脑一般都会提供摄像头拍照功能。在Android中提供了专门用于处理摄像头相关事件的类,即android.hardware包中的Camera类。Camera类没有构造方法,可以通过其提供的open()方法打开摄像头。打开摄像头后,可以通过Camera.Parameters类处理摄像头的拍照参数。拍照参数设置完成后,可以调用startPreview()方法预览拍照画面,也可以调用takePicture()方法进行拍照。结束程序时,可以调用Camera类的stopPreview()方法结束预览,并调用release()方法释放摄像头资源。Camera类常用的方法如表10.9所示。

表10.9  Camera类常用的方法

下面通过一个实例来说明控制摄像头拍照的具体过程。

实例  实现控制摄像头拍照功能

在Android Studio中创建Module,名称为“Camera”,在该Module中实现本实例,具体步骤如下。

(1)修改布局文件activity_main.xml,首先将默认添加的布局管理器修改为帧布局管理器,然后将TextView组件删除,再添加一个SurfaceView组件(用于显示摄像头预览画面),最后添加一个预览按钮和一个拍照按钮。具体代码请参见光盘。

(2)打开MainActivity类,该类继承Activity,然后在该类中,定义所需的成员变量,关键代码如下:

01  private Camera camera;                                  //定义相机对象

02  private boolean isPreview = false;                     //定义非预览状态

(3)在MainActivity类的onCreate()方法中,首先设置全屏显示,然后判断手机是否安装SD卡,关键代码如下:

01  //设置全屏显示

02  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

03          WindowManager.LayoutParams.FLAG_FULLSCREEN);

04  if (!Environment.getExternalStorageState().equals(   //判断手机是否安装SD卡

05          Environment.MEDIA_MOUNTED)) {

06      Toast.makeText(this, "请安装SD卡!", Toast.LENGTH_SHORT).show(); // 提示安装SD卡

07  }

(4)获取SurfaceView组件与SurfaceHolder对象,用于显示摄像头预览,关键代码如下:

01  //获取SurfaceView组件,用于显示摄像头预览

02  SurfaceView sv = (SurfaceView) findViewById(R.id.surfaceView); 

03   final SurfaceHolder sh = sv.getHolder();              //获取SurfaceHolder对象

04  //设置该SurfaceHolder自己不维护缓冲

05  sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  

06  ImageButton preview = (ImageButton) findViewById(R.id.preview);        //获取“预览”按钮

07  ImageButton takePicture = (ImageButton) findViewById(R.id.takephoto);  //获取“拍照”按钮

(5)为预览按钮添加单击事件监听器,实现摄像头的预览功能,关键代码如下:

01  preview.setOnClickListener(new View.OnClickListener() {         //实现摄像头预览功能

02      @Override

03      public void onClick(View v) {

04          // 如果摄像头为非预览模式,则打开相机

05          if (!isPreview) {

06              camera = Camera.open();                /打开相机

07              isPreview = true;                       //设置为预览状态

08          }

09          try {

10              camera.setPreviewDisplay(sh);           //设置用于显示预览的SurfaceView

11              Camera.Parameters parameters = camera.getParameters();  //获取相机参数

12              parameters.setPictureFormat(PixelFormat.JPEG);    //指定图片为JPEG图片

13              parameters.set("jpeg-quality", 80);   //设置图片的质量

14              camera.setParameters(parameters);      //重新设置相机参数

15              camera.startPreview();                  //开始预览

16              camera.autoFocus(null);                 //设置自动对焦

17          } catch (IOException e) {                   //输出异常信息

18              e.printStackTrace();

19          }

20      }

21  });

(6)在MainActivity中,创建实现重新预览的方法resetCamera(),在该方法中,当isPreview变量的值为真时,调用摄像头的startPreview()方法开启预览,具体代码如下:

01  private void resetCamera() {        //创建resetCamera()方法,实现重新预览功能

02      if (!isPreview) {                //如果为非预览模式

03          camera.startPreview();       //开启预览

04          isPreview = true;

05      }

06  }

(8)实现拍照的回调接口,在重写的onPictureTaken()方法中,首先根据拍照所得的数据创建位图,然后保存所拍摄的图片,再把保存的图片文件插入到系统图库,最后通知图库更新,具体代码如下:

01   

02  //实现将照片保存到系统图库中

03  final Camera.PictureCallback jpeg = new Camera.PictureCallback() {  //照片回调函数

04      @Override

05      public void onPictureTaken(byte[] data, Camera camera) {

06          // 根据拍照所得的数据创建位图

07          final Bitmap bm = BitmapFactory.decodeByteArray(data, 0,

08                  data.length);

09          camera.stopPreview();                                          //停止预览

10          isPreview = false;                                             //设置为非预览状态

11          //获取sd卡根目录

12          File appDir = new File(Environment.getExternalStorageDirectory(), "/DCIM/Camera/");

13          if (!appDir.exists()) {                   //如果该目录不存在

14              appDir.mkdir();                        //创建该目录

15          }

16          //将获取的当前系统时间设置为照片名称

17          String fileName = System.currentTimeMillis() + ".jpg";

18          File file = new File(appDir, fileName);    //创建文件对象

19          try {  //保存拍到的图片

20              FileOutputStream fos = new FileOutputStream(file); //创建一个文件输出流对象

21              //将图片内容压缩为JPEG格式输出到输出流对象中

22              bm.compress(Bitmap.CompressFormat.JPEG, 100, fos);

23              //将缓冲区中的数据全部写出到输出流中

24              fos.flush();

25              fos.close();                            //关闭文件输出流对象

26          } catch (FileNotFoundException e) {

27              e.printStackTrace();

28          } catch (IOException e) {

29              e.printStackTrace();

30          }

31          //将照片插入到系统图库

32          try {

33              MediaStore.Images.Media.insertImage(MainActivity.this.getContentResolver(),

34                      file.getAbsolutePath(), fileName, null);

35          } catch (FileNotFoundException e) {

36              e.printStackTrace();

37          }

38          //最后通知图库更新

39          Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

40          Uri uri = Uri.fromFile(file);

41          intent.setData(uri);

42          MainActivity.this.sendBroadcast(intent);   //这个广播的目的就是更新图库

43          Toast.makeText(MainActivity.this, "照片保存至:" + file, Toast.LENGTH_LONG).show();

44          resetCamera();                                //调用重新预览resetCamera()方法

45      }

46  };

(9)在onCreate()方法中,为拍照按钮添加单击事件监听器,实现摄像头的拍照功能,关键代码如下:

01  takePicture.setOnClickListener(new View.OnClickListener() {

02      @Override

03      public void onClick(View v) {

04          if (camera != null) {                          //相机不为空

05              camera.takePicture(null, null, jpeg);    //进行拍照

06          }

07      }

08  });

(10)重写Activity的onPause()方法,用于当暂停Activity时,停止预览并释放摄像头资源,具体代码如下:

01  @Override

02  protected void onPause() {   

03      if (camera != null) {                         //如果摄像头不为空

04          camera.stopPreview();                     //停止预览

05          camera.release();                          //释放资源

06      }

07      super.onPause();

08  }

(11)由于本程序需要访问SD卡和控制摄像头,所以需要在AndroidManifest.xml文件中赋予程序访问SD卡和控制摄像头的权限,关键代码如下:

01  <!-- 授予程序可以向SD卡中保存文件的权限 -->

02  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

03  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

04  <!-- 授予程序使用摄像头的权限 -->

05  <uses-permission android:name="android.permission.CAMERA"/>

06  <uses-feature android:name="android.hardware.camera.autofocus"/>

07  <uses-feature android:name="android.hardware.camera"/>

(12)在AndroidManifest.xml文件的<activity>标记中添加screenOrientation属性,设置其横屏显示,关键代码如下:

android:screenOrientation="landscape"

(13)在工具栏中找到下拉列表框,选择要运行的应用(这里为Camera),再单击右侧的按钮,在显示的界面中,单击预览按钮,启动摄像头,单击拍照按钮进行拍照,如图10.9所示。

图10.9  预览与拍照

说明:本实例需要摄像头硬件的支持,这里我们使用真机测试。读者需要在手机中手动开启摄像头权限与sd卡读写权限。

本文来自明日科技出版的《零基础学Android,转载请注明出处!!!

原文地址:https://www.cnblogs.com/mrxy/p/8242232.html

时间: 2024-08-28 20:37:42

控制摄像头拍照的相关文章

在WPF中使用AForge.net控制摄像头拍照

原文:在WPF中使用AForge.net控制摄像头拍照 利用AForge.net控制摄像头拍照最方便的方法就是利用PictureBox显示摄像头画面,但在WPF中不能直接使用PictureBox.必须通过<WindowsFormsHost></WindowsFormsHost>来提供交换功能.其解决方法如下: 1.按照常规方法新建一个WPF应用程序: 2.添加引用 WindowsFormsIntegration  (与WinForm交互的支持) System.Windows.For

如何在SAP UI5应用里添加使用摄像头拍照的功能

昨天Jerry的文章 纯JavaScript实现的调用设备摄像头并拍照的功能 介绍了纯JavaScript借助WebRTC API来开发支持调用设备的摄像头拍照的web应用.而我同事遇到的实际情况是,需要使用SAP UI5这个前端框架来开发web应用.在有了前一篇文章的知识储备后,在SAP UI5里完成这个功能,可以采取同样的思路. 我们先回忆前一篇文章里提到的技术实现的要点: (1) 在web应用的HTML页面里定义HTML5用于显示视频的原生标签:video (2) 使用WebRTC的API

android调用摄像头拍照

调用手机摄像头拍照,获取拍照后的图片数据.以下代码是在activity中:     // 调用摄像头         Button b = (Button) findViewById(R.id.btn1);     b.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             // Here we fire the inte

win8 metro 自己写摄像头拍照项目

这个项目不是用的系统自带的CameraCaptureUI,是自己写的摄像头的调用,界面做的不好所以,不放了,但是可以实现拍照功能: 下面是using 程序命名空间: using Windows.Media.Capture; using Windows.Media.MediaProperties; using Windows.UI.Xaml.Media.Imaging; using Windows.Storage; using Windows.Storage.Pickers; using Wind

VS2010开发MFC ActiveX,摄像头拍照上传Webservice(2)

继续记录,第二步开发摄像头拍照功能. 使用vfw.h开发摄像头拍照功能,关于vfw网上有很多文章,很多代码可以参考 参考:http://blog.163.com/huangqiao_8/blog/static/33900492008017111847364/ Vedio for Windows 是WIN32 SDK 中多媒体编程SDK 的视频开发工具.在微软的Visual C ++中提供了Vedio for Windows 的头文件vfw.h 和库文件vfw32.lib. 在ActiveX中显示

C# 使用摄像头拍照 支持Win7 64位

原文:C# 使用摄像头拍照 支持Win7 64位 So, how do we capture an image from a WebCam? Once you download the source code that is attached to the article you should have the following three projects: Demo – simple Windows Forms project that demonstrates how a WebCam

利用html5调用本地摄像头拍照上传图片[转]

利用html5调用本地摄像头拍照上传图片 html5概念啥的就不废话了,不知道的 百度, 谷歌一堆..今天学了学html5中的Canvas结合新增的<video>标签来获取本地摄像头,在html5之前,要在浏览器获取本地摄像头只有通过插件(ActiveX,但是这种只有IE支持)或者是flash来获取(或许你没学过flash那就很坑爹了),在之后微软的silvertlight中也可以获取,但这些都比较麻烦,在html5的世界里,要获取本地摄像头,只要配合js就可以轻松获取.. 目前支持html5

Ionic系列——调用摄像头拍照和选择图库照片功能的实现

1.需求描述 最近要做一个功能就是调用摄像头拍照,然后上传照片的功能,或者直接打开图库选择照片然后上传. 2.准备 ①.添加插件$cordovaCamera cordova plugin add cordova-plugin-camera ②.在controller中添加依赖 3.代码实现 $scope.takePhoto=function(){     var options = {                                                        

android: 调用摄像头拍照

很多应用程序都可能会使用到调用摄像头拍照的功能,比如说程序里需要上传一张图片 作为用户的头像,这时打开摄像头拍张照是最简单快捷的.下面就让我们通过一个例子来学 习一下,如何才能在应用程序里调用手机的摄像头进行拍照. 新建一个 ChoosePicTest 项目,然后修改 activity_main.xml 中的代码,如下所示: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" andro