我的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)