Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android多媒體開發 Pro Android Media 第一章 Android圖像編程入門 2

Android多媒體開發 Pro Android Media 第一章 Android圖像編程入門 2

編輯:關於Android編程

采集更大的圖像

為了解決大小限制,從Android 1.5開始,在大多數機器上,我們傳入一個extra到激活相機應用的Intent中。此extra的名字在MediaStore類中定義為EXTRA_OUTPUT。它的值(extra以名稱-值對的形式存在)以URI的形式,為相機應用指定了拍攝的圖像保存的地方。

下面的代碼段要求相機應用將圖像保存到設備的SD卡,文件名為myfavoritepicture.png。

String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()
    + "/myfavoritepicture.jpg"; 
File imageFile = new File(imageFilePath);  
Uri imageFileUri = Uri.fromFile(imageFile);  
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);  
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);  
startActivityForResult(i, CAMERA_RESULT); 
注意:上述創建圖像文件URI的代碼段可以簡化如下:
imageFileUri =  Uri.parse("file:///sdcard/myfavoritepicture.jpg"); 
雖然在實踐中,所示的方法設備無關性更強,而且當SD卡的命名規則或者URI的語法因本地系統改變時,仍然能夠兼容。

顯示大圖像

加載和顯示圖像涉及大量使用內存。例如,HTC G1手機擁有一個320萬像素的攝像頭。320M像素的攝像頭,拍攝的圖像通常為2048x1536像素。顯示32位的這樣大小的圖像需要多達100663kb,大約13MB的內存。雖然不能肯定我們的應用就會耗盡內存,但是它顯然使內存耗盡的可能性大大增加了。

Android給我們提供了一個名為BitmapFactory的工具類,它提供了一系列的靜態方法從各種源加載位圖圖像。我們的需求是從文件加載圖像,並把它顯示在我們最初的activity中。幸運的是,BitmapFactory提供的加載方法都接受BitmapFactory.Options類,它允許我們定義將位圖讀入到內存的方式。具體來說,我們可以設置BitmapFactory加載圖像的采樣大小。指定BitmapFactory.Options類的inSampleSize參數,得到的位圖圖像將為原圖大小inSampleSize分之一。例如,像我在這裡做的,inSampleSize設置為8,將生成一個原圖1/8大小的圖像。

BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();  
bmpFactoryOptions.inSampleSize = 8;  
Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);  
imv.setImageBitmap(bmp);

這是一個快速加載大圖像的方法,但是沒有考慮圖像的原始大小以及屏幕的大小。如果我們縮放圖像使之適應我們的屏幕,那就更好了。

下面的代碼段說明了如何使用屏幕的大小確定加載圖像時的采樣值。當我們采用這些方法時,圖像能夠確保盡可能的填充屏幕。然而,如果圖像的任一維度只顯示100像素,則這個值將用來替換屏幕的維度。獲取顯示屏維度的代碼如下:

Display currentDisplay = getWindowManager().getDefaultDisplay();  
int dw = currentDisplay.getWidth();  
int dh = currentDisplay.getHeight(); 

需要計算,才能得出圖像的尺寸。為此,我們使用BitmapFactory和BitmapFactory.Options來幫忙。將BitmapFactory.Options.inJustDecodeBounds的值設置為true。這會告知BitmapFactory只需給出圖像大小信息,無需解碼圖像本身。當我們使用這個方法時,BitmapFactory將給BitmapFactory.Options.outHeight和BitmapFactory.Options.outWidth兩個變量賦值。

//加載圖像的外形尺寸,而非圖像本身 
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();  
bmpFactoryOptions.inJustDecodeBounds = true; 
Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);  
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);  

int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);  
Log.v("HEIGHTRATIO",""+heightRatio);  
Log.v("WIDTHRATIO",""+widthRatio); 

用圖像的高度和寬度分別除以顯示屏的高度和寬度,得到高度比和寬度比。然後,我們其中較大的那個作為縮放的比值。將這個比值賦給BitmapFactory.Options.inSampleSize變量,就可以得到一個加載到內存,大小接近我們所需的圖像—在本例中,接近屏幕大小。

//如果兩個比值都大於1,
//那麼圖像的某一邊大於屏幕 
if (heightRatio > 1 && widthRatio > 1)  {  
    if (heightRatio > widthRatio)  { 
        //高度比較大,以它進行縮小
        bmpFactoryOptions.inSampleSize = heightRatio;  
    }  
    else  {  
        //寬度比較大,以它進行縮小
        bmpFactoryOptions.inSampleSize = widthRatio;  
    }  
}  
// 真正解碼圖像
bmpFactoryOptions.inJustDecodeBounds = false;  
bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);

這裡是通過Intent使用內置相機應用,並顯示所得圖片的完整例子代碼。圖1-3 顯示了此示例產生的,滿屏大小的圖像。

package com.apress.proandroidmedia.ch1.sizedcameraintent;  
import java.io.File;  
import android.app.Activity;  
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.util.Log;  
import android.view.Display;  
import android.widget.ImageView;  

public class SizedCameraIntent extends Activity {  
    final static int CAMERA_RESULT = 0;  
    ImageView imv;  String imageFilePath;  

    @Override  public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() 
            + "/myfavoritepicture.jpg";  
        File imageFile = new File(imageFilePath);  
        Uri imageFileUri = Uri.fromFile(imageFile);  
        Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);  
        i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);  
        startActivityForResult(i,CAMERA_RESULT);  
    }  

    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {  
        super.onActivityResult(requestCode, resultCode, intent);  
        if (resultCode == RESULT_OK)  {  
            //取得ImageView的引用 
            imv = (ImageView) findViewById(R.id.ReturnedImageView);
  
            Display currentDisplay = getWindowManager().getDefaultDisplay();  
            int dw = currentDisplay.getWidth();  
            int dh = currentDisplay.getHeight(); 

            //加載圖片的尺寸信息,而非圖像本身
            BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();  
            bmpFactoryOptions.inJustDecodeBounds = true;  
            Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); 
 
            int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);  
            int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);
            Log.v("HEIGHTRATIO",""+heightRatio);  
            Log.v("WIDTHRATIO",""+widthRatio); 

            // 如果兩個比值都大於1,
            // 那麼圖像的某一邊大於屏幕 
            if (heightRatio > 1 && widthRatio > 1)  {  
                if (heightRatio > widthRatio)  { 
                    // 高度比較大,以它進行縮小
                    bmpFactoryOptions.inSampleSize = heightRatio; 
                }  
                else  { 
                    // 寬度比較大,以它進行縮小
                    bmpFactoryOptions.inSampleSize = widthRatio;  
                }
             }  

             // 真正解碼圖像
             bmpFactoryOptions.inJustDecodeBounds = false;  
             bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); 

             // 顯示圖像 
             imv.setImageBitmap(bmp);  
         }  
    }  
}

上述代碼需要下面的 layout/main.xml文件:

  

 
    
      
 

圖1-3. 返回的滿屏大小圖像顯示在ImageView中


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved