`
mmdev
  • 浏览: 12845681 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

android camera(3)

 
阅读更多

先说说我的测试机器:nexus s。以下的结果都是通过nexus s上测试通过。

还是先上代码:

package com.TestCamera1;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;

public class TestCamera1Activity extends Activity {
	/** Called when the activity is first created. */
	private SurfaceHolder surfaceHolder;
	private Camera camera;
	private int cameraId;
	private SurfaceView surfaceView;
	private Button btn;
	private boolean flag;
	private Camera.PreviewCallback previewCallBack;
	private AutoFocusCallback cb = new AutoFocusCallback() {//自动对焦实现
		public void onAutoFocus(boolean success, Camera camera) {
			if (success) {
				camera.setOneShotPreviewCallback(pcb);
			} else {
				Log.i("autofocus:", "fail");
			}
		}
	};
	private PreviewCallback pcb=new PreviewCallback(){
		public void onPreviewFrame(byte[] data,Camera arg1){
			if(data!=null){				
				String picDirStr = Environment.getExternalStorageDirectory()
					+ "/";
				File picDir = new File(picDirStr);
				if (!picDir.exists()) {
					picDir.mkdir();
				}
				String picName = picDirStr + System.currentTimeMillis()
					+ "auto.jpg";
			 	File myCaptureFile = new File(picName);
				Camera.Parameters parameters=camera.getParameters();
				int imageFormat=parameters.getPreviewFormat();
				if(imageFormat==ImageFormat.NV21){
					Bitmap image=null;
					int w=parameters.getPreviewSize().width;
					int h=parameters.getPreviewSize().height;					
					Rect rect=new Rect(0,0,w,h);
					YuvImage img=new YuvImage(data,ImageFormat.NV21,w,h,null);				
					try {
						BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
						img.compressToJpeg(rect, 100, bos);
						bos.flush();
						bos.close();
						camera.startPreview();// 重新打开预览图,进行下一次的拍照准备,必须等到onPictureCallback函数调用才能调用
						Log.i("autopic", "ok!");
					} catch (Exception e) {
							Log.i("autopic", e.toString());
					}
				}				
			}else{
				Log.i("data:", "null");
			}
		}
	};
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		btn = (Button) findViewById(R.id.button1);
		surfaceView = (SurfaceView) findViewById(R.id.preview_view);
		surfaceHolder = surfaceView.getHolder();
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		surfaceView.getHolder().addCallback(new SurfaceViewCallback());
		btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				camera.autoFocus(cb);// 自动对焦				
			}
		});
	}

	private final class SurfaceViewCallback implements SurfaceHolder.Callback {

		public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
				int arg3) {
			// TODO Auto-generated method stub
			Camera.Parameters parameters = camera.getParameters();
			// 选择合适的预览尺寸
			List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
			Camera.Size cameraSize = (Camera.Size) sizeList.get(1);
			parameters.setPreviewSize(cameraSize.width, cameraSize.height);
			parameters.setPreviewFrameRate(5);
			parameters.setPictureFormat(PixelFormat.JPEG);
			parameters.set("jpeg-quality", 100);
			int rotation = TestCamera1Activity.this.getWindowManager()
					.getDefaultDisplay().getRotation();
			Log.e("default", rotation + "");
			if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
				camera.setDisplayOrientation(90);
				flag = true;
				Log.i("por", "1");
			}
			if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
				parameters.set("orientation", "landscape");
				parameters.set("rotation", 0);
				flag = false;
				Log.i("orientation", "1");
			}

			camera.setParameters(parameters);
			try {
				camera.setPreviewDisplay(surfaceHolder);
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
			camera.startPreview();
		}

		public void surfaceCreated(SurfaceHolder arg0) {
			// TODO Auto-generated method stub
			camera = Camera.open();

		}

		public void surfaceDestroyed(SurfaceHolder arg0) {
			// TODO Auto-generated method stub
			if (camera != null) {
				camera.stopPreview();
			}
			camera.release();
			camera = null;
		}
	}

}

自动对焦比较简单,只需要调用camera.autoFocus(cb)。然后调用自动对焦的回调函数private AutoFocusCallback cb = new AutoFocusCallback() {},当然你也可以不构造这个函数即是camera.autoFocus(null),前提是你保证你的手机支持自动对焦。然后就是照相了,可以调用camera.setOneShotPreviewCallback或者camera.setPreviewCallback,他们的区别就是前者记录对焦时候预览图的一帧,而后者就不停地调用,即你可以得到很多对焦过程中得到的预览图。


需要注意的是预览图的格式是NV21,而BitmapFactory不支持这种格式的解码。所以需要转换。


如果你想不断的对照就需要一个Timer不断出发autoFocus函数了。


最后我想说说takepicture和preview。他们都可以照相,那么他们有什么区别呢?所谓的照相我觉得就是得到data,把这个data输出成照片就完成照相功能了,那么他们都能完成这个功能,所以在这点上他们没有太大差别。只是preview可以得到一幅对焦后的图片,比takepicture清晰。你当然可以autofocus之后再takepicture,那么得到的图片就跟preview一样了。

附上android camera(3)的demo:android camera.rar

下集说的是利用zxing对条形码和二维码进行解码,其实这个是我的原本目的。因为zxing解码需要照相机我才去恶补一下camera的知识。


忘了警告:android camera系列的文章是由一个刚接触android不到一个月的菜鸟所写,所以必然存在很多错误,请大家指出

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics