zoukankan      html  css  js  c++  java
  • 个人封装的一个Camera类

    好久不写博客了,代码写了不少,但大多数都是拿来主义,要不是网上,要不就是自己曾经的代码拼装。

    新工作是搞Android开发的,近期任务要求我封装一个Carmera类,自己也认为还是封装以后方便使用,弄了半天写好一个,能够调用手机前置后置摄像头进行拍照摄像,并能够依据设置相机各种參数,进行保存。发到这里分享下。


    package com.hourglass.camerademo;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.List;
    
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.CompressFormat;
    import android.graphics.BitmapFactory;
    import android.graphics.Matrix;
    import android.hardware.Camera;
    import android.hardware.Camera.CameraInfo;
    import android.hardware.Camera.PictureCallback;
    import android.hardware.Camera.Size;
    import android.media.MediaRecorder;
    import android.os.Build;
    import android.os.Environment;
    import android.os.StatFs;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceHolder.Callback;
    import android.view.SurfaceView;
    
    /**
     * 拍照录像封装类
     * 
     * @author Hourglass 2014年4月21日 Q331956750
     * @version 1.2
     */
    public class MediaCamera {
    	private static int cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;
    
    	private static String tag = "MediaCamera---------------------";
    
    	private static int back_PictureWidth;
    	private static int back_PictureHeight;
    	private static int back_PreviewWidth;
    	private static int back_PreviewHeight;
    	private static int back_degrees;
    	private static String back_FocusMode;
    	private static int back_pixel_format;
    
    	private static int front_PictureWidth;
    	private static int front_PictureHeight;
    	private static int front_PreviewWidth;
    	private static int front_PreviewHeight;
    	private static int front_degrees;
    	private static String front_FocusMode;
    	private static int front_pixel_format;
    
    	private static int back_output_format;
    	private static int back_video_encoder;
    	private static int back_Video_width;
    	private static int back_Video_height;
    	private static int back_Video_rate;
    
    	private static int front_output_format;
    	private static int front_video_encoder;
    	private static int front_Video_width;
    	private static int front_Video_height;
    	private static int front_Video_rate;
    
    	private Bitmap mBitmap = null;
    
    	private MediaRecorder mediarecorder;
    	public boolean isRecording;
    
    	private static String DefaultImagePath = Environment
    			.getExternalStorageDirectory().getPath() + "/Pictures/";
    	private static String DefaultImageName = "Image";
    	private static String DefaultVedioPath = Environment
    			.getExternalStorageDirectory().getPath() + "/Pictures/";
    	private static String DefaultVedioName = "Video";
    
    	private Camera camera = null;
    	private SurfaceView surfaceView = null;
    	private SurfaceHolder surfaceHolder = null;
    
    	public MediaCamera(SurfaceView surfaceView) {
    		super();
    		this.surfaceView = surfaceView;
    		surfaceHolder = surfaceView.getHolder();
    		surfaceHolder.addCallback(surfaceHolderCallback);
    		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
    			surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    	}
    
    	/******************************* 静态检測类 ********************************************/
    	/**
    	 * 检測设备是否有摄像头
    	 * 
    	 * @param context
    	 *            执行上下文
    	 * @return 若有摄像头 返回true 若无返回false
    	 */
    	public static boolean checkCameraHardware(Context context) {
    		return context.getPackageManager().hasSystemFeature(
    				PackageManager.FEATURE_CAMERA) ? true : false;
    	}
    
    	/**
    	 * 检測设备SD卡状态
    	 * 
    	 * @return 正常返回true 不正常返回false
    	 */
    	public static boolean checkDeviceSDEnable() {
    		return android.os.Environment.getExternalStorageState().equals(
    				android.os.Environment.MEDIA_MOUNTED) ? true : false;
    	}
    
    	/**
    	 * 检測设备SD卡剩余空间
    	 * 
    	 * @return 单位MB
    	 */
    	public static long getSDFreeSize() {
    		// 取得SD卡文件路径
    		File path = Environment.getExternalStorageDirectory();
    		StatFs sf = new StatFs(path.getPath());
    		// 获取单个数据块的大小(Byte)
    		long blockSize = sf.getBlockSize();
    		// 空暇的数据块的数量
    		long freeBlocks = sf.getAvailableBlocks();
    		// 返回SD卡空暇大小
    		// return freeBlocks * blockSize; //单位Byte
    		// return (freeBlocks * blockSize)/1024; //单位KB
    		return (freeBlocks * blockSize) / 1024 / 1024; // 单位MB
    	}
    
    	/**
    	 * 检測设备SD卡总容量
    	 * 
    	 * @return 单位MB
    	 */
    	public static long getSDAllSize() {
    		// 取得SD卡文件路径
    		File path = Environment.getExternalStorageDirectory();
    		StatFs sf = new StatFs(path.getPath());
    		// 获取单个数据块的大小(Byte)
    		long blockSize = sf.getBlockSize();
    		// 获取全部数据块数
    		long allBlocks = sf.getBlockCount();
    		// 返回SD卡大小
    		// return allBlocks * blockSize; //单位Byte
    		// return (allBlocks * blockSize)/1024; //单位KB
    		return (allBlocks * blockSize) / 1024 / 1024; // 单位MB
    	}
    
    	/******************************* 静态检測类结束 ********************************************/
    	/**
    	 * 打开或切换前后摄像头
    	 */
    	public void OpenCamera() {
    		int cameraCount = 0;
    		CameraInfo cameraInfo = new CameraInfo();
    		cameraCount = Camera.getNumberOfCameras();
    		for (int i = 0; i < cameraCount; i++) {
    			Camera.getCameraInfo(i, cameraInfo);
    			releaseCamera();
    			if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT) {
    				// 如今是后置,变更为前置
    				cameraPosition = Camera.CameraInfo.CAMERA_FACING_BACK;
    				try {
    					camera = Camera.open(cameraPosition);
    					camera.setPreviewDisplay(surfaceHolder);
    				} catch (Exception e) {
    					Log.d(tag, "前置相机无法打开或正在被占用");
    				}
    				try {
    					setCameraParameters(camera, 1);
    				} catch (Exception e) {
    					e.printStackTrace();
    					Log.d(tag, "前置相机无法设置參数");
    				}
    				camera.startPreview();
    				break;
    			} else {
    				// 如今是前置, 变更为后置
    				cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;
    				try {
    					camera = Camera.open(cameraPosition);
    					camera.setPreviewDisplay(surfaceHolder);
    				} catch (Exception e) {
    					Log.d(tag, "后置相机无法打开或正在被占用");
    				}
    				try {
    					setCameraParameters(camera, 0);
    				} catch (Exception e) {
    					e.printStackTrace();
    					Log.d(tag, "前置相机无法设置參数");
    				}
    				camera.startPreview();
    				break;
    			}
    		}
    	}
    
    	/**
    	 * Camera拍照
    	 * 
    	 * @param Suffix
    	 *            生成JPEG 0 生成PNG 1
    	 */
    	public void takePhoto(int Suffix) {
    		if (camera != null) {
    			try {
    				if (Suffix == 0)
    					camera.takePicture(null, null, JpegCallback);
    				else
    					camera.takePicture(null, null, PngCallback);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    		camera.startPreview();
    	}
    
    	/**
    	 * JPEG回调方法
    	 * **/
    	private PictureCallback JpegCallback = new PictureCallback() {
    		public void onPictureTaken(byte[] data, Camera camera) {
    			if (null != data) {
    				mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
    
    			}
    			Matrix matrix = new Matrix();
    			matrix.postRotate((float) 0.0);
    			Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
    					mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);
    			if (null != rotaBitmap) {
    				savePicture(rotaBitmap, DefaultImagePath,
    						Bitmap.CompressFormat.JPEG, DefaultImageName, ".jpeg");
    			}
    		}
    	};
    	/**
    	 * Png回调方法
    	 * **/
    	private PictureCallback PngCallback = new PictureCallback() {
    		public void onPictureTaken(byte[] data, Camera camera) {
    			if (null != data) {
    				mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
    			}
    			Matrix matrix = new Matrix();
    			matrix.postRotate((float) 0.0);
    			Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
    					mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);
    			if (null != rotaBitmap) {
    				savePicture(rotaBitmap, DefaultImagePath,
    						Bitmap.CompressFormat.PNG, DefaultImageName, ".png");
    			}
    		}
    	};
    
    	/**
    	 * 保存Bitmap
    	 * 
    	 * @param bitmap
    	 * @param savePath
    	 * @param format
    	 *            编码格式
    	 * @param filename
    	 *            文件名称 Null则依照当前毫秒命名
    	 * @param suffix
    	 *            后缀名
    	 */
    	private void savePicture(Bitmap bitmap, String savePath,
    			CompressFormat format, String filename, String suffix) {
    		File folder = new File(savePath);
    		if (!folder.exists()) {
    			folder.mkdir();
    		}
    		String jpegName;
    		if (filename == null || filename.length() == 0)
    			jpegName = savePath + System.currentTimeMillis() + suffix;
    		else {
    			jpegName = savePath + filename + suffix;
    		}
    		try {
    			FileOutputStream fout = new FileOutputStream(jpegName);
    			BufferedOutputStream bos = new BufferedOutputStream(fout);
    
    			bitmap.compress(format, 100, bos);
    			bos.flush();
    			bos.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    	private void setCameraParameters(Camera myCamera, int type) {
    		if (null != myCamera) {
    			Camera.Parameters myParam = myCamera.getParameters();
    
    			if (type == 1) {
    				myParam.setPictureFormat(back_pixel_format);
    				myParam.setPictureSize(back_PictureWidth,
    						back_PictureHeight);
    				myParam.setPreviewSize(back_PreviewWidth,
    						back_PreviewHeight);
    				myCamera.setDisplayOrientation(back_degrees);
    				myParam.setFocusMode(back_FocusMode);
    			} else {
    				myParam.setPictureFormat(front_pixel_format);
    				myParam.setPictureSize(front_PictureWidth, front_PictureHeight);
    				myParam.setPreviewSize(front_PreviewWidth, front_PreviewHeight);
    				myCamera.setDisplayOrientation(front_degrees);
    				myParam.setFocusMode(front_FocusMode);
    			}
    
    			myCamera.setParameters(myParam);
    		}
    	}
    
    	private void setRecordParameters(int type) {
    		mediarecorder.setCamera(camera);
    		mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    		if (type == 0) {
    			mediarecorder.setOutputFormat(back_output_format);
    			mediarecorder.setVideoEncoder(back_video_encoder);
    			mediarecorder.setVideoFrameRate(back_Video_rate);
    			mediarecorder.setVideoSize(back_Video_width, back_Video_height);
    		} else {
    			mediarecorder.setOutputFormat(front_output_format);
    			mediarecorder.setVideoEncoder(front_video_encoder);
    			mediarecorder.setVideoFrameRate(front_Video_rate);
    			mediarecorder.setVideoSize(front_Video_width, front_Video_height);
    		}
    		mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());
    		if (front_output_format == MediaRecorder.OutputFormat.MPEG_4)
    			mediarecorder.setOutputFile(DefaultVedioPath + DefaultVedioName
    					+ ".mp4");
    		else if (front_output_format == MediaRecorder.OutputFormat.THREE_GPP)
    			mediarecorder.setOutputFile(DefaultVedioPath + DefaultVedioName
    					+ ".3gp");
    		else
    			new Exception("不支持的生成视频格式");
    	}
    
    	/**
    	 * 初始化相机參数方法(后置)
    	 * 
    	 * @param myCamera
    	 *            Camera实例
    	 * @param pixel_format
    	 *            设置拍照后存储的图片格式
    	 * @param PictureWidth
    	 *            存储的图片像素X
    	 * @param PictureHeight
    	 *            存储的图片像素Y
    	 * @param PreviewWidth
    	 *            显示宽度X
    	 * @param PreviewHeight
    	 *            显示高度Y
    	 * @param degrees
    	 *            旋转角度
    	 * @param FocusMode
    	 *            调焦方式
    	 */
    	public static void initCameraParameters_back(int pixel_format,
    			int PictureWidth, int PictureHeight, int PreviewWidth,
    			int PreviewHeight, int degrees, String FocusMode) {
    		MediaCamera.back_pixel_format = pixel_format;
    		MediaCamera.back_PictureWidth = PictureWidth;
    		MediaCamera.back_PictureHeight = PictureHeight;
    		MediaCamera.back_PreviewWidth = PreviewWidth;
    		MediaCamera.back_PreviewHeight = PreviewHeight;
    		MediaCamera.back_degrees = degrees;
    		MediaCamera.back_FocusMode = FocusMode;
    	}
    
    	/**
    	 * 初始化相机參数方法(前置)
    	 * 
    	 * @param myCamera
    	 *            Camera实例
    	 * @param pixel_format
    	 *            设置拍照后存储的图片格式
    	 * @param PictureWidth
    	 *            存储的图片像素X
    	 * @param PictureHeight
    	 *            存储的图片像素Y
    	 * @param PreviewWidth
    	 *            显示宽度X
    	 * @param PreviewHeight
    	 *            显示高度Y
    	 * @param degrees
    	 *            旋转角度
    	 * @param FocusMode
    	 *            调焦方式
    	 */
    	public static void initCameraParameters_front(int pixel_format,
    			int PictureWidth, int PictureHeight, int PreviewWidth,
    			int PreviewHeight, int degrees, String FocusMode) {
    		MediaCamera.front_pixel_format = pixel_format;
    		MediaCamera.front_PictureWidth = PictureWidth;
    		MediaCamera.front_PictureHeight = PictureHeight;
    		MediaCamera.front_PreviewWidth = PreviewWidth;
    		MediaCamera.front_PreviewHeight = PreviewHeight;
    		MediaCamera.front_degrees = degrees;
    		MediaCamera.front_FocusMode = FocusMode;
    	}
    
    	/**
    	 * 初始化相机摄像參数方法(后置)
    	 * 
    	 * @param surfaceView
    	 * @param output_format
    	 *            视频的封装格式MediaRecorder.OutputFormat THREE_GPP为3gp.MPEG_4为mp4
    	 * @param video_encoder
    	 *            视频编码MediaRecorder.VideoEncoder h263 h264
    	 * @param width
    	 *            分辨率width
    	 * @param height
    	 *            分辨率height
    	 * @param rate
    	 *            视频的码率
    	 * @param path
    	 *            文件输出的路径
    	 */
    	public static void initRecordParameters_back(int output_format,
    			int video_encoder, int Video_width, int Video_height, int Video_rate) {
    		MediaCamera.back_output_format = output_format;
    		MediaCamera.back_Video_width = Video_width;
    		MediaCamera.back_Video_height = Video_height;
    		MediaCamera.back_output_format = output_format;
    		MediaCamera.back_Video_rate = Video_rate;
    
    	}
    
    	/**
    	 * 初始化相机摄像參数方法(前置)
    	 * 
    	 * @param surfaceView
    	 * @param back_output_format
    	 *            视频的封装格式MediaRecorder.OutputFormat THREE_GPP为3gp.MPEG_4为mp4
    	 * @param back_video_encoder
    	 *            视频编码MediaRecorder.VideoEncoder h263 h264
    	 * @param width
    	 *            分辨率width
    	 * @param height
    	 *            分辨率height
    	 * @param rate
    	 *            视频的码率
    	 * @param path
    	 *            文件输出的路径
    	 */
    	public static void initRecordParameters_front(int output_format,
    			int video_encoder, int Video_width, int Video_height, int Video_rate) {
    		MediaCamera.front_output_format = output_format;
    		MediaCamera.front_Video_width = Video_width;
    		MediaCamera.front_Video_height = Video_height;
    		MediaCamera.front_output_format = output_format;
    		MediaCamera.front_Video_rate = Video_rate;
    
    	}
    
    	/**
    	 * 设置相片保存路径
    	 * 
    	 * @param defaultFilePath
    	 *            路径 example: "/mnt/sdcard/Pictures/"
    	 */
    	public static void setDefaultImagePath(String defaultFilePath) {
    		DefaultImagePath = defaultFilePath;
    	}
    
    	/**
    	 * 设置相片名称
    	 * 
    	 * @param defaultFilePath
    	 */
    	public static void setDefaultImageName(String defaultFileName) {
    		DefaultImageName = defaultFileName;
    	}
    
    	/**
    	 * 设置视频保存路径
    	 * 
    	 * @param defaultFilePath
    	 *            路径 example: "/mnt/sdcard/Pictures/"
    	 */
    	public static void setDefaultVedioPath(String defaultFilePath) {
    		DefaultVedioPath = defaultFilePath;
    	}
    
    	/**
    	 * 设置视频名称
    	 * 
    	 * @param defaultFilePath
    	 */
    	public static void setDefaultVedioName(String defaultFileName) {
    		DefaultVedioName = defaultFileName;
    	}
    
    	/**
    	 * 開始录像方法
    	 * */
    	public void startRecording() {
    		camera.unlock();
    		mediarecorder = new MediaRecorder();
    		setRecordParameters(cameraPosition);
    		try {
    			mediarecorder.prepare();
    			mediarecorder.start();
    		} catch (IllegalStateException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		isRecording = true;
    
    	}
    
    	/**
    	 * 停止录像方法
    	 * */
    	public void stopRecording() {
    		if (mediarecorder != null) {
    			mediarecorder.stop();
    			mediarecorder.release();
    			mediarecorder = null;
    		}
    	}
    
    	/**
    	 * SurfaceHolderCallback 重写
    	 * **/
    	Callback surfaceHolderCallback = new Callback() {
    
    		@Override
    		public void surfaceDestroyed(SurfaceHolder arg0) {
    			surfaceView = null;
    			surfaceHolder = null;
    			releaseCamera();
    		}
    
    		@Override
    		public void surfaceCreated(SurfaceHolder arg0) {
    			OpenCamera();
    			camera.startPreview();
    		}
    
    		@Override
    		public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
    				int arg3) {
    			// setCameraParameters(camera);
    			camera.startPreview();
    
    		}
    	};
    
    	private void releaseCamera() {
    		if (camera != null) {
    			camera.setPreviewCallback(null);
    			camera.stopPreview();
    			camera.release();
    			camera = null;
    		}
    	}
    }
    

    使用时依照下面步骤调用就能够了:

    1.Activity中布局SurfaceView.用于预览.
    2.调用MediaCamera静态检測方法对设备检測.
    3.对MediaCamera中前后置摄像头相关參数进行设定.
    /* 拍照參数 */MediaCamera.setDefaultImagePath( );
    MediaCamera.initCameraParameters_back( );
    MediaCamera.initCameraParameters_front( );
    /* 摄像參数 */
    MediaCamera.setDefaultVedioPath( );
    MediaCamera.initRecordParameters_back( );
    MediaCamera.initRecordParameters_front( );
    4. new MediaCamera()传入SurfaceView.
    5. takePhoto()拍照
    6. startRecording();
    stopRecording();
    可通过isRecording标记推断拍摄是否完毕


    资源已上传CSDN 地址:点此下载


    欢迎拍砖指点,转载请注明出处,谢谢

  • 相关阅读:
    AVLTree的实现以及左右旋转维持自平衡
    哈希函数之布隆过滤器
    LeetCode——线段树解决区间总和问题
    第23章 Windows身份验证
    第22章 使用外部身份提供商登录
    第21章 登录
    第20章 定义客户端
    第19章 定义资源
    第18章 启动
    第17章 社区快速入门和模板
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3833751.html
Copyright © 2011-2022 走看看