1
我有一個應用程序,它允許用戶拍照。照片拍完後,用戶可以將其發送到我的網絡服務器。但在我這樣做之前,它需要調整位圖的大小,因爲我希望將一致的大小發送到我的網絡服務器。用於android的單聲道內存高效位圖處理
無論如何,我用來將位圖加載到內存然後操作它的代碼似乎佔用了大量內存。此代碼目前正在使用:
/*
* This method is used to calculate image size.
* And also resize/scale image down to 1600 x 1200
*/
private void ResizeBitmapAndSendToWebServer(string album_id) {
Bitmap bm = null;
// This line is taking up to much memory each time..
Bitmap bitmap = MediaStore.Images.Media.GetBitmap(Android.App.Application.Context.ApplicationContext.ContentResolver,fileUri);
/*
* My question is : Could i do the next image manipulation
* before i even load the bitmap into memory?
*/
int width = bitmap.Width;
int height = bitmap.Height;
if (width >= height) { // <-- Landscape picture
float scaledWidth = (float)height/width;
if (width > 1600) {
bm = Bitmap.CreateScaledBitmap (bitmap, 1600, (int)(1600 * scaledWidth), true);
} else {
bm = bitmap;
}
} else {
float scaledHeight = (float)width/height;
if (height > 1600) {
bm = Bitmap.CreateScaledBitmap (bitmap, (int)(1600 * scaledHeight), 1600 , true);
} else {
bm = bitmap;
}
}
// End of question code block.
MemoryStream stream = new MemoryStream();
bitmap.Compress (Bitmap.CompressFormat.Jpeg, 80, stream);
byte[] bitmapData = stream.ToArray();
bitmap.Dispose();
app.api.SendPhoto (Base64.EncodeToString (bitmapData, Base64Flags.Default), album_id);
}
什麼將是一個很好,乾淨的方法來解決這種內存問題?
編輯1:
閱讀其他職位後,很明顯,我認爲我在做一些低效的事情與我的代碼。這是我一直在做的事情:
- 將完整的位圖加載到內存中。
- 決定它是不是風景。
- 然後用正確的尺寸創建新的位圖。
- 然後將此位圖轉換爲字節數組
- 處置初始位圖。 (但不要從內存中刪除縮放的位圖)。
我真正應該做的:
確定真正的位圖尺寸,而不加載到內存:
private void FancyMethodForDeterminingImageDimensions() { BitmapFactory.Options options = new BitmapFactory.Options(); options.InJustDecodeBounds = true; BitmapFactory.DecodeFile(fileUri.Path, options); // Now the dimensions of the bitmap are known without loading // the bitmap into memory. // I am not further going to explain this, i think the purpose is // explaining enough. int outWidth = options.OutWidth; int outHeight = options.OutHeight; }
如果設置爲true,解碼器將返回null(無位圖),但仍然會設置out ...字段,允許調用者查詢 位圖,而不必爲其像素分配內存。
- 現在我知道真正的尺寸。所以我可以下載它之前我加載到內存中。
- (在我的情況)將位圖轉換爲base64字符串併發送它。
- 處理所有內容以清除內存。
我目前不能測試這個,因爲我不在我的開發機器上。任何人都可以給我一些反饋,如果這是正確的方式?將不勝感激。
無法在服務器端調整大小嗎?你也不使用(或處置)你的'bm'變量,爲什麼? –
看到我的答案http://stackoverflow.com/questions/16183635/out-of-memory-error-on-setimageresource/16184893#16184893 –
@Chintan allthough你的方法是正確的,它並不總是給權利inSampleSize。看到我的評論在這裏:[鏈接](http://stackoverflow.com/questions/17319361/best-practis-for-handling-bitmaps-in-android-with-mono-droid-xamarin-android/17330028?noredirect=1 #comment25150832_17330028) – jHogen