gpt4 book ai didi

android - 如何在 Android 中加载大图像并避免内存不足错误?

转载 作者:IT老高 更新时间:2023-10-28 23:26:53 27 4
gpt4 key购买 nike

我正在开发一个使用大图像(1390 × 870:150kb - 50kb)的应用程序。我在点击触发器/ImageView 时添加图像。

在某个时刻,我遇到了内存不足错误:

java.lang.OutOfMemoryError
E/AndroidRuntime(23369): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
E/AndroidRuntime(23369): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:613)
E/AndroidRuntime(23369): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:378)

要调整图像的大小,我正在这样做:

Bitmap productIndex = null;
final String imageLoc = IMAGE_LOCATION;
InputStream imageStream;
try {
imageStream = new FileInputStream(imageLoc);
productIndex = decodeSampledBitmapFromResource(getResources(), imageLoc, 400, 400);

productIV.setImageBitmap(productIndex);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}


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

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

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

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(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 / 3;
final int halfWidth = width / 3;

// 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;
}

我从 Android Docs 中得到了这种调整大小以节省空间的方法: Loading Large Bitmaps Efficiently

根据日志,这是 decodeSampledBitmapFromResource 方法中的罪魁祸首:

return BitmapFactory.decodeFile(resId, options);

----- 编辑 -----这是我将每个项目添加到 FrameLayout 的方法。

for(int ps=0;ps<productSplit.size();ps++){
//split each product by the equals sign
List<String> productItem = Arrays.asList(productSplit.get(ps).split("="));

String tempCarID = productItem.get(0);
tempCarID = tempCarID.replace(" ", "");
if(String.valueOf(carID).equals(tempCarID)){

ImageView productIV = new ImageView(Configurator.this);
LayoutParams productParams = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
productIV.setId(Integer.parseInt(partIdsList.get(x)));
productIV.setLayoutParams(productParams);

final String imageLoc = productItem.get(2);

InputStream imageStream;
try {
imageStream = new FileInputStream(imageLoc);
productIndex = decodeSampledBitmapFromResource(getResources(), imageLoc, 400, 400);
productIV.setImageBitmap(productIndex);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

productLayers.addView(productIV);

}
}

最佳答案

您可以使用另一个位图配置来大幅减小图像的大小。默认值为 RGB-config ARGB8888,这意味着使用四个 8 位 channel (红色、绿色、蓝色、alhpa)。 Alpha 是位图的透明度。这会占用大量内存 - 图像大小 X 4。因此,如果图像大小为 4 兆像素,则将立即在堆上分配 16 兆字节 - 很快就会耗尽内存。

改为 - 使用 RGB_565,这在一定程度上会降低质量 - 但为了弥补这一点,您可以抖动图像。

所以 - 到您的方法 decodeSampledBitmapFromResource - 添加以下 fragment :

 options.inPreferredConfig = Config.RGB_565;
options.inDither = true;

在您的代码中:

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

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

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

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
options.inPreferredConfig = Config.RGB_565;
options.inDither = true;
return BitmapFactory.decodeFile(resId, options);
}

引用资料:

http://developer.android.com/reference/android/graphics/Bitmap.Config.html#ARGB_8888

关于android - 如何在 Android 中加载大图像并避免内存不足错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21392972/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com