本文轉自:http://blog.csdn.net/wz331956750/article/details/24291479
好久不寫博客了,代碼寫了不少,但大多數都是拿來主義,要不是網上,要不就是自己以前的代碼拼裝。
新工作是搞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;
- }
- }
- }
使用時按照以下步驟調用就可以了: