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();
}
}
}
|