Android Camera(攝像頭)
通過以下兩種方式,可以在應用程序中使用攝像機
使用現有應用程序中Android攝像頭應用程序
直接使用應用程序提供的Android攝像頭API
使用現有應用程序的Android攝像頭應用程序
使用 MediaStore.ACTION_IMAGE_CAPTURE 啓動安裝在手機上的攝像頭應用程序。它的語法下面給出:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
除了以上,也可以通過 MediaStore 提供其它可用的意圖。它們列出如下
Sr.No
意圖類型和說明
1
ACTION_IMAGE_CAPTURE_SECURE
它返回照相機拍攝到的圖像,設備被固定
2
ACTION_VIDEO_CAPTURE
它調用已有的視頻應用程序在Android中捕獲視頻
3
EXTRA_SCREEN_ORIENTATION
它是用來在屏幕的方向設置:垂直或橫向
4
EXTRA_FULL_SCREEN
它被用來控制ViewImage的用戶接口
5
INTENT_ACTION_VIDEO_CAMERA
這個意圖是用來啓動攝像機在視頻模式
6
EXTRA_SIZE_LIMIT
它用於指定的視頻或圖像捕獲尺寸大小限制
現在使用startActivityForResult()函數推出活動,並等待它的結果。它的語法下面給出:
startActivityForResult(intent,0)
這種方法已在活動 activity 類被定義。從主活動調用它。有在做同樣的工作的活動類中定義的方法,但是當它不是從活動要求,但在其他地方使用。它們被列在下面:
Sr.No
活動功能說明
1
startActivityForResult(Intent intent, int requestCode, Bundle options)
它開始的活動,但可以利用它選擇額外的包
2
startActivityFromChild(Activity child, Intent intent, int requestCode)
啓動活動時,活動是任何其他活動的子活動
3
startActivityFromChild(Activity child, Intent intent, int requestCode, Bundle options)
它的工作與上述相同,但它可以在捆綁與它的形狀採取額外的值
4
startActivityFromFragment(Fragment fragment, Intent intent, int requestCode)
它啓動的碎片活動當前所在內部
5
startActivityFromFragment(Fragment fragment, Intent intent, int requestCode, Bundle options)
它不僅啓動從碎片的活性,但可以採用額外的值
不管用來啓動其活動功能,它們都返回結果。其結果可以通過覆蓋 onActivityResult 方法獲得。
例子
這裏有一個例子,說明如何啓動現有的攝像機應用程序捕獲的圖像和位圖的形式顯示結果
爲了試驗這個例子,需要在支持攝像機的實際設備上運行此應用程序。
Steps
描述
1
使用Eclipse IDE創建Android應用程序,並將其命名爲Camera。在創建這個項目,確保目標SDK編譯在Android SDK中的最新版本或使用更高級別的API。
2
修改src/MainActivity.java 文件中添加意圖啓動活動代碼,由result方法來接受輸出。
3
修改所需的佈局XML文件 res/layout/activity_main.xml 添加GUI組件。在這裏,我們只添加ImageView和一個TextView
4
修改res/values/strings.xml 定義所需的常量值
5
運行應用程序並選擇運行Android設備,並在其上安裝的應用和驗證結果。
以下是修改後的主活動文件的內容:src/com.yiibai.camera/MainActivity.java.
package com.example.camera; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; public class MainActivity extends Activity { ImageView imgFavorite; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imgFavorite = (ImageView)findViewById(R.id.imageView1); imgFavorite.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { open(); } }); } public void open(){ Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); Bitmap bp = (Bitmap) data.getExtras().get("data"); imgFavorite.setImageBitmap(bp); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
以下是文件 res/layout/activity_main.xml file 的內容:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ImageView android:id="@+id/imageView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="34dp" android:layout_marginTop="36dp" android:contentDescription="@string/hello_world" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignRight="@+id/imageView1" android:text="@string/tap" android:textAppearance="?android:attr/textAppearanceLarge" />
以下將是 res/values/strings.xml 的內容,以定義一個新的常量
以下是 AndroidManifest.xml 的默認內容:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yiibai.camera" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.yiibai.camera.MainActivity" android:label="@string/app_name" >
讓我們試着運行相機應用程序。假設已經連接實際的Android移動設備到計算機。顯示如下窗口,選擇要運行的Android應用程序的選項。
選擇移動設備作爲一個選項,然後檢查您的移動設備將顯示如下界面:
現在只需輕點圖標的android的圖像,相機將被打開。只需拍攝一張照片。捕獲後,兩個按鈕就會出現或者把它丟棄
只需按下抽動(綠色)按鈕,將被帶回應用程序使用Android圖標拍攝的圖像
直接使用應用程序提供的Android攝像頭API
使用照相機API給攝像機整合在應用中
首先,需要使用靜態方法通過API calledCamera.open提供並初始化相機對象。它的語法如下:
Camera object = null; object = Camera.open();
除了上述功能,也有這是下面列出由Camera類提供的其它功能
Sr.No
方法 & 描述
1
getCameraInfo(int cameraId, Camera.CameraInfo cameraInfo)
它返回一個特定攝像機信息
2
getNumberOfCameras()
它返回限定的可用的設備上的照相機的整數
3
lock()
它被用來鎖定相機,所以沒有其他應用程序可以訪問它
4
release()
它被用來釋放在鏡頭鎖定,所以其他應用程序可以訪問它
5
open(int cameraId)
它是用來打開特定相機時,支持多個攝像機
6
enableShutterSound(boolean enabled)
它被用來使能/禁止圖像俘獲的默認快門聲音
現在,需要做一個獨立的類和SurfaceView擴展它並實現SurfaceHolder接口。
已經使用的兩種類具有以下目的
類
描述
Camera
它是用來控制攝像機和拍攝圖像或從相機拍攝的視頻
SurfaceView
這個類是用來展示實時攝像頭預覽給用戶
必須調用攝像機類的預覽方法來啓動攝像機的預覽給用戶
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback { private Camera theCamera; public void surfaceCreated(SurfaceHolder holder) { theCamera.setPreviewDisplay(holder); theCamera.startPreview(); } public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3){ } public void surfaceDestroyed(SurfaceHolder arg0) { } }
除了預覽,可以使用照相機API提供的其它功能中設置的攝像機的其它選項
Sr.No
方法 & 描述
1
startFaceDetection()
此功能啓動人臉檢測相機
2
stopFaceDetection()
它是用來阻止其通過上述功能啓用的臉部檢測
3
startSmoothZoom(int value)
這需要一個整數值,並調整攝像機的焦距非常順暢的值
4
stopSmoothZoom()
它是用來阻止攝像機的變焦
5
stopPreview()
它是用來阻止相機的預覽給用戶
6
takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg)
它被用來使能/禁止圖像拍攝的默認快門聲音
例子
下面的例子演示了攝像機API的應用程序中的使用
爲了試驗這個例子中,需要搭載最新的Android OS實際的移動設備,因爲攝像機不支持模擬器
Steps
描述
1
使用Android Studio創建Android應用程序,並將其命名爲:Camera。在創建這個項目,確保目標SDK和編譯在Android SDK的最新版本或使用更高級別的API。
2
修改src/MainActivity.java文件引用添加攝像機的代碼,並獲得了XML的組件
3
創建一個新的文件ShowCamera.java使用SurfaceView擴展和實現SurfaceHolder接口。
4
修改所需的佈局XML文件res/layout/activity_main.xml 添加GUI組件。在這裏我們只添加FrameView,一個按鈕和一個ImageView。
5
修改 res/values/strings.xml 定義所需的常量值
6
修改 AndroidManifest.xml 如下圖所示,添加必要的權限攝像機
7
運行應用程序並選擇運行Android的設備,並在其上安裝的應用和驗證結果。
下面是修改後的主活動文件 src/com.yiibai.camera1/MainActivity.java. 的內容。
package com.example.camera1; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends Activity { private Camera cameraObject; private ShowCamera showCamera; private ImageView pic; public static Camera isCameraAvailiable(){ Camera object = null; try { object = Camera.open(); } catch (Exception e){ } return object; } private PictureCallback capturedIt = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length); if(bitmap==null){ Toast.makeText(getApplicationContext(), "not taken", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "taken", Toast.LENGTH_SHORT).show(); } cameraObject.release(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pic = (ImageView)findViewById(R.id.imageView1); cameraObject = isCameraAvailiable(); showCamera = new ShowCamera(this, cameraObject); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(showCamera); } public void snapIt(View view){ cameraObject.takePicture(null, null, capturedIt); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
創建新java文件:src/com.yiibai.camera1/ShowCamera.java. 並添加以下代碼
package com.example.camera1; import java.io.IOException; import android.content.Context; import android.hardware.Camera; import android.view.SurfaceHolder; import android.view.SurfaceView; public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holdMe; private Camera theCamera; public ShowCamera(Context context,Camera camera) { super(context); theCamera = camera; holdMe = getHolder(); holdMe.addCallback(this); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { } @Override public void surfaceCreated(SurfaceHolder holder) { try { theCamera.setPreviewDisplay(holder); theCamera.startPreview(); } catch (IOException e) { } } @Override public void surfaceDestroyed(SurfaceHolder arg0) { } }
修改 res/layout/activity_main.xml 的內容
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="0.30" android:orientation="vertical" > <FrameLayout android:id="@+id/camera_preview" android:layout_width="fill_parent" android:layout_height="199dp" /> <Button android:id="@+id/button_capture" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="snapIt" android:text="@string/Capture" /> <ImageView android:id="@+id/imageView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="fitXY" android:src="@drawable/ic_launcher" /> < /LinearLayout>
修改 res/values/string.xml 的內容
修改AndroidManifest.xml 的內容,並添加必要的權限,如下圖所示。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yiibai.camera1" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.CAMERA"/> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.yiibai.camera1.MainActivity" android:label="@string/app_name" >
讓我們試着運行 Camera 應用程序。假設已經連接實際的Android移動設備到計算機。啓動應用程序之前會顯示如下窗口,選擇要運行的Android應用程序的選項。
選擇移動設備作爲一個選項,然後檢查移動設備將顯示如下界面:
相機將開始顯示在上半屏的預覽。只需點擊捕捉按鈕。現在,可以存儲所拍攝的圖像,將其上傳到網上或者是放棄它。