我的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. */@Overridepublic 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() {/** * 界面打开时该方法自动调用 * 打开相机,设置预览效果 ; */@Overridepublic 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;}}}/** * 当预览界面的格式和大小发生改变时,该方法被调用 */@Overridepublic void surfaceChanged(SurfaceHolder holder, int format,int width, int height) {}/** * 当预览界面被关闭时,该方法被调用 * 停止相机拍摄;释放相机资源 */@Overridepublic 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() {/** * 在相机快门关闭时候的回调接口,通过这个接口来通知用户快门关闭的事件, * 普通相机在快门关闭的时候都会发出响声,根据需要可以在该回调接口中定义各种动作, 例如:使设备震动 */@Overridepublic void onShutter() {// just log ,do nothingLog.d("ShutterCallback", "...onShutter...");}}, null, new PictureCallback() {// 当用户拍完一张照片的时候触发onPictureTaken,这时候对拍下的照片进行相应的处理操作@Overridepublic 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() {@Overridepublic void onAutoFocus(boolean success, Camera camera) {/* 对到焦点拍照 */if (success) {// just log ,do nothingLog.d("AutoFocusCallback", "...onFocus...");}}});}}/** 当触摸屏幕的时候,将对焦和拍照按钮布局显示出来 */@Overridepublic 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 listview中嵌套Checkbox的布局文件
- android studio导入 so ,jar 文件。
- IDA动态调试Android的DEX文件
- android反编译apk文件
- android工程下的文件资源类型
- linux内核启动android文件系统过程分析
- Android 从properties配置文件读取数据
- Android SAX和DOM解析XML文件