核心流程
- 啟動相機
ACTION_IMAGE_CAPTURE,指定輸出檔案 Uri(使用 FileProvider)。
onActivityResult 收到結果,呼叫縮圖產生函式。
- 使用
inSampleSize 解碼縮圖,避免 OOM。
- 儲存縮圖檔案,通知
MediaScanner 更新相簿。
- 在 ImageView 顯示縮圖。
關鍵工具方法
// 從檔案路徑解碼縮圖
public static Bitmap decodeSampledBitmapFromFile(String filePath, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options); // 只讀邊界
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.RGB_565; // 節省記憶體
return BitmapFactory.decodeFile(filePath, options);
}
private 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;
}
// 掃描媒體檔案讓相簿可見
public static void scanMediaFile(Context context, File file) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
context.sendBroadcast(intent);
}
onActivityResult 範例
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) {
File photoFile = ...; // 儲存原圖的檔案
// 產生縮圖
Bitmap thumb = decodeSampledBitmapFromFile(photoFile.getAbsolutePath(), 200, 200);
File thumbFile = new File(getCacheDir(), "thumb_" + photoFile.getName());
try (FileOutputStream fos = new FileOutputStream(thumbFile)) {
thumb.compress(Bitmap.CompressFormat.JPEG, 80, fos);
} catch (IOException e) { e.printStackTrace(); }
// 顯示縮圖
imageView.setImageBitmap(thumb);
// 掃描原圖與縮圖
scanMediaFile(this, photoFile);
scanMediaFile(this, thumbFile);
}
}
注意事項
- 原圖儲存路徑建議用
getExternalFilesDir(Environment.DIRECTORY_PICTURES) 或 MediaStore 插入。
- 縮圖可儲存於
getCacheDir()(應用卸載自動清理)。
- Android 10+ 使用
MediaStore 插入時無需掃描廣播。