Chinaunix首页 | 论坛 | 博客
  • 博客访问: 478737
  • 博文数量: 60
  • 博客积分: 7346
  • 博客等级: 少将
  • 技术积分: 1980
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-08 15:56
文章分类

全部博文(60)

文章存档

2022年(1)

2014年(5)

2012年(12)

2011年(1)

2010年(2)

2009年(34)

2008年(5)

我的朋友

分类: Java

2009-10-21 18:26:20

参考文章1:
This article is exerpted from of the Wrox book by and is reused by permission of the publisher. This may not be reused without publisher permission
Using the Camera

The popularity of digital cameras (particularly within phone handsets) has caused their prices to drop just as their size has shrunk dramatically. It’s now becoming difficult to even find a mobile phone without a camera, and Android devices are unlikely to be exceptions.
To access the camera hardware, you need to add the CAMERA permission to your application manifest, as shown here:
java5 Code:
This grants access to the Camera Service. The Camera class lets you adjust camera settings, take pictures, and manipulate streaming camera previews.
To access the Camera Service, use the static open method on the Camera class. When your application has finished with the camera, remember to relinquish your hold on the Service by calling release following the simple use pattern shown in the code snippet below:
java5 Code:
Camera camera = Camera.open();
  [ … Do things with the camera … ]
camera.release();
Controlling Camera Settings
The current camera settings are available as a Camera.Parameters object. Call the getParameters method on the Camera to access the current parameters.
You can use the set* methods on the returned Parameters to modify the settings. To apply changes, call setParameters, passing in the modified values as shown below:
java5 Code:
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(parameters);
The Camera Parameters can be used to specify the image and preview size, image format, and preview frame rate.
Using the Camera Preview
Access to the camera’s streaming video means that you can incorporate live video into your applications. Some of the most exciting early Android applications have used this functionality as the basis for augmenting reality.
The camera preview can be displayed in real time onto a Surface, as shown in the code snippet below:
java5 Code:
camera.setPreviewDisplay(mySurface);
camera.startPreview();
[ … ]
camera.stopPreview();
You’ll learn more about Surfaces in the following chapter, although Android includes an excellent example of using a SurfaceView to display the camera preview in real time. This example is available in the graphics/CameraPreview project in the SDK API demos.
You can also assign a PreviewCallback to be fired for each preview frame, allowing you to manipulate or display each preview frame individually. Call the setPreviewCallback method on the Camera object, passing in a new PreviewCallback implementation overriding the onPreviewFrame method as shown here:
java5 Code:
camera.setPreviewCallback(new PreviewCallback() {
 
  public void onPreviewFrame(byte[] _data, Camera _camera) {
   // TODO Do something with the preview image.
  }
});
Taking a Picture
Take a picture by calling takePicture on a Camera object, passing in a ShutterCallback and PictureCallback implementations for the RAW and JPEG-encoded images. Each picture callback will receive a byte array representing the image in the appropriate format, while the shutter callback is triggered immediately after the shutter is closed.
java5 Code:
private void takePicture() {
  camera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
 
ShutterCallback shutterCallback = new ShutterCallback() {
  public void onShutter() {
    // TODO Do something when the shutter closes.
  }
};
 
PictureCallback rawCallback = new PictureCallback() {
  public void onPictureTaken(byte[] _data, Camera _camera) {
    // TODO Do something with the image RAW data.
  }
};
 
PictureCallback jpegCallback = new PictureCallback() {
  public void onPictureTaken(byte[] _data, Camera _camera) {
    // TODO Do something with the image JPEG data.
  }
};

 

参考文章2:


  目前的智能手机拥有很多强大的功能,例如摄像头、GPS和无线上网等,现在是我们开始充分使用这些功能的时候了,在本篇文章中我们一起学习,如何在谷歌Android编程环境中,以最简单的方式实现谷歌Android摄像头拍照。

  在本文示例中,我们需要用到两个文件:布局文件和Activity文件。

  小提示

  数日前,Android 1.5(代号cupcake)新版发布,在安全方面有诸多改进,其中之一与摄像头权限控制有关。在此之前,你能够创建无需用户许可就可实现拍照的应用。现在该问题已被修复,如果你想在自己的应用中使用摄像头,需要在AndroidManifest.xml中增加以下代码:

<uses-permission android:name="android.permission.CAMERA"/>

  设定摄像头布局

  这是开发工作的基础,也就是说我们希望在应用程序中增加多少辅助性元素,如摄像头各种功能按钮等。在本文中我们采取最简方式,除了拍照外,没有多余摄像头功能。下面我们一起看一下本文示例将要用到的布局文件“camera_surface.xml”。

<LinearLayout xmlns:android=""

android:layout_width
="fill_parent" android:layout_height="fill_parent"

android:orientation
="vertical">

<SurfaceView android:id="@+id/surface_camera"

android:layout_width
="fill_parent" android:layout_height="10dip"

android:layout_weight
="1">  

SurfaceView>  

LinearLayout>

  小提示:记住不要在资源文件名称中使用大写字母,如果你把该文件命名为“CameraSurface.xml”,会给你带来不必要的麻烦。

  该布局非常简单,只有一个LinearLayout视图组,在它下面只有一个SurfaceView视图,也就是我们的摄像头屏幕

  摄像头实现代码

  现在我们已经查看了摄像头的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编程有简单的了解,应该能够很容易理解本文示例。

另外需要注意的是,取景镜头的方向设置,第一次在真机上运行的时候发现手机屏幕上看到的景象转了90度,解决方法是设置orientation方向:
parameters.set("orientation", "portrait")  //"portrait"是竖向
这也是从别人blog里看来的:http://dai-lm.javaeye.com/blog/471217

阅读(3216) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~