一、概述

Camera是手机的一个很重要的设备,可以说现在的每一部手机上都有。回想当时在Linux搞摄像头编程真的要捏一把汗。有人会说在Linux下装个opencv就可以通过它的函数来使用摄像头啦,但我并没有这么做,我还是用最原始的方法(V4L2)实现了。之前研究过Android关于摄像头这部分的源码,毫无疑问,Android关于摄像头底层的实现用的也是V4L2。


二、实现

新建工程MyCamera,修改/res/layout/main.xml文件,使用RelativeLayout布局,并添加一个SurfaceView和一个Button,完整的main.xml如下:

 1 <?xml version="1.0" encoding="utf-8"?>
2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 android:orientation="vertical"
6 >
7
8 <SurfaceView
9 android:id="@+id/surfaceview"
10 android:layout_width="fill_parent"
11 android:layout_height="wrap_content"
12 android:layout_alignParentTop="true"
13 android:layout_above="@+id/button"
14 />
15
16 <Button
17 android:id="@+id/button"
18 android:layout_width="fill_parent"
19 android:layout_height="wrap_content"
20 android:layout_alignParentBottom="true"
21 android:text="拍照"
22 />
23
24 </RelativeLayout>

接着,修改MyCameraActivity.java文件,实现了SurfaceHolder.Callback接口,用于初始化、释放摄像头和Camera.PictureCallback接口,用于保存图片数据到文件里。完整的内容如下:

  1 package com.nan.camera;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 import android.app.Activity;
9 import android.graphics.Bitmap;
10 import android.graphics.BitmapFactory;
11 import android.graphics.PixelFormat;
12 import android.hardware.Camera;
13 import android.os.Bundle;
14 import android.os.Environment;
15 import android.view.SurfaceHolder;
16 import android.view.SurfaceView;
17 import android.view.View;
18 import android.widget.Button;
19 import android.widget.Toast;
20
21 public class MyCameraActivity extends Activity
22 {
23 private SurfaceView mSurfaceView = null;
24 private SurfaceHolder mSurfaceHolder = null;
25 private Button takePictureButton = null;
26 private Camera mCamera;
27 //记录保存的是第几张图片
28 private int whichPicture = 0;
29
30 /** Called when the activity is first created. */
31 @Override
32 public void onCreate(Bundle savedInstanceState)
33 {
34 super.onCreate(savedInstanceState);
35 setContentView(R.layout.main);
36
37 takePictureButton = (Button)this.findViewById(R.id.button);
38 mSurfaceView = (SurfaceView)this.findViewById(R.id.surfaceview);
39 mSurfaceHolder = mSurfaceView.getHolder();
40 mSurfaceHolder.addCallback(new SurfaceHolderCallback());
41 //设置缓冲区类型
42 mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
43 //拍照按钮监听
44 takePictureButton.setOnClickListener(new View.OnClickListener()
45 {
46
47 @Override
48 public void onClick(View v)
49 {
50 // TODO Auto-generated method stub
51 //拍照
52 mCamera.takePicture(null, null, pictureCallback);
53 }
54 });
55
56 }
57
58 private class SurfaceHolderCallback implements SurfaceHolder.Callback
59 {
60
61 @Override
62 public void surfaceChanged(SurfaceHolder holder, int format, int width,
63 int height) {
64 // TODO Auto-generated method stub
65
66 }
67
68 @Override
69 public void surfaceCreated(SurfaceHolder holder)
70 {
71 // TODO Auto-generated method stub
72 //打开摄像头
73 mCamera = Camera.open();
74 try {
75 mCamera.setPreviewDisplay(mSurfaceHolder);
76 } catch (IOException e) {
77 // TODO Auto-generated catch block
78 e.printStackTrace();
79 }
80 //获取摄像头参数
81 Camera.Parameters mParameters = mCamera.getParameters();
82 //设置图片格式
83 mParameters.setPictureFormat(PixelFormat.JPEG);
84 mCamera.setParameters(mParameters);
85 //开始预览
86 mCamera.startPreview();
87 }
88
89 @Override
90 public void surfaceDestroyed(SurfaceHolder holder)
91 {
92 // TODO Auto-generated method stub
93 if(mCamera!=null)
94 {
95 //停止预览
96 mCamera.stopPreview();
97 //释放摄像头
98 mCamera.release();
99 mCamera = null;
100 }
101 }
102
103 }
104
105 //拍照回调
106 private Camera.PictureCallback pictureCallback = new Camera.PictureCallback()
107 {
108
109 @Override
110 public void onPictureTaken(byte[] data, Camera camera)
111 {
112 // TODO Auto-generated method stub
113 //停止预览
114 mCamera.stopPreview();
115 Bitmap mBitmap;
116 mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
117 //文件路径和文件名
118 File pictureFile = new File(Environment.getExternalStorageDirectory(),"camera"+Integer.toString(whichPicture)+".jpg");
119
120 try
121 {
122 FileOutputStream mFileOutputStream = new FileOutputStream(pictureFile);
123 //将图像数据压入文件
124 mBitmap.compress(Bitmap.CompressFormat.JPEG, 75, mFileOutputStream);
125 try {
126 //关闭输出流
127 mFileOutputStream.close();
128 } catch (IOException e) {
129 // TODO Auto-generated catch block
130 e.printStackTrace();
131 }
132 }
133 catch (FileNotFoundException e)
134 {
135 // TODO Auto-generated catch block
136 e.printStackTrace();
137 }
138 displayToast("保存成功!");
139 whichPicture++;
140 //开始预览
141 mCamera.startPreview();
142 }
143
144 };
145
146 //显示Toast函数
147 private void displayToast(String s)
148 {
149 Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
150 }
151
152 }

在真机上运行该程序:

按一下“拍照”按钮:

图片会被保存到sd卡的根目录下面。




更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Eclipse中Android(安卓)SDK Manager无法打开
  6. apk签名机制与SHA1算法
  7. Android(安卓)用系统相机拍照android.os.FileUriExposedExceptio
  8. Android中常用的adb或adb shell命令
  9. Android:详解如何创建Google风格的SettingsActivity

随机推荐

  1. Android如何连接SQLServer数据库
  2. Android动态布局,并动态为TextView控件设
  3. 使用adb出现假emulator的解决方法
  4. Android(安卓)RecyclerView 设置分割线(i
  5. android 中使用Java反射Reflect,输出类中
  6. 安卓实现标题和按钮在一行,按钮靠最右边布
  7. Android应用开发攻略
  8. 解决Android(安卓)SDK Manager更新、下载
  9. Android(安卓)Q适配(4)-------针对后台 Act
  10. 将网页变成灰色(只限IE)