Social Icons

2010年10月16日 星期六

如何有效率的讀取圖片

我們知道現在手機的畫數動則幾百萬,可是手機對於記憶的管制非常嚴,直接讀取常常會失敗,哪有什麽好方法嗎?
其實是有的,簡單的步驟分為三。

1. 先讀取照片的長寬。
2. 利用要顯示的長寬來找出讀取後的倍率。
3. 依照倍率來讀取適當的照片。

下面是簡單的範例程式:
BitmapFactory.Options option1s = new BitmapFactory.Options();
option1s.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mediaPath, option1s);
int oriheight = option1s.outHeight;
int oriwidth = option1s.outWidth;
double widthScale = (double)oriwidth / (double)(drawRect.right-drawRect.left+1);
double heightScale = (double)oriheight / (double)(drawRect.bottom - drawRect.top+1);
int scale = 1;
if (widthScale > heightScale)
scale = (int)heightScale;
else
scale = (int)widthScale;
if (scale < 1)
    scale = 1;
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = scale; 
Bitmap bmp = BitmapFactory.decodeFile(mediaPath, options);

上面的讀法實際讀出來的照片的大小會比顯示區域大一些,使用縮小倍率最小的邊來縮圖, 所以顯示的時候要注意。如果要將照片和現實位置的中心點對齊的話,在draw的時候就要做一些處理。
int newWidth = (drawRect.right-drawRect.left);
int newHeight = (drawRect.bottom-drawRect.top);
if (bmp.getWidth() < newWidth)
    newWidth = bmp.getWidth();
if (bmp.getHeight() < newHeight)
    newHeight = bmp.getHeight();
Bitmap resizeBmp = Bitmap.createBitmap(bmp, (bmp.getWidth()/2)-(newWidth/2), (bmp.getHeight()/2)-(newHeight/2), newWidth, newHeight);

另外,如果希望縮小的倍率是2的倍數,可以參考下面的演算法:
if (widthScale > heightScale) {
    scale = 2 ^ ((int) Math.ceil(Math.log((drawRect.bottom-drawRect.top+1) / (double) oriheight) / Math.log(0.5)) -2);
} else {
    scale = 2 ^ ((int) Math.ceil(Math.log((drawRect.right-drawRect.left+1) / (double) oriwidth) / Math.log(0.5)) -2);
}

1 則留言:

  1. 可以請問
    (double)(drawRect.right-drawRect.left+1)
    drawRect是什麼東西嗎

    回覆刪除