您的位置:首页 > 移动开发 > Android开发

Android中级第四讲--相机程序开发

2013-02-27 14:20 519 查看
博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved !  

今天我们来讲一下在Android平台上开发相机的问题!Two choices!
第一种使用intent方法来调用系统方法
一般以动作按钮的方式来操作,101仅作为一个标示
Button button =new Button(this);
button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//打开系统相机,拍照数据存在mCurrentPhotoFile里里
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(mCurrentPhotoFile));
startActivityForResult(intent, 101);
}
});
实现Activity里的onActivityResult
/* 反应事件 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//RESULT_OK是个系统变量,代表操作成功,那么我们就可以进行下面的操作了。
if (resultCode != Activity.RESULT_OK) {
return;
}
switch (requestCode) {
/* 拍照 */
case 101:
//保存了data就保存了图片
super.onActivityResult(requestCode, resultCode, data);
break;
}
}

第二种自定义相机
1、从xml文件中得到surfaceview对象

surfaceView = (SurfaceView) findViewById(R.id.g3_server_preview);
2、之后声明一些回调方法,用于打开相机,设置相机的参数(在这里可以设置图片的尺寸,以及预览界面的尺寸)

// SurfaceHodler 回调,处理打开相机,关闭相机以及照片尺寸的改变
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 打开相机
camera = Camera.open();
try {
// 设置预览
camera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// 获得相机参数
Camera.Parameters parameters = camera.getParameters();
// SDK版本选择,兼容
if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
setDisplayOrientation(camera, 90);
} else {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
parameters.set("orientation", "portrait");
parameters.set("rotation", 90);
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "landscape");
parameters.set("rotation", 90);
}
}
// 设置预览大小
parameters.setPreviewSize(width, height);
pic_Width = g3_setting.getInt(AppData.G3_PIC_WIDTH, 640);
pic_Height = g3_setting.getInt(AppData.G3_PIC_HEIGHT, 800);
Log.i("Travel", pic_Width + ":" + pic_Height);
// 设置照片大小
parameters.setPictureSize(pic_Width, pic_Height);
// 设置照片格式
// parameters.setPictureFormat(PixelFormat.RGB_565);
// 开始预览
camera.startPreview();
// 设置相机参数
camera.setParameters(parameters);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 停止预览
if (camera != null) {
camera.stopPreview();
// 释放相机资源
camera.release();
camera = null;
}
}
};
protected void setDisplayOrientation(Camera camera, int angle) {
Method downPolymorphic;
try {
downPolymorphic = camera.getClass().getMethod(
"setDisplayOrientation", new Class[] { int.class });
if (downPolymorphic != null)
downPolymorphic.invoke(camera, new Object[] { angle });
} catch (Exception e1) {
}
}
3、然后设置surfaceview参数,加载回调方法 // 设置屏幕常亮
surfaceView.setKeepScreenOn(true);
surfaceView.setFocusable(true);
releaseCamera();
// 从SurfaceView中获得SurfaceHolder
surfaceView.getHolder().addCallback(surfaceCallback);
// 为SurfaceHolder 添加回调
// surfaceHolder.addCallback(surfaceCallback);
surfaceView.getHolder()
.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);释放相机资源
private void releaseCamera() {
// TODO Auto-generated method stub
if (camera != null) {
camera.stopPreview();
// 释放相机资源
camera.release();
camera = null;
}
}


4、配置相机响声音还是震动的回调方法Camera.ShutterCallback shutter = new ShutterCallback() {

@Override
public void onShutter() {
// TODO Auto-generated method stub
if (tone == null) {
// 发出提示用户的声音
tone = new ToneGenerator(AudioManager.STREAM_SYSTEM,
ToneGenerator.MAX_VOLUME);
}
if (g3_setting.getBoolean(AppData.G3_CONFIG_AUDIO, true)) {
tone.startTone(ToneGenerator.TONE_PROP_BEEP);
} else {
tone.stopTone();
Vibrator vibrator = (Vibrator) context
.getSystemService(Service.VIBRATOR_SERVICE);
vibrator.vibrate(100);
}
}
};

小插曲,判断系统声音能否关闭File file = new File("/system/media/audio/ui/Camera_click.ogg");
if (!file.canWrite()) {
Tools.showToast(context, "设置声音无效!");
} else {
file.renameTo(new File("/system/media/audio/ui/Camera_click.ogg1"));
}
5、自动对焦并拍照// 对焦成功再拍照
camera.autoFocus(new AutoFocusCallback() {

@Override
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub
// success为true表示对焦成功
if (success) {
if (camera != null) {
// 停止预览
camera.stopPreview();
// 拍照
camera.takePicture(shutter, null, pictureCallback);
}
}
}
});

// 照片回调
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i("G3", "picture operating.............");
new SavePictureTask().execute(data);
camera.startPreview();
}
};

// 保存照片任务类
class SavePictureTask extends AsyncTask<byte[], String, String> {
@Override
protected String doInBackground(byte[]... params) {
Log.i("G3", "picture saving.............");
File path = new File(Tools.getSDPath());
if (!path.exists()) {
path.mkdirs();
}
// 创建文件
File picture = new File(Tools.getSDPath(), Tools.initPhotoName());
try {
// 获得文件输出流
FileOutputStream fos = new FileOutputStream(picture.getPath());
// 写到该文件
fos.write(params[0]);
// 关闭文件流
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
6、注意事项:
a.本项目代码已经实现对焦功能,如果你的相机不能对焦,那是手机本身不支持,与硬件有关
b.分辨率的设置,在第3步的surfaceChanged方法里已经实现,镜头和设置不能在同一界面,所以如果你实现此功能,还请指教!
SurfaceView一个重要特性是在子线程也能刷新,原因在于它生成时向窗口申请一块透明空间,具有独立的绘图表面,不占用主线程时间。

测试源码下载地址:http://download.csdn.net/detail/liuxian13183/5088495
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: