標籤:
連結地址:http://www.cnblogs.com/lknlfy/archive/2012/03/06/2382679.html
一、概述
Camera是手機的一個很重要的裝置,可以說現在的每一部手機上都有。回想當時在Linux搞網路攝影機編程真的要捏一把汗。有人會說在Linux下裝個opencv就可以通過它的函數來使用網路攝影機啦,但我並沒有這麼做,我還是用最原始的方法(V4L2)實現了。之前研究過Android關於網路攝影機這部分的源碼,毫無疑問,Android關於網路攝影機底層的實現用的也是V4L2。
二、實現
建立工程MyCamera,修改/res/layout/main.xml檔案,使用RelativeLayout布局,並添加一個SurfaceView和一個Button,完整的main.xml如下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 android:orientation="vertical"
6 >
7
8 <SurfaceView
9 android:id="@+id/surfaceview"
10 android:layout_width="fill_parent"
11 android:layout_height="wrap_content"
12 android:layout_alignParentTop="true"
13 android:layout_above="@+id/button"
14 />
15
16 <Button
17 android:id="@+id/button"
18 android:layout_width="fill_parent"
19 android:layout_height="wrap_content"
20 android:layout_alignParentBottom="true"
21 android:text="拍照"
22 />
23
24 </RelativeLayout>
接著,修改MyCameraActivity.java檔案,實現了SurfaceHolder.Callback介面,用於初始化、釋放網路攝影機和Camera.PictureCallback介面,用於儲存圖片資料到檔案裡。完整的內容如下:
1 package com.nan.camera;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 import android.app.Activity;
9 import android.graphics.Bitmap;
10 import android.graphics.BitmapFactory;
11 import android.graphics.PixelFormat;
12 import android.hardware.Camera;
13 import android.os.Bundle;
14 import android.os.Environment;
15 import android.view.SurfaceHolder;
16 import android.view.SurfaceView;
17 import android.view.View;
18 import android.widget.Button;
19 import android.widget.Toast;
20
21 public class MyCameraActivity extends Activity
22 {
23 private SurfaceView mSurfaceView = null;
24 private SurfaceHolder mSurfaceHolder = null;
25 private Button takePictureButton = null;
26 private Camera mCamera;
27 //記錄儲存的是第幾張圖片
28 private int whichPicture = 0;
29
30 /** Called when the activity is first created. */
31 @Override
32 public void onCreate(Bundle savedInstanceState)
33 {
34 super.onCreate(savedInstanceState);
35 setContentView(R.layout.main);
36
37 takePictureButton = (Button)this.findViewById(R.id.button);
38 mSurfaceView = (SurfaceView)this.findViewById(R.id.surfaceview);
39 mSurfaceHolder = mSurfaceView.getHolder();
40 mSurfaceHolder.addCallback(new SurfaceHolderCallback());
41 //設定緩衝區類型
42 mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
43 //拍照按鈕監聽
44 takePictureButton.setOnClickListener(new View.OnClickListener()
45 {
46
47 @Override
48 public void onClick(View v)
49 {
50 // TODO Auto-generated method stub
51 //拍照
52 mCamera.takePicture(null, null, pictureCallback);
53 }
54 });
55
56 }
57
58 private class SurfaceHolderCallback implements SurfaceHolder.Callback
59 {
60
61 @Override
62 public void surfaceChanged(SurfaceHolder holder, int format, int width,
63 int height) {
64 // TODO Auto-generated method stub
65
66 }
67
68 @Override
69 public void surfaceCreated(SurfaceHolder holder)
70 {
71 // TODO Auto-generated method stub
72 //開啟網路攝影機
73 mCamera = Camera.open();
74 try {
75 mCamera.setPreviewDisplay(mSurfaceHolder);
76 } catch (IOException e) {
77 // TODO Auto-generated catch block
78 e.printStackTrace();
79 }
80 //擷取網路攝影機參數
81 Camera.Parameters mParameters = mCamera.getParameters();
82 //設定圖片格式
83 mParameters.setPictureFormat(PixelFormat.JPEG);
84 mCamera.setParameters(mParameters);
85 //開始預覽
86 mCamera.startPreview();
87 }
88
89 @Override
90 public void surfaceDestroyed(SurfaceHolder holder)
91 {
92 // TODO Auto-generated method stub
93 if(mCamera!=null)
94 {
95 //停止預覽
96 mCamera.stopPreview();
97 //釋放網路攝影機
98 mCamera.release();
99 mCamera = null;
100 }
101 }
102
103 }
104
105 //拍照回調
106 private Camera.PictureCallback pictureCallback = new Camera.PictureCallback()
107 {
108
109 @Override
110 public void onPictureTaken(byte[] data, Camera camera)
111 {
112 // TODO Auto-generated method stub
113 //停止預覽
114 mCamera.stopPreview();
115 Bitmap mBitmap;
116 mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
117 //檔案路徑和檔案名稱
118 File pictureFile = new File(Environment.getExternalStorageDirectory(),"camera"+Integer.toString(whichPicture)+".jpg");
119
120 try
121 {
122 FileOutputStream mFileOutputStream = new FileOutputStream(pictureFile);
123 //將映像資料壓入檔案
124 mBitmap.compress(Bitmap.CompressFormat.JPEG, 75, mFileOutputStream);
125 try {
126 //關閉輸出資料流
127 mFileOutputStream.close();
128 } catch (IOException e) {
129 // TODO Auto-generated catch block
130 e.printStackTrace();
131 }
132 }
133 catch (FileNotFoundException e)
134 {
135 // TODO Auto-generated catch block
136 e.printStackTrace();
137 }
138 displayToast("儲存成功!");
139 whichPicture++;
140 //開始預覽
141 mCamera.startPreview();
142 }
143
144 };
145
146 //顯示Toast函數
147 private void displayToast(String s)
148 {
149 Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
150 }
151
152 }
在真機上運行該程式:
按一下“拍照”按鈕:
圖片會被儲存到sd卡的根目錄下面。
Android應用開發提高篇(5)-----Camera使用