1. 程式人生 > >Android開發之控制相機

Android開發之控制相機

前言

如何通過使用Android框架所提供的API來直接控制相機硬體?

這篇部落格將會講解如何建立一個特殊的相機應用或將相機整合在我們的應用當中。

1.開啟相機物件

獲取一個 Camera 物件是直接控制相機的第一步。正如Android自帶的相機程式一樣,比較好的訪問相機的方式是在onCreate()方法裡面另起一個執行緒來開啟相機。這種辦法可以避免因為啟動時間較長導致UI執行緒被阻塞。另外還有一種更好的方法:可以把開啟相機的操作延遲到onResume()方法裡面去執行,這樣可以使得程式碼更容易重用,還能保持控制流程更為簡單。

如果我們在執行Camera.open()方法的時候相機正在被另外一個應用使用,那麼函式會丟擲一個Exception,我們可以利用try語句塊進行捕獲:

    private boolean safeCameraOpen(int id) {
        boolean qOpened = false;

        try {
            realeaseCameraAndPreview();
            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 realeaseCameraAndPreview() { mPreview.setCamera(null); if (mCamera != null) { mCamera.release(); mCamera = null; } }

自從API Level 9開始,相機框架可以支援多個相機。如果使用舊的API,在呼叫open()時不傳入引數 ,那麼我們會獲取後置攝像頭

2.建立相機預覽介面

拍照通常需要向用戶提供一個預覽介面來顯示待拍攝的事物。我們可以使用SurfaceView來展現照相機採集的影象。

2.1 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);
    }
...
}

2.2 設定和啟動Preview

一個Camera例項與它相關的Preview必須以特定的順序來建立,其中Camera物件首先被建立。在下面的示例中,初始化Camera的動作被封裝了起來,這樣,無論使用者想對Camera做什麼樣的改變,Camera.startPreview()都會被setCamera()呼叫。另外,Preview物件必須在surfaceChanged()這一回調方法裡面重新啟用(restart)。

        public void setCamera(Camera camera) {
            if (mCamera == camera)
                return;

            stopPreviewAndFreeCamera();

            mCamera = camera;

            if (mCamera != null) {
                List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
                mSupportedPreviewSize = localSizes;
                requestLayout();

                mCamera.setPreviewDisplay(mHolder);

                // Important: Call startPreview() to start updating the preview
                // surface. Preview must be started before you can take a picture.
                mCamera.startPreview();
            }
        }

3.修改相機設定

相機設定可以改變拍照的方式,從縮放級別到曝光補償等。下面的例子僅僅演示瞭如何改變預覽大小:

@Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            // 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();
        }

4.設定預覽方向

大多數相機程式會鎖定預覽為橫屏狀態,因為該方向是相機感測器的自然方向。當然這一設定並不會阻止我們去拍豎屏的照片,因為裝置的方向資訊會被記錄在EXIF頭中。setCameraDisplayOrientation()方法可以讓你在不影響照片拍攝過程的情況下,改變預覽的方向。然而,對於Android API Level 14及以下版本的系統,在改變方向之前,我們必須先停止預覽,然後再去重啟它。

5.拍攝照片

只要預覽開始之後,可以使用Camera.takePicture()方法拍攝照片。我們可以建立Camera.PictureCallback與Camera.ShutterCallback物件並將他們傳遞到Camera.takePicture()中。

如果我們想要進行連拍,可以建立一個Camera.PreviewCallback並實現onPreviewFrame()方法。我們可以拍攝選中的預覽幀,或是為呼叫takePicture()建立一個延遲。

6.重啟Preview

在拍攝好圖片後,我們必須在使用者拍下一張圖片之前重啟預覽。下面的示例使用快門按鈕來實現重啟。

    @Override
    public void onClick(View v) {
        switch (mPreviewState) {
        case K_STATE_FROZEN:
            mCamera.startPreview();
            mPreviewState = K_STATE_FROZEN;
            break;

        default:

            mCamera.takePicture(null, rawCallback, null);
            mPreviewState = K_STATE_BUSY;
            break;
        }
        shutterBtnConfig();
    }

7.停止預覽並釋放相機

當應用使用好相機後,我們有必要進行清理操作。特別地,我們必須釋放Camera物件,不然的話可能會引起其他應用崩潰,包括我們自己應用的新例項。

那麼何時應該停止預覽並釋放相機呢?在預覽的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;
    }
}

相關推薦

Android開發控制相機

前言 如何通過使用Android框架所提供的API來直接控制相機硬體? 這篇部落格將會講解如何建立一個特殊的相機應用或將相機整合在我們的應用當中。 1.開啟相機物件 獲取一個 Camera 物件是直接控制相機的第一步。正如Android自帶的相機程式

Unity遊戲開發控制相機跟隨主角

