Android 开发一个简单的照相机程序

转载 2013年12月03日 13:41:19

Android开发相机比较简单,而且帮助文档中有详细的说明,但是对于刚刚开始学习android的程序员来说,仍然是一件很有挑战性的事情,本人由于工作需要,开发了一个很简单的照相机程序(只能拍照并保存而已,呵呵),下边将简述开发相机程序的主要步骤,并在最后给出源码。

首先给出API文档中开发相机程序的步骤描述:(比较懒,直接截图了)

1.获取系统提供的照相机服务:

 
1
Camera.open(); //上图中给出的是open(int)这个方法,这是SDK升级的结果,因为现在很多手机已经不止一个摄像头了,为了兼容性,我们使用open()方法

2.这一步对应上图中的2-4步,主要作用是获取相机的配置参数,并按照自己的需求对参数进行修改,例如预览区的尺寸,保存图片的尺寸,相机的角度等等。

 
1
2
3
4
5
6
7
Camera.Parameters parameters = camera.getParameters(); //获取相机的配置参数
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); //不同手机支持的预览区的大小是不一样的,而且也不是任意的,该方法的作用是获取手机支持的预览区大小,以便按自己的需求进行自定义
Camera.Size previewSize = previewSizes.get( 0 ); //为了演示,选择第一个
parameters.setPreviewSize(previewSize.width, previewSize.height); //设置预览区的大小
List<Camera.Size> picSizes = parameters.getSupportedPictureSizes(); //和预览区的设置一样,相机最后捕获的照片的大小也是因手机厂商的不同而不同,而且不能随便定义
Camera.Size picSize = picSizes.get( 0 ); //为了演示,随便选择一个
parameters.setPictureSize(picSize.width, picSize.height); //设置保存图片的大小,还有很多其他的参数,具体看API吧

3.设置好参数之后,就可以开启预览了,正如API中说的,必须定义一个SurfaceHolder的实例,传送给camera,然后调用startPreView就可以实现预览了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//下边给我自己定义个Preview
public class Preview extends SurfaceView implements SurfaceHolder.Callback {
      
     SurfaceHolder mHolder;
     public Camera camera;
  
     public Preview(Context context, Camera camera) {
         super (context);
         this .camera = camera;
         mHolder = getHolder();
         mHolder.addCallback( this );
         mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     }
  
     public void surfaceCreated(SurfaceHolder holder) {
         try {
         camera.setPreviewDisplay(holder);
         } catch (IOException exception) {
         camera.release();
         camera = null ;
         }
     }
  
     public void surfaceDestroyed(SurfaceHolder holder) {
         if (camera != null ) {
         camera.stopPreview();
         camera.setPreviewCallback( null );
         camera.release();
         camera = null ;
         }
     }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { //系统会自动调用这个方法
         Camera.Parameters parameters = camera.getParameters();
         List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
         Camera.Size previewSize = previewSizes.get( 0 );
         parameters.setPreviewSize(previewSize.width, previewSize.height);
         List<Camera.Size> picSizes = parameters.getSupportedPictureSizes();
         Camera.Size picSize = picSizes.get( 0 );
         parameters.setPictureSize(picSize.width, picSize.height);
         camera.setParameters(parameters);
         camera.startPreview();
     }
  
     @Override
     public void draw(Canvas canvas) {
         super .draw(canvas);
     }
}

4.最后就是获取相机捕获的数据了,这步比较简单,就是将比特流保存为最后的图片,需要说明的是保存图片的操作必须在Camera.PictureCallback这个接口实现,因为保存相机数据的方法是:

?
1
camera.takePicture( null , null , m_PicCallback); //前两个参数不用管,最后一个参数是保存相机数据的地方

我的保存相机数据的接口如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MyPictureCallback implements Camera.PictureCallback {
  
     public void onPictureTaken( byte [] data, Camera camera) {
         Bitmap bm = BitmapFactory.decodeByteArray(data, 0 , data.length);
         String picDirStr = Environment.getExternalStorageDirectory() + "/pic/" ;
         File picDir = new File(picDirStr);
         if (!picDir.exists()){
         picDir.mkdir();
         }
         String picName = picDirStr + System.currentTimeMillis() + ".jpg" ;
         File myCaptureFile = new File(picName);
         try {
         BufferedOutputStream bos = new BufferedOutputStream(
         new FileOutputStream(myCaptureFile));
         bm.compress(Bitmap.CompressFormat.JPEG, 80 , bos);
         bos.flush();
         bos.close();
         camera.startPreview();
         } catch (Exception e) {
         e.printStackTrace();
         }
     }
  
}
 

安卓下自定义相机简单实现

关于安卓自定义相机,网上有不少的源码。但是功能实现上一般都还会略有不足比如对焦方式,camera资源的释放等等。还有的自定义相机是基于opnCV实现,应用于AR场景,在这里我们暂时用不到这样高大上的技...
  • lucasey
  • lucasey
  • 2016年05月11日 14:12
  • 1482

Android学习之调用系统相机实现拍照功能

一、今天,来介绍如何调用系统自带的相机进行拍照,主要有以下2种实现的方式: 1、Camera应用程序包含了一个意图过滤器,即intent filter,它使得开发人员能够提供与Camera应用程序同...
  • u012561176
  • u012561176
  • 2015年11月28日 12:26
  • 5353

Android简单通讯录的开发

本次开发分为4步: 1、获取手机通讯录的信息; 2、手机通讯录的数据封装; 3、手机通讯录的信息的UI适配; 4、对ListView的优化。 GetNumber.java: 用来获取手机通讯录。下面...
  • qq_25585701
  • qq_25585701
  • 2016年07月07日 16:02
  • 3085

【Android 开发入门】为按钮添加Click单击事件处理程序,显示/隐藏另一个按钮

在上篇“走进Android开发的世界,HelloWorld”,我们创建了一个Android 项目 HelloWorld,并演示了如何通过USB连接手机查看运行效果;这里讲一下如何为应用添加一个按钮,并...
  • testcs_dn
  • testcs_dn
  • 2016年12月19日 20:04
  • 1660

Android 开发环境搭建和HelloWorld程序

  • 2014年03月12日 00:36
  • 2.15MB
  • 下载

一个 2 年 Android 开发者的 18 条忠告

我仍记得2014年我决定做安卓开发的那天,这是我一生中做出的最好决定之一。到现在已经有2年半了, 最初的时候,并没有人告诉我如何做才是正确的。我犯了很多错误,浪费了很多时间。 一年半之后,我有机会...
  • ql15010832315
  • ql15010832315
  • 2016年11月12日 13:07
  • 202

看到一篇关于如何养成一个良好的 Android 开发习惯文章,感觉不错

Android编码规范
  • py1102
  • py1102
  • 2016年11月19日 09:01
  • 296

养成一个良好的 Android 开发习惯(整理)

一、Android编码规范 1.java代码中不出现中文,最多注释中可以出现中文;2.局部变量命名、静态成员变量命名:只能包含字母,单词首字母出第一个都为大写,其他字母都为小写;3.常量命名:只能包...
  • sx1650840284
  • sx1650840284
  • 2016年11月19日 00:12
  • 600

一个 2 年 Android 开发者的 18 条忠告

原文:What 2 Years of Android Development Have Taught Me the Hard Way 前言 不要重复造轮子 不要盲目的选择library 坐下来喝杯咖啡...
  • yyh352091626
  • yyh352091626
  • 2016年11月08日 09:36
  • 3300

Android 开发一个天气预报桌面小部件

一 本片文章主要记录了如何开发一个桌面小部件,以及如何获取天气预报信息,并实时异步更新...
  • free092875
  • free092875
  • 2014年05月13日 13:22
  • 1603
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 开发一个简单的照相机程序
举报原因:
原因补充:

(最多只允许输入30个字)