android——创建camera应用(译)
只是选择相机部分来翻译。下面是主要内容
有些开发者可能需要Camera的接口,来定制自己程序的外观和特殊功能。创建自定义的Camera界面比使用using an Intent需要编写更多的代码,但是它能提供更好的体验给用户。
创建自定义camera界面的一般步骤,可以参考一下步骤:
- 检测和连接相机—检测camera是否存在和请求连接
- 创建预览类—创建Preview,它继承SurfaceView和实现了SurfaceHolder接口。这个类可以预览相机中动态的画面。
- 构造预览的布局一旦你拥有了Preview类,就需要创建一个View布局。布局中放入Preview和你想要的其他UI。
- 给拍照设置监听器—连接监听器去启动拍照,来响应用户的动作,例如按下按钮。
- 拍照和保存文件—编写代码实现拍照和保存输出。
- 释放相机—使用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应用(译)的更多相关文章
- Android 创建自己的Camera App
在sdk中找到/sdk/docs/guide/topics/media/camera.html#custom-camera,里面有详细的api参考 在清单文件中添加相应的权限: <uses-pe ...
- 介绍 Android 的 Camera 框架
总体介绍 Android Camera 框架从整体上看是一个 client/service 的架构,有两个进程:一个是 client 进 程,可以看成是 AP 端,主要包括 JAVA 代码与一些 na ...
- Android之Camera控制拍照
package com.android.xiong.cameratest; import java.io.File; import java.io.FileOutputStream; import j ...
- MTK6577+Android之Camera驱动
MTK6577+Android之Camera驱动 <MTK安卓平台的Camera效果在线调试> 1. Camera拍照相关概念 1.1 ISP isp--(Image Signa ...
- Android 开发 Camera类的拍照与录像
前言 在开发Android应用的时候,如果需要调用摄像头拍照或者录像,除了通过Intent调用系统现有相机应用进行拍照录像之外,还可以通过直接调用Camera硬件去去获取摄像头进行拍照录像的操作.本篇 ...
- 【转】Android 创建AVD各参数详解
一.Eclipse中图形创建AVD: Device: 即设备,指具体的手机设备型号,可以在window->Android Virtual Device Manager->Device De ...
- Android:Camera
Android Camera开发 Android手机关于Camera的使用,一是拍照,二是摄像,由于Android提供了强大的组件功能,为此对于在Android手机系统上进行Camera的开发,我们可 ...
- Android 自定义Camera 随笔
一.权限 <uses-permission android:name="android.permission.CAMERA" /> <uses-permiss ...
- 【Android】Camera 使用浅析
Camera的简单使用浅析 由于最近工作上用到android.hardware.Camera这个类,于是简单的学习了一些基本用法. 首先注意:Camera这个类在API21以后就不推荐使用了,官方提供 ...
随机推荐
- Unity3d插件iTween的使用
iTween.cs 下载地址:http://pan.ceeger.com/viewfile.php?file_id=1830&file_key=0UJAymOJ 版本为2.0.43 一.iTw ...
- Increase SharePoint Execution Timeout
<system.web> <compilation batch="false" batchTimeout="600" maxBatchSize ...
- Java注解处理器(转)
Java中的注解(Annotation)是一个很神奇的东西,特别现在有很多Android库都是使用注解的方式来实现的.一直想详细了解一下其中的原理.很有幸阅读到一篇详细解释编写注解处理器的文章.本文的 ...
- linux mint 五笔安装方法
终于可以使用五笔了,方法就是安装好ibus后要设置首选项,这样在首选项里设置就可以了.
- C# DataTable
http://www.cnblogs.com/xun126/archive/2010/12/30/1921557.html http://msdn.microsoft.com/zh-cn/librar ...
- 配置单节点伪分布式Hadoop
先写的这一篇,很多东西没再重复写. 一.所需软件 jdk和ubuntu都是32位的. 二.安装JDK 1.建jdk文件夹 cd usr sudo mkdir javajdk 2.移动mv或者复制cp安 ...
- Samza文档翻译 : Comparison Introduction
http://samza.incubator.apache.org/learn/documentation/0.7.0/comparisons/introduction.html 这里有一些使得Sam ...
- linux fork函数与vfork函数
一.fork1. 调用方法#include <sys/types.h>#include <unistd.h> pid_t fork(void);正确返回:在父进程中返回子进程的 ...
- 几款国产开源的Windows界面库
上次介绍的几款图形界面库http://blog.okbase.net/vchelp/archive/23.html都是国外的开源项目,今天介绍的几款都是国人的开源项目,大部分是采用DirectUI设计 ...
- Android学习 RadioButton
http://blog.csdn.net/cuiran/article/details/45065477 https://www.baidu.com/s?wd=BadgeView%20RadioBut ...