Декодирование битовых массивов в Android с правильным размером

Я декодирую битовые массивы от использования SD-карты BitmapFactory.decodeFile. Иногда битовые массивы больше, чем, что потребности приложения или что "куча" позволяет, таким образом, я использую BitmapFactory.Options.inSampleSize запрашивать подвыбранный (меньший) битовый массив.

Проблема состоит в том, что платформа не осуществляет точное значение inSampleSize, и я иногда заканчиваю с битовым массивом, или слишком маленьким, или все еще слишком большим для доступной памяти.

Из http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize:

Примечание: декодер попытается обработать этот запрос, но полученное растровое изображение может иметь различные размеры, что точно, что требовали. Кроме того, полномочия 2 часто более быстры/легче, чтобы декодер соблюдал.

Как я должен декодировать битовые массивы от SD-карты для получения битового массива точного размера, в котором я нуждаюсь при потреблении как можно меньшей памяти для декодирования ее?

Править:

Текущий исходный код:

BitmapFactory.Options bounds = new BitmapFactory.Options();
this.bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, bounds);
if (bounds.outWidth == -1) { // TODO: Error }
int width = bounds.outWidth;
int height = bounds.outHeight;
boolean withinBounds = width <= maxWidth && height <= maxHeight;
if (!withinBounds) {
    int newWidth = calculateNewWidth(int width, int height);
    float sampleSizeF = (float) width / (float) newWidth;
    int sampleSize = Math.round(sampleSizeF);
    BitmapFactory.Options resample = new BitmapFactory.Options();
    resample.inSampleSize = sampleSize;
    bitmap = BitmapFactory.decodeFile(filePath, resample);
}

61
задан hpique 23 April 2010 в 09:34
поделиться

5 ответов

Вы на правильном пути, однако вы пытаетесь сделать сразу две вещи: прочитать файл и масштабировать его до подходящего размера.

Первым шагом является считывание файла в растровое изображение немного большего размера, чем требуется, с помощью BitmapFactory.Options.inSampleSize, чтобы гарантировать, что вы не потребляете чрезмерное количество памяти при чтении большого растрового изображения, когда все, что вам нужно, - это уменьшенная миниатюра или разрешение экрана. изображение.

Второй шаг - вызвать Bitmap.createScaledBitmap () для создания нового растрового изображения с точным разрешением, которое вам требуется.

Убедитесь, что вы очистили временное растровое изображение, чтобы освободить его память. (Либо позвольте переменной выйти за пределы области видимости и позвольте сборщику мусора заниматься этим, либо вызовите для нее .recycle (), если вы загружаете много изображений и не хватает памяти.)

45
ответ дан 24 November 2019 в 17:23
поделиться

Вы можете использовать inJustDecodeBounds . Установите значение TRUE и загрузите файл как есть.

Изображение не загружается в память. Но свойства outheight и outwidth для BitmapFactory.Options будут содержать параметры фактического размера указанного изображения. Подсчитайте, сколько вы хотите получить субдискретизацию. т.е. 1/2, 1/4 или 1/8 и т. д. и назначьте 2/4/8 и т. д. в соответствии с inSampleSize .

Теперь установите для inJustDecodeBounds значение FALSE и вызовите BitmapFactory.decodeFile () , чтобы загрузить изображение точного размера, как рассчитано выше.

15
ответ дан 24 November 2019 в 17:23
поделиться

Поскольку API уже заявляет, что размер выборки может или не может быть соблюден. Думаю, вам не повезло при использовании BitmapFactory .

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

Я бы постарался не слишком беспокоиться о небольшом дополнительном потреблении памяти, но попытался бы выяснить, почему не соблюдаются значения. К сожалению, я понятия не имею об этом: (

1
ответ дан 24 November 2019 в 17:23
поделиться

Поскольку я использую inSampleSize, я больше не сталкиваюсь с проблемами нехватки памяти. Так что inSampleSize у меня работает довольно стабильно. Я бы порекомендовал вам дважды проверить проблему. Размер может быть не таким, как вы просили. Но его все равно надо уменьшить и больше не должно быть "Out of memory". Я бы также рекомендовал разместить здесь свой фрагмент кода, возможно, с ним что-то не так.

0
ответ дан 24 November 2019 в 17:23
поделиться

Как the100rabh сказал, что если вы используете BitmapFactory, у вас действительно нет большого выбора. Однако декодирование растрового изображения действительно просто, и в зависимости от алгоритма масштабирования, который вы хотите использовать, обычно довольно просто масштабировать его на лету без необходимости считывать большие части исходного растрового изображения в память (как правило, вы нужно только удвоить объем памяти, необходимый для 1-2 строк исходного растрового изображения).

0
ответ дан 24 November 2019 в 17:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: