调用摄像头功能的方法详解
来源:互联网 发布:道亨软件多少钱 编辑:程序博客网 时间:2024/06/08 11:36
第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码
摄像头权限:
<
uses-permission
android:name
=
"android.permission.CAMERA"
/>
SD卡读写权限:
<
uses-permission
android:name
=
"android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
/>
<
uses-permission
android:name
=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
第二步,要将摄像头捕获的图像实时地显示在手机上。
我们是用SurfaceView这个视图组件来实现的,因此在main.xml中加入下列代码
<
SurfaceView
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
android:id
=
"@+id/surfaceview"
/>
第三步,设置窗口的显示方式
首先获得当前窗口
Window window = getWindow();
//得到窗口
接着设置没有标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
//没有标题
接着设置全屏
当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码
至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要)
setContentView(R.layout.main);
第四步,设置SurficeView显示控件的属性
找到surficeView
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
设置它的像素为800x600
surfaceView.getHolder().setFixedSize(
800
,
480
);
//下面设置surfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
第五步,就是为surficeView加入回调方法(callBack)
surfaceView.getHolder().addCallback(
new
SurfaceCallback());
上面的回调类是我们自己定义的,代码如下
private
class
SurfaceCallback
implements
SurfaceHolder.Callback{
@Override
public
void
surfaceCreated(SurfaceHolder holder) {
try
{
camera = Camera.open();
//打开硬件摄像头,这里导包得时候一定要注意是android.hardware.Camera
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
//得到窗口管理器
Display display = wm.getDefaultDisplay();
//得到当前屏幕
Camera.Parameters parameters = camera.getParameters();
//得到摄像头的参数
parameters.setPreviewSize(display.getWidth(), display.getHeight());
//设置预览照片的大小
parameters.setPreviewFrameRate(
3
);
//设置每秒3帧
parameters.setPictureFormat(PixelFormat.JPEG);
//设置照片的格式
parameters.setJpegQuality(
85
);
//设置照片的质量
parameters.setPictureSize(display.getHeight(), display.getWidth());
//设置照片的大小,默认是和 屏幕一样大
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceView.getHolder());
//通过SurfaceView显示取景画面
camera.startPreview();
//开始预览
isPreview =
true
;
//设置是否预览参数为真
}
catch
(IOException e) {
Log.e(TAG, e.toString());
}
}
@Override
public
void
surfaceChanged(SurfaceHolder holder,
int
format,
int
width,
int
height) {
// TODO Auto-generated method stub
}
@Override
public
void
surfaceDestroyed(SurfaceHolder holder) {
if
(camera!=
null
){
if
(isPreview){
//如果正在预览
camera.stopPreview();
camera.release();
}
}
}
}
第六步,我们必须对按键事件进行监听,如是拍照还是聚焦,代码如下
public
boolean
onKeyDown(
int
keyCode, KeyEvent event) {
//处理按键事件
if
(camera!=
null
&&event.getRepeatCount()==
0
)
//代表只按了一下
{
switch
(keyCode){
case
KeyEvent.KEYCODE_BACK:
//如果是搜索键
camera.autoFocus(
null
);
//自动对焦
break
;
case
KeyEvent.KEYCODE_DPAD_CENTER:
//如果是中间键
camera.takePicture(
null
,
null
,
new
TakePictureCallback());
//将拍到的照片给第三个对象中,这里的TakePictureCallback()是自己定义的,在下面的代码中
break
;
}
}
return
true
;
//阻止事件往下传递,否则按搜索键会变成系统默认的
}
private
final
class
TakePictureCallback
implements
PictureCallback{
public
void
onPictureTaken(
byte
[] data, Camera camera) {
try
{
Bitmap bitmap = BitmapFactory.decodeByteArray(data,
0
, data.length);
File file =
new
File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+
".jpg"
);
FileOutputStream outputStream =
new
FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG,
100
, outputStream);
outputStream.close();
camera.stopPreview();
camera.startPreview();
//处理完数据之后可以预览
}
catch
(Exception e) {
Log.e(TAG, e.toString());
}
}
}
注意,代码中有两个回调类,一个是SurfaceCallback(),另外一个是TakePictureCallback(),初学者可能一时难以理解,通俗地讲,前者是用来监视surficeView这个暂时存放图片数据的显示控件的,根据它的显示情况调用不同的方法,包括surfaceCreated(),surfaceChanged(),surfaceDestroyed(),也就不难理解为什么会有这三个回调方法了(注意,在surfaceDestroyed()方法中必须释放摄像头,详细代码参见上方)。TakePictureCallback()是为了监视是否拍照而设计的接口,期中也仅有一个方法,camera将拍照得到的数据传入方法,我们便可以对拍照得到的数据进行进一步处理了。
至此,简单的拍照功能介绍完毕!
package
cn.camera.rxm;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.util.Calendar;
import
java.util.Locale;
import
org.apache.commons.logging.Log;
import
android.text.format.DateFormat;
import
android.util.*;
import
android.app.Activity;
import
android.content.Context;
import
android.graphics.Bitmap;
import
android.graphics.Bitmap.CompressFormat;
import
android.graphics.BitmapFactory;
import
android.graphics.PixelFormat;
import
android.hardware.Camera;
import
android.hardware.Camera.PictureCallback;
import
android.os.Bundle;
import
android.os.Environment;
import
android.view.LayoutInflater;
import
android.view.Menu;
import
android.view.MenuItem;
import
android.view.SurfaceHolder;
import
android.view.SurfaceView;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
//import android.widget.Toast;
public
class
MycamActivity
extends
Activity {
private
Preview mPreview;
private
Camera mCamera;
Bitmap CameraBitmap;
SurfaceHolder mHolder;
private
static
final
int
OPTION_SNAPSHOT =
0
;
private
static
final
int
OPTION_STOPCAMERA =
1
;
private
View viewStart;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
LayoutInflater flater =
this
.getLayoutInflater();
viewStart = flater.inflate(R.layout.main,
null
);
setContentView(viewStart);
Button btn1 = (Button)findViewById(R.id.button1);
btn1.setOnClickListener(
new
OnClickListener(){
public
void
onClick(View v){
mPreview =
new
Preview(getBaseContext());
setContentView(mPreview);
};
}
);
}
public
boolean
onCreateOptionsMenu(Menu menu){
//
menu.add(
0
, OPTION_SNAPSHOT,
0
, R.string.take);
//
menu.add(
0
, OPTION_STOPCAMERA,
1
, R.string.back);
//
return
true
;
//super.onCreateOptionsMenu(menu);
}
public
boolean
onOptionsItemSelected(MenuItem item) {
//
int
itemId = item.getItemId();
//
switch
(itemId){
case
OPTION_SNAPSHOT:
//拍摄照片
mCamera.takePicture(
null
,
null
, jpegCallback);
try
{
Thread.sleep(
4000
);
}
catch
(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
break
;
case
OPTION_STOPCAMERA:
mPreview =
null
;
setContentView(viewStart);
break
;
}
return
true
;
}
private
PictureCallback jpegCallback =
new
PictureCallback(){
//
public
void
onPictureTaken(
byte
[] data, Camera camera) {
try
{
String name =
new
DateFormat().format(
"yyyyMMdd_hhmmss"
,
Calendar.getInstance(Locale.CHINA)) +
".jpg"
;
FileOutputStream fileout =
new
FileOutputStream(
"/mnt/sdcard/sdcard/DCIM/"
+ name);
System.out.println(name);
fileout.write(data,
0
,data.length);
fileout.flush();
fileout.close();
}
catch
(IOException e) {
// TODO: handle exception
System.out.println(e);
}
}
};
class
Preview
extends
SurfaceView
implements
SurfaceHolder.Callback
{
Preview(Context context)
{
super
(context);
mHolder=getHolder();
mHolder.addCallback(
this
);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public
void
surfaceCreated(SurfaceHolder holder)
{
mCamera=Camera.open();
try
{
mCamera.setPreviewDisplay(holder);
}
catch
(IOException exception)
{
mCamera.release();
mCamera=
null
;
}
}
public
void
surfaceDestroyed(SurfaceHolder holder)
{
mCamera.stopPreview();
mCamera.release();
}
@Override
public
void
surfaceChanged(SurfaceHolder holder,
int
format,
int
w,
int
h) {
// TODO Auto-generated method stub
Camera.Parameters parameters=mCamera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setPreviewSize(
1024
,
1024
);
mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(
90
);
mCamera.startPreview();
}
}
}
- 调用摄像头功能的方法详解
- 调用摄像头的拍照功能
- Android开发中调用摄像头功能详解
- flex调用摄像头功能
- Android调用前置摄像头的方法
- OpenCV调用树莓派原装摄像头的方法
- 基于Unity3D的调用摄像头功能的实现
- Android 调用摄像头功能【拍照】
- Android开发中如何调用摄像头的功能
- Android开发中如何调用摄像头的功能
- Android开发中如何调用摄像头的功能
- Android开发中如何调用摄像头的功能
- Android开发中如何调用摄像头的功能
- Android开发中如何调用摄像头的功能
- Android开发中如何调用摄像头的功能
- Dedecms调用缓存功能方法详解
- html5 调用手机摄像头详解
- j2me 摄像头的调用
- echarts中画布的清空
- [编程题] 最大的奇约数
- [Leetcode] 576. Out of Boundary Paths
- bfs 大逃亡
- 「LibreOJ β Round #4」求和 莫比乌斯函数
- 调用摄像头功能的方法详解
- 35、异步编程和多线程编程的区别
- UVA 1189
- 程序基本结构和简单分支
- 【洛谷】P1455 搭配购买
- iOS 使用UICollectionView实现轮播图
- 函数节流与防抖的实现
- UVA 12101
- selenium webdriver 学习总结-浏览器启动方式(二)