我的Android进阶之旅------>Android拍照小例子
今天简单的学习了一下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拍照小例子的更多相关文章
- 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比和十六进制对应关系以及计算方法
我的Android进阶之旅-->Android颜色值(RGB)所支持的四种常见形式 透明度百分比和十六进制对应关系表格 透明度 十六进制 100% FF 99% FC 98% FA 97% F7 ...
- 我的Android进阶之旅------>Android中查看应用签名信息
一.查看自己的证书签名信息 如上一篇文章<我的Android进阶之旅------>Android中制作和查看自定义的Debug版本Android签名证书>地址:http://blog ...
- 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计
要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...
- 我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(三)Android客户端功能实现
我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端(地址:http://blog.csdn.net/ouyang_pen ...
- 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色
通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用Tex ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之实现游戏逻辑(五)
在上一篇<我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)>中提到的两个类: GameConf:负责管理游戏的 ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)
正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)
对于游戏玩家而言,游戏界面上看到的"元素"千变万化:但是对于游戏开发者而言,游戏界面上的元素在底层都是一些数据,不同数据所绘制的图片有所差异而已.因此建立游戏的状态数据模型是实现游 ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之开发游戏界面(二)
连连看的游戏界面十分简单,大致可以分为两个区域: 游戏主界面区 控制按钮和数据显示区 1.开发界面布局 本程序使用一个RelativeLayout作为整体的界面布局元素,界面布局上面是一个自定义组件, ...
随机推荐
- JavaScript闭包函数的写法
<script type="text/javascript"> //通过js内置的函数构造器创建函数 var func=new Function('a','b','re ...
- 【css3+JavaScript】:一个优雅的对话框
实现效果: 演示地址:http://codepen.io/anon/pen/BNjYrR ======2015/5/11====== 优化滚动条(scroll):默认的滚动条太丑,忍不住优化下 ::- ...
- 多封装,少开放。强烈建议C++标准添加class之间的注入机制
近日在改动了一下下引擎代码(为了自己的组件),发现有些接口是仅仅有特定类及其内部函数才去訪问,却不使用友元声明的形式进行数据訪问--当然使用了普通非virtual的形式也就是意味着不建议重载. 故此: ...
- telnet IP不通/sybase central工具无法连接到数据库
问题描述:客户端sybase central工具无法连接到数据库 服务端操作系统:RHEL5.8_x64,安装sybase-ASE15.7,端口号4112 IP:192.168.1.220 hos ...
- asp.net获取ip地址的方法
在ASP中使用 Request.ServerVariables("REMOTE_ADDR") 来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的I ...
- java 静态文件使用注解
spring框架为我们代码的编写带来了极大的便利,特别是注解的使用.但是有个问题,当我们在静态文件中使用注解的时候,这个时候就会报错了.如以下代码: @Autowired private UserSe ...
- SQL 经典练习
SQL 基础练习 CREATE TABLE STUDENT(SNO VARCHAR(3) NOT NULL, SNAME VARCHAR(4) NOT NULL,SSEX VARCHAR(2) NOT ...
- FFT与多项式、生成函数题目泛做
题目1 COGS 很强的乘法问题 高精度乘法用FFT加速 #include <cstdlib> #include <iostream> #include <algorit ...
- poj3258 二分 最小值最大化问题
River Hopscotch Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10842 Accepted: 4654 ...
- Codeforces Round #350 (Div. 2)A,B,C,D1
A. Holidays time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...