`
zkl_1987
  • 浏览: 245770 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

android 笔记 --- 相机应用

阅读更多
现在的手机几乎都实现照相机功能了,而且在硬件的支持下像素也越来越高,在现实生活中的用途也越来越广,而在Android中专门 提供了Camera来处理相机相关的事件,Camera 是一个专门用来连接和断开相机服务的类,Camera 下面包括如下几个事件:

Camera.AutoFocusCallback: 自动调焦功能;
Camera.ErrorCallback:错误信息捕捉;
Camera.Parameters :相机的属性参数
Camera.PictureCallback:拍照、产生图片时触发;
Camera.PreviewCallback:相机预览设置;
Camera.ShutterCallback:快门设置;
Camera.Size:图片尺寸;

要在Android中使用相机服务很简单,Camera没有构造方法,我们要使用它直接通过open()方法来打开相机设备,然后通过 Camera.Parameters 对相机的一些属性进行设置,比如输出图片的格式、大小等等。下面是Camera类一些常用的方法介绍。

Camera类的方法
方法 说明
autoFocus 设置自动对焦
getParameters 得到相机的参数
open 启动相机服务
release 释放Camera服务
setPreviewDisplay 设置预览
setParameters 设置预览参数
startPreview 开始预览
stopPreview 停止预览
takePicture 拍照

这里重点说明一下拍照的方法和使用, takePicture 方法要实现3个回调函数,分别是: Camera.ShutterCallback (快门) 和 两个Camera.PictureCallback(图像数据)。这里我们在拍照之后要取得图像数据就需要实现Camera.PictureCallback 的 onPictureTaken 方法。onPictureTaken 中第一个参数就是图像数据, 第二个参数则是相机。
下面是一个相机拍照的例子。相机需要一个界面来预览当前拍摄的效果,这里可以使用SurfaceView类。 我们先来看看在模拟器上的运行效果吧。



下面我们来看具体如何使用相机服务预览效果,最后按导航键中键来拍照,将照片保存到SD卡中(当然首先要确认有SD卡插入)。 代码如下

package xiaohang.zhimeng;
 
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
 
public class Activity01 extends Activity {
 
	private Preview mPreview;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
 
        //Create our Preview view and set it as the content of our activity.
        mPreview = new Preview(this);
        setContentView(mPreview);
    }
 
    public boolean onKeyUp(int keyCode, KeyEvent event){
    	switch (keyCode) {
		case KeyEvent.KEYCODE_DPAD_CENTER:
			mPreview.takePicture();
			break;
		}
    	return true;
    }
}  
    /*Preview-显示Preview*/
    class Preview extends SurfaceView implements SurfaceHolder.Callback{
 
    	SurfaceHolder mHolder;
    	Camera mCamera;
    	Bitmap cameraBitmap;
 
		public Preview(Context context) {
			super(context);
			//得到SurfaceHolder对象
			mHolder = getHolder();
			//添加回调函数
			mHolder.addCallback(this);
			//设置SurfaceHolder 的类型
			mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}
 
		//在Surface的大小发生改变时激发
		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			/*构建Camera.Parameters对相机的参数进行设置*/
			Camera.Parameters parameters = mCamera.getParameters();
			/*设置拍照的图片格式*/
			parameters.setPictureFormat(PixelFormat.JPEG);
			/*设置Preview(预览)的尺寸*/
			parameters.setPreviewSize(320, 480);
			mCamera.setParameters(parameters);
			/*开始预览*/
			mCamera.startPreview();
		}
 
		/*拍照片*/
		public void takePicture(){
			if (mCamera != null) {
				mCamera.takePicture(null, null, jpegCallback);
			}
		}
		/*拍照后输出图片*/
		private PictureCallback jpegCallback = new PictureCallback(){
 
			@Override
			public void onPictureTaken(byte[] data, Camera camera) {
				// TODO Handle JPEG image data
				//解码一个不可变的位图 从指定的字节数组
				cameraBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
				File myCaptureFile = new File("/sdcard/camera1.jpg");
				try {
					BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
					//压缩位图到指定的OutputStream
					cameraBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
					//刷新此缓冲区的输出流
					bos.flush();
					//关闭此输出流并释放与此流有关的所有系统资源
					bos.close();
					/*将拍到的图片绘制出来*/
					//锁定画布
					Canvas canvas = mHolder.lockCanvas();
					canvas.drawBitmap(cameraBitmap, 0, 0, null);
					//绘制后解锁,绘制后必须解锁才能显示
					mHolder.unlockCanvasAndPost(canvas);
				} catch (Exception e) {
					e.getMessage();
				}
			}
		};
 
		//在创建Surface时激发
		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			/*启动Camera*/
			mCamera = Camera.open();
			try {
				mCamera.setPreviewDisplay(holder);
			} catch (Exception e) {
				/*释放mCamera*/
				mCamera.release();
				mCamera = null;
			}
		}       
 
		//在销毁Surface时激发
		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			/*停止预览*/
			mCamera.stopPreview();
			mCamera = null;
		}
    }


最后大家不要忘记了加上权限声明
<uses-permission android:name="android.permission.CAMERA" />
	<uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />




Android Camera照相机

package com.Aina.Android;  
 
import java.io.BufferedOutputStream;  
import java.io.File;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
 
import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.graphics.Canvas;  
import android.graphics.PixelFormat;  
import android.hardware.Camera;  
import android.util.Log;  
import android.view.KeyEvent;  
import android.view.SurfaceHolder;  
import android.view.SurfaceView;  
 
/** 
 * com.Aina.Android Pro_Camera 
 *  
 * @author Aina.huang E-mail: 674023920@qq.com 
 * @version 创建时间:2010 Jul 7, 2010 2:50:15 PM 类说明 
 */  
public class PreView extends SurfaceView implements SurfaceHolder.Callback {  
 
    private SurfaceHolder holder = null;  
    private Camera mCamera = null;  
    private Bitmap mBitmap = null;  
 
    public PreView(Context context) {  
        super(context);  
        Log.i("TAG", "PreView()");  
        // TODO Auto-generated constructor stub  
        holder = this.getHolder();  
        holder.addCallback(this);  
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
    }  
 
    public void surfaceChanged(SurfaceHolder holder, int format, int width,  
            int height) {  
        Log.i("TAG", "surfaceChanged");  
        // TODO Auto-generated method stub  
        Camera.Parameters parameters = mCamera.getParameters();  
        parameters.setPictureFormat(PixelFormat.JPEG);//设置图片格式  
        parameters.setPreviewSize(320, 480);//设置尺寸  
//      parameters.setPictureSize(320, 480);//设置分辨率  
        mCamera.setParameters(parameters);  
        mCamera.startPreview();//开始预览  
    }  
 
    public void surfaceCreated(SurfaceHolder holder) {  
        Log.i("TAG", "surfaceCreated");  
        // TODO Auto-generated method stub  
        mCamera = Camera.open();//启动服务  
        try {  
            mCamera.setPreviewDisplay(holder);//设置预览  
        } catch (IOException e) {  
            mCamera.release();//释放  
            mCamera = null;  
        }  
    }  
 
    public void surfaceDestroyed(SurfaceHolder holder) {  
        Log.i("TAG", "surfaceDestroyed");  
        // TODO Auto-generated method stub  
        mCamera.stopPreview();//停止预览  
        mCamera = null;  
    }  
 
    public boolean onKeyDown(int keyCode, KeyEvent event) {  
        if(keyCode==KeyEvent.KEYCODE_DPAD_CENTER){  
            if(mCamera !=null){  
                mCamera.takePicture(null, null,pic);  
            }  
        }  
        return super.onKeyDown(keyCode, event);  
    }  
    //拍照后输出图片  
    public Camera.PictureCallback pic = new Camera.PictureCallback(){  
 
        public void onPictureTaken(byte[] data, Camera camera) {  
            // TODO Auto-generated method stub  
            mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);  
            File f = new File(android.os.Environment.getExternalStorageDirectory()+"/camera1.jpg");  
            try {  
                BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(f));  
                mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, os);  
                os.flush();  
                os.close();  
                Canvas canvas = holder.lockCanvas();  
                canvas.drawBitmap(mBitmap, 0, 0, null);  
                holder.unlockCanvasAndPost(canvas);  
            } catch (FileNotFoundException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
 
    };  
}


package com.Aina.Android;  
 
import android.app.Activity;  
import android.os.Bundle;  
import android.view.KeyEvent;  
import android.view.Window;  
 
public class Test extends Activity {  
    /** Called when the activity is first created. */  
    private PreView pv = null;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
        pv = new PreView(this);  
        setContentView(pv);  
    }  
 
    @Override  
    public boolean onKeyDown(int keyCode, KeyEvent event) {  
        // TODO Auto-generated method stub  
        return pv.onKeyDown(keyCode, event);  
    }  
 
}


<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
      package="com.Aina.Android"  
      android:versionCode="1"  
      android:versionName="1.0">  
    <application android:icon="@drawable/icon" android:label="@string/app_name">  
        <activity android:name=".Test"  
                  android:label="@string/app_name">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
        </activity>  
 
    </application>  
 <uses-permission android:name="android.permission.CAMERA" />   
 <uses-feature android:name="android.hardware.camera" />   
 <uses-feature android:name="android.hardware.camera.autofocus" />  
 
</manifest>



分享到:
评论
1 楼 ihopethatwell 2012-04-24  
楼主,我运行拍不了照,为什么?onkeydown()

相关推荐

    《Android应用开发揭秘》读书笔记

    《Android应用开发揭秘》读书笔记不仅是一份个人学习历程的记录,更是一部深入浅出的Android开发指南。本书籍及笔记覆盖了从基础知识到高级应用的广泛内容,为初学者和有经验的开发者提供了宝贵的资源。 ### ...

    Android记事本-demo

    在Android开发中,创建一个记事本应用是一个常见的学习任务,它涵盖了多个核心知识点。以下是对这个"Android记事本-demo"中涉及的关键技术的详细解释: 1. **文本数据的存储**:在Android中,有多种方式可以存储...

    Android高级应用源码-最全的OCR图像识别技术源码内有说明.rar

    例如,一个笔记应用可以使用OCR来自动转录纸质笔记,或者一个购物应用可以识别商品条形码快速查找价格信息。 总结起来,这个源码包提供了全面的OCR技术实现示例,对于开发者来说,它是学习和实践Android平台上OCR...

    基于Android平台的 酷相机

    在Android平台上,酷相机是一款流行的拍照应用,它利用了Android系统的多媒体处理能力和丰富的API接口,为用户提供了多种拍照和编辑功能。本项目是基于Android平台的酷相机的完整代码实现,旨在帮助开发者深入理解...

    全网最全Android开发笔记.zip

    【Android开发笔记】是一部全面覆盖Android开发核心技术与实践的综合资料,旨在帮助开发者从零基础到精通,深入了解Android系统的工作原理以及应用开发的各种技巧。笔记包含了大量的实例代码、技术解析和实战经验,...

    android 学习笔记(全全整理)

    Android学习笔记全全整理,是针对想要深入理解并掌握Android开发技术的学习者们的一份宝贵资源。这份笔记涵盖了从基础到高级的多个方面,旨在帮助读者建立起完整的Android知识体系。以下将详细介绍其中可能包含的...

    Android学霸学习笔记

    根据提供的文件内容,这是一份详细的Android学习笔记,涵盖了从基础入门到高级特性的各个知识点。以下是从这些内容中提取的知识点: 1. Android入门基础: - 建立第一个App:介绍如何创建Android项目和执行程序。 ...

    Android 开发随手笔记之使用摄像头拍照

    通过创建一个Intent,设置ACTION_IMAGE_CAPTURE动作,并将拍摄结果的输出Uri传递给相机应用: ```java Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, ...

    Android笔记之 图片自由裁剪 DEMO

    本篇将详细探讨如何实现“Android笔记之图片自由裁剪DEMO”,并结合提供的`ImageCutDemo`来深入理解相关知识点。 1. **Intent选择图片** Android系统提供了Intent机制,用于启动系统服务或与其他应用程序进行交互...

    MTK-Android开发笔记资料

    【MTK-Android开发笔记资料】是针对基于MediaTek处理器的Android系统开发的一份详尽文档,涵盖了多个关键领域的知识。MediaTek是一家知名的芯片制造商,其产品广泛应用于智能手机和平板电脑等设备。以下是对这些知识...

    Android-TravelMate一个完整的旅游指南开源AndroidApp

    9. **相机和笔记**:旅行途中可以拍照、记笔记,记录美好瞬间和旅行心得。 **三、技术栈** 1. **Android Studio**:作为开发环境,用于编写和调试代码。 2. **Kotlin**:选用Kotlin作为主要编程语言,提高代码...

    新版Android开发教程+笔记

    7. **应用、permission、资源** (13 - 应用、permission、资源(待续).pdf): 应用权限管理是Android系统的一个重要特性,开发者必须明确声明需要的权限才能访问特定的功能(如相机、位置等)。同时,了解如何管理和...

    新版Android开发教程 笔记

    9. **多媒体处理**:涵盖音频、视频的播放与录制,相机API的使用,以及图像处理和加载库(如Glide或Picasso)的应用。 10. **动画和过渡**:介绍如何创建视图动画、属性动画,以及在Activity和Fragment之间进行过渡...

    android-webrtc-demo:使用原生 Webrtc API 在 Android 上使用相机镜像

    这是一个示例,展示了如何在Android平台上使用Flint协议和WebRTC库来做相机镜像。 如何使用 下载源代码 使用Eclipse编译位于sender目录下的 Android sender 应用程序。 在应该有摄像头(一两个)的 Android 移动...

    android-development-study:项目和笔记创建android开发学习

    本项目"android-development-study"是一个集成了项目实践与学习笔记的资源库,旨在帮助开发者深入理解Android应用开发的各个方面。下面,我们将详细介绍这个学习资源包中可能包含的知识点,并展开讨论。 1. **...

Global site tag (gtag.js) - Google Analytics