亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【Android Developers Training】 50. 控制相機

系統 1824 0

注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。

原文鏈接: http://developer.android.com/training/camera/cameradirect.html


在這節課中,我們討論如何直接通過框架內的API來控制相機硬件。

直接控制一個相機硬件需要的代碼,比通過已存在的相機應用拍攝照片和視頻所需要的代碼要多。然而,如果你希望構建一個特制的相機應用,或者需要將一些東西整合入你的應用界面,那么這節課將會教授你如何去做。


一). 打開一個相機對象

要直接控制相機,首先應當獲得一個相機( Camera )對象的實例。就像Android自己的相機應用所做的,推薦的訪問相機的方法是在 onCreate() 方法中,通過一個獨立的線程來啟動。這個方法的優點在于訪問相機需要一定的時間,這就導致如果在UI線程例訪問相機,可能會造成UI停滯。在一個更加基本的實現中,打開一個相機可以推遲到 onResume() 方法中,使得代碼重用更加方便,同時還能讓控制流更加簡潔。

調用 Camera.open() 后,如果相機已經再被另一個應用使用,那么會拋出一個異常,我們可以在try塊中捕獲它。

      
        private
      
      
        boolean
      
       safeCameraOpen(
      
        int
      
      
         id) {

    
      
      
        boolean
      
       qOpened = 
      
        false
      
      
        ;

  

    
      
      
        try
      
      
         {

        releaseCameraAndPreview();

        mCamera 
      
      =
      
         Camera.open(id);

        qOpened 
      
      = (mCamera != 
      
        null
      
      
        );

    } 
      
      
        catch
      
      
         (Exception e) {

        Log.e(getString(R.string.app_name), 
      
      "failed to open Camera"
      
        );

        e.printStackTrace();

    }



    
      
      
        return
      
      
         qOpened;    

}




      
      
        private
      
      
        void
      
      
         releaseCameraAndPreview() {

    mPreview.setCamera(
      
      
        null
      
      
        );

    
      
      
        if
      
       (mCamera != 
      
        null
      
      
        ) {

        mCamera.release();

        mCamera 
      
      = 
      
        null
      
      
        ;

    }

}
      
    

從API Level 9之后,相機框架能夠支持多個相機。如果你使用過去的API,并且調用了無傳遞參數的 open() 方法,你會得到第一個后置攝像頭。


二). 創建相機預覽

拍攝照片通常需要讓你的用戶可以在按下快門鍵之前看見一個實時預覽界面。要這樣做,一可以使用 SurfaceView 來繪制相機預覽,顯示傳感器元件捕捉到的實時畫面。

Preview類

要開始顯示一個相機預覽,你需要Preview類。它需要實現 android.view.SurfaceHolder.Callback 接口,用來將圖像數據從相機硬件傳遞給應用。

      
        class
      
       Preview 
      
        extends
      
       ViewGroup 
      
        implements
      
      
         SurfaceHolder.Callback {



    SurfaceView mSurfaceView;

    SurfaceHolder mHolder;



    Preview(Context context) {

        
      
      
        super
      
      
        (context);



        mSurfaceView 
      
      = 
      
        new
      
      
         SurfaceView(context);

        addView(mSurfaceView);



        
      
      
        //
      
      
         Install a SurfaceHolder.Callback so we get notified when the

        
      
      
        //
      
      
         underlying surface is created and destroyed.
      
      

        mHolder =
      
         mSurfaceView.getHolder();

        mHolder.addCallback(
      
      
        this
      
      
        );

        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

...

}
      
    

Preview類必須在激活的相機預覽啟動之前傳遞給 Camera 對象,這方面知識將在下一節展開。

設置并啟動預覽

一個相機實例和與它相關聯的相機預覽必須以一個特定的順序創建,相機對象在先。在下面的代碼片段中,初始化相機的操作已經封裝好了,所以我們可以看到 Camera.startPreview() setCamera() 方法中被調用,不管何時用戶做了什么事情來改變當前激活的攝像頭。預覽界面必須在preview類中的 surfaceChanged()回調函數中重新啟動。

      
        public
      
      
        void
      
      
         setCamera(Camera camera) {

    
      
      
        if
      
       (mCamera == camera) { 
      
        return
      
      
        ; }

    

    stopPreviewAndFreeCamera();

    

    mCamera 
      
      =
      
         camera;

    

    
      
      
        if
      
       (mCamera != 
      
        null
      
      
        ) {

        List
      
      <Size> localSizes =
      
         mCamera.getParameters().getSupportedPreviewSizes();

        mSupportedPreviewSizes 
      
      =
      
         localSizes;

        requestLayout();

      

        
      
      
        try
      
      
         {

            mCamera.setPreviewDisplay(mHolder);

        } 
      
      
        catch
      
      
         (IOException e) {

            e.printStackTrace();

        }

      

        
      
      
        //
      
      
         Important: Call startPreview() to start updating the preview

        
      
      
        //
      
      
         surface. Preview must be started before you can take a picture.
      
      
                mCamera.startPreview();

    }

}
      
    

三). 修改相機設置

