2015-08-28 86 views
1

根据我的要求,我有一个用于调整位图图像大小的简单类。有负责它的简单方法如下:位图调整大小会导致内存不足

public static Bitmap ResizeRichImages(Bitmap bitmap, Context mContext){ 
     try { 
     float originalBitmapWidth = bitmap.getWidth(); 
     float originalBitmapHeight = bitmap.getHeight(); 
     float originalAspectRatio = originalBitmapWidth/originalBitmapHeight; 
     double width_percentage = (0.05*screenWidthPixels(mContext)); 
     float newWidth = (float)((int)screenWidthPixels(mContext)-width_percentage); 
     float newBitmapWidth = newWidth; 
     float newBitmapHeight = newBitmapWidth/originalAspectRatio; 
     bitmap = Bitmap.createScaledBitmap(bitmap, (int) newWidth, (int)newBitmapHeight, false); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return bitmap; 

    } 

这是我如何调用此方法:

String URL = "https://maps.googleapis.com/maps/api/staticmap?center=-33.86527274921529,151.2050531328867&zoom=15&size=640x360&sensor=false&markers=color:blue%7Clabel:!%7C-33.86527274921529,151.2050531328867"; 

try { 
bmp = Picasso.with(ViewStory.this).load(URL) 
                  .get(); 
bmp = ImageController.ResizeRichImages(bmp, ViewStory.this); 
               } catch (Exception e) { 
                e.printStackTrace(); 
               } 

但是,几乎每一个我收到了内存异常,同时调用时间ResizeRichImages方法。我哪里错了?

+0

何去何从是screenWidthPixels(mContext) –

+0

请检查:http://stackoverflow.com/questions/26296344/out-of-memory-error-for-files-greater-than-3mb-though-upload-using-chunk/26296433#26296433 – pbespechnyi

+0

''android:largeHeap“'只隐藏问题......非常普遍的**你不应该使用它** ...但它通常被糟糕的程序员使用(没有知识和技能)和noobs – Selvin

回答

-1

你还没有告诉我们你的位图有多大。也许它只是用尽所有的空闲内存,特别是如果你有其他大型位图(或其他)占用了大部分空间。

我会尝试在小位图上运行该过程,并且newBitmapWidth和newBitmapHeight减少到现在的十分之一。如果这消除了这个异常,那么在你能够处理全尺寸之前,你很确定你需要优化你的内存使用。

+0

该图像可以与您从https://maps.googleapis.com/maps/api/staticmap?center=-33.86527274921529,151.2050531328867&zoom=15&​​size=640x360&sensor=false&markers=color:blue%7Clabel:!%下载的图片一样大7C-33.86527274921529,151.2050531328867 – kittu88

0
  • 取而代之,在清单中使用largeHeap选项应始终是最后一个选项,您可以尝试压缩,如下面的代码片段所示。

*

byteArrImage = NULL;

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
if(data != null) thumbnail = (Bitmap) data.getExtras().get("data"); 
if(thumbnail != null) { 
    //thumbnail.compress(Bitmap.CompressFormat.PNG, 85, baos); 
    thumbnail.compress(Bitmap.CompressFormat.JPEG, 85, baos); 
    byteArrImage = baos.toByteArray(); 
    uploadImageToServer(); 
} 
0

我之前得到了同样的错误,但经过一番搜索,我发现另一种方式来调整大位图图像。当您使用大图像的位图时,必须使用BitmapFactory.Options.inSampleSize缩放图像。样本大小是任一维度中与解码位图中的单个像素对应的像素数量。当你使用inSampleSize = 4时,它会返回一个1/4的宽度/高度的图像。你也可以在android开发者网站上看到更多的细节。

使用这种方法在活动调整

private Bitmap decodeFileWithSmallSize(String sdcard_path) { 
final BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 4; 
Bitmap myBitmap = BitmapFactory.decodeFile(sdcard_path, options); 
return myBitmap; 
} 

使用

try { 
    Bitmap bitmap = null; 
    if (bitmap != null) { 
     bitmap.recycle(); 
     bitmap = null; 
    } 
    bitmap = decodeFileWithSmallSize("path"); 
} 
catch (OutOfMemoryError e) 
{ 
    Log.e("TAG", 
      "OutOfMemoryError Exception" + e.getMessage()); 
} 
+0

你知道他已经有毕加索的位图吗?这个答案如何适用于他的问题?或者对于所有OOME的问题,你是普遍的答案? – Selvin

0

一般同时处理位图,我们需要通过降低位图的基础上我们要求的宽度的采样大小,以减少内存大小和高度。

这个函数需要位图文件的路径,如果你想传递位图改变它与你的要求。但这是适当的方式来有效地加载图像。

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
    int reqWidth, int reqHeight) { 

// First decode with inJustDecodeBounds=true to check dimensions 
final BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
BitmapFactory.decodeResource(res, resId, options); 

// Calculate inSampleSize 
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

// Decode bitmap with inSampleSize set 
options.inJustDecodeBounds = false; 
return BitmapFactory.decodeResource(res, resId, options); 
} 

该函数计算所需图像的样本大小,以减少他的记忆。

public static int calculateInSampleSize(
     BitmapFactory.Options options, int reqWidth, int reqHeight) { 
// Raw height and width of image 
final int height = options.outHeight; 
final int width = options.outWidth; 
int inSampleSize = 1; 

if (height > reqHeight || width > reqWidth) { 

    final int halfHeight = height/2; 
    final int halfWidth = width/2; 

    // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
    // height and width larger than the requested height and width. 
    while ((halfHeight/inSampleSize) > reqHeight 
      && (halfWidth/inSampleSize) > reqWidth) { 
     inSampleSize *= 2; 
    } 
} 

return inSampleSize; 
} 

欲了解更多信息请参考以下链接:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

在你的情况,如果你的目标分钟级别19,然后用重新配置功能,您可在API级别19 visit developers site

+0

你知道他已经有毕加索的位图吗?这个答案如何适用于他的问题?或者对于所有OOME的问题,你是普遍的答案? – Selvin

+0

@Selvin可以请你清楚地看到这个问题,他已经得到了一个位图(代码名为bmp),并在尝试调整它的大小时,他得到了错误。 – Vishwa

+0

@Selvin他没有任何问题,直到他致电ResizeRichImages函数 – Vishwa