在 Android 開發中,將圖片轉換為 Bitmap 是常見需求(如設定桌布、圖片處理、上傳壓縮)。根據圖片來源不同,處理方式有所差異。
使用 BitmapFactory.decodeResource() 直接解碼:
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_resource);
需在背景執行緒執行網路請求,避免阻塞 UI 執行緒(Android 4.0+ 會拋出 NetworkOnMainThreadException):
new Thread(() -> {
try {
URL url = new URL("https://example.com/image.jpg");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();
// 回主執行緒更新 UI
runOnUiThread(() -> imageView.setImageBitmap(bitmap));
} catch (IOException e) {
e.printStackTrace();
}
}).start();
File file = new File(Environment.getExternalStorageDirectory(), "download/image.jpg");
if (file.exists()) {
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
// 或使用 FileInputStream 更安全
// FileInputStream fis = new FileInputStream(file);
// Bitmap bitmap = BitmapFactory.decodeStream(fis);
}
手機記憶體有限,直接載入高解析度圖片極易導致 OOM。請使用 inSampleSize 進行次採樣:
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {
// 1. 僅解析邊界,不載入像素
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// 2. 計算縮放比例
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// 3. 正式解碼
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
int inSampleSize = 1;
if (options.outHeight > reqHeight || options.outWidth > reqWidth) {
int halfH = options.outHeight / 2;
int halfW = options.outWidth / 2;
while ((halfH / inSampleSize) >= reqHeight && (halfW / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
手動管理執行緒、快取、生命週期極易出錯。建議直接使用成熟庫:
Glide.with(context).load(url).into(imageView)Picasso.get().load(url).into(imageView)imageView.load(url)這些庫自動處理記憶體/磁碟快取、預載入、佔位圖、錯誤重試、生命週期感知,極大降低 OOM 風險與開發負擔。