技术开发 频道

编程实现谷歌Android摄像头拍照

  摄像头实现代码

  现在我们已经查看了摄像头的xml代码,下面再来看一下Android代码。让我们创建一个名为“CameraView”的Activity类,实现SurfaceHolder.Callback接口:

  public class CamaraView extends Activity implements SurfaceHolder.Callback

 

  接口SurfaceHolder.Callback被用来接收摄像头预览界面变化的信息。它实现了三个方法:

  surfaceChanged

  当预览界面的格式和大小发生改变时,该方法被调用。

  surfaceCreated

  初次实例化,预览界面被创建时,该方法被调用。

  surfaceDestroyed

  当预览界面被关闭时,该方法被调用。

  下面我们一起看一下在摄像头应用中如何使用这个接口,首先看一下在Activity类中的onCreate方法。

  super.onCreate(icicle);

  getWindow().setFormat(PixelFormat.TRANSLUCENT);

  requestWindowFeature(Window.FEATURE_NO_TITLE);

  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

  WindowManager.LayoutParams.FLAG_FULLSCREEN);

  setContentView(R.layout.camera);

  mSurfaceView
= (SurfaceView) findViewById(R.id.surface_camera);

  mSurfaceHolder
= mSurfaceView.getHolder();

  mSurfaceHolder.addCallback(this);

  mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

  }

 

  下面我们逐一对代码进行一下说明。

  getWindow().setFormat(PixelFormat.TRANSLUCENT);

  requestWindowFeature(Window.FEATURE_NO_TITLE);

  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

  WindowManager.LayoutParams.FLAG_FULLSCREEN);

 

  通过上述代码,我们告诉屏幕两点信息:

  1、摄像头预览界面将通过全屏显示,没有“标题(title)”;

  2、屏幕格式为“半透明”。

  setContentView(R.layout.camera_surface );

  mSurfaceView
= (SurfaceView) findViewById(R.id.surface_camera);

 

  在以上代码中,我们通过setContentView来设定Activity的布局为前面我们创建的camera_surface,并创建一个SurfaceView对象,从xml文件中获得它。

  mSurfaceHolder = mSurfaceView.getHolder();

  mSurfaceHolder.addCallback(this);

  mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

 

  通过以上代码,我们从surfaceview中获得了holder,并增加callback功能到“this”。这意味着我们的操作(activity)将可以管理这个surfaceview。

  我们看一下callback功能时如何实现的:

  public void surfaceCreated(SurfaceHolder holder) {

  mCamera
= Camera.open();

  mCamera是“Camera”类的一个对象。在surfaceCreated方法中我们“打开”摄像头。这就是启动它的方式。

  
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

  
if (mPreviewRunning) {

  mCamera.stopPreview();

  }

  Camera.Parameters p
= mCamera.getParameters();

  p.setPreviewSize(w, h);

  mCamera.setParameters(p);

  try {

  mCamera.setPreviewDisplay(holder);

  } catch (IOException e) {

  e.printStackTrace();

  }

  mCamera.startPreview();

  mPreviewRunning
= true;

  }

 

  该方法让摄像头做好拍照准备,设定它的参数,并开始在Android屏幕中启动预览画面。我使用了一个“semaphore”参数来防止冲突:当mPreviewRunning为true时,意味着摄像头处于激活状态,并未被关闭,因此我们可以使用它。

  public void surfaceDestroyed(SurfaceHolder holder) {

  mCamera.stopPreview();

  mPreviewRunning
= false;

  mCamera.release();

  }

 

  通过这个方法,我们停止摄像头,并释放相关的资源。正如大家所看到的,我们在这儿设置mPreviewRunning为false,以此来防止在surfaceChanged方法中的冲突。原因何在?因为这意味着我们已经关闭了摄像头,而且我们不能再设置其参数或在摄像头中启动图像预览。

  最后我们看一下本例中最重要的方法:

  Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {

  
public void onPictureTaken(byte[] imageData, Camera c) {

  }

  };

 

  当拍照时,该方法被调用。举例来说,你可以在界面上创建一个OnClickListener,当你点击屏幕时,调用PictureCallBack方法。这个方法会向你提供图像的字节数组,然后你可以使用Android提供的Bitmap和BitmapFactory类,将其从字节数组转换成你想要的图像格式。

  结束语

  希望这篇文章对所有人都有所帮助。如果你对Android编程有简单的了解,应该能够很容易理解本文示例。
 

0
相关文章