using System.Collections; using System.Collections.Generic; using UnityEngine; public class FollowTarget : MonoBehaviour {          priva

Android開發呼叫相機拍照與本地相簿選擇圖片

使用者看到的介面如下,也是我的xml介面: demo中有一個按鈕,點選彈出對話方塊提示使用者選擇:拍照、相簿。如下圖: 點選拍照,會開啟手機相機開始拍照,拍攝完後可以裁剪,如下圖: 這時候你可以直接點選確定,也可

Android開發控制攝像頭拍照

        現在的手機一般都會提供相機功能,有些相機的鏡頭甚至支援1300萬以上畫素,有些甚至支援獨立對焦、光學變焦這些只有單反才有的功能,甚至有些手機直接宣傳可以拍到星星。可以說手機已經變成了專業數碼相機。為了充分利用手機上的相機功能, Android系統提供了Cam

Android開發呼叫相機拍照和呼叫系統相簿

Android應用程式中呼叫相機進行拍照和選擇相簿中的照片是經常會使用到的,那麼我們就來實現以下這個功能。 首先建立一個工程CameraTest,佈局檔案一個ImageView,兩個Button。 <?xml version="1.0" en

Android 開發自定義控制元件開發-01

最近一直在忙於公司的專案,因為要去現場測試正式使用,專案不大但是經手了三個人,到我這裡只能去填坑了,不說這個了,說一下今天得主題,自定義控制元件之基本圖形繪製。 我們平時畫圖需要兩種工具:紙和筆。在Android中 Paint 就是畫筆,而Canvas類就是紙,在這裡叫做畫布。 所以

Android開發基本控制元件和詳解四種佈局方式

Android中的控制元件的使用方式和iOS中控制元件的使用方式基本相同,都是事件驅動。給控制元件新增事件也有介面回撥和委託代理的方式。今天這篇部落格就總結一下Android中常用的基本控制元件以及佈局方式。說到佈局方式Android和iOS還是區別挺大的,在iOS中有F

Android開發RadioGroup與RadioButton控制元件使用

      RadioButton即單選按鈕,它在開發中提供了一種“多選一”的操作模式,是Android開發中常用的一種元件,例如在使用者註冊時,選擇性別時只能從“男”或者“女”中選擇一個。與Web開發不同的是,在Android中可以使用RadioGroup來定義單選按鈕元件

android開發wheel控制元件使用詳解

出門在外生不起病呀,隨便兩盒藥60多塊錢。好吧,不廢話了,今天我們來看看wheel控制元件的使用,這是GitHub上的一個開源控制元件,用起來十分方便,我們可以用它做許多事情,比如做一個自定義的datepicker,在一些電商App中,經常用它來做省市縣三級聯動,總之用途還是

android開發在activity中控制另一個activity的UI更新

第一種方法: 遇到一個問題,需要在一個activity中控制另一個acitivity做一些更新,沒想到傳遞handler的方法,通過以下方式解決。 1.在MyAPP中定義屬性handler package jason.com; import jason.com.MasterAc

Android 開發自定義控制元件開發-02

1.畫筆的基本設定 : 1.setColor() 該函式的作用是設定畫筆顏色,完整的函式宣告如下: void setColor(int color) 我們知道,一種顏色是由紅、綠、藍三色合成出來的,所以引數 color 只能取8位的0xAARRGGBB樣式顏色值。 其中:

Android開發按鍵控制

<span style="font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; background-color: rgb(250, 247, 239);">Android手機一般都有三個鍵

Android開發控制元件設定圓角邊框

先上效果圖: 具體步驟: 1.在drawable資料夾下新建一個xml檔案。 2.在裡面填上以下內容: <?xml version="1.0" encoding="utf-8"?> <!--自定義的控制元件圓角背景--> <shape xm

Android開發自定義控制元件--ViewPager

package com.itheima18.viewpager; import java.util.ArrayList; import java.util.Timer; import java.util.concurrent.Executors; import java.util.concurrent.Sc

Android開發自定義控制元件(一)---onMeasure詳解

         話說一個有十年的程式設計經驗的老漢,決定改行書法,在一個熱火炎炎的中午,老漢拿著毛筆,在一張白紙上寫了個“Hello World!”,從此開啟了他的書法旅程。那麼問題來了請問自定義一個控制元件需要怎樣的流程?我們經常說自定義控制元件,那麼究竟怎樣去自定義一

Android開發玩轉FlexboxLayout佈局(可用於普通控制元件實現流式佈局,也可結合RecycleView實現流式佈局)

在這之前,我曾認真的研究過鴻洋大神的Android 自定義ViewGroup 實戰篇 -> 實現FlowLayout,按照大神的思路寫出了一個流式佈局,所有的東西都是難者不會會者不難,當自己能自定義流式佈局的時候就會覺得這東西原來很簡單了。如果各位小夥伴也看過那篇

Android開發AutoCompleteTextView控制元件,自動提示

AutoCompleteTextView是一個提供了聯想詞的控制元件,可以看做是EditText的升級版本 佈局: <AutoCompleteTextView android:

Android開發最新Recyclerview控制元件的使用詳解(一)

    本篇博文主要給大家分享關於RecyclerView控制元件的使用及通過繼承RecyclerView來實現滑動時載入圖片的優化方案,也同樣能解決防止圖片亂序的問題,之前有在網上有看到大神對Android中ListView非同步載入圖片亂序問題進行過分析,並深入剖析原理

android開發自定義TextView設定字間距以及通過TextView控制元件屬性設定行間距

眾所周知,我們的TextView控制元件是沒有設定字間距的屬性滴!為了現實這一夢想,我玩起來了自定義TextView,從而來設定字間距: 自定義TextView設定字間距 第一步:建立自定義TextView: package com.zanel

Android開發getX,getRawX,getWidth,getTranslationX等的區別

save string hlist getwidth sta 是我 touch 項目 寬度 轉載請註明出處:http://blog.csdn.net/dmk877/article/details/51550031 好久沒寫博客了,最近工作確實挺忙的,剛剛結束了一個