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

Я работаю над приложением обработки изображений для Android, которое распознает нотацию музыки по фотографиям, сделанным из музыкальных листов.

Я попытался загрузить все изображение в растровое изображение с помощью метода BitmapFactory.decodeFile (imgPath), но из-за недостатка памяти на моем телефоне возникает ошибка "Размер кучи виртуальной машины". Чтобы обойти это, я хотел бы нарезать полное изображение на более мелкие кусочки, но я не уверен, как это сделать.

Я также увидел, что можно уменьшить размер памяти для растрового изображения, используя свойство inSampleSize класса BitmapFactory.Option, но если я это сделаю, то не получу изображение с высоким разрешением, которое мне нужно для процесса распознавания нотной записи.

Есть ли способ справиться с этим, не переходя в NDK?

3 ответа

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);

Легко:)

Если вы имеете дело с изображениями в формате JPEG, посмотрите мой ответ на этот вопрос, а также на этот пример.

Я не знаю, насколько возможно получить libijg на Android, но если это так, то стоит попробовать.

Если это с камеры, изображение, скорее всего, будет в формате JPEG. Вы можете использовать внешнюю библиотеку jpeg - либо в java, либо через NDK, что бы вы ни нашли - чтобы лучше контролировать и загружать ее по частям за раз. Если вам это нужно как android.graphics.Bitmap тогда я подозреваю, что тогда вам нужно будет перекодировать субизображение как PNG или JPEG и передать его BitmapFactory.decodeByteArray(), (Если проблема связана с памятью, обязательно забудьте о ссылках на фрагменты растрового изображения, чтобы сборщик мусора мог работать эффективно.)

Эта же методика также будет работать, если входная графика имеет формат PNG или что-то еще, при условии, что вы можете найти подходящий код декодирования для нее.

Я думаю, что, загружая изображение по частям, вы ставите перед собой алгоритмическую задачу, решая, в каких частях вы действительно заинтересованы во всех деталях. Я замечаю что BitmapFactory.Options включает опцию подвыборки, которая может быть полезна, если вы хотите проанализировать обзор изображения, чтобы решить, какие области загружать в деталях.

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