当前位置: 代码迷 >> Android >> 小弟我的Android进阶之旅->Android拍照小例子
  详细解决方案

小弟我的Android进阶之旅->Android拍照小例子

热度:70   发布时间:2016-04-28 07:59:03.0
我的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

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

  相关解决方案