Android 呼叫攝像頭拍照

油燜茄子發表於2016-01-26

很多應用程式都可能會使用到呼叫攝像頭拍照的功能,比如說程式裡需要上傳一張圖片作為使用者的頭像,這時開啟攝像頭拍張照是最簡單快捷的。下面就讓我們通過一個例子來學習一下,如何才能在應用程式裡呼叫手機的攝像頭進行拍照。

新建一個ChoosePicTest專案,然後修改activity_main.xml中的程式碼,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >


    <Button

        android:id="@+id/take_photo"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Take Photo" />


    <ImageView

        android:id="@+id/picture"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="center_horizontal" />


</LinearLayout>

可以看到,佈局檔案中只有兩個控制元件,一個Button和一個ImageViewButton是用於開啟攝像頭進行拍照的,而ImageView則是用於將拍到的圖片顯示出來。

然後開始編寫呼叫攝像頭的具體邏輯,修改MainActivity中的程式碼,如下所示:

public class MainActivity extends Activity {


public static final int TAKE_PHOTO = 1;


public static final int CROP_PHOTO = 2;


private Button takePhoto;


private ImageView picture;


private Uri imageUri;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

takePhoto = (Button) findViewById(R.id.take_photo);

picture = (ImageView) findViewById(R.id.picture);

takePhoto.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//建立File物件,用於儲存拍照後的圖片

File outputImage = new File(Environment. getExternalStorageDirectory(), "tempImage.jpg");

try {

if (outputImage.exists()) {

outputImage.delete();

}

outputImage.createNewFile();

} catch (IOException e) {

e.printStackTrace();

}

imageUri = Uri.fromFile(outputImage);

Intent intent = new Intent("android.media.action. IMAGE_CAPTURE");

intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

startActivityForResult(intent, TAKE_PHOTO); //啟動相機程式

}

});

}


@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

switch (requestCode) {

case TAKE_PHOTO:

if (resultCode == RESULT_OK) {

Intent intent = new Intent("com.android.camera.action.CROP");

intent.setDataAndType(imageUri, "image/*");

intent.putExtra("scale", true);

intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

startActivityForResult(intent, CROP_PHOTO); //啟動裁剪程式

}

break;

case CROP_PHOTO:

if (resultCode == RESULT_OK) {

try {

Bitmap bitmap = BitmapFactory.decodeStream (getContentResolver()

.openInputStream(imageUri));

picture.setImageBitmap(bitmap); //將裁剪後的照片顯示出來

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

break;

default:

break;

}

}

}

上述程式碼稍微有點複雜,我們來仔細地分析一下。在MainActivity中要做的第一件事自然是分別獲取到ButtonImageView的例項,並給Button註冊上點選事件,然後在Button的點選事件裡開始處理呼叫攝像頭的邏輯,我們重點看下這部分程式碼。

首先這裡建立了一個File物件,用於儲存攝像頭拍下的圖片,這裡我們把圖片命名為output_image.jpg,並將它存放在手機SD卡的根目錄下,呼叫EnvironmentgetExternalStorageDirectory()方法獲取到的就是手機SD卡的根目錄。然後再呼叫UrifromFile()方法將File物件轉換成Uri物件,這個Uri物件標識著output_image.jpg這張圖片的唯一地址。接著構建出一個Intent物件,並將這個Intentaction指定為android.media.action. IMAGE_CAPTURE,再呼叫IntentputExtra()方法指定圖片的輸出地址,這裡填入剛剛得到的Uri物件,最後呼叫startActivityForResult()來啟動活動。由於我們使用的是一個隱式Intent,系統會找出能夠響應這個Intent的活動去啟動,這樣照相機程式就會被開啟,拍下的照片將會輸出到output_image.jpg中。

注意剛才我們是使用startActivityForResult()來啟動活動的,因此拍完照後會有結果返回到onActivityResult()方法中。如果發現拍照成功,則會再次構建出一個Intent物件,並把它的action指定為com.android.camera.action.CROP。這個Intent是用於對拍出的照片進行裁剪的,因為攝像頭拍出的照片都比較大,而我們可能只希望擷取其中的一小部分。然後給這個Intent設定上一些必要的屬性,並再次呼叫startActivityForResult()來啟動裁剪程式。裁剪後的照片同樣會輸出到output_image.jpg中。

裁剪操作完成之後,程式又會回撥到onActivityResult()方法中,這個時候我們就可以呼叫BitmapFactorydecodeStream()方法將output_image.jpg這張照片解析成Bitmap物件,然後把它設定到ImageView中顯示出來。

由於這個專案涉及到了向SD卡中寫資料的操作,因此我們還需要在AndroidManifest.xml中宣告許可權:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.choosepictest"

    android:versionCode="1"

    android:versionName="1.0" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

  ……

</manifest>

這樣程式碼就都編寫完了,現在將程式執行到手機上,然後點選Take Photo按鈕就可以進行拍照了,如圖所示。


拍照完成後點選確定則可以對照片進行裁剪,如圖所示。


點選完成,就會回到我們程式的介面。同時,裁剪後的照片當然也會顯示出來了,如圖所示。



















相關文章