我被困3天了。我得到了一个Dicom文件,我需要使用缓冲读取器进行解析,该读取器从文档的标题和图像的原始数据中返回一些信息。之后,我在raw上应用LUT将字节转换为灰度,然后将其抛入Bitmap.create
。这对于小图片来说是完美的,但是现在,我必须加载13Mo图像,不仅需要花费很长时间才能打开它(大约20秒),而且,在应用位图方法的LUT时,Android会抛出关于Bitmap的错误{ {1}} 29052480-byte external allocation too large for this process.
。我知道有很多线程关于这个错误,但在我的情况下,它有点原始,因为我只想打开一个图像(所以它不是关于堆叠多位图)。我可以给你看一些代码:
RefreshBmp:
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
哪个叫我的LUT:
private void refreshBmp(int windowWidth, int windowCentre) {
int[] colorArray = process.transformBuffer(myDicomObject.getRawData(),
myDicomObject.isInverted(), windowWidth, windowCentre,
myDicomObject.getnBits());
Bitmap bmp = Bitmap.createBitmap(colorArray,
myDicomObject.getColumns(), myDicomObject.getRows(),
Bitmap.Config.ARGB_8888);
dicomImageView.setImageBitmap(bmp);
}
希望有人知道一种节省内存分配的方法,特别是LUT方法。
答案 0 :(得分:0)
如果你不需要它,你应该尝试直接修改rawData
。像这样:
public void transformBuffer(int[] rawData, boolean inverted,
int windowWidth, int windowCenter, int nBits) {
/*
change rowData instead resultBuffer
*/
}
public void methodThatCallsTransformBuffer(...) {
transformBuffer(data, inverted, ...);
//now data is transformed
}
另外,使用lutBuffer
,您可以为每个像素计算colorValue
。你会节省一些内存会慢一点:
int colorValue = 0;
if (inverted) {
if (rawData[i] < min) {
colorValue = 255;
} else {
if (rawData[i] < max) {
double value = doubleGrayScale * ((i - dmin + 1) / (dmax - dmin + 1));
colorValue = (int) (doubleGrayScale - value) >> intDivisionFactor;
}
}
} else {
if (rawData[i] >= min && rowData[i] < max) {
double value = doubleGrayScale * ((i - dmin + 1) / (dmax - dmin + 1));
colorValue = (int) (doubleGrayScale - value) >> intDivisionFactor;
} else if (rowData[i] > max) {
colorValue = 255;
}
}
答案 1 :(得分:0)
当我最终找到解决方案时,我决定回答自己。使用那些大的Bitmap数据可以避免这个OutOfMemory
错误的唯一方法是进行分箱后(如果它是实际名称,我就不知道了)。它包括拍摄每个替代像素。您可以通过读取一个像素,跳过一个,读取另一个像素,跳过一个并继续执行此操作直到到达行尾,然后跳过一行并继续此过程到数据缓冲区的末尾来执行此操作。
我希望它可以帮助别人。