相機設置改變相機拍攝照片的方式,相機設置從變焦到曝光補償等等。下面的例子值修改了預覽的尺寸,可以通過閱讀相機源碼來學習更多其他的設置。

      
        public
      
      
        void
      
       surfaceChanged(SurfaceHolder holder, 
      
        int
      
       format, 
      
        int
      
       w, 
      
        int
      
      
         h) {

    
      
      
        //
      
      
         Now that the size is known, set up the camera parameters and begin

    
      
      
        //
      
      
         the preview.
      
      

    Camera.Parameters parameters =
      
         mCamera.getParameters();

    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

    requestLayout();

    mCamera.setParameters(parameters);



    
      
      
        //
      
      
         Important: Call startPreview() to start updating the preview surface.

    
      
      
        //
      
      
         Preview must be started before you can take a picture.
      
      
            mCamera.startPreview();

}
      
    

四). 設置預覽方向

大多數相機應用會將顯示鎖定在橫屏模式,因為那是攝像頭的自然方向。但這不會令你無法拍攝豎屏模式的照片,因為設備的方向會被記錄在EXIF頭中。 setCameraDisplayOrientation() 方法可以讓你再不影響照片是如何拍攝的情況下改變預覽的方向。然而,在Android API Level 14之前,你必須在改變方向之前停止你的相機預覽,然后重新啟動它。


五). 拍攝照片

一旦相機預覽啟動了,就可以通過 Camera.takePicture() 方法來拍攝照片。你可以創建 Camera.PictureCallback Camera.ShutterCallback 對象,并將它們傳遞給 Camera.takePicture()

如果你希望連續抓拍圖像,你可以創建一個實現了 onPreviewFrame() Camera.PreviewCallback 。在這兩件事情之間,你可以值捕獲選中的預覽框,或者設置一個調用 takePicture() 的延遲。


六). 重啟相機預覽

當一個照片拍好后,你必須在用戶拍攝另一張照片之前重啟相機預覽。在下面的例子中,通過重載快門按鈕,實現了重啟的操作:

      
        @Override


      
      
        public
      
      
        void
      
      
         onClick(View v) {

    
      
      
        switch
      
      
        (mPreviewState) {

    
      
      
        case
      
      
         K_STATE_FROZEN:

        mCamera.startPreview();

        mPreviewState 
      
      =
      
         K_STATE_PREVIEW;

        
      
      
        break
      
      
        ;



    
      
      
        default
      
      
        :

        mCamera.takePicture( 
      
      
        null
      
      , rawCallback, 
      
        null
      
      
        );

        mPreviewState 
      
      =
      
         K_STATE_BUSY;

    } 
      
      
        //
      
      
         switch
      
      
            shutterBtnConfig();

}
      
    

七). 停止相機預覽并且釋放相機

一旦你的應用完成了相機的拍攝,那么久到了釋放資源的時間了。尤其要注意的是你要釋放相機對象,不然的話你可能會導致其它應用的崩潰,這也包括你自己的應用。

那么什么時候應該停止預覽并釋放相機呢?當你的預覽Surface被銷毀時,那么這是一個信號,你需要停止預覽并釋放相機,見下面的例子,這些方法都來自Preview類:

      
        public
      
      
        void
      
      
         surfaceDestroyed(SurfaceHolder holder) {

    
      
      
        //
      
      
         Surface will be destroyed when we return, so stop the preview.
      
      
        if
      
       (mCamera != 
      
        null
      
      
        ) {

        
      
      
        //
      
      
         Call stopPreview() to stop updating the preview surface.
      
      
                mCamera.stopPreview();

    }

}




      
      
        /**
      
      
        

 * When this function returns, mCamera will be null.

 
      
      
        */
      
      
        private
      
      
        void
      
      
         stopPreviewAndFreeCamera() {



    
      
      
        if
      
       (mCamera != 
      
        null
      
      
        ) {

        
      
      
        //
      
      
         Call stopPreview() to stop updating the preview surface.
      
      
                mCamera.stopPreview();

    

        
      
      
        //
      
      
         Important: Call release() to release the camera for use by other

        
      
      
        //
      
      
         applications. Applications should release the camera immediately

        
      
      
        //
      
      
         during onPause() and re-open() it during onResume()).
      
      
                mCamera.release();

    

        mCamera 
      
      = 
      
        null
      
      
        ;

    }

}
      
    

中這堂課的前半部分,上述步驟也是“ setCamera() ”方法的一部分,所以初始化一個相機一般都始于停止相機預覽。

【Android Developers Training】 50. 控制相機


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲狠狠操 | 婷婷综合久久中文字幕一本 | 国产精品四虎视频一区 | 80岁色老头69av | 久久福利网 | 久久久久久天天夜夜天天 | 污视频在线看网站 | 国内自拍青青草 | 日韩性大片免费 | 国产大战女模特在线视频 | 在线亚洲欧洲国产综合444 | 久久精品国产福利国产秒 | 怡红院成人永久免费看 | 999久久狠狠免费精品 | 久久久久国产精品美女毛片 | 香蕉视频网站在线播放 | 97影院理伦片 | 全部免费国产潢色一级 | 伊人精品视频一区二区三区 | 欧美精品 在线播放 | 97婷婷狠狠成人免费视频 | 免费在线黄色网 | 久久中文娱乐网 | 日本在线色 | 经典日韩| 色婷婷精品 | 91中文| 久久国产精品久久久久久小说 | 激情五月色播 | 久久精品国产一区二区三区 | 欧美乱人免费视频观看 | 日本高清不卡在线观看 | 香蕉视频国产在线观看 | 久久免费观看国产99精品 | 久久国产亚洲高清观看5388 | 亚洲第一综合网站 | 亚欧免费视频 | 四虎在线播放 | 国产麻豆高清视频在线第一页 | 欧美日韩国产综合一区二区三区 | 99热久久国产综合精品久久国产 |