好久不写博客了,代码写了不少,但大多数都是拿来主义,要不是网上,要不就是自己曾经的代码拼装。
新工作是搞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 地址:点此下载
欢迎拍砖指点,转载请注明出处,谢谢