安卓自定义相机拍照功能全解(不调用系统相机)
Android实现了相机的基本功能。
启动和释放相机
由于摄影功能一般需要实时预览,耗电量更大,因此需要在窗口恢复和暂停函数中启动和释放相机
private Camera camera;
//重写窗口函数,重启摄像头
@Override
protected void onResume() {
super.onResume();
camera = Camera.open(); //打开相机
init();
Log.v("拍照", "启动摄像头");
}
//重写窗口函数,释放摄像头
@Override
protected void onPause() {
super.onPause();
camera.release();
Log.v("拍照", "释放摄像头");
}
实时预览
SurfaceView需要用于预览视图,所以SurfaceView应该在你的xml布局文件中定义。
并实现SurfaceHolder.Callback预览回调接口,当然,你通常看到的教程都是在当前的activity中实现的。
public class Camera_Activity extends Activity implements SurfaceHolder.Callback {
private Camera camera; //定义一个相机
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_activity);
SurfaceView surface = (SurfaceView)findViewById(R.id.surfaceView);
SurfaceHolder holder = surface.getHolder();
holder.addCallback(this); //在当前窗口中实现回调接口
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.setFixedSize(400, 300);
}
//实现接口函数
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder); //设置使用哪个SurfaceView来显示取景图片
camera.startPreview(); //开始预览取景
camera.startFaceDetection(); //启动人脸识别
//必要时在预览上进行绘制
} catch (IOException e) {
Log.v("拍照", e.getMessage());
}
}
//实现接口函数
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopFaceDetection(); //停止人脸识别检测
camera.stopPreview(); //停止预览取景
}
//实现接口函数
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
相机的基本操作函数
camera.setDisplayOrientation(90);//设置方向
camera.setErrorCallback(cb); //设置错误回调函数
camera.setFaceDetectionListener(listener); //设置人脸检测监听
camera.setPreviewCallback(cb); //设置预览回调
camera.takePicture(shutter, raw, jpeg); //拍照
camera.autoFocus(cb); //自动聚焦
camera.setPreviewDisplay(holder); //设置预览视图对象
camera.startPreview();//启动预览
camera.startFaceDetection();//启动人脸识别
camera.stopFaceDetection();//停止人脸识别
camera.stopPreview(); //停止预览
camera.getParameters(); //获取参数
camera.setParameters(params); //设置参数
拍照
拍照函数使用takePicture,需要传输的参数分别是快门按下回调函数,获得拍照的原始图片数据后的回调函数,获得压缩后的jpeg图片数据回调函数。
//拍照函数
private void takePicture() {
camera.takePicture(shutterCallback, rawCallback, jpegCallback); //拍照,参数:快门函数、获取原始图片函数、获取压缩后图片函数
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
//快门关闭时执行的函数
Log.v("拍照", "快门关闭");
}
};
//拍照后raw原始图像数据
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
//对图像的原始数据做一些处理
Log.v("拍照", "获取拍照后的原始数据");
}
};
//拍照后jpeg编码图像数据
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// 将图像的jpeg数据保存到sd卡中
FileOutputStream outStream = null;
try {
String path = Environment.getExternalStorageDirectory() + "\test.jpg";
outStream = new FileOutputStream(path);
outStream.write(data);
outStream.close();
Log.v("拍照", "获取拍照后的jpeg压缩数据");
} catch (FileNotFoundException e) {
Log.v("拍照", "没有发现文件", e);
} catch (IOException e) {
Log.v("拍照", "IO接口出错", e);
}
}
};
自动聚焦
设置自动聚焦使用autoFocus函数,参数为聚焦完成回调函数,包含聚焦成功或失败。
//聚焦函数
private void focus()
{
camera.autoFocus(mycallfun);
}
//自定义聚焦完成回调函数
AutoFocusCallback mycallfun = new AutoFocusCallback(){
@Override
public void onAutoFocus(boolean success, Camera camera)
{
if (success)
{
// success为true表示对焦成功,改变对焦状态图像
Log.v("拍照", "聚焦成功");
}
}
};
读取并修改EXIF数据
拍照后获取的jpeg图片,不仅包含像素信息,还包含拍摄日期,时间,摄像头设置,图片设置,以及图像描述和位置等信息。这些信息被叫做EXIF数据
登录后复制
private void modifyExif() {
File file = new File(Environment.getExternalStorageDirectory(),"test.jpg");
try {
ExifInterface exif = new ExifInterface(file.getCanonicalPath());
//读取摄像头模型和位置属性
String model = exif.getAttribute(ExifInterface.TAG_MODEL);
Log.v("拍照", "Model: " + model);
//设置摄像头的品牌
exif.setAttribute(ExifInterface.TAG_MAKE, "My Phone");
} catch (IOException e) {
Log.v("拍照", "IO Exception", e);
}
}