Как загрузить плитки из большого растрового изображения в Android?

Если у меня есть большой растровый файл, который обычно генерирует исключение "Недостаточно памяти", как я могу загрузить его в виде плиток? Например, у меня есть изображение размером 10 000 x 100 000, я хочу разделить его на сетку размером 10 x 10 пикселей размером 1000 x 1000 пикселей.

Я видел функцию Bitmap.createBitmap(sourceBitmap, x, y, width, height) но это требует моего большого изображения в качестве источника ввода.

Как я могу получить плитку из моего входного изображения без полной загрузки входного изображения?

3 ответа

Решение

Ответ от Romain Guy in Можно ли нарезать растровое изображение на маленькие кусочки, не загружая все это в память?:

Android 2.3.3 имеет новый API под названием android.graphics.BitmapRegionDecoder, который позволяет вам делать именно то, что вы хотите.

Вы, например, сделали бы следующее:

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

Легко:)

Если вам очень повезло, вы можете найти библиотеку, которая может загружать куски изображения из хранилища, а не загружать все это. Это зависит от формата изображения и от того, какие библиотеки доступны для его чтения. Кроме того, библиотека, вероятно, будет написана на C, поэтому вам придется перенести ее на Java или использовать NDK.

Было бы гораздо лучше разбить изображение на плитки до того, как оно будет помещено на телефон.

Если ни один из этих вариантов не работает для вас, я думаю, вам не повезло.

Если изображение хранится в виде сжатого растрового изображения, то практически невозможно рассчитать, где в файле находится конкретная область изображения. Чтобы найти конкретный регион, вы должны декодировать построчно, отбрасывая результаты, пока не доберетесь до строки y. Затем вы продолжаете декодирование для строк высоты, отбрасывая пиксели слева от вашей координаты X и справа от ширины X+.... очень медленно, если вы перемещаетесь по нижней части большого растрового изображения.

Читая между строк, кажется, что BitmapRegionDecoder(), упомянутый ранее, делает это в фоновом режиме, если isShareable имеет значение true. В противном случае создается впечатление, что оно может распаковать изображение и сохранить несжатую копию. С 1 байтом на пиксель потребуется 100 МБ для хранения вашего растрового изображения размером 10 000x100 000.

Другие вопросы по тегам