位图-避免在缩放过程中不必要地加载到内存中

时间:2018-11-04 10:13:50

标签: android

我有一种方法来调整从文件路径解码的位图的大小,或者使用ThumbnailUtils创建缩略图。然后将位图设置为自定义视图的背景或在画布上绘制。

在少数情况下,它会导致OutOfMemoryError

java.lang.OutOfMemoryError: 
  at dalvik.system.VMRuntime.newNonMovableArray (VMRuntime.java)
  at android.graphics.Bitmap.nativeCreate (Bitmap.java)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:942)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:913)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:844)
  at android.media.ThumbnailUtils.transform (ThumbnailUtils.java:425)
  at android.media.ThumbnailUtils.extractThumbnail (ThumbnailUtils.java:228)
  at android.media.ThumbnailUtils.extractThumbnail (ThumbnailUtils.java:203)

主要由ThumbnailUtils引起,可能是因为我在提取缩略图之前没有按比例缩小位图吗?

如何在不增加内存负载的情况下执行此操作,以及通常如何更好地优化此方法

// w = view Width, h = view Height
public BitmapDrawable decodeBitmap(int w, int h) {
    Bitmap bitmap = null;
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = false;
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        options.inDither = true;
        bitmap = BitmapFactory.decodeFile(BackgroundImage,options);
        if(scaleType==0) { //center crop
            bitmap = cropCenter(bitmap,w,h);
        }else if(scaleType==1) { //fitxy
            bitmap = resize(bitmap,w,h);
        }
        return new BitmapDrawable(mContext.getResources(), bitmap);
    } catch (Exception e) {

    }
    return null;
}

private Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
    try{
        if (maxHeight > 0 && maxWidth > 0) {
            int width = image.getWidth();
            int height = image.getHeight();
            float ratioBitmap = (float) width / (float) height;
            float ratioMax = (float) maxWidth / (float) maxHeight;

            int finalWidth = maxWidth;
            int finalHeight = maxHeight;
            if (ratioMax > ratioBitmap) {
                finalWidth = (int) ((float) maxHeight * ratioBitmap);
            } else {
                finalHeight = (int) ((float) maxWidth / ratioBitmap);
            }
            image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, false);
            return image;
        }
    } catch (Exception e) {

    }
    return image;
}
private Bitmap cropCenter(Bitmap bmp, int maxWidth, int maxHeight) {
    try{
        return ThumbnailUtils.extractThumbnail(bmp, maxWidth, maxHeight);
    } catch (Exception e) {

    }
    return bmp;
}

我正在使用BitmapDrawable来使用setBackground(Drawable);

1 个答案:

答案 0 :(得分:0)

您可以使用滑行。它可以提高性能并减少处理时的滞后现象

https://github.com/bumptech/glide是滑行库。

您可以在https://futurestud.io/tutorials/glide-image-resizing-scaling上找到有关调整大小的示例。 下面的内容来自于提及站点,解释了如何调整图像大小

使用Glide 4

GlideApp  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .override(600, 200) // resizes the image to these dimensions (in pixel). resize does not respect aspect ratio
    .into(imageViewResize);

使用Glide 3

Glide  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .override(600, 200) // resizes the image to these dimensions (in pixel). resize does not respect aspect ratio
    .into(imageViewResize);
相关问题