【问题标题】:Large Canvas/Bitmap in Scrollview or redraw Canvas on scroll? What way is faster and also avoids java.lang.OutOfMemoryError滚动视图中的大画布/位图或在滚动时重绘画布?什么方法更快,也可以避免 java.lang.OutOfMemoryError
【发布时间】:2014-11-24 20:12:51
【问题描述】:

我知道我的位图/画布太大并且抛出 java.lang.OutOfMemoryError 的已知问题。 我的问题是什么最适合我的需求。 画布应该绘制一个图形(具有给定点)并且可以非常宽(例如 3000 像素或更多,理论上它的宽度可能更大,例如 20000 像素)。高度是固定的。 因为这对于任何屏幕来说都太宽了,所以我将它放在 Scrollview 中并将整个图形绘制到画布中。 所以这对于位图来说太宽了,我得到了错误。 第二种可能性是固定大小的画布,我将在其中编写一个“onScroll”方法,根据用户的滑动重绘图形。所以它只会绘制图表的一部分。 那会是更好的方法还是有办法使第一个选项起作用? 无论如何,请给我一些提示和解决方案的示例代码。

代码如下:

Bitmap bitmap  = Bitmap.createBitmap(speedCanvasWidth,speedCanvasHeight,Bitmap.Config.RGB_565); //I also tried ARGB_8888
speedCanvas    = new Canvas(bitmap);
graph.setImageBitmap(bitmap);

提前致谢

【问题讨论】:

    标签: java android canvas bitmap out-of-memory


    【解决方案1】:

    您可以使用BitmapRegionDecoder 处理此问题。只需创建一个指向您的图像的实例。系统将维护图像的句柄,然后您可以根据要在画布中显示的矩形在解码器上调用decode。必须根据您的需要处理对画布的更新。这将有助于防止加载您必须处理的大图像。

    您可以通过检查位图信息进一步获取相关位图的详细信息。这可以通过将位图加载到内存中来完成,并将 BitmapFactory.Options 标志设置为 true 为 inJustDecodeBounds。这可以防止位图在检查期间实际加载到内存中。

    例如,可以通过以下方式进行快速检索:

    BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance("pathToFile", true);
    Bitmap regionOfInterestBitmap = decoder.decodeRegion(rectWithinImage, null);//Or with options you have decided to load.
    

    【讨论】:

    • 问题是我没有图片。我正在画布上“实时”绘制图形。因此,使用此解决方案,我必须创建画布(一个非常宽的画布),在画布上绘制整个图形,然后使用您的解决方案将画布的一部分加载到位图中?如果是这样,那将是一个好主意。一些简短的提示如何做到这一点?
    • @Hömafreak 哦。这有点不同。我试图描述的解决方案的重点是防止基于您已经控制的图像将不必要的像素加载到内存中。如果您一次将它们全部加载到画布上,您将用尽内存来创建您想要的大小。移动系统上没有足够的可用内存来一次加载非常大的图像。
    • 好的,我也想过这个。那么更好的解决方案是我提到的第二种可能性?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多