android 照相机-GeoWay
首先给出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(); } } } |