Android 摄像头组件 Camera类的使用 自动对焦 拍照

今天的这个例子是要利用android.hardware.Camera类实现类似Android系统自带相机的功能,可以动态预览摄像头拍到的画面,可以拍照并存到SD卡,支持自动对焦。暂时还没有实现录像功能。经真机测试,以下代码可以在关屏时正常拍照,但在Service中无法运行,即使亮着屏幕,原因未知。
布局:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1">
	<SurfaceView android:id="@+id/surfaceView1" android:layout_width="320dp" android:layout_height="220dp"/>
	<LinearLayout android:layout_height="wrap_content" android:id="@+id/linearLayout1" android:layout_width="fill_parent">
		<Button android:text="拍照" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
	</LinearLayout>
	<ImageView android:layout_height="220dp" android:id="@+id/imageView1"  android:layout_width="320dp"></ImageView>
</LinearLayout>

一个 SurfaceView用于实时显示摄像头拍摄到的画面,一个控制拍照的按钮,还有一个ImageView,拍到照片后会把拍到的图片显示在这里。
Java代码:


package com.pocketdigi.camera;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class CameraActivity extends Activity implements SurfaceHolder.Callback {
    /** Called when the activity is first created. */
	SurfaceHolder surfaceHolder;
	SurfaceView surfaceView1;
	Button button1;
	ImageView imageView1;
	Camera camera;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        button1=(Button)findViewById(R.id.button1);
        //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        //设为横向显示。因为摄像头会自动翻转90度,所以如果不横向显示,看到的画面就是翻转的。
        //本例中不横向
        
        surfaceView1=(SurfaceView)findViewById(R.id.surfaceView1);
        imageView1=(ImageView)findViewById(R.id.imageView1);
        surfaceHolder=surfaceView1.getHolder();
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceHolder.addCallback(this);
        button1.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				camera.autoFocus(afcb);
				//自动对焦
				
			}});
        
    }
    PictureCallback jpeg =new PictureCallback(){

		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			// TODO Auto-generated method stub
			Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
			//byte数组转换成Bitmap
			imageView1.setImageBitmap(bmp);
			//拍下图片显示在下面的ImageView里
			FileOutputStream fop;
			try {
				fop=new FileOutputStream("/sdcard/dd.jpg");
				//实例化FileOutputStream,参数是生成路径
				bmp.compress(Bitmap.CompressFormat.JPEG, 100, fop);
				//压缩bitmap写进outputStream 参数:输出格式  输出质量  目标OutputStream
				//格式可以为jpg,png,jpg不能存储透明
				fop.close();
				System.out.println("拍成功");
				//关闭流
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("FileNotFoundException");

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("IOException");
			}
			camera.startPreview();
			//需要手动重新startPreview,否则停在拍下的瞬间
		}
    	
    };

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		camera=Camera.open();
		try {
			
			Camera.Parameters parameters=camera.getParameters();
			parameters.setPictureFormat(PixelFormat.JPEG);
                        //每台机器可用的PreviewSize不同,可以parameters.getSupportedPreviewSizes();获取支持的size
			parameters.setPreviewSize(320, 220);
			camera.setParameters(parameters);
			//设置参数
			camera.setPreviewDisplay(surfaceHolder);
			//摄像头画面显示在Surface上
			camera.startPreview();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		System.out.println("surfaceDestroyed");
		camera.stopPreview();
		//关闭预览
		camera.release();
		//释放资源
	}
	
	AutoFocusCallback afcb= new AutoFocusCallback(){

		@Override
		public void onAutoFocus(boolean success, Camera camera) {
			// TODO Auto-generated method stub
			if(success){
				//对焦成功才拍照
				camera.takePicture(null, null, jpeg);
			}
		}
		
		
	};
}

在AndroidManifest.xml中要添加拍照及写入存储卡权限:


    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

© 2011 – 2013, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记