CameraAPI中的 自訂照相功能,cameraapi照相

來源:互聯網
上載者:User

CameraAPI中的 自訂照相功能,cameraapi照相

前幾天的項目需要使用CameraAPI自己定義照相機,之前用過的二維碼也要自己寫底層代碼,於是總結一下使用CameraAPI的幾點事項。現在由於JDK7.0及其以上版本的官方文檔已經不再推薦使用camera包而是camera2包,但這次還是先講camera的使用,至於camera2等以後再講。

首先是添加照相機許可權,在資訊清單檔中必須添加網路攝影機硬體許可權和使用功能,其中功能可以根據項目需求選擇性放入。

 1     <uses-permission android:name="android.permission.CAMERA"/> 2     <!--使用網路攝影機硬體功能--> 3     <uses-feature android:name="android.hardware.camera"/> 4     <!--自動對焦功能--> 5     <uses-feature android:name="android.hardware.camera.autofocus"/> 6     <!--閃光燈功能--> 7     <uses-feature android:name="android.hardware.camera.flash"/> 8     <!--自拍--> 9     <uses-feature android:name="android.hardware.camera.front"/>

關於許可權和對應的功能可以參考文章 http://www.cnblogs.com/BobGo/articles/5646751.html;

我在項目中需要兩個功能,一是在顯示網路攝影機的SurfaceView上添加一層ImageView,可以在ImageView上繪製不同的遮罩層;還有一個功能是網路攝影機拍攝照片之後顯示及儲存圖片。

第一是網路攝影機簡單的使用,在這裡可能會遇到在SurfaceView中網路攝影機的預覽出現變形問題,下面會提到解決措施:

1         SurfaceHolder surfaceHolder = surfaceView.getHolder();2         surfaceHolder.addCallback(this);3         surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

在當前類中實現SurfaceHolder.Callback 介面,重寫三個方法 surfaceCreated(), surfaceChanged(), surfaceDestroy(),這三個方法就是SurfaceView對應的生命週期;

surfaceCreated()中執行Camera.open()返回一個Camera對象,開啟網路攝影機硬體,在surfaceDestroy()中,Camera對象調用release()釋放網路攝影機;在surfaceChanged()中,設定網路攝影機參數,其中getBestSize()是確定手機網路攝影機硬體可以使用的最合適大小,這個演算法是官方提供的。我在之前不採用這個演算法而直接設定大小,導致在測試機運行時SurfaceView顯示的圖片出現變形。

 1 @Override 2     public void surfaceCreated(SurfaceHolder holder) { 3         camera = Camera.open(); 4     } 5  6     @Override 7     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 8         //已經獲得Surface的width和height,設定Camera的參數 9         Camera.Parameters parameters = camera.getParameters();10         Camera.Size size=getBestSize(parameters.getSupportedPreviewSizes());11         int w=size.width;12         int h=size.height;13         parameters.setPreviewSize(w, h);14         parameters.setPictureSize(w, h);15 //        List<Camera.Size> vSizeList = parameters.getSupportedPictureSizes();16 //        for (int num = 0; num < vSizeList.size(); num++) {17 //            Camera.Size vSize = vSizeList.get(num);18 //        }19 //        if (t?his.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {20             //強制豎屏模式21             parameters.set("orientation", "portrait");22             //在2.2以上可以使用,預覽顯示旋轉9023 //        parameters.setRotation(90);24             camera.setDisplayOrientation(90);25 //        } else {26 //            parameters.set("orientation", "landscape");27             //在2.2以上可以使用28 //            camera.setDisplayOrientation(90);29 //        }30         camera.setParameters(parameters);31         try {32             //設定顯示33             camera.setPreviewDisplay(holder);34         } catch (IOException exception) {35             camera.release();36             camera = null;37         }38         //開始預覽39         camera.startPreview();40         //設定自動對焦41         camera.autoFocus(new Camera.AutoFocusCallback() {42             @Override43             public void onAutoFocus(boolean success, Camera camera) {44                 if (success) {45                     // success為true表示對焦成功,改變對焦狀態映像46                 }47             }48         });49     }50 51     private Camera.Size getBestSize(List<Camera.Size> supportedPreviewSizes) {52         Camera.Size largestSize=supportedPreviewSizes.get(0);53         int largestArea= supportedPreviewSizes.get(0).height*supportedPreviewSizes.get(0).width;54         for (Camera.Size s:supportedPreviewSizes){55             int area=s.width*s.height;56             if(area>largestArea){57                 largestArea=area;58                 largestSize=s;59             }60         }61         return largestSize;62 63     }64 65     @Override66     public void surfaceDestroyed(SurfaceHolder holder) {67         // 釋放手機網路攝影機68         camera.release();69     }

 也可以在surfaceChanged()中設定閃光燈等功能:

1 parameters.setFlashMode(isChecked?Camera.Parameters.FLASH_MODE_ON:Camera.Parameters.FLASH_MODE_OFF);

最後在需要攝像的點擊監聽中調用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)函數來完成拍照,這個函數中可以四個回調介面,ShutterCallback是快門按下的回調,在這裡我們可以設定播放“哢嚓”聲之類的操作,後面有三個PictureCallback介面,分別對應三份映像資料:原始映像、縮放和壓縮映像和JPG映像,映像資料可以在PictureCallback介面的void onPictureTaken(byte[] data, Camera camera)中獲得,三份資料相應的三個回調正好按照參數順序調用,通常我們只關心JPG映像資料,此時前面兩個PictureCallback介面參數可以直接傳null

每次調用takePicture() 擷取映像後,網路攝影機會停止預覽,假如需要繼續拍照,則我們需要在上面的PictureCallbackonPictureTaken() 函數末尾,Camera對象再次調用startPreview() 函數;在不需要拍照的時候,Camera對象需要主動調用stopPreview() 停止預覽功能;

第二個功能是攝像圖片的顯示和儲存,在這個功能中可能會出現兩個問題,一個是拍攝圖片橫屏顯示,另一個是將上邊SurfaceView上方的ImageView遮罩層一同儲存到使用者手機,實作類別似於映像合成的效果;

關於圖片橫屏顯示的問題,是因為Android官方認為手機橫屏才是網路攝影機的正確開啟檔案,所以儲存的圖片也是橫屏儲存的,所以如果想豎屏顯示圖片,就要把圖片順時針旋轉90度,調整到豎屏顯示模式,具體代碼如下:

1 private void setImageByte(ImageView showImage, byte[] data) {2         Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length);3         showImage.setImageBitmap(bitmap);4         Matrix matrix = showImage.getImageMatrix();5         matrix.setRotate(90);6         showImage.setImageBitmap(Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true));7     }

還有一個問題是解決兩個控制項內容同時儲存的問題,這個其實想到了方法就很簡單了,自訂一個FrameLayout的子布局,在該布局中只加入一個方法

1     public Bitmap getBitmap(){2         //設定緩衝3         setDrawingCacheEnabled(true);4         buildDrawingCache();5         //從緩衝中擷取當前螢幕的圖片6         return getDrawingCache();7     }

然後在上文用到的xml布局中將該布局作為要同時儲存映像的父控制項。

最後在java代碼中需要儲存合成圖片的地方,只需要執行個體化剛剛自訂的FrameLayout對象調用getBitmap(),就能返回合成之後的Bitmap對象;

所以我們的功能就能完全實現了。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.