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