【Android Training - Multimedia】捕獲照片 [Lesson 1 - 簡單的拍照動作]


這節課會介紹如何利用現有的camera程序來拍一張照片。

假設你想通過你的客戶端程序實現一個聚合全球天氣的地圖,上面會有各地的當前天氣圖片。那麼集合圖片只是你程序的一部分。你想要最簡單的動作來獲取圖片,而不是重新發明(reinvent)一個camera。幸運的是,大多數Android設備都已經至少安裝了一款相機程序。在這節課中,你會學習,如何拍照。[暈,說了這麼多的話做引子,下次遇到這樣的“廢話”真的不想翻譯了]

Request Camera Permission [請求相機權限]

在寫程序之前,需要在你的程序的manifest文件中添加下面的權限:
<manifest ... >
    <uses-feature android:name="android.hardware.camera" />
    ...
</manifest ... >
如果你的程序並不需要一定有Camera,可以添加android:required="false" 的tag屬性。這樣的話,Google Play 也會允許沒有camera的設備下載這個程序。當然你有必要在使用Camera之前通過hasSystemFeature(PackageManager.FEATURE_CAMERA)方法來檢查設備上是否有Camera。如果沒有,你應該關閉你的Camera相關的功能![這個幾乎沒有人去做檢查,因爲目前所有的智能手機都會有相機]

Take a Photo with the Camera App [使用相機程序拍照]

Android中的方法是:啓動一個Intent來完成你想要的動作。這個步驟包含三部分: Intent 本身,啓動的外部 Activity, 與一些處理返回照片的代碼。如:

private void dispatchTakePictureIntent(int actionCode) {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(takePictureIntent, actionCode);
}
當然在發出Intent之前,你需要檢查是否有app會來handle這個intent,否則會引起啓動失敗:

public static boolean isIntentAvailable(Context context, String action) {
    final PackageManager packageManager = context.getPackageManager();
    final Intent intent = new Intent(action);
    List<ResolveInfo> list =
            packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

View the Photo [查看照片]

Android的Camera程序會把拍好的照片編碼爲bitmap,使用extra value的方式添加到返回的 Intent 當中, 對應的key爲data。

private void handleSmallCameraPhoto(Intent intent) {
    Bundle extras = intent.getExtras();
    mImageBitmap = (Bitmap) extras.get("data");
    mImageView.setImageBitmap(mImageBitmap);
}
Note: 這僅僅是處理一張很少的縮略圖而已,如果是大的全圖,需要做更多的事情來避免ANR。

Save the Photo [保存照片]

如果你提供一個file對象給Android的Camera程序,它會保存這張全圖到給定的路徑下。你必須提供存儲的卷名,文件夾名與文件名。對於2.2以上的系統,如下操作即可:

storageDir = new File(
    Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES
    ), 
    getAlbumName()
);	

  • Set the file name [設置文件名]
正如上面描述的那樣,文件的路徑會有設備的系統環境決定。你自己需要做的只是定義個不會引起文件名衝突的命名scheme。下面會演示一種解決方案:

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = 
        new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
    File image = File.createTempFile(
        imageFileName, 
        JPEG_FILE_SUFFIX, 
        getAlbumDir()
    );
    mCurrentPhotoPath = image.getAbsolutePath();
    return image;
}

  • Append the file name onto the Intent [把文件名添加到網絡上]
Once you have a place to save your image, pass that location to the camera application via the Intent.

File f = createImageFile();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));

Add the Photo to a Gallery [添加照片到相冊]

對於大多數人來說,最簡單查看你的照片的方式是通過系統的Media Provider。下面會演示如何觸發系統的Media Scanner來添加你的照片到Media Provider的DB中,這樣使得相冊程序與其他程序能夠讀取到那些圖片。

private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}

Decode a Scaled Image [解碼縮放圖片]

在有限的內存下,管理全尺寸的圖片會很麻煩。下面會介紹如何縮放圖片來適應程序的顯示:

private void setPic() {
    // Get the dimensions of the View
    int targetW = mImageView.getWidth();
    int targetH = mImageView.getHeight();
  
    // Get the dimensions of the bitmap
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;
  
    // Determine how much to scale down the image
    int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
  
    // Decode the image file into a Bitmap sized to fill the View
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;
  
    Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    mImageView.setImageBitmap(bitmap);
}

學習自:http://developer.android.com/training/camera/photobasics.html,歡迎一起交流!

轉載請註明出自:http://blog.csdn.net/kesenhoo,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章