gpt4 book ai didi

java - Android 位图重用

转载 作者:行者123 更新时间:2023-12-02 00:10:12 25 4
gpt4 key购买 nike

我是 Android 新手!我在使用 Android 的 SDK 时遇到了一些大问题,因为我正在开发一个使用巨大位图(> 1200 * 1000)的应用程序,问题是在应用程序期间我需要相同大小的多个图层/位图(其中 3-5 个) 。问题是内存堆在这些分配之一上消耗得非常快,并且会触发 OutOfMemory 异常。

好的一点是我不需要同时使用所有位图。

我尝试了 recycle() 方法调用,尽管我知道它已经过时了,因为位图的内存现在驻留在堆上,而不是 native 内存上。我还尝试删除特定位图中的所有引用,甚至手动调用 System.gc() 但没有用,位图无法删除。好吧,也许会有我不知道的内存泄漏,尽管我对此表示怀疑。

我尝试了各种解决方案,但都不起作用。

对我来说最好的选择是重用位图,但 BitmapFactory 的解码方法只知道分配一个消耗内存的新位图。

我的问题是,你知道一种可以在 Android 上使用的重用位图像素的方法(覆盖位图的像素而不分配另一个位图/像素数组)吗???问题是我不能驻留在 GarbageCollector 解决方案上,因为我的应用程序中有特定的时刻,我必须确定这些位图已从内存中删除/其他位图不会被分配。

另一个解决方案是:您知道一种直接在SD卡上绘制一些位图而不通过堆内存的方法吗?有时,当我尝试分配一个大位图(原始大小的两倍)来连接其他两个已处理的位图时,它会崩溃......这就是我问的原因。是否有可能直接从数据流实例化 Canvas 或其他绘图对象?

其他解决方案是使用虚拟交换内存之类的东西,它可以模拟堆内存,但在 SDCARD 或其他东西上进行缓存。但也找不到这样做的方法。

最佳答案

编写一个单独的类来执行自定义位图操作:

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;


class BitmapLoader
{
public static int getScale(int originalWidth,int originalHeight,
final int requiredWidth,final int requiredHeight)
{
//a scale of 1 means the original dimensions
//of the image are maintained
int scale=1;

//calculate scale only if the height or width of
//the image exceeds the required value.
if((originalWidth>requiredWidth) || (originalHeight>requiredHeight))
{
//calculate scale with respect to
//the smaller dimension
if(originalWidth<originalHeight)
scale=Math.round((float)originalWidth/requiredWidth);
else
scale=Math.round((float)originalHeight/requiredHeight);

}

return scale;
}

public static BitmapFactory.Options getOptions(String filePath,
int requiredWidth,int requiredHeight)
{

BitmapFactory.Options options=new BitmapFactory.Options();
//setting inJustDecodeBounds to true
//ensures that we are able to measure
//the dimensions of the image,without
//actually allocating it memory
options.inJustDecodeBounds=true;

//decode the file for measurement
BitmapFactory.decodeFile(filePath,options);

//obtain the inSampleSize for loading a
//scaled down version of the image.
//options.outWidth and options.outHeight
//are the measured dimensions of the
//original image
options.inSampleSize=getScale(options.outWidth,
options.outHeight, requiredWidth, requiredHeight);

//set inJustDecodeBounds to false again
//so that we can now actually allocate the
//bitmap some memory
options.inJustDecodeBounds=false;

return options;

}



public static Bitmap loadBitmap(String filePath,
int requiredWidth,int requiredHeight){


BitmapFactory.Options options= getOptions(filePath,
requiredWidth, requiredHeight);

return BitmapFactory.decodeFile(filePath,options);
}
}

然后从您的 Activity 中调用此类的 Bitmap reqBitmap = loadBitmap(String filePath,int requiredWidth,int requiredHeight) 方法,提供从sd 卡,并将 requiredWidth 和 requiredHeight 设置为您希望将位图缩放到的尺寸。现在使用reqBitmap

这样,大位图在加载到堆内存之前将被缩小。我遇到了同样的问题,这为我解决了。 :)

关于java - Android 位图重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13011424/

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