Android開發之呼叫相機拍照和呼叫系統相簿
阿新 • • 發佈:2019-02-09
Android應用程式中呼叫相機進行拍照和選擇相簿中的照片是經常會使用到的,那麼我們就來實現以下這個功能。
首先建立一個工程CameraTest,佈局檔案一個ImageView,兩個Button。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">
<ImageView
android:id="@+id/iv_photo"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<Button
android:id="@+id/btn_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="點選拍照"/>
<Button
android:id="@+id/btn_photo_album"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="從相簿中選取"/>
</LinearLayout>
MainActivity中主要對兩個按鈕進行了監聽,跳到相應的介面。
拍照採用隱式意圖來呼叫相機,並將拍好的照片儲存在sd卡根目錄。由於拍的照片可能比較大,
所以在拍照之後啟用了系統自帶的裁剪功能,裁剪完成後載入到ImageView上。
呼叫系統相簿也同樣採用隱式意圖來呼叫,選取之後同樣的對其進行裁剪,然後載入到ImageView上。
package com.example.cameratest;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
public static final int Cut_PHOTO = 1;
public static final int SHOW_PHOTO = 2;
public static final int PHOTO_ALBUM = 3;
public static final int SHOW_PHOTO_ALBUM = 4;
private Uri imageUri;
private ImageView iv_photo;
private Button btn_photo;
private Button btn_photo_album;
private Uri uri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_photo = (ImageView) this.findViewById(R.id.iv_photo);
btn_photo = (Button) this.findViewById(R.id.btn_photo);
btn_photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//建立File物件,用於儲存選擇的照片
File outputImage = new File(Environment.getExternalStorageDirectory(), "test.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, Cut_PHOTO);
}
});
btn_photo_album = (Button) this.findViewById(R.id.btn_photo_album);
btn_photo_album.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 建立File物件,用於儲存選擇的照片
File outputImage = new File(Environment.getExternalStorageDirectory(), "outputTest.jpg");
try {
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
imageUri = Uri.fromFile(outputImage);
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
//允許裁剪
intent.putExtra("crop", true);
//允許縮放
intent.putExtra("scale", true);
//圖片的輸出位置
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent,PHOTO_ALBUM);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case Cut_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, SHOW_PHOTO);
}
break;
case SHOW_PHOTO:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
// 將裁剪後的照片顯示出來
iv_photo.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
case PHOTO_ALBUM:
if (resultCode == RESULT_OK) {
uri = data.getData();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
// 啟動裁剪
startActivityForResult(intent, SHOW_PHOTO_ALBUM);
}
break;
case SHOW_PHOTO_ALBUM:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
// 將裁剪後的照片顯示出來
iv_photo.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
}
當然,別忘了加對sd卡操作的許可權。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
由於要呼叫相機進行拍照,所以我選擇執行在真機上進行測試。
將程式執行在小米3上,介面如下。
點選拍照按鈕,我拍了張照片,點選 "√" 之後跳到如下介面。
調整好裁剪的大小之後點選應用,發現我們剛才裁剪的照片已經載入到ImageView上了。
然後點選從相簿中選取按鈕,我選了張美女圖片,如下,它已經跳到了裁剪介面。
選好裁剪效果之後點選應用。效果就出來了。
從相簿中選取照片的時候可能會載入不上,如果出現這個問題,在清單檔案中<activity>節點下,
配置不要開啟硬體加速。
android:hardwareAccelerated="false"
在實際的應用開發中載入圖片使用Bitmap的時候要對圖片進行縮放,不然很容易就會造成OOM了。
如有希望瞭解Bitmap載入圖片
請點選
拍照和相簿選取的功能我們就完成了。如有錯誤請指出,謝謝!