Android Camera使用小结

Android关于Camera的使用,一是capture image,二是video。
由于android提供了强大的组件功能,因此对camera的开发,可以使用两种方法:
(1)借助Intent和MediaStore调用系统Camera App程序来实现capture image和video
(2)根据Camera API编写Camera程序
调用Camera App实现
Android 系统强大的组件功能,使得我们只需要通过Intent就可以方便的打开系统自带的Camera App,action为android.media.action.STILL_IMAGE_CAMERA
Intent intent = new Intent();

intent.setAction("android.media.action.STILL_IMAGE_CAMERA");

startActivity(intent);
总结:
(1)调用Camera App实现拍照和摄像功能,可以满足我们的需求,但是自由度降低,并且拍照的界面就是系统的样子
(2)不需要任何权限

 根据Camera API编写Camera程序

(1)在manifest内声明使用权限
 <uses-permission android:name="android.permission.CAMERA" />
 <uses-feature android:name="android.hardware.camera" />
 <uses-feature android:name="android.hardware.camera.autofocus" />
(2)一般拍照和摄像的时候需要写到SD card,所以还要声明权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
(3)做摄像功能时,需要音频录制和视频录制功能,所以需要声明下面两项权限
<uses-permissionandroid:name="android.permission.RECORD_VIDEO"/>
<uses-permissionandroid:name="android.permission.RECORD_AUDIO"/>
 
(4)使用Camera API拍照或摄像,都需要使用到预览,预览就要用到SurfaceView, 为此Activity的布局中必须有SurfaceView
拍照流程描述
(1)在Activity的OnCreate函数中设置好SurfaceView,包括设置SurfaceHolder.Callback对象和SurfaceHolder对象的类型
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceView.getHolder().setFixedSize(320, 240);
// Add a Callback interface for this holder
surfaceView.getHolder().addCallback(surfaceViewCallback);

 
(2)在SurfaceHolder.Callback的surfaceCreated函数中,使用Camera的Open函数开启摄像头硬件,Android2.3以后支持多摄像头,所以开启前可以通过getNumberOfCameras先获取摄像头数目,再通过getCameraInfo得到需要开启的摄像头id,然后传入Open函数开启摄像头,如果摄像头开启成功,则返回一个Camera对象,否则就抛出异常;
(3)开启成功的情况下,在SurfaceHolder.Callback的surfaceChanged函数中调用getParameters函数得到已打开的摄像头的配置参数Parameters对象,如果有需要就修改对象的参数,然后调用setParameters函数设置进去;
(4)同样在surfaceChanged函数中,通过Camera::setPreviewDisplay为摄像头设置SurfaceHolder对象,设置成功后调用Camera::startPreview函数开启预览功能;
(5)在需要拍照的时候,调用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)函数来完成拍照,这个函数中可以四个回调接口,ShutterCallback是快门按下的回调,在这里我们可以设置播放“咔嚓”声之类的操作,后面有三个PictureCallback接口,分别对应三份图像数据,分别是原始图像、缩放和压缩图像和JPG图像,图像数据可以在PictureCallback接口的void onPictureTaken(byte[] data, Camera camera)中获得,三份数据相应的三个回调正好按照参数顺序调用,通常我们只关心JPG图像数据,此时前面两个PictureCallback接口参数可以直接传null;
(6)每次调用takePicture获取图像后,摄像头会停止预览,假如需要继续拍照,则我们需要在上面的PictureCallback的onPictureTaken函数末尾,再次调用Camera::startPreview函数;在不需要拍照的时候,我们需要主动调用Camera::stopPreview函数停止预览功能,并且调用Camera::release函数释放Camera,以便其他应用程序调用
 
package com.example.camerademo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;

public class CameraAPIActivity extends Activity {

	private SurfaceView surfaceView;
	private Button takePhotos;
	private Camera camera;
	private boolean preview = false;
	private String filePath = "/data/log/camera" + System.currentTimeMillis() + ".jpg";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// turning off the title at the top of the screen
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

		// set full screen and screen on
		Window window = getWindow();
		window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

		setContentView(R.layout.camera_api);

		surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
		surfaceView.getHolder().setFixedSize(320, 240);
		// Add a Callback interface for this holder
		surfaceView.getHolder().addCallback(surfaceViewCallback);

		takePhotos = (Button) findViewById(R.id.takePhotos);
		takePhotos.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (camera != null) {
					camera.takePicture(null, null, pictureCallback);
				}

			}
		});
	}

	public Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {

		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
			File file = new File(filePath);
			try {
				FileOutputStream fos = new FileOutputStream(file);
				bitmap.compress(CompressFormat.JPEG, 100, fos);
				fos.close();
				camera.stopPreview();
				camera.startPreview();
				preview = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	};

	private SurfaceHolder.Callback surfaceViewCallback = new SurfaceHolder.Callback() {

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
			// 2.Get existing (default) settings
			Parameters parameters = camera.getParameters();
			// 3.modify the returned Camera.Parameters object
			parameters.setPictureFormat(ImageFormat.JPEG);
			parameters.set("jpeg-quality", 100);
			parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
			camera.setParameters(parameters);
			// 4.Sets the Surface to be used for live preview
			try {
				camera.setPreviewDisplay(holder);
			} catch (IOException e) {
				e.printStackTrace();
			}
			// 5.start updating the preview surface. Preview must be started
			// before you can take a picture
			camera.startPreview();
			preview = true;
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			// 1.Obtain an instance of Camera
			camera = Camera.open();
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			if (camera != null) {
				if (preview) {
					camera.stopPreview();
					preview = false;
				}
				camera.release();
				camera = null;
			}
		}
	};
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值