打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Android手机摄像头编程入门

Android学习指南第三十六讲:Android手机摄像头编程入门

本讲内容:Android手机摄像头编程入门

智能手机中的摄像头和普通手机中的摄像头最大的区别在于,智能机上的摄像头可以由程序员写程序控制,做一些有趣的应用譬如,画中画,做一些有用的应用譬如二维码识别,等等。本讲打算通过一个实例,来介绍一下摄像头编程,相关解释都写在代码中了,请注意看代码注释。

实例:窈窈照相机,功能很简单,就是点击程序弹出照相预览界面,点击相机按钮完成照相功能,所照相片会存储在手机存储卡根目录。

1、创建一个项目 Lesson36_Camera ,主程序文件为 MainActivity.java

2、AndroidManifest.xml 中设置屏幕为横屏,并且声明摄像头和存储卡的使用权限,具体代码如下:

1234567891011121314151617
<?xml version="1.0" encoding="utf-8"?><manifest package="basic.android.lesson36" xmlns:android="http://schemas.android.com/apk/res/android" android:versioncode="1" android:versionname="1.0">	<application android:label="@string/app_name" android:icon="@drawable/icon">		<activity android:label="@string/app_name" android:name=".MainActivity" android:screenorientation="landscape" android:configchanges="orientation|keyboardHidden|keyboard">			<intent -filter="">				<action android:name="android.intent.action.MAIN">				<category android:name="android.intent.category.LAUNCHER">			</category></action></intent>		</activity> 	</application>	<uses -sdk="" android:minsdkversion="8">	<uses -permission="" android:name="android.permission.CAMERA"></uses>	<uses -permission="" android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses>	<uses -feature="" android:name="android.hardware.camera">	<uses -feature="" android:name="android.hardware.camera.autofocus"></uses></uses></uses></manifest>

3、本例中不需要布局文件main.xml,因为本例中的UI组建都是动态添加上去的。

4、最后MainActivity.java的代码如下:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
package basic.android.lesson36; import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.Calendar;import java.util.Locale; import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.PixelFormat;import android.hardware.Camera;import android.os.Bundle;import android.text.format.DateFormat;import android.util.Log;import android.view.KeyEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.Window;import android.view.WindowManager;import android.widget.FrameLayout;import android.widget.TextView;import android.widget.Toast; public class MainActivity extends Activity { 	private CameraView cv;	//准备一个相机对象	private Camera mCamera = null;	//准备一个Bitmap对象	private Bitmap mBitmap = null;	 	//准备一个保存图片的PictureCallback对象	public Camera.PictureCallback pictureCallback = new Camera.PictureCallback() { 		public void onPictureTaken(byte[] data, Camera camera) {			Log.i("yao","onPictureTaken");			Toast.makeText(getApplicationContext(), "正在保存……", Toast.LENGTH_LONG).show();			//用BitmapFactory.decodeByteArray()方法可以把相机传回的裸数据转换成Bitmap对象			mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);			//接下来的工作就是把Bitmap保存成一个存储卡中的文件			File file = new File("/sdcard/YY"+ new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg");			try {				file.createNewFile();				BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));				mBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);				os.flush();				os.close();				Toast.makeText(getApplicationContext(), "图片保存完毕,在存储卡的根目录", Toast.LENGTH_LONG).show();			} catch (IOException e) {				e.printStackTrace();			}		} 	}; 	//Activity的创建方法	@Override	public void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState); 		//窗口去掉标题        requestWindowFeature(Window.FEATURE_NO_TITLE);        //窗口设置为全屏        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);        //设置窗口为半透明        getWindow().setFormat(PixelFormat.TRANSLUCENT);         //提供一个帧布局        FrameLayout  fl = new FrameLayout(this);               //创建一个照相预览用的SurfaceView子类,并放在帧布局的底层        cv = new CameraView(this);		fl.addView(cv); 		//创建一个文本框添加在帧布局中,我们可以看到,文字自动出现在了SurfaceView的前面,由此你可以在预览窗口做出各种特殊效果		TextView tv = new TextView(this);		tv.setText("请按\"相机\"按钮拍摄");		fl.addView(tv); 		//设置Activity的根内容视图		setContentView(fl); 	} 	//相机按键按下的事件处理方法	public boolean onKeyDown(int keyCode, KeyEvent event) {		Log.i("yao","MainActivity.onKeyDown");		if (keyCode == KeyEvent.KEYCODE_CAMERA) {			if (mCamera != null) {				Log.i("yao","mCamera.takePicture");				//当按下相机按钮时,执行相机对象的takePicture()方法,该方法有三个回调对象做入参,不需要的时候可以设null				mCamera.takePicture(null, null, pictureCallback);			}		}		return cv.onKeyDown(keyCode, event);	} 	// 照相视图	class CameraView extends SurfaceView { 		private SurfaceHolder holder = null; 		//构造函数		public CameraView(Context context) {			super(context);			Log.i("yao","CameraView"); 			// 操作surface的holder			holder = this.getHolder();			// 创建SurfaceHolder.Callback对象			holder.addCallback(new SurfaceHolder.Callback() { 				@Override				public void surfaceDestroyed(SurfaceHolder holder) {					// 停止预览					mCamera.stopPreview();					// 释放相机资源并置空					mCamera.release();					mCamera = null;				} 				@Override				public void surfaceCreated(SurfaceHolder holder) {					//当预览视图创建的时候开启相机					mCamera = Camera.open();					try {						//设置预览						mCamera.setPreviewDisplay(holder);					} catch (IOException e) {						// 释放相机资源并置空						mCamera.release();						mCamera = null;					} 				} 				//当surface视图数据发生变化时,处理预览信息				@Override				public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 					//获得相机参数对象					Camera.Parameters parameters = mCamera.getParameters();					//设置格式					parameters.setPictureFormat(PixelFormat.JPEG);					//设置预览大小,这里我的测试机是Milsstone所以设置的是854x480					parameters.setPreviewSize(854, 480);					//设置自动对焦					parameters.setFocusMode("auto");					//设置图片保存时的分辨率大小					parameters.setPictureSize(2592, 1456);					//给相机对象设置刚才设定的参数					mCamera.setParameters(parameters);					//开始预览					mCamera.startPreview();				}			});			// 设置Push缓冲类型,说明surface数据由其他来源提供,而不是用自己的Canvas来绘图,在这里是由摄像头来提供数据			holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);		} 	} }

5、连接Milestone,编译并运行程序:悲剧的是,截图只能看到黑黑的一片,无法截取到摄像头传输过来SurfaceView信息,而在真机中是能看到预览效果的。

还是上一张照好的图片给大家吧,(用了好多年的小黑……)

好了,本讲就到这里,谢谢大家的支持和鼓励,下次再见。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android--使用Camera拍照
【流媒體】Android 实时视频采集
Android 照相机 camera 操作封装
Android如何实现边采集边上传
Android 放大镜效果实现
Android拍照,上传,预览综合【修改】
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服