前言:
最近為了某種需要,前置作業必須打通camera這道關卡,程式碼在Acer Iconia B1 A71上面測過是OK的,相關程式碼以及開發過程稍微整理一下就寫了這篇blog. 若有不周,歡迎批評指教, 缺漏的部份日後會慢慢補上. 轉貼或引用本篇blog內文章段落&程式碼, 不必交代出處.
過程:
想要寫個android apps去開啟裝置本身的鏡頭, 以Acer Iconia B1 A71這個裝置來講, 它的鏡頭就只有一個:前置鏡頭(front-facing,自拍用,視訊會議用,用來拍自己的臉,鏡頭就跟螢幕在同一面,在背面的就叫後置鏡頭back-facing).
首先要搞清楚到底要用哪個鏡頭. 單單寫一行Camera.open();是不行的. 起初就是天真的整個拿書本上的例子來編譯執行,結果畫面空空如也,看不到預覽畫面,去看debug error,不斷的出現startpreview()或setpreviewdisplay(holder) nullpointexception, 換個例子try, 結果使用呼叫系統內建camera apps,竟然成功?!然後開始懷疑acer那台只允許透過呼叫系統內建的去打開camera.
打開camera有兩種方式一種是透過呼叫系統內建的camera介面(android系統的,在螢幕_應用程式集打開就會看到'照相機'),另外一種就是等會介紹的先建立一個Camera物件,然後開始預覽startpreview,用takepicture來拍照,
隔天不甘心去官網看,照著10個步驟去做還是不行,最後檢查到第一個步驟建立Camera物件,然後Camera.open(),他老兄竟然沒open,得到null,叫它怎麼繼續做底下的事情?!最後程式寫麻煩一點, 去掃一遍裝置底下到底有幾個鏡頭,每個的代號是多少, 打開那個front-facing的鏡頭就ok了!
拍照的步驟:
1.建立Camera物件(Camera.open();),詳細的code請參考底下網址.
2.得到目前鏡頭一些設定值(preview畫面的長寬)->getParameters();
3.必要的話可以用 setParameters(Camera.Parameters);來修改設定值,
4.也可呼叫 setDisplayOrientation(int);來改變螢幕畫面的方向,
5.想要有預覽畫面要先 setPreviewDisplay(SurfaceHolder).
6.然後呼叫 startPreview() 開始預覽.
7.想要真正的拍照時,呼叫 mCamera.takePicture(null, null, mPicture); 第三個參數是callback function會幫你處理後續的動作,被鏡頭抓進來的這個frame做何處理之類的,本例是將她轉成bitmap秀在imageView的區域內,若你想額外存檔也行.
8.拍照後,預覽畫面就停格了,再呼叫一次 startPreview() 就可以再繼續預覽畫面.
9.呼叫 stopPreview() 來停止預覽.
10.當關閉apps不想再使用camera這個裝置要記得呼叫 Camera.release();來釋放這個share resource不然整個camera就被佔住了,之後的其它apps想來使用都不行,除非重開機.
11.因為需要Camera的功能, 所以在AndroidMainfest.xml內要加入:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
第二行跟第三行的android:required="false"意思是在沒有鏡頭的裝置上跑此篇介紹的android apps也是可以的.沒加的話,去google play下載這個apps,檢查到你的裝置沒鏡頭是不給安裝的.
p.s.官網是這樣寫,實際上我沒試過!
12.layout就是一個linearlayout裡面包1個button,1個ImageView,1個framelayout,
所有程式碼下載連結:
https://docs.google.com/file/d/0B6EVEd5P2B9cODVYWVlUak9tZEk/edit?usp=sharing
請問一下 若我照片想額外存檔該從哪邊改?
回覆刪除private PictureCallback mPicture = new PictureCallback() {
刪除@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(data,0,data.length);
imageView.setImageBitmap(cameraBitmap);
//這邊可以寫存檔的程式碼
mCamera.startPreview();
}
};
再問一下 我在AndroidMainfest.xml內加入android:screenOrientation="landscape"
回覆刪除然後直立拍照,拍出來的照片轉了180度,想問改哪邊可以轉照片?
android:screenOrientation="landscape"
刪除這句話是說 : 將螢幕固定為"水平"(橫向),
然後你又直立(直向,垂直)拍照,所以照片應該會轉90度吧?!
1.要嘛你就這行不加, 隨G-sensor去感應到底現在是將手機直立或橫向,拍出來的照片就是依當時看到的直立或橫向,
2.不然你也可以將這行的landscape改成portrait(直立),這樣你直立拍照應該就不會轉了180度,