这是一个用surfaceview来捕捉摄像头画面并拍照存储图片到sdcard的demo。众所周知,在一个应用中,我们可以通过intent来调用系统自带的相机功能进行拍
照,但,这样做不如自己写一个拍照界面来的酷!用surfaceview的方式来做,你可以随心所欲的设计自己的界面。
在这个例子中,我用代码制作了一个拍摄界面,里面只有三个控件,一个是自己封装的CameraView,它继承了SurfaceView,一个是悬浮在CameraView上的按
钮,点击它可以捕捉画面并把图像存储到sdCard的根目录下,还有一个是悬浮在CameraView上的TextView,它不过显示一行文字而已。
程序运行截图如下:
存储在sdcard根目录下的图片如下:
你可以看到,在surfaceview中所呈现的图像和保存的图像是一样的,这样做保证了所见即所得。
代码如下:
这是MainActivity,程序一运行就打开的Activity:
public class MainActivity extends Activity {
private CameraView mCameraView;
private Button takePictureBtn;
private Camera mCamera;
private Bitmap mBitmap;
private int bitmapWidth;
private int bitmapHeight;
private RelativeLayout rl;
// 准备一个保存图片的pictureCallback对象
public Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
if(camera != null){
Toast.makeText(getApplicationContext(), "正在保存...", Toast.LENGTH_LONG).show();
// 用BitmapFactory.decodeByteArray()方法可以把相机传回的裸数据转换成Bitmap对象
// 这里通过BitmapFactory.Options类指定解码方法
BitmapFactory.Options options = new BitmapFactory.Options();
// 在解码图片的时候设置inJustDecodeBounds属性为true,可以避免内存分配
// options.inJustDecodeBounds = true; 这句话已开启就会死机
mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
bitmapWidth = options.outWidth;
bitmapHeight = options.outHeight;
// 把bitmap保存成一个存储卡中的文件
File file = new File("/sdcard/YY"+ new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".png");
try {
file.createNewFile();
BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
Toast.makeText(getApplicationContext(), "图片 " + bitmapWidth + "X" +