今天简单的学习了一下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. JAVA泛型编程笔记

    1介绍 Java泛型编程是JDK1.5版本后引入的.泛型让编程人员能够使用类型抽象,通常用于集合里面. 下面是一个不用泛型例子: List myIntList=new LinkedList(); // ...

  2. iOS UILabel UITextView UIButton 等等显示文本行间距

    iOS UILabel  UITextView UIButton 等等显示文本行间距都用如下方法 NSMutableParagraphStyle *paragraphStyle = [[NSMutab ...

  3. 为MyEclipse加入自己定义凝视

    非常多时候我们默认的MyEclipse的类凝视是这种,例如以下图 能够通过改动MyEclipse的凝视规则来改变,不但能够改动类的.还能够改动字段.方法等凝视规则,操作方法例如以下 1.针对方法的凝视 ...

  4. Eclipse+Java+OpenCV246环境搭建和代码测试

    1.首先下载OpenCV2.4.6,下载的时候,选择windows版的.然后安装 2.其实安装的过程就是解压的过程,并没有什么安装向导之类的,安装完成后,我们最关心的是这个目录:opencv\buil ...

  5. Cuts the cake_hdu_2134.java

    Cuts the cake Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  6. [RxJS] Reactive Programming - Clear data while loading with RxJS startWith()

    In currently implemention, there is one problem, when the page load and click refresh button, the us ...

  7. git的0基础使用

    1.申请一个git帐号 2.项目开发者将你增加这个项目 3.在终端随意一个目录克隆 该项目地址 git clone 该项目地址 4.进nginx配置 5.更新的时候进入项目目录 git pull

  8. Verilog 读写文件

    Verilog 读写文件 在数字设计验证中,有时我们需要大量的数据,这时可以通过文件输入,有时我们需要保存数据,可以通过写文件保存. 读写文件testbench module file_rw_tb() ...

  9. [转]iOS hybrid App 的实现原理及性能监测

    转自:http://www.cocoachina.com/ios/20151118/14270.html iOS hybrid App 的实现原理及性能监测 2015-11-18 11:39 编辑:  ...

  10. asp.net获取ip地址的方法

    在ASP中使用 Request.ServerVariables("REMOTE_ADDR") 来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的I ...