上篇讲的都是一些基本的使用,这篇就来自己定义一个相机了

参照Google API:http://developer.android.com/guide/topics/media/camera.html

我们还是在原来的demo上修改,新增一个button,点击跳转到CameraActivity,我们在CameraActivity内实现我们的自定义相机,这里值得注意的是,我们拍照时要一直捕捉拍照的过程,普通的view肯定不行,google给我们提供了一个view叫做

53f9e39e058e429dbca5ac138d66e3b8

一.获取相机

这里有个前提,记得添加权限

我们新增一个方法来获取系统的相机实例

/**

* 获取系统相机

*

* @return

*/

private Camera getcCamera() {

Camera camera = null;

try {

camera = Camera.open();

} catch (Exception e) {

camera = null;

}

return camera;

}

这里值得注意的是,camera是废弃的对象,那是因为google新给出来一个新的api

80fee826aebe472baf3d6dc2329362c1

但是其实新出的api只是作为高级使用的时候才会用,一般来讲,我们还是用回以前的api

二.SurfaceView预览

要使用SurfaceView还是要

implements SurfaceHolder.Callback

activity_camera.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/sv"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1" />

android:id="@+id/btn_camera"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="拍照" />

预览图像

/**

* 与SurfaceView传播图像

*/

private void showViews(Camera camera, SurfaceHolder holder) {

// 预览相机,绑定

try {

camera.setPreviewDisplay(holder);

// 系统相机默认是横屏的,我们要旋转90°

camera.setDisplayOrientation(90);

// 开始预览

camera.startPreview();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

释放占用内存

/**

* 释放相机的内存

*/

private void clearCamera() {

// 释放hold资源

if (mCamera != null) {

// 停止预览

mCamera.stopPreview();

mCamera.setPreviewCallback(null);

// 释放相机资源

mCamera.release();

mCamera = null;

}

}

绑定生命周期

@Override

protected void onResume() {

// TODO Auto-generated method stub

super.onResume();

// 在activity运行时绑定

if (mCamera == null) {

mCamera = getcCamera();

if (sh != null) {

showViews(mCamera, sh);

}

}

}

@Override

protected void onPause() {

// TODO Auto-generated method stub

super.onPause();

// activity暂停时我们释放相机内存

clearCamera();

}

SurfaceView回调并同步预览

@Override

public void surfaceCreated(SurfaceHolder holder) {

// 开始预览

showViews(mCamera, sh);

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

// 重启功能

mCamera.stopPreview();

showViews(mCamera, sh);

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// 释放

clearCamera();

}

写到这里,基本上我们的可以预览了,我们来运行一下

9ea9c0bc6bbb4fabb72ab44445db960c

这里因为是模拟器,他只有前置摄像头,本应该旋转270°的,我们只要知道通过以上的方法可以同步预览影像就可以了

拍照保存图片

我们设置拍照这个button的点击事件

btn_camera = (Button) findViewById(R.id.btn_camera);

btn_camera.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// 获取当前相机参数

Camera.Parameters parameters = mCamera.getParameters();

// 设置相片格式

parameters.setPictureFormat(ImageFormat.JPEG);

// 设置预览大小

parameters.setPreviewSize(800, 480);

// 设置对焦方式,这里设置自动对焦

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

mCamera.autoFocus(new AutoFocusCallback() {

@Override

public void onAutoFocus(boolean success, Camera camera) {

// 判断是否对焦成功

if (success) {

// 拍照 第三个参数为拍照回调

mCamera.takePicture(null, null, pc);

}

}

});

}

});

这里的pc是一个回调方法,我们重写

private PictureCallback pc = new PictureCallback() {

@Override

public void onPictureTaken(byte[] data, Camera camera) {

// data为完整数据

File file = new File("/sdcard/photo.png");

// 使用流进行读写

try {

FileOutputStream fos = new FileOutputStream(file);

try {

fos.write(data);

// 关闭流

fos.close();

// 查看图片

Intent intent = new Intent(CameraActivity.this,

PhotoActivity.class);

// 传递路径

intent.putExtra("path

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