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();
        }
    }
  
}
posted @ 2012-07-27 17:50  张峰_r  阅读(367)  评论(0编辑  收藏  举报