我在一个文件中有一个大位图(比如3888x2592).现在,我想将该位图的大小调整为800x533并将其保存到另一个文件中.我通常会通过调用Bitmap.createBitmap
方法来缩放位图,但它需要一个源位图作为第一个参数,我无法提供,因为将原始图像加载到Bitmap对象当然会超出内存(例如,请参见此处).
我也无法读取位图,例如,BitmapFactory.decodeFile(file, options)
提供a BitmapFactory.Options.inSampleSize
,因为我想将其调整为精确的宽度和高度.使用inSampleSize
会将位图的大小调整为972x648(如果我使用inSampleSize=4
)或778x518(如果我使用inSampleSize=5
,它甚至不是2的幂).
我还想避免使用inSampleSize在第一步中使用例如972x648读取图像,然后在第二步中将其大小调整为800x533,因为与直接调整原始图像大小相比,质量会很差.
总结我的问题:是否有办法读取10MP或更高的大图像文件并将其保存到新的图像文件,调整大小到特定的新宽度和高度,而不会得到OutOfMemory异常?
我也尝试BitmapFactory.decodeFile(file, options)
手动将Options.outHeight和Options.outWidth值设置为800和533,但它不起作用.
我需要检查我的应用程序是否有内存泄漏,我还需要查看我的应用程序的内存分配.我下载并安装了eclipse内存分析器,看起来第一步是打开堆转储.但什么是堆转储,我如何创建堆转储.我将如何使用这个软件,我做了一些谷歌搜索,但我找不到任何有用的信息谢谢
在启用largeHeap
选项之前,我正在处理大型位图,它几乎消耗了应用程序可用的整个内存,并且通过导航回收它并加载新的内存几乎可以在完整的堆上运行.但是,当某些操作需要更多内存时,应用程序崩溃.所以我启用largeHeap=true
了更多的内存.
但这样做有一个意外的行为,它看起来像recycle()
位图的方法不工作的大部分时间,并在58MB工作的内存(并超过有时抛出的应用程序OutOfMemoryException
)现在消耗内存成倍而且还在不断增加(目前测试我确实来了231Mb分配的内存),预期的行为是内存管理继续工作,应用程序将不会使用超过60Mb.
我怎么能避免这种情况?还是有效地回收位图?
编辑:实际上,我OutOfMemoryError
在设备上分配超过390Mb的内存时给了它一个.读取GC_*日志显示只有GC_FOR_ALLOC有时会释放3.8Mb,但几乎从未在其他GC运行中释放过某些内容.
我试图找出这个内存泄漏.
我有两个SurfaceViews
,A
而且B
.我开始A
,然后导航到B
,然后按后退按钮返回A
,然后我B
再次导航.
我每次执行此操作时都可以看到分配的内存增加,最终我会出现内存不足错误.
以下是我B
从SurfaceView
连接内部导航到的方式A
Context context = this.getContext();
Intent i =new Intent(context, StartCareer.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
Run Code Online (Sandbox Code Playgroud)
在这两个视图中,我都有很多位图绘制.在B
,我找不到任何引用A
,并且在我可以想到的上下文之外的唯一引用是对我所拥有的Global类的引用.我还在后台进行了一些分析工作.我想,这可能是一百万种不同的东西
我在Eclipse上有DDMS视图,但我不确定我在看什么,或者如何找到不断重复的确切对象.
我接受DDMS分配跟踪器上的崩溃课程/教程,或者有人指出我做错了什么.
附加信息:
我有一些位图正在绘制SurfaceView
.这样的例子B
是:
////At class level
Bitmap rightB,leftB;
////In the constructor
rightB = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.right), 100,75, true);
////In doDraw
canvas.drawBitmap(rightB, rbX, rbY, null);
Run Code Online (Sandbox Code Playgroud)
还有我的onDestroys
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mThread.isAlive()){
mThread.setMenuRunning(false);
}
}
Run Code Online (Sandbox Code Playgroud)
所以我运行MAT并发现一次泄漏,至少.我的 …