android调用手机摄像头拍照
2013-02-26 17:18
387 查看
网上调用android手机摄像头拍照的代码也挺多,总的来说都能使.但是对于刚开始接触的人用处不大,都是转来转去,看着都烦
下面我就来写一个,用代码来详细解释android手机拍照的过程
首先是使用camera需要用到的权限。
importjava.io.BufferedOutputStream;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.text.SimpleDateFormat;
importnet.cartravel.app.AppContext;
importnet.cartravel.app.AppException;
importnet.cartravel.app.AppManager;
importnet.cartravel.app.R;
importnet.cartravel.app.api.RequestData;
importnet.cartravel.app.api.RequestResult;
importnet.cartravel.app.bean.CarParkingRecord;
importnet.cartravel.app.bean.URLs;
importnet.cartravel.app.common.UIHelper;
importandroid.app.ProgressDialog;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Matrix;
importandroid.graphics.PixelFormat;
importandroid.hardware.Camera;
importandroid.hardware.Camera.AutoFocusCallback;
importandroid.hardware.Camera.PictureCallback;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.view.KeyEvent;
importandroid.view.Menu;
importandroid.view.MenuItem;
importandroid.view.MotionEvent;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
importandroid.view.Window;
importandroid.widget.ImageView;
importandroid.widget.ImageView.ScaleType;
importandroid.widget.LinearLayout.LayoutParams;
publicclassCameraActivityextendsActivity{
privateCameracamera;//定义Camera对象,调用系统的摄像头
privatePreviewpreview;//声明Preview,自定义类
privateImageViewivFocus;//声明相机焦点
SimpleDateFormatdateFormat=newSimpleDateFormat("yyyyMMddHHmmss");//时间转换
privateStringrandomImage="car.jpg";//文件名
byte[]image;
intk=0;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
//TODOAuto-generatedmethodstub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//无标题
preview=newPreview(this);//创建Preview对象,传入当前Activity.
setContentView(preview);//设置preview为显示界面
ivFocus=newImageView(this);//创建ImageView组件
}
@Override
publicbooleanonTouchEvent(MotionEventevent){
//TODOAuto-generatedmethodstub
if(event.getAction()==KeyEvent.ACTION_DOWN){//按下事件
openOptionsMenu();//打开菜单栏
}
returnsuper.onTouchEvent(event);
}
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
//TODOAuto-generatedmethodstub
menu.add(0,Menu.FIRST,0,"拍照")
.setIcon(R.drawable.camera);
menu.add(0,Menu.FIRST+1,0,"取消")
.setIcon(R.drawable.close);
returnsuper.onCreateOptionsMenu(menu);
}
@Override
publicbooleanonOptionsItemSelected(MenuItemitem){
switch(item.getItemId()){
caseMenu.FIRST:
if(k==0){
camera.autoFocus(newAutoFocusCallback(){//自动对焦
publicvoidonAutoFocus(booleansuccess,Cameracamera){
if(success){
//success为true表示对焦成功,改变对焦状态图像(一个绿色的png图像)
preview.takePicture();//进行拍照
k=1;
ivFocus.setImageResource(R.drawable.white);//white为图片
}
}
});
}
break;
caseMenu.FIRST+1:
camera.startPreview();//开始亮灯,重新获取拍摄界面
ivFocus.setImageResource(R.drawable.focus1);//focus1为图片
k=0;
break;
}
returnsuper.onOptionsItemSelected(item);
}
/*
*使用接口的原因:因为使用SurfaceView有一个原则,所有的绘图工作必须得在Surface被创建之后才能开始(Surface—表面,这个概念在图形编程中常常被提到。基本上我们可以把它当作显存的一个映射,写入到Surface的内容
可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface被销毁之前必须结束。所以Callback中的surfaceCreated和surfaceDestroyed就成了绘图处理代码的边界
*/
classPreviewextendsSurfaceViewimplementsSurfaceHolder.Callback{
//定义SurfaceHolder对象
privateSurfaceHolderholder;
//创建一个PictureCallback对象,并实现其中的onPictureTaken方法
privatePictureCallbackpictureCallback=newPictureCallback(){
//该方法用于处理拍摄后的照片数据
publicvoidonPictureTaken(byte[]data,Cameracamera){
//data参数值就是照片数据,将这些数据以key-value形式保存,以便其他调用该Activity的程序可
//以获得照片数据
BitmapcameraBitmap;
////文件名
cameraBitmap=BitmapFactory.decodeByteArray(data,0,
data.length);
if(getWindowManager().getDefaultDisplay().getOrientation()==0)
{
Matrixmatrix=newMatrix();
matrix.setRotate(90);
cameraBitmap=Bitmap.createBitmap(cameraBitmap,0,0,
cameraBitmap.getWidth(),cameraBitmap.getHeight(),
matrix,true);//生成图片数据
}
FilemyCaptureFile=newFile("/sdcard/DCIM/Camera/"+randomImage);
try{
BufferedOutputStreambos=newBufferedOutputStream(newFileOutputStream(myCaptureFile));
cameraBitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);//压缩图片像素,将图片数据写入
bos.flush();
bos.close();
cameraBitmap.recycle();//回收Bitmap的空间
camera.reconnect();//重新连接摄像机
}catch(Exceptione){
e.printStackTrace();
}
}
};
//Preview类的构造方法
publicPreview(Contextcontext)
{
super(context);
holder=getHolder();//显示一个surface的抽象接口,使你可以控制surface的大小和格式,以及在surface上编辑像素,和监视surface的改变。
holder.addCallback(this);//指定用于捕捉拍照事件的SurfaceHolder.Callback对象
//设置SurfaceHolder对象的类型
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,在Camera图像预览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅。
}
//开始拍照时调用该方法
publicvoidsurfaceCreated(SurfaceHolderholder){
//获得Camera对象
camera=Camera.open();
try{
//设置用于控制surface对象
camera.setPreviewDisplay(holder);
}
catch(IOExceptionexception){
//释放手机摄像头
camera.release();
}
}
//停止拍照时调用该方法
publicvoidsurfaceDestroyed(SurfaceHolderholder){
//释放手机摄像头
camera.release();
}
//拍照状态变化时调用该方法
publicvoidsurfaceChanged(finalSurfaceHolderholder,intformat,
intw,inth){
try{
Camera.Parametersparameters=camera.getParameters();
//设置照片格式
parameters.setPictureFormat(PixelFormat.JPEG);
camera.setDisplayOrientation(90);
//设置拍摄照片的实际分辨率,在本例中的分辨率是1024*768
parameters.setPictureSize(1024,768);
//设置保存的图像大小
camera.setParameters(parameters);
//开始拍照
camera.startPreview();
//准备用于表示对焦状态的图像
ivFocus.setImageResource(R.drawable.focus1);
//设置摄像图片布局
LayoutParamslayoutParams=newLayoutParams(
LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
ivFocus.setScaleType(ScaleType.CENTER);
addContentView(ivFocus,layoutParams);
ivFocus.setVisibility(VISIBLE);
}
catch(Exceptione){
//释放手机摄像头
camera.release();
}
}
//停止拍照,并将拍摄的照片传入PictureCallback接口的onPictureTaken方法
publicvoidtakePicture(){
if(camera!=null){
camera.takePicture(null,null,pictureCallback);
}
}
}
@Override
protectedvoidonPause(){
//TODOAuto-generatedmethodstub
super.onPause();
finish();
}
@Override
protectedvoidonRestart(){
//TODOAuto-generatedmethodstub
super.onRestart();
}
}
由于时间问题,我不会把每一个类,每一个配置文件都写出来,我只写一些核心代码.
亲测了下,没问题.图片你们自己准备把,就是小图标
就写到这吧,不懂的QQ468903507具体问我,应该注释得很详细了.下篇写写百度地图api的使用,以及如何在地图上进行一些画图、标注等操作.
下面我就来写一个,用代码来详细解释android手机拍照的过程
首先是使用camera需要用到的权限。
文件写入
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--摄像头拍照-->
<uses-permissionandroid:name="android.permission.CAMERA"/>
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-featureandroid:name="android.hardware.camera"/>
importjava.io.BufferedOutputStream;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.text.SimpleDateFormat;
importnet.cartravel.app.AppContext;
importnet.cartravel.app.AppException;
importnet.cartravel.app.AppManager;
importnet.cartravel.app.R;
importnet.cartravel.app.api.RequestData;
importnet.cartravel.app.api.RequestResult;
importnet.cartravel.app.bean.CarParkingRecord;
importnet.cartravel.app.bean.URLs;
importnet.cartravel.app.common.UIHelper;
importandroid.app.ProgressDialog;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Matrix;
importandroid.graphics.PixelFormat;
importandroid.hardware.Camera;
importandroid.hardware.Camera.AutoFocusCallback;
importandroid.hardware.Camera.PictureCallback;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.view.KeyEvent;
importandroid.view.Menu;
importandroid.view.MenuItem;
importandroid.view.MotionEvent;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
importandroid.view.Window;
importandroid.widget.ImageView;
importandroid.widget.ImageView.ScaleType;
importandroid.widget.LinearLayout.LayoutParams;
publicclassCameraActivityextendsActivity{
privateCameracamera;//定义Camera对象,调用系统的摄像头
privatePreviewpreview;//声明Preview,自定义类
privateImageViewivFocus;//声明相机焦点
SimpleDateFormatdateFormat=newSimpleDateFormat("yyyyMMddHHmmss");//时间转换
privateStringrandomImage="car.jpg";//文件名
byte[]image;
intk=0;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
//TODOAuto-generatedmethodstub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//无标题
preview=newPreview(this);//创建Preview对象,传入当前Activity.
setContentView(preview);//设置preview为显示界面
ivFocus=newImageView(this);//创建ImageView组件
}
@Override
publicbooleanonTouchEvent(MotionEventevent){
//TODOAuto-generatedmethodstub
if(event.getAction()==KeyEvent.ACTION_DOWN){//按下事件
openOptionsMenu();//打开菜单栏
}
returnsuper.onTouchEvent(event);
}
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
//TODOAuto-generatedmethodstub
menu.add(0,Menu.FIRST,0,"拍照")
.setIcon(R.drawable.camera);
menu.add(0,Menu.FIRST+1,0,"取消")
.setIcon(R.drawable.close);
returnsuper.onCreateOptionsMenu(menu);
}
@Override
publicbooleanonOptionsItemSelected(MenuItemitem){
switch(item.getItemId()){
caseMenu.FIRST:
if(k==0){
camera.autoFocus(newAutoFocusCallback(){//自动对焦
publicvoidonAutoFocus(booleansuccess,Cameracamera){
if(success){
//success为true表示对焦成功,改变对焦状态图像(一个绿色的png图像)
preview.takePicture();//进行拍照
k=1;
ivFocus.setImageResource(R.drawable.white);//white为图片
}
}
});
}
break;
caseMenu.FIRST+1:
camera.startPreview();//开始亮灯,重新获取拍摄界面
ivFocus.setImageResource(R.drawable.focus1);//focus1为图片
k=0;
break;
}
returnsuper.onOptionsItemSelected(item);
}
/*
*使用接口的原因:因为使用SurfaceView有一个原则,所有的绘图工作必须得在Surface被创建之后才能开始(Surface—表面,这个概念在图形编程中常常被提到。基本上我们可以把它当作显存的一个映射,写入到Surface的内容
可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface被销毁之前必须结束。所以Callback中的surfaceCreated和surfaceDestroyed就成了绘图处理代码的边界
*/
classPreviewextendsSurfaceViewimplementsSurfaceHolder.Callback{
//定义SurfaceHolder对象
privateSurfaceHolderholder;
//创建一个PictureCallback对象,并实现其中的onPictureTaken方法
privatePictureCallbackpictureCallback=newPictureCallback(){
//该方法用于处理拍摄后的照片数据
publicvoidonPictureTaken(byte[]data,Cameracamera){
//data参数值就是照片数据,将这些数据以key-value形式保存,以便其他调用该Activity的程序可
//以获得照片数据
BitmapcameraBitmap;
////文件名
cameraBitmap=BitmapFactory.decodeByteArray(data,0,
data.length);
if(getWindowManager().getDefaultDisplay().getOrientation()==0)
{
Matrixmatrix=newMatrix();
matrix.setRotate(90);
cameraBitmap=Bitmap.createBitmap(cameraBitmap,0,0,
cameraBitmap.getWidth(),cameraBitmap.getHeight(),
matrix,true);//生成图片数据
}
FilemyCaptureFile=newFile("/sdcard/DCIM/Camera/"+randomImage);
try{
BufferedOutputStreambos=newBufferedOutputStream(newFileOutputStream(myCaptureFile));
cameraBitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);//压缩图片像素,将图片数据写入
bos.flush();
bos.close();
cameraBitmap.recycle();//回收Bitmap的空间
camera.reconnect();//重新连接摄像机
}catch(Exceptione){
e.printStackTrace();
}
}
};
//Preview类的构造方法
publicPreview(Contextcontext)
{
super(context);
holder=getHolder();//显示一个surface的抽象接口,使你可以控制surface的大小和格式,以及在surface上编辑像素,和监视surface的改变。
holder.addCallback(this);//指定用于捕捉拍照事件的SurfaceHolder.Callback对象
//设置SurfaceHolder对象的类型
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,在Camera图像预览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅。
}
//开始拍照时调用该方法
publicvoidsurfaceCreated(SurfaceHolderholder){
//获得Camera对象
camera=Camera.open();
try{
//设置用于控制surface对象
camera.setPreviewDisplay(holder);
}
catch(IOExceptionexception){
//释放手机摄像头
camera.release();
}
}
//停止拍照时调用该方法
publicvoidsurfaceDestroyed(SurfaceHolderholder){
//释放手机摄像头
camera.release();
}
//拍照状态变化时调用该方法
publicvoidsurfaceChanged(finalSurfaceHolderholder,intformat,
intw,inth){
try{
Camera.Parametersparameters=camera.getParameters();
//设置照片格式
parameters.setPictureFormat(PixelFormat.JPEG);
camera.setDisplayOrientation(90);
//设置拍摄照片的实际分辨率,在本例中的分辨率是1024*768
parameters.setPictureSize(1024,768);
//设置保存的图像大小
camera.setParameters(parameters);
//开始拍照
camera.startPreview();
//准备用于表示对焦状态的图像
ivFocus.setImageResource(R.drawable.focus1);
//设置摄像图片布局
LayoutParamslayoutParams=newLayoutParams(
LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
ivFocus.setScaleType(ScaleType.CENTER);
addContentView(ivFocus,layoutParams);
ivFocus.setVisibility(VISIBLE);
}
catch(Exceptione){
//释放手机摄像头
camera.release();
}
}
//停止拍照,并将拍摄的照片传入PictureCallback接口的onPictureTaken方法
publicvoidtakePicture(){
if(camera!=null){
camera.takePicture(null,null,pictureCallback);
}
}
}
@Override
protectedvoidonPause(){
//TODOAuto-generatedmethodstub
super.onPause();
finish();
}
@Override
protectedvoidonRestart(){
//TODOAuto-generatedmethodstub
super.onRestart();
}
}
由于时间问题,我不会把每一个类,每一个配置文件都写出来,我只写一些核心代码.
亲测了下,没问题.图片你们自己准备把,就是小图标
就写到这吧,不懂的QQ468903507具体问我,应该注释得很详细了.下篇写写百度地图api的使用,以及如何在地图上进行一些画图、标注等操作.
相关文章推荐
- H5调用手机的摄像头拍照上传以及手机相册选取照片但不支持Android的分析
- Android应用中调用手机摄像头拍照并保存
- Android调用手机摄像头拍照和录音功能
- Android 调用手机相册、摄像头拍照及剪裁照片
- Android——调用系统摄像头拍照的问题
- Android笔记:调用摄像头拍照保存至指定目录
- Android初级教程调用手机拍照与摄像功能
- Android实现调用摄像头拍照与视频功能
- Android调用摄像头和拍照
- 利用Android手机里的摄像头进行拍照
- 微信浏览器内兼容android iOS调取手机摄像头进行拍照、打水印、压缩、预览
- Android调用相机实现拍照并裁剪图片,调用手机中的相冊图片并裁剪图片
- Android 多媒体应用:调用摄像头拍照
- 实现调用Android手机的拍照功能
- Android初级教程调用手机拍照与摄像功能
- Android从相册选择图片和调用系统摄像头拍照
- android 调用系统相册选取照片或者打开相机拍照获取图片,返回时回到手机桌面,然后才会跳转到当前activity
- Android 调用摄像头拍照并裁剪
- HTML5调用手机摄像头拍照
- Android调用手机拍照以及从相册选择照片