链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/06/2382679.html

一、概述

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卡的根目录下面。

Android应用开发提高篇(5)-----Camera使用的更多相关文章

  1. Android应用开发提高篇(1)-----获取本地IP

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/21/2361802.html 一.概述 习惯了Linux下的网络编程,在还没用智能机之前就一直想 ...

  2. Android JNI开发提高篇

    有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢? Android平台上的JN ...

  3. Android应用开发提高篇(6)-----FaceDetector(人脸检测)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/10/2388776.html 一.概述 初次看到FaceDetector这个类时,心里想:And ...

  4. Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html 一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把 ...

  5. Android应用开发提高篇(3)-----传感器(Sensor)编程

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/29/2373420.html 一.概述 Android支持的传感器种类越来越多了,这确实是一件可 ...

  6. Android应用开发提高篇(2)-----文本朗读TTS(TextToSpeech)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/26/2368696.html 一.概述 TextToSpeech,就是将文本内容转换成语音,在其 ...

  7. Android应用开发基础篇(1)-----Button

    Android应用开发基础篇(1)-----Button   一.概述        Button,顾名思义就是按钮的意思,它主要的功能是响应用户按下按钮时的动作. 二.应用      新建一个工程, ...

  8. android 串口开发第二篇:利用jni实现android和串口通信

    一:串口通信简介 由于串口开发涉及到jni,所以开发环境需要支持ndk开发,如果未配置ndk配置的朋友,或者对jni不熟悉的朋友,请查看上一篇文章,android 串口开发第一篇:搭建ndk开发环境以 ...

  9. Android UI开发第四十一篇——墨迹天气3.0引导界面及动画实现

    周末升级了墨迹天气,看着引导界面做的不错,模仿一下,可能与原作者的代码实现不一样,但是实现的效果还是差不多的.先分享一篇以前的文章,android动画的基础知识,<Android UI开发第十二 ...

随机推荐

  1. cocos2d-x获取系统时间

    欢迎转载,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585 之前使用过cocos2d-x获取系统时间,毫秒级的 long ge ...

  2. wxWidgets刚開始学习的人导引(2)——下载、安装wxWidgets

    wxWidgets刚開始学习的人导引全目录   PDF版及附件下载 1 前言2 下载.安装wxWidgets3 wxWidgets应用程序初体验4 wxWidgets学习资料及利用方法指导5 用wxS ...

  3. 662 - Fast Food

    描述:状态方程p[i][j]=dp[i-1][k]+dist(k+1,j),由于没搞懂距离dist是怎么计算的,以为是num[j]-num[k+1],结果wa了一次,在状态转移的时候,采用一个数组sc ...

  4. css组件规范

    7月份研究了下 写了下总结. 笔记地址

  5. Asp.net 获取服务器指定文件夹目录文件,并提供下载

    string dirPath = HttpContext.Current.Server.MapPath("uploads/"); if (Directory.Exists(dirP ...

  6. JavaSE复习日记 : 实例化对象/构造方法和this关键字

    /* * 实例化对象/对象的构造方法/this关键字 */ /* * 实例化对象 * * 就是实例化某一个类; * 从不同角度去理解的话就是: * 1. 从人的认知角度: * 就是具体化某个东西; * ...

  7. Hadoop 处理“Name node is in safe mode”问题(转)

    运行hadoop程序时,有时候会报以下错误:org.apache.hadoop.dfs.SafeModeException: Cannot delete /user/hadoop/input. Nam ...

  8. 一个原生js写的加减乘除运算

    根据我的经验我说的再多也没人看,不过还是简单介绍下效果吧,可以选择+,-,*,/,去计算数据,喜欢的话就粘贴复制自己看去吧! <!DOCTYPE html PUBLIC "-//W3C ...

  9. javascript --推箱子

    <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" ...

  10. less做个径向菜单

    在慕课网发现了一个有意思的课程,叫 数学知识在CSS动画中的应用 .用到的数学知识是如何计算圆上每个点的坐标.统一名称,中间的菜单叫触发菜单,四周发散的菜单叫子菜单, 效果预览 慕课网通过jquery ...