今天简单的学习了一下android拍照的简单实现。 当然该程序是个小例子,非常简单,没有什么复杂的操作,但是可以学习到Android 拍照API流程。

1.在布局文件中添加一个 surfaceView (用来展示预览的图片)
2.根据 SurfaceView  获得 Holder
3.给固定器设置 SurfaceHolder.Callback ; 这个 Callback 有一系列的周期方法,
比如:surfaceCreated,surfaceChanged,surfaceDestroyed等方法.
① 在surfaceCreated 中 打开相机,设置预览效果 ;
② 在surfaceChanged中可以初始化相机( Camera );比如相机的参数: 像素, 大小,格式,开始预览,等等
③ 在surfaceDestroyed可以可以停止相机拍摄;释放相机资源
4. 相机自动对焦 的回调处理
Camera.autoFocus( AutoFocusCallback )

下面就看看该小例子的代码吧。

文件1.该应用的布局文件,res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 帧布局 -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<!-- 用来展示画面 -->
<SurfaceView android:id="@+id/surfaceView"
android:layout_width="fill_parent" android:layout_height="fill_parent" />
<!-- 相对布局,该界面默认不显示出来,当触摸屏幕时候显示出来-->
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="fill_parent" android:visibility="gone"
android:id="@+id/buttonlayout">
<!-- 拍照按钮 -->
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" android:layout_marginRight="5dp"
android:text="@string/takepicture" android:onClick="takepicture"
android:id="@+id/takePicture" />
<!-- 对焦按钮 -->
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_toLeftOf="@id/takePicture"
android:layout_alignTop="@id/takePicture" android:layout_marginRight="20dp"
android:text="@string/autofocus" android:onClick="autofocus"
android:id="@+id/autofocus" />
</RelativeLayout>
</FrameLayout>

文件2:布局文件所用到的资源文件,res/values/string.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">拍照小应用</string>
<string name="takepicture">拍照</string>
<string name="autofocus">对焦</string>
<string name="noSDcard">检测到手机没有存储卡!请插入手机存储卡再开启本应用</string>
</resources>

文件3:该应用的主程序,PictureActivity.java

package cn.oyp.picture;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast; public class PictureActivity extends Activity {
// 对焦和拍照按钮布局
private View buttonlayout;
// 用来显示图片
private SurfaceView surfaceView;
// 摄像头
private Camera camera; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 窗口特效为无标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 设置窗口全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 设定屏幕显示为横向
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
buttonlayout = this.findViewById(R.id.buttonlayout);
surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);
// 获取的画面直接输出到屏幕上
surfaceView.getHolder()
.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// 画面分辨率
surfaceView.getHolder().setFixedSize(176, 144);
// 保持屏幕高亮
surfaceView.getHolder().setKeepScreenOn(true);
// 监听 surfaceView何时创建
surfaceView.getHolder().addCallback(new Callback() {
/**
* 界面打开时该方法自动调用
* 打开相机,设置预览效果 ;
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// 打开摄像头
camera = Camera.open();
// 摄像头参数
Camera.Parameters parameters = camera.getParameters();
// 将摄像头参数打印出来,各种机型的参数不一样,所以得根据具体机型来设置参数
// Log.i("MainActivity", parameters.flatten());
// 设置预览图片大小
parameters.setPreviewSize(800, 480);
// 设置每秒钟捕获画面的频率
parameters.setPreviewFrameRate(5);
// 设置图片格式
parameters.setPictureFormat(ImageFormat.JPEG);
// 设置图片大小
parameters.setPictureSize(1024, 768);
// 设置图片质量
parameters.setJpegQuality(80);
// 将参数设置给摄像头
camera.setParameters(parameters);
// 设置预览显示
camera.setPreviewDisplay(holder);
// 开始预览
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
// 释放摄像头
if (camera != null) {
camera.release();
camera = null;
}
}
} /**
* 当预览界面的格式和大小发生改变时,该方法被调用
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
} /**
* 当预览界面被关闭时,该方法被调用
* 停止相机拍摄;释放相机资源
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 停止预览
camera.stopPreview();
// 释放摄像头
if (camera != null) {
camera.release();
camera = null;
}
}
});
} // 按下拍照按钮后,开始拍照
public void takepicture(View v) {
if (camera != null) {
camera.takePicture(new ShutterCallback() {
/**
* 在相机快门关闭时候的回调接口,通过这个接口来通知用户快门关闭的事件,
* 普通相机在快门关闭的时候都会发出响声,根据需要可以在该回调接口中定义各种动作, 例如:使设备震动
*/
@Override
public void onShutter() {
// just log ,do nothing
Log.d("ShutterCallback", "...onShutter...");
}
}, null, new PictureCallback() {
// 当用户拍完一张照片的时候触发onPictureTaken,这时候对拍下的照片进行相应的处理操作
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// 判断是否存在SD卡
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
try {
// 将拍的照片保存到sd卡中
File jpgFile = new File(Environment
.getExternalStorageDirectory(), System
.currentTimeMillis() + ".jpg");
FileOutputStream outputStream = new FileOutputStream(
jpgFile);
outputStream.write(data);
outputStream.close();
// 处理完照片后,又开始预览
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(),
R.string.noSDcard, Toast.LENGTH_LONG).show();
}
}
});
}
} // 按下对焦按钮后,开始对焦
public void autofocus(View v) {
if (camera != null) {
// 相机自动对焦的回调处理
camera.autoFocus(new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
/* 对到焦点拍照 */
if (success) {
// just log ,do nothing
Log.d("AutoFocusCallback", "...onFocus...");
}
}
});
}
} /** 当触摸屏幕的时候,将对焦和拍照按钮布局显示出来 */
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
buttonlayout.setVisibility(ViewGroup.VISIBLE);
return true;
}
return super.onTouchEvent(event);
} }

文件4:该应用的描述文件 ,AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.oyp.picture"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" /> <!-- 摄像头权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- 在SD卡中创建和删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SD卡中写入数据的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="PictureActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> </application>
</manifest>

用的描述了解更多关于Android拍照的例子,可以参考以下几篇博文

http://blog.csdn.net/cfwdl/article/details/5746708

http://mjbb.iteye.com/blog/1018006

http://blog.csdn.net/hellogv/article/details/5962494

http://aokunsang.iteye.com/blog/1295813

==================================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

==================================================================================================

我的Android进阶之旅------>Android拍照小例子的更多相关文章

  1. 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比和十六进制对应关系以及计算方法

    我的Android进阶之旅-->Android颜色值(RGB)所支持的四种常见形式 透明度百分比和十六进制对应关系表格 透明度 十六进制 100% FF 99% FC 98% FA 97% F7 ...

  2. 我的Android进阶之旅------>Android中查看应用签名信息

    一.查看自己的证书签名信息 如上一篇文章<我的Android进阶之旅------>Android中制作和查看自定义的Debug版本Android签名证书>地址:http://blog ...

  3. 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计

    要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...

  4. 我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(三)Android客户端功能实现

    我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端(地址:http://blog.csdn.net/ouyang_pen ...

  5. 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色

    通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...

  6. 我的Android进阶之旅------> Android在TextView中显示图片方法

    面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用Tex ...

  7. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之实现游戏逻辑(五)

    在上一篇<我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)>中提到的两个类: GameConf:负责管理游戏的 ...

  8. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)

    正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...

  9. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)

    对于游戏玩家而言,游戏界面上看到的"元素"千变万化:但是对于游戏开发者而言,游戏界面上的元素在底层都是一些数据,不同数据所绘制的图片有所差异而已.因此建立游戏的状态数据模型是实现游 ...

  10. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之开发游戏界面(二)

    连连看的游戏界面十分简单,大致可以分为两个区域: 游戏主界面区 控制按钮和数据显示区 1.开发界面布局 本程序使用一个RelativeLayout作为整体的界面布局元素,界面布局上面是一个自定义组件, ...

随机推荐

  1. pyqt cvs保存

    # -*- coding: utf-8 -*-__author__ = 'Administrator'import sys, csvfrom PyQt4 import QtGui, QtCore cl ...

  2. Android_HTML解析器_jsoup

    jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据. Jsou ...

  3. hdu 4756 Install Air Conditioning

    非正规做法,一个一个的暴,减一下枝,还得采用sort,qsort居然过不了…… #include <cstdio> #include <cmath> #include < ...

  4. JS 事件冒泡整理 浏览器的事件流

    JavaScript与HTML的交互通过事件来实现.而浏览器的事件流是一个非常重要的概念.不去讨论那些古老的浏览器有事件捕获与事件冒泡的争议, 只需要知道在DOM2中规定的事件流包括了三个部分,事件捕 ...

  5. html中行内元素与块级元素的区别。

    在标准文档流里面,块级元素具有以下特点 1.总是在新行上开始,占据一整行: 2.高度,行高以及外边框和内边距都可以控制: 3.宽度始终是与游览器宽度一样,与内容无关: 4.它可以容纳内联元素和其他块级 ...

  6. (转)第一天 XHTML CSS基础知识 文章出处:标准之路(http://www.aa25.cn/div_css/902.shtml)

    欢迎大家学习<十天学会web标准>,也就是我们常说的DIV+CSS.不过这里的DIV+CSS是一种错误的叫法,建议大家还是称之为web标准. 学习本系列教程需有一定html和css基础,也 ...

  7. WebApi实现跨域功能

    在配置文件的system.webServer节点中加入以下配置信息 <httpProtocol> <customHeaders> <add name="Acce ...

  8. cocos2dx 音效 粒子 数据存储

    1.音效 引入头文件 #include "simpleAudioEngine.h" 命名空间 using namespace CocosDenshion; //创建一个背景 Siz ...

  9. SQL中将某个表中的多行数据在一个字段显示

    项目需求:将某个表中的多行数据在一个字段显示,如下: 比如表A中有字段 ID,NAME, 表B中有字段ID,PID,DES, 表A,表B中的数据分别如下: ID NAME1 张三2 李四 ID PID ...

  10. 如何在hadoop中控制map的个数

    hadooop提供了一个设置map个数的参数mapred.map.tasks,我们可以通过这个参数来控制map的个数.但是通过这种方式设置map的个数,并不是每次都有效的.原因是mapred.map. ...