Android开发教程之调用摄像头功能的方法详解

本文实例讲述了Android调用摄像头功能的方法。分享给大家供大家参考,具体如下:

我们要调用摄像头的拍照功能,显然

第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在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);//没有标题

接着设置全屏复制代码 代码如下:window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏

当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码复制代码 代码如下:window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//设置高亮

至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要)

setContentView(R.layout.main);

第四步,设置SurficeView显示控件的属性

找到surficeView

surfaceView = (SurfaceView) findViewById(R.id.surfaceview);

设置它的像素为800×600

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{@Overridepublic void surfaceCreated(SurfaceHolder holder) {try {camera = Camera.open();//打开硬件摄像头,这里导包得时候一定要注意是android.hardware.CameraWindowManager 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());}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}@Overridepublic 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 blocke.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 exceptionSystem.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();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {// TODO Auto-generated method stubCamera.Parameters parameters=mCamera.getParameters();parameters.setPictureFormat(PixelFormat.JPEG);parameters.setPreviewSize(1024, 1024);mCamera.setParameters(parameters);mCamera.setDisplayOrientation(90);mCamera.startPreview();}}}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android文件操作技巧汇总》、《Android编程开发之SD卡操作方法汇总》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

人若勇敢就是自己最好的朋友

Android开发教程之调用摄像头功能的方法详解

相关文章:

你感兴趣的文章:

标签云: