只是选择相机部分来翻译。下面是主要内容

  有些开发者可能需要Camera的接口,来定制自己程序的外观和特殊功能。创建自定义的Camera界面比使用using an Intent需要编写更多的代码,但是它能提供更好的体验给用户。

创建自定义camera界面的一般步骤,可以参考一下步骤:

  1. 检测和连接相机—检测camera是否存在和请求连接
  2. 创建预览类—创建Preview,它继承SurfaceView和实现了SurfaceHolder接口。这个类可以预览相机中动态的画面。
  3. 构造预览的布局一旦你拥有了Preview类,就需要创建一个View布局。布局中放入Preview和你想要的其他UI。
  4. 给拍照设置监听器—连接监听器去启动拍照,来响应用户的动作,例如按下按钮。
  5. 拍照和保存文件—编写代码实现拍照和保存输出。
  6. 释放相机—使用camera后,程序必须合理的释放它,给其他程序使用。

  相机硬件上一个共享的资源,必须被安全的管理,所以当使用相机时,你的程序不能和其他程序冲突。下面部分讲述怎样检测相机硬件,怎样连接相机,怎样拍照和当不使用时怎样释放相机。

  注意:当应用程序不使用相机时,记得通过调用Camera.release()来释放Camera对象。如果没有合理释放camera,后面全部对camera的连接都会失败,将导致你的或其他程序被关闭。

检测相机硬件

   如果你的程序没有在manifest声明需要相机,你应该在代码运行时检测相机是否可用。使用PackageManage.hasSystemFeature()方法来执行检测,下面是例子:

 /** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}

  android设备可以用多个相机,例如后置相机用来拍照,前置相机用来摄像。Aandroid 2.3(API Level 9)和以后版本,你可以使用Camera.getNumberOfCameras()方法来检测相机的数目。

连接相机

  如果你已经确定程序运行的设备上有相机,你必须请求连接来获取一个Camera实例(除非你使用intent来连接相机)。

  使用Camera.opern()连接主要的相机,要确保捕获异常,就像下面的代码:

 /** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}

  注意:当使用Camera.open()时,总是要检查异常。如果不检查,当相机正在被使用或者不存在时,你的程序将会被系统关闭。

  运行Android 2.3(API Level 9)或以上版本的设备,你可以使用Camera.open(int)连接特定的相机。上面的代码将会连接设备的第一个后置相机,如果存在多个相机。

检查相机特征

  一旦你获取到相机的连接,你可以使用Camera.getParameters()方法获取有关它的功能的更多信息,检查返回的Camera.Parameters对象来知道相机支持的功能。

  当使用API Level 9或以上的版本,使用Camera.getCameraInfo()确定相机是前置还是后置,图片的方向。

创建预览类

  为了用户能有效地拍照,他们必须能够看到设备相机看到的。一个相机预览类是一个SurfaceView,它能展示来自相机的动态的图像数据,所以用户可以能拍摄到照片。

  下面的例子展示了如何创建一个基本的相机预览类,它被包含在一个View布局中。这个类实现了SurfaceHolder.Callback接口,为了能捕捉到创建和销毁这个类时的回调事件。

 /** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera; public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera; // Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
} public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
} public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it. if (mHolder.getSurface() == null){
// preview surface does not exist
return;
} // stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
} // set preview size and make any resize, rotate or
// reformatting changes here // start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview(); } catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}

  如果你想为相机预览类设定一个特定的大小,在上面的surfaceChaned()方法中设定。当设定大小时,你必须从getSupportedPreviewSizes()获取数值。不要随意设定一个值。

放置preview入一个布局中

  相机预览类,如同上面展示的,它必须被放置进Activity的布局中,这样其他UI可以控制拍照。下面一节展示了如何为这个preview创建一个基本的布局和Activity。

  下面的布局代码提供了一个非常基本的view来展示相机预览类。在这个例子中,FrameLayout元素就是相机预览类的容器。使用这个布局类型,可以把另外的图片信息或者控制覆盖在动态相机预览图像上。

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/> <Button
android:id="@+id/button_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>

  在大多数设备中,相机预览默认的方向是横向的。这个例子设定了水平布局,下面的代码中修改了应用程序的方向为横向。为了使相机预览类渲染简单,你应该应该把照着下面在manifest中把应用程序预览所在的ctivity为横向。

 <activity android:name=".CameraActivity"
android:label="@string/app_name" android:screenOrientation="landscape">
<!-- configure this activity to use landscape orientation --> <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

  注意:相机预览不一定要是横向的。从android 2.2(API 8)开始,你可以使用setDisplayOrientation()方法去旋转预览的图像。当用户改变了手机方向,如果要调整预览的方向,可以在预览类的surfaceChanged()方法中,先使用Camer.stopPreview()停止预览,然后改变方向,最后再使用Camera.startPreview()打开预览.

  在你相机视图所在的activity中,下面的例子中,添加了预览类到FrameLayout元素中。这个activity必须确保当它被暂停(paused)或者关闭时,要释放相机。下面的例子,展示了如何向activity添加预览类(在创建预览类一节提到的)。

 public class CameraActivity extends Activity {

     private Camera mCamera;
private CameraPreview mPreview; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // Create an instance of Camera
mCamera = getCameraInstance(); // Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
}

注意:getCameraInstance()方法,是在连接相机一节的。

拍照

  一旦你构建了预览类(preview)和一个展示它的视图布局,你将要在你的应用程序中开始编写拍照了。你必须设置监听器给你的UI去响应用户的拍照动作。
为了获取照片,使用Camera.takePicture()方法。这个方法需要三个参数,它们从camera中获取数据。为了获取JPEG格式的数据,你必须实现一个Camera.PictureCallback接口来获取图像数据,并且写入一个文件中。

  下面的代码展示了一个基本的实现,如何保存来自camera的图像。

 private PictureCallback mPicture = new PictureCallback() {

     @Override
public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " +
e.getMessage());
return;
} try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};

  

  通过Camera.takePicture()触发拍照。下面的例子展示了如何通过button的View.OnClickListener调用此方法。

 // Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);

  提示:mPicture成员变量来自上面的例子。
  注意:记得当你的应用程序停止使用Camera对象时通过Camera.release()释放它。如何释放camera的细节,情况释放相机一节。

释放相机

  相机作用一种资源,被设备中的多个应用程序共享。你的应用程序在获取Camera实例后可以使用它,当你的程序停止使用它时,或者一旦你的程序暂停(Activity.onPause()),你必须特别注意去释放它。如果你的程序没有适当的释放它,所有后续对它的连接请求,都会导致你的程序或者其他程序都会被关闭。

  使用Camera.release()方法释放一个Camera对象的实例,下面是例子。

 public class CameraActivity extends Activity {
private Camera mCamera;
private SurfaceView mPreview; ... @Override
protected void onPause() {
super.onPause();
releaseCamera(); // release the camera immediately on pause event
} private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
}

参考:http://developer.android.com/guide/topics/media/camera.html

android——创建camera应用(译)的更多相关文章

  1. Android 创建自己的Camera App

    在sdk中找到/sdk/docs/guide/topics/media/camera.html#custom-camera,里面有详细的api参考 在清单文件中添加相应的权限: <uses-pe ...

  2. 介绍 Android 的 Camera 框架

    总体介绍 Android Camera 框架从整体上看是一个 client/service 的架构,有两个进程:一个是 client 进 程,可以看成是 AP 端,主要包括 JAVA 代码与一些 na ...

  3. Android之Camera控制拍照

    package com.android.xiong.cameratest; import java.io.File; import java.io.FileOutputStream; import j ...

  4. MTK6577+Android之Camera驱动

    MTK6577+Android之Camera驱动 <MTK安卓平台的Camera效果在线调试> 1.     Camera拍照相关概念 1.1  ISP isp--(Image Signa ...

  5. Android 开发 Camera类的拍照与录像

    前言 在开发Android应用的时候,如果需要调用摄像头拍照或者录像,除了通过Intent调用系统现有相机应用进行拍照录像之外,还可以通过直接调用Camera硬件去去获取摄像头进行拍照录像的操作.本篇 ...

  6. 【转】Android 创建AVD各参数详解

    一.Eclipse中图形创建AVD: Device: 即设备,指具体的手机设备型号,可以在window->Android Virtual Device Manager->Device De ...

  7. Android:Camera

    Android Camera开发 Android手机关于Camera的使用,一是拍照,二是摄像,由于Android提供了强大的组件功能,为此对于在Android手机系统上进行Camera的开发,我们可 ...

  8. Android 自定义Camera 随笔

      一.权限 <uses-permission android:name="android.permission.CAMERA" /> <uses-permiss ...

  9. 【Android】Camera 使用浅析

    Camera的简单使用浅析 由于最近工作上用到android.hardware.Camera这个类,于是简单的学习了一些基本用法. 首先注意:Camera这个类在API21以后就不推荐使用了,官方提供 ...

随机推荐

  1. Unity3d插件iTween的使用

    iTween.cs 下载地址:http://pan.ceeger.com/viewfile.php?file_id=1830&file_key=0UJAymOJ 版本为2.0.43 一.iTw ...

  2. Increase SharePoint Execution Timeout

    <system.web> <compilation batch="false" batchTimeout="600" maxBatchSize ...

  3. Java注解处理器(转)

    Java中的注解(Annotation)是一个很神奇的东西,特别现在有很多Android库都是使用注解的方式来实现的.一直想详细了解一下其中的原理.很有幸阅读到一篇详细解释编写注解处理器的文章.本文的 ...

  4. linux mint 五笔安装方法

    终于可以使用五笔了,方法就是安装好ibus后要设置首选项,这样在首选项里设置就可以了.

  5. C# DataTable

    http://www.cnblogs.com/xun126/archive/2010/12/30/1921557.html http://msdn.microsoft.com/zh-cn/librar ...

  6. 配置单节点伪分布式Hadoop

    先写的这一篇,很多东西没再重复写. 一.所需软件 jdk和ubuntu都是32位的. 二.安装JDK 1.建jdk文件夹 cd usr sudo mkdir javajdk 2.移动mv或者复制cp安 ...

  7. Samza文档翻译 : Comparison Introduction

    http://samza.incubator.apache.org/learn/documentation/0.7.0/comparisons/introduction.html 这里有一些使得Sam ...

  8. linux fork函数与vfork函数

    一.fork1. 调用方法#include <sys/types.h>#include <unistd.h> pid_t fork(void);正确返回:在父进程中返回子进程的 ...

  9. 几款国产开源的Windows界面库

    上次介绍的几款图形界面库http://blog.okbase.net/vchelp/archive/23.html都是国外的开源项目,今天介绍的几款都是国人的开源项目,大部分是采用DirectUI设计 ...

  10. Android学习 RadioButton

    http://blog.csdn.net/cuiran/article/details/45065477 https://www.baidu.com/s?wd=BadgeView%20RadioBut ...