個人封裝的一個Camera類

本文轉自:http://blog.csdn.net/wz331956750/article/details/24291479

好久不寫博客了,代碼寫了不少,但大多數都是拿來主義,要不是網上,要不就是自己以前的代碼拼裝。

新工作是搞Android開發的,最近任務要求我封裝一個Carmera類,自己也覺得還是封裝以後方便使用,弄了半天寫好一個,可以調用手機前置後置攝像頭進行拍照攝像,並可以根據設置相機各種參數,進行保存。發到這裏分享下。


  1. package com.hourglass.camerademo;  
  2.   
  3. import java.io.BufferedOutputStream;  
  4. import java.io.File;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.util.List;  
  8.   
  9. import android.content.Context;  
  10. import android.content.pm.PackageManager;  
  11. import android.graphics.Bitmap;  
  12. import android.graphics.Bitmap.CompressFormat;  
  13. import android.graphics.BitmapFactory;  
  14. import android.graphics.Matrix;  
  15. import android.hardware.Camera;  
  16. import android.hardware.Camera.CameraInfo;  
  17. import android.hardware.Camera.PictureCallback;  
  18. import android.hardware.Camera.Size;  
  19. import android.media.MediaRecorder;  
  20. import android.os.Build;  
  21. import android.os.Environment;  
  22. import android.os.StatFs;  
  23. import android.util.Log;  
  24. import android.view.SurfaceHolder;  
  25. import android.view.SurfaceHolder.Callback;  
  26. import android.view.SurfaceView;  
  27.   
  28. /** 
  29.  * 拍照錄像封裝類 
  30.  *  
  31.  * @author Hourglass 2014年4月21日 Q331956750 
  32.  * @version 1.2 
  33.  */  
  34. public class MediaCamera {  
  35.     private static int cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;  
  36.   
  37.     private static String tag = "MediaCamera---------------------";  
  38.   
  39.     private static int back_PictureWidth;  
  40.     private static int back_PictureHeight;  
  41.     private static int back_PreviewWidth;  
  42.     private static int back_PreviewHeight;  
  43.     private static int back_degrees;  
  44.     private static String back_FocusMode;  
  45.     private static int back_pixel_format;  
  46.   
  47.     private static int front_PictureWidth;  
  48.     private static int front_PictureHeight;  
  49.     private static int front_PreviewWidth;  
  50.     private static int front_PreviewHeight;  
  51.     private static int front_degrees;  
  52.     private static String front_FocusMode;  
  53.     private static int front_pixel_format;  
  54.   
  55.     private static int back_output_format;  
  56.     private static int back_video_encoder;  
  57.     private static int back_Video_width;  
  58.     private static int back_Video_height;  
  59.     private static int back_Video_rate;  
  60.   
  61.     private static int front_output_format;  
  62.     private static int front_video_encoder;  
  63.     private static int front_Video_width;  
  64.     private static int front_Video_height;  
  65.     private static int front_Video_rate;  
  66.   
  67.     private Bitmap mBitmap = null;  
  68.   
  69.     private MediaRecorder mediarecorder;  
  70.     public boolean isRecording;  
  71.   
  72.     private static String DefaultImagePath = Environment  
  73.             .getExternalStorageDirectory().getPath() + "/Pictures/";  
  74.     private static String DefaultImageName = "Image";  
  75.     private static String DefaultVedioPath = Environment  
  76.             .getExternalStorageDirectory().getPath() + "/Pictures/";  
  77.     private static String DefaultVedioName = "Video";  
  78.   
  79.     private Camera camera = null;  
  80.     private SurfaceView surfaceView = null;  
  81.     private SurfaceHolder surfaceHolder = null;  
  82.   
  83.     public MediaCamera(SurfaceView surfaceView) {  
  84.         super();  
  85.         this.surfaceView = surfaceView;  
  86.         surfaceHolder = surfaceView.getHolder();  
  87.         surfaceHolder.addCallback(surfaceHolderCallback);  
  88.         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)  
  89.             surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
  90.     }  
  91.   
  92.     /******************************* 靜態檢測類 ********************************************/  
  93.     /** 
  94.      * 檢測設備是否有攝像頭 
  95.      *  
  96.      * @param context 
  97.      *            運行上下文 
  98.      * @return 若有攝像頭 返回true 若無返回false 
  99.      */  
  100.     public static boolean checkCameraHardware(Context context) {  
  101.         return context.getPackageManager().hasSystemFeature(  
  102.                 PackageManager.FEATURE_CAMERA) ? true : false;  
  103.     }  
  104.   
  105.     /** 
  106.      * 檢測設備SD卡狀態 
  107.      *  
  108.      * @return 正常返回true 不正常返回false 
  109.      */  
  110.     public static boolean checkDeviceSDEnable() {  
  111.         return android.os.Environment.getExternalStorageState().equals(  
  112.                 android.os.Environment.MEDIA_MOUNTED) ? true : false;  
  113.     }  
  114.   
  115.     /** 
  116.      * 檢測設備SD卡剩餘空間 
  117.      *  
  118.      * @return 單位MB 
  119.      */  
  120.     public static long getSDFreeSize() {  
  121.         // 取得SD卡文件路徑  
  122.         File path = Environment.getExternalStorageDirectory();  
  123.         StatFs sf = new StatFs(path.getPath());  
  124.         // 獲取單個數據塊的大小(Byte)  
  125.         long blockSize = sf.getBlockSize();  
  126.         // 空閒的數據塊的數量  
  127.         long freeBlocks = sf.getAvailableBlocks();  
  128.         // 返回SD卡空閒大小  
  129.         // return freeBlocks * blockSize; //單位Byte  
  130.         // return (freeBlocks * blockSize)/1024; //單位KB  
  131.         return (freeBlocks * blockSize) / 1024 / 1024// 單位MB  
  132.     }  
  133.   
  134.     /** 
  135.      * 檢測設備SD卡總容量 
  136.      *  
  137.      * @return 單位MB 
  138.      */  
  139.     public static long getSDAllSize() {  
  140.         // 取得SD卡文件路徑  
  141.         File path = Environment.getExternalStorageDirectory();  
  142.         StatFs sf = new StatFs(path.getPath());  
  143.         // 獲取單個數據塊的大小(Byte)  
  144.         long blockSize = sf.getBlockSize();  
  145.         // 獲取所有數據塊數  
  146.         long allBlocks = sf.getBlockCount();  
  147.         // 返回SD卡大小  
  148.         // return allBlocks * blockSize; //單位Byte  
  149.         // return (allBlocks * blockSize)/1024; //單位KB  
  150.         return (allBlocks * blockSize) / 1024 / 1024// 單位MB  
  151.     }  
  152.   
  153.     /******************************* 靜態檢測類結束 ********************************************/  
  154.     /** 
  155.      * 打開或切換前後攝像頭 
  156.      */  
  157.     public void OpenCamera() {  
  158.         int cameraCount = 0;  
  159.         CameraInfo cameraInfo = new CameraInfo();  
  160.         cameraCount = Camera.getNumberOfCameras();  
  161.         for (int i = 0; i < cameraCount; i++) {  
  162.             Camera.getCameraInfo(i, cameraInfo);  
  163.             releaseCamera();  
  164.             if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT) {  
  165.                 // 現在是後置,變更爲前置  
  166.                 cameraPosition = Camera.CameraInfo.CAMERA_FACING_BACK;  
  167.                 try {  
  168.                     camera = Camera.open(cameraPosition);  
  169.                     camera.setPreviewDisplay(surfaceHolder);  
  170.                 } catch (Exception e) {  
  171.                     Log.d(tag, "前置相機無法打開或正在被佔用");  
  172.                 }  
  173.                 try {  
  174.                     setCameraParameters(camera, 1);  
  175.                 } catch (Exception e) {  
  176.                     e.printStackTrace();  
  177.                     Log.d(tag, "前置相機無法設置參數");  
  178.                 }  
  179.                 camera.startPreview();  
  180.                 break;  
  181.             } else {  
  182.                 // 現在是前置, 變更爲後置  
  183.                 cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;  
  184.                 try {  
  185.                     camera = Camera.open(cameraPosition);  
  186.                     camera.setPreviewDisplay(surfaceHolder);  
  187.                 } catch (Exception e) {  
  188.                     Log.d(tag, "後置相機無法打開或正在被佔用");  
  189.                 }  
  190.                 try {  
  191.                     setCameraParameters(camera, 0);  
  192.                 } catch (Exception e) {  
  193.                     e.printStackTrace();  
  194.                     Log.d(tag, "前置相機無法設置參數");  
  195.                 }  
  196.                 camera.startPreview();  
  197.                 break;  
  198.             }  
  199.         }  
  200.     }  
  201.   
  202.     /** 
  203.      * Camera拍照 
  204.      *  
  205.      * @param Suffix 
  206.      *            生成JPEG 0 生成PNG 1 
  207.      */  
  208.     public void takePhoto(int Suffix) {  
  209.         if (camera != null) {  
  210.             try {  
  211.                 if (Suffix == 0)  
  212.                     camera.takePicture(nullnull, JpegCallback);  
  213.                 else  
  214.                     camera.takePicture(nullnull, PngCallback);  
  215.             } catch (Exception e) {  
  216.                 e.printStackTrace();  
  217.             }  
  218.         }  
  219.         camera.startPreview();  
  220.     }  
  221.   
  222.     /** 
  223.      * JPEG回調方法 
  224.      * **/  
  225.     private PictureCallback JpegCallback = new PictureCallback() {  
  226.         public void onPictureTaken(byte[] data, Camera camera) {  
  227.             if (null != data) {  
  228.                 mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);  
  229.   
  230.             }  
  231.             Matrix matrix = new Matrix();  
  232.             matrix.postRotate((float0.0);  
  233.             Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 00,  
  234.                     mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);  
  235.             if (null != rotaBitmap) {  
  236.                 savePicture(rotaBitmap, DefaultImagePath,  
  237.                         Bitmap.CompressFormat.JPEG, DefaultImageName, ".jpeg");  
  238.             }  
  239.         }  
  240.     };  
  241.     /** 
  242.      * Png回調方法 
  243.      * **/  
  244.     private PictureCallback PngCallback = new PictureCallback() {  
  245.         public void onPictureTaken(byte[] data, Camera camera) {  
  246.             if (null != data) {  
  247.                 mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);  
  248.             }  
  249.             Matrix matrix = new Matrix();  
  250.             matrix.postRotate((float0.0);  
  251.             Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 00,  
  252.                     mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);  
  253.             if (null != rotaBitmap) {  
  254.                 savePicture(rotaBitmap, DefaultImagePath,  
  255.                         Bitmap.CompressFormat.PNG, DefaultImageName, ".png");  
  256.             }  
  257.         }  
  258.     };  
  259.   
  260.     /** 
  261.      * 保存Bitmap 
  262.      *  
  263.      * @param bitmap 
  264.      * @param savePath 
  265.      * @param format 
  266.      *            編碼格式 
  267.      * @param filename 
  268.      *            文件名 Null則按照當前毫秒命名 
  269.      * @param suffix 
  270.      *            後綴名 
  271.      */  
  272.     private void savePicture(Bitmap bitmap, String savePath,  
  273.             CompressFormat format, String filename, String suffix) {  
  274.         File folder = new File(savePath);  
  275.         if (!folder.exists()) {  
  276.             folder.mkdir();  
  277.         }  
  278.         String jpegName;  
  279.         if (filename == null || filename.length() == 0)  
  280.             jpegName = savePath + System.currentTimeMillis() + suffix;  
  281.         else {  
  282.             jpegName = savePath + filename + suffix;  
  283.         }  
  284.         try {  
  285.             FileOutputStream fout = new FileOutputStream(jpegName);  
  286.             BufferedOutputStream bos = new BufferedOutputStream(fout);  
  287.   
  288.             bitmap.compress(format, 100, bos);  
  289.             bos.flush();  
  290.             bos.close();  
  291.         } catch (IOException e) {  
  292.             e.printStackTrace();  
  293.         }  
  294.     }  
  295.   
  296.     private void setCameraParameters(Camera myCamera, int type) {  
  297.         if (null != myCamera) {  
  298.             Camera.Parameters myParam = myCamera.getParameters();  
  299.   
  300.             if (type == 1) {  
  301.                 myParam.setPictureFormat(back_pixel_format);  
  302.                 myParam.setPictureSize(back_PictureWidth,  
  303.                         back_PictureHeight);  
  304.                 myParam.setPreviewSize(back_PreviewWidth,  
  305.                         back_PreviewHeight);  
  306.                 myCamera.setDisplayOrientation(back_degrees);  
  307.                 myParam.setFocusMode(back_FocusMode);  
  308.             } else {  
  309.                 myParam.setPictureFormat(front_pixel_format);  
  310.                 myParam.setPictureSize(front_PictureWidth, front_PictureHeight);  
  311.                 myParam.setPreviewSize(front_PreviewWidth, front_PreviewHeight);  
  312.                 myCamera.setDisplayOrientation(front_degrees);  
  313.                 myParam.setFocusMode(front_FocusMode);  
  314.             }  
  315.   
  316.             myCamera.setParameters(myParam);  
  317.         }  
  318.     }  
  319.   
  320.     private void setRecordParameters(int type) {  
  321.         mediarecorder.setCamera(camera);  
  322.         mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);  
  323.         if (type == 0) {  
  324.             mediarecorder.setOutputFormat(back_output_format);  
  325.             mediarecorder.setVideoEncoder(back_video_encoder);  
  326.             mediarecorder.setVideoFrameRate(back_Video_rate);  
  327.             mediarecorder.setVideoSize(back_Video_width, back_Video_height);  
  328.         } else {  
  329.             mediarecorder.setOutputFormat(front_output_format);  
  330.             mediarecorder.setVideoEncoder(front_video_encoder);  
  331.             mediarecorder.setVideoFrameRate(front_Video_rate);  
  332.             mediarecorder.setVideoSize(front_Video_width, front_Video_height);  
  333.         }  
  334.         mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());  
  335.         if (front_output_format == MediaRecorder.OutputFormat.MPEG_4)  
  336.             mediarecorder.setOutputFile(DefaultVedioPath + DefaultVedioName  
  337.                     + ".mp4");  
  338.         else if (front_output_format == MediaRecorder.OutputFormat.THREE_GPP)  
  339.             mediarecorder.setOutputFile(DefaultVedioPath + DefaultVedioName  
  340.                     + ".3gp");  
  341.         else  
  342.             new Exception("不支持的生成視頻格式");  
  343.     }  
  344.   
  345.     /** 
  346.      * 初始化相機參數方法(後置) 
  347.      *  
  348.      * @param myCamera 
  349.      *            Camera實例 
  350.      * @param pixel_format 
  351.      *            設置拍照後存儲的圖片格式 
  352.      * @param PictureWidth 
  353.      *            存儲的圖片像素X 
  354.      * @param PictureHeight 
  355.      *            存儲的圖片像素Y 
  356.      * @param PreviewWidth 
  357.      *            顯示寬度X 
  358.      * @param PreviewHeight 
  359.      *            顯示高度Y 
  360.      * @param degrees 
  361.      *            旋轉角度 
  362.      * @param FocusMode 
  363.      *            調焦方式 
  364.      */  
  365.     public static void initCameraParameters_back(int pixel_format,  
  366.             int PictureWidth, int PictureHeight, int PreviewWidth,  
  367.             int PreviewHeight, int degrees, String FocusMode) {  
  368.         MediaCamera.back_pixel_format = pixel_format;  
  369.         MediaCamera.back_PictureWidth = PictureWidth;  
  370.         MediaCamera.back_PictureHeight = PictureHeight;  
  371.         MediaCamera.back_PreviewWidth = PreviewWidth;  
  372.         MediaCamera.back_PreviewHeight = PreviewHeight;  
  373.         MediaCamera.back_degrees = degrees;  
  374.         MediaCamera.back_FocusMode = FocusMode;  
  375.     }  
  376.   
  377.     /** 
  378.      * 初始化相機參數方法(前置) 
  379.      *  
  380.      * @param myCamera 
  381.      *            Camera實例 
  382.      * @param pixel_format 
  383.      *            設置拍照後存儲的圖片格式 
  384.      * @param PictureWidth 
  385.      *            存儲的圖片像素X 
  386.      * @param PictureHeight 
  387.      *            存儲的圖片像素Y 
  388.      * @param PreviewWidth 
  389.      *            顯示寬度X 
  390.      * @param PreviewHeight 
  391.      *            顯示高度Y 
  392.      * @param degrees 
  393.      *            旋轉角度 
  394.      * @param FocusMode 
  395.      *            調焦方式 
  396.      */  
  397.     public static void initCameraParameters_front(int pixel_format,  
  398.             int PictureWidth, int PictureHeight, int PreviewWidth,  
  399.             int PreviewHeight, int degrees, String FocusMode) {  
  400.         MediaCamera.front_pixel_format = pixel_format;  
  401.         MediaCamera.front_PictureWidth = PictureWidth;  
  402.         MediaCamera.front_PictureHeight = PictureHeight;  
  403.         MediaCamera.front_PreviewWidth = PreviewWidth;  
  404.         MediaCamera.front_PreviewHeight = PreviewHeight;  
  405.         MediaCamera.front_degrees = degrees;  
  406.         MediaCamera.front_FocusMode = FocusMode;  
  407.     }  
  408.   
  409.     /** 
  410.      * 初始化相機攝像參數方法(後置) 
  411.      *  
  412.      * @param surfaceView 
  413.      * @param output_format 
  414.      *            視頻的封裝格式MediaRecorder.OutputFormat THREE_GPP爲3gp.MPEG_4爲mp4 
  415.      * @param video_encoder 
  416.      *            視頻編碼MediaRecorder.VideoEncoder h263 h264 
  417.      * @param width 
  418.      *            分辨率width 
  419.      * @param height 
  420.      *            分辨率height 
  421.      * @param rate 
  422.      *            視頻的碼率 
  423.      * @param path 
  424.      *            文件輸出的路徑 
  425.      */  
  426.     public static void initRecordParameters_back(int output_format,  
  427.             int video_encoder, int Video_width, int Video_height, int Video_rate) {  
  428.         MediaCamera.back_output_format = output_format;  
  429.         MediaCamera.back_Video_width = Video_width;  
  430.         MediaCamera.back_Video_height = Video_height;  
  431.         MediaCamera.back_output_format = output_format;  
  432.         MediaCamera.back_Video_rate = Video_rate;  
  433.   
  434.     }  
  435.   
  436.     /** 
  437.      * 初始化相機攝像參數方法(前置) 
  438.      *  
  439.      * @param surfaceView 
  440.      * @param back_output_format 
  441.      *            視頻的封裝格式MediaRecorder.OutputFormat THREE_GPP爲3gp.MPEG_4爲mp4 
  442.      * @param back_video_encoder 
  443.      *            視頻編碼MediaRecorder.VideoEncoder h263 h264 
  444.      * @param width 
  445.      *            分辨率width 
  446.      * @param height 
  447.      *            分辨率height 
  448.      * @param rate 
  449.      *            視頻的碼率 
  450.      * @param path 
  451.      *            文件輸出的路徑 
  452.      */  
  453.     public static void initRecordParameters_front(int output_format,  
  454.             int video_encoder, int Video_width, int Video_height, int Video_rate) {  
  455.         MediaCamera.front_output_format = output_format;  
  456.         MediaCamera.front_Video_width = Video_width;  
  457.         MediaCamera.front_Video_height = Video_height;  
  458.         MediaCamera.front_output_format = output_format;  
  459.         MediaCamera.front_Video_rate = Video_rate;  
  460.   
  461.     }  
  462.   
  463.     /** 
  464.      * 設置相片保存路徑 
  465.      *  
  466.      * @param defaultFilePath 
  467.      *            路徑 example: "/mnt/sdcard/Pictures/" 
  468.      */  
  469.     public static void setDefaultImagePath(String defaultFilePath) {  
  470.         DefaultImagePath = defaultFilePath;  
  471.     }  
  472.   
  473.     /** 
  474.      * 設置相片名稱 
  475.      *  
  476.      * @param defaultFilePath 
  477.      */  
  478.     public static void setDefaultImageName(String defaultFileName) {  
  479.         DefaultImageName = defaultFileName;  
  480.     }  
  481.   
  482.     /** 
  483.      * 設置視頻保存路徑 
  484.      *  
  485.      * @param defaultFilePath 
  486.      *            路徑 example: "/mnt/sdcard/Pictures/" 
  487.      */  
  488.     public static void setDefaultVedioPath(String defaultFilePath) {  
  489.         DefaultVedioPath = defaultFilePath;  
  490.     }  
  491.   
  492.     /** 
  493.      * 設置視頻名稱 
  494.      *  
  495.      * @param defaultFilePath 
  496.      */  
  497.     public static void setDefaultVedioName(String defaultFileName) {  
  498.         DefaultVedioName = defaultFileName;  
  499.     }  
  500.   
  501.     /** 
  502.      * 開始錄像方法 
  503.      * */  
  504.     public void startRecording() {  
  505.         camera.unlock();  
  506.         mediarecorder = new MediaRecorder();  
  507.         setRecordParameters(cameraPosition);  
  508.         try {  
  509.             mediarecorder.prepare();  
  510.             mediarecorder.start();  
  511.         } catch (IllegalStateException e) {  
  512.             e.printStackTrace();  
  513.         } catch (IOException e) {  
  514.             e.printStackTrace();  
  515.         }  
  516.         isRecording = true;  
  517.   
  518.     }  
  519.   
  520.     /** 
  521.      * 停止錄像方法 
  522.      * */  
  523.     public void stopRecording() {  
  524.         if (mediarecorder != null) {  
  525.             mediarecorder.stop();  
  526.             mediarecorder.release();  
  527.             mediarecorder = null;  
  528.         }  
  529.     }  
  530.   
  531.     /** 
  532.      * SurfaceHolderCallback 重寫 
  533.      * **/  
  534.     Callback surfaceHolderCallback = new Callback() {  
  535.   
  536.         @Override  
  537.         public void surfaceDestroyed(SurfaceHolder arg0) {  
  538.             surfaceView = null;  
  539.             surfaceHolder = null;  
  540.             releaseCamera();  
  541.         }  
  542.   
  543.         @Override  
  544.         public void surfaceCreated(SurfaceHolder arg0) {  
  545.             OpenCamera();  
  546.             camera.startPreview();  
  547.         }  
  548.   
  549.         @Override  
  550.         public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,  
  551.                 int arg3) {  
  552.             // setCameraParameters(camera);  
  553.             camera.startPreview();  
  554.   
  555.         }  
  556.     };  
  557.   
  558.     private void releaseCamera() {  
  559.         if (camera != null) {  
  560.             camera.setPreviewCallback(null);  
  561.             camera.stopPreview();  
  562.             camera.release();  
  563.             camera = null;  
  564.         }  
  565.     }  
  566. }  

使用時按照以下步驟調用就可以了:

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標記判斷拍攝是否完成


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章