Больший объем памяти при использовании BitmapFactory.DecodeFile в C # (и огромная память для крошечного изображения)

1

Я просто хочу узнать, заметил ли кто-нибудь еще, что при загрузке изображений в память тот же С# -код использует больше памяти для хранения изображений (~ 1.5x сумма в Java).

Этот Java-код дает общий объем памяти 105,5 МБ:

Bitmap[] bitmaps = new Bitmap[100];

for (int i = 0; i < 100; i++)
{
    String root = Environment.getExternalStorageDirectory().getAbsolutePath();
    String imagePath = "/evolution/threesixty/216/Edaphosaurus_001.jpg";

    bitmaps[i] = BitmapFactory.decodeFile(root + imagePath);
}

Этот код С# приводит к 148,1 МБ:

Bitmap[] bitmaps = new Bitmap[100];

for (int i = 0; i < 100; i++)
{
    string root = Environment.ExternalStorageDirectory.AbsolutePath;
    string imagePath = "/evolution/threesixty/216/Edaphosaurus_001.jpg";

    bitmaps[i] = BitmapFactory.DecodeFile(root + imagePath);
}  

У кого-нибудь есть идеи относительно того, почему? Я понимаю, что обертки.NET могут использовать немного больше для хранения дополнительных данных привязки или вещей, но, конечно же, не так много?

Кроме того, в качестве побочного вопроса: каждое изображение составляет всего 60 Кбайт на диске, почему в версии с памятью 1 МБ? Я знаю, что мой метод загрузки не проверяет выборку/плотность, но это не было целью. Несомненно, загрузка изображения <100 КБ не должна превышать 100 КБ памяти?

Вот изображение, которое я использую (994x748px @300dpi):

Изображение 174551

Теги:
xamarin.android
image
memory
bitmap

2 ответа

2
Лучший ответ

На основе ответов из списка рассылки Mono для Android:

Изображения, которые вы загружаете, сжаты jpg. Растровое изображение - несжатый формат. Небольшой Googling показал типичный коэффициент сжатия JPEG от 10: 1 до 20: 1 без потери заметного качества изображения. 60 КБ → 1 МБ в этом диапазоне.

И другой:

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

Посмотрев на эту информацию об сжатии (я понятия не имею, что происходит в моей голове, поскольку я понимаю, что сжатие уменьшает объем памяти в памяти для сохранения и загрузки, а затем распаковывает его в память), теперь я понимаю, как все работает; ) Изображение будет распаковано до почти 2 МБ при сохранении в виде растрового изображения - и если я посмотрю на свойства изображения в Irfanview.

Итак, теперь я устанавливаю размер выборки Bitmap.Config.Rgb565 2 и использую Bitmap.Config.Rgb565. Это уменьшает общий размер изображений до примерно 30 МБ, что намного лучше. Хотя качество не так хорошо, я могу загрузить изображение с более высоким разрешением, когда оно мне нужно, и пользователь не знает.

4

Ваша цифра 148,1 МБ для 100 изображений - это точная цифра, которую я ожидал бы для этого. 994 x 748 дает 743 512 пикселей; предполагая, что вы используете формат, который использует 2 байта на пиксель (что очень низкокачественно для изображения, FWIW - формат RGB565 должен был быть запрещен на международном уровне несколько десятилетий назад), что дает вам 1.481 МБ на изображение. Это, конечно, намного больше размера изображения на диске, потому что файл изображения сжимается.

Я понятия не имею, почему версия Java будет потреблять всего 105,5 МБ; нет никакого формата растрового изображения, который я знаю, который использует 1.333 байт на пиксель. Скорее всего, вы неправильно читаете использование памяти, иначе среда выполнения Java кэширует некоторые изображения на диск, а не сохраняет их в памяти.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню