简体   繁体   English

如何从Android中的大位图加载切片?

[英]How to load tiles from a large bitmap in Android?

If I have a large bitmap file that would normally generate an "Out of memory" exception, how can I load it as tiles? 如果我有一个通常会产生“内存不足”异常的大型位图文件,我该如何将其加载为tile? eg I have a 10,000x10,000 image, I want to split it up into a 10x10 grid of 1,000x1,000 pixel tiles. 例如,我有10,000x10,000的图像,我想将其分成10x10网格的1,000x1,000像素图块。

I've seen the function Bitmap.createBitmap(sourceBitmap, x, y, width, height) but it requires my large image as the source input. 我见过函数Bitmap.createBitmap(sourceBitmap, x, y, width, height)但它需要我的大图像作为源输入。

How can I get a tile from my input image, without fully loading the input image? 如何在不完全加载输入图像的情况下从输入图像中获取图块?

Answer from Romain Guy in Is it possible to chop a bitmap to small pieces without loading the entire thing into memory? 来自Romain Guy的回答是否可以将位图切成小块而不将整个内容加载到内存中? :

Android 2.3.3 has a new API called android.graphics.BitmapRegionDecoder that lets you do exactly what you want. Android 2.3.3有一个名为android.graphics.BitmapRegionDecoder的新API,可让您完全按照自己的意愿行事。

You would for instance do the following: 例如,您可以执行以下操作:

 BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false); Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null); 

Easy :) 简单 :)

If the image is stored as a compressed bitmap, then it's virtually impossible to calculate where a particular region of the image is located in the file. 如果图像存储为压缩位图,则几乎不可能计算图像的特定区域在文件中的位置。 To find a particular region, you would decode line by line, throwing away the results until you get to row y. 要查找特定区域,您将逐行解码,丢弃结果,直到您到达y行。 You then continue decoding for height rows, throwing away the pixels to the left of your X coordinate and to the right of X+width.... very slow if you're panning across the bottom of a large bitmap. 然后,您继续解码高度行,将像素丢弃到X坐标的左侧和X +宽度的右侧....如果您在大位图的底部平移,则非常慢。

Reading between the lines, it appears that the BitmapRegionDecoder() mentioned earlier does this in the background if 'isShareable' is true. 在行之间进行读取,如果'isShareable'为真,前面提到的BitmapRegionDecoder()似乎在后台执行此操作。 Otherwise it seems that it may uncompress the image, and store the uncompressed copy. 否则,它似乎可以解压缩图像,并存储未压缩的副本。 With 1 byte per pixel, it will take 100MB to hold your 10,000x10,000 bitmap. 每像素1个字节,占用10,000x10,000位图需要100MB。

If you're very lucky, you can find a library that can load chunks of an image from storage rather than loading the entire thing. 如果你很幸运,你可以找到一个可以从存储中加载图像块而不是加载整个图像的库。 It depends on the image format, and what libraries are available to read it. 这取决于图像格式,以及可用于读取的库。 Plus, the library will probably be written in C, so you'll have to port it to Java or use the NDK. 另外,库可能是用C语言编写的,因此您必须将其移植到Java或使用NDK。

It would be far better to break the image into tiles before it's placed onto the phone. 在将图像放入手机之前将图像分解成图块要好得多。

If neither of these options work for you, I think you're out of luck. 如果这些选项都不适合你,我认为你运气不好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM