Загрузка и загрузка изображений Android с помощью Base64 в JSON вызывает ошибку в памяти

В настоящее время я кодирую и декодирую изображения на Base64. Я преодолел первоначальную проблему с помощью OOM с использованием потоков для кодирования изображений в строки.

Моя проблема в том, что я не могу понять, как добавить несколько закодированных строк Base64 для изображений с несколькими разрешениями (5620 x 3747 – 4,92 МБ или 3264 x 1836 – 1,35 МБ) в объект JSON через Gson. В настоящее время Gons выбрасывает исключение OOM только с 2 строками Base64 из изображения 5312 x 2988 – 4.95 МБ.

Я понимаю, что андроид может только сэкономить 16 / 20Mb на одно приложение, поэтому это преобразование должно превышать лимит.

Как написать строку Base64 в потоке для объекта JSON, который будет содержать конкретные значения, необходимые для публикации на моем сервере?

Было бы проще изменить мой сервер, чтобы принять запрос Multi-Part вместо POJO на основе JSON с несколькими Base64 Strings? В настоящее время я использую Volley, и нет официального запроса Multi-Part, а также потоковой передачи ввода-вывода.

Если это вопрос сжатия, сколько сжатий следует применять к изображению перед кодированием в String Base64? Я в идеале хочу практически потерять качество, но иметь оптимальные уровни сжатия.

Бит больше информации

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

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

В некоторых случаях изображения, которые будут загружены, могут занимать от 1 до 200.

Я пытаюсь найти наиболее оптимальное решение, которое будет хорошо масштабироваться.

Solutions Collecting From Web of "Загрузка и загрузка изображений Android с помощью Base64 в JSON вызывает ошибку в памяти"

… для изображений с несколькими разрешениями (5620 x 3747 – 4,92 МБ или 3264 х 1836 – 1,35 МБ) …

Не уверен, что это размер файла или память, необходимая для размещения изображения в памяти, но взглянув на следующую ссылку: http://www.scantips.com/basics1d.html , я вижу следующее:

Для изображения размером 4000 x 2500 пикселей,

Затем: 4000 x 2500 пикселей = 4000×2500 = 10 мегапикселей

4000×2500 x 3 = 30 миллионов байт (если 24-бит RGB)

30 000 000 байтов / (1024 x 1024) = 28,61 мегабайт (МБ)

Это просто, насколько велики данные. Для ЛЮБОГО 24-битного 10-мегапиксельного изображения, но JPG-файлы сжимают его меньше (только в файле).

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

Кроме того, взглянув на этот вопрос и ответ: https://stackoverflow.com/a/11402374/3393666 , мы знаем, что представление base64 изображения занимает до 37% больше памяти, чем исходный размер изображения.

Как написать строку Base64 в потоке для объекта JSON, который будет содержать конкретные значения, необходимые для публикации на моем сервере?

Я думаю, вы могли бы сделать это (с небольшими изображениями не большими), просто добавив представление base64 изображения в объект JSON, а затем отправляя его на сервер.

Было бы проще изменить мой сервер, чтобы принять запрос Multi-Part вместо POJO на основе JSON с несколькими Base64 Strings?

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

В настоящее время я использую Volley, и нет официального запроса Multi-Part, а также потоковой передачи ввода-вывода.

Вы можете взглянуть на этот ответ: https://stackoverflow.com/a/16803473/3393666 , вы можете определенно сделать это с помощью волейбола, но если вам нужна альтернатива, вы можете попробовать с модификацией ( http: // square. Github.io/retrofit/ ), они поддерживают Multipart из коробки.

например:

@Multipart @PUT("user/photo") Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description); 

Я изучил использование Volley как механизма транспортировки больших объектов JSON на сервер и нашел этот ответ . Этот ответ по существу доказал, что Воллей будет плохой идеей для того, чего я хотел.

Я переключился на OkHttp и теперь использую их потоковые методы, позволяющие передавать JSON на сервер, а затем читать ответ с оптимизированным подходом. Я использовал библиотеку GSON для анализа ответа, так как OKHttp позволяет передавать JSON / Object JSON / Object в объект считывателя, который затем использует Gson для внутренней потоковой передачи и разбора в класс POJO.

Одна из причин, по которым я не переключился на запрос Multi-Part, был из-за того, что реализация на стороне сервера была жесткой и неизменной для покрытия запросов Multi-Part, она строго ожидала представления данных и файлов JSON.

Для обработки изображений Base64 на Android я настоятельно рекомендую не использовать представление String и просто конвертировать в Bytes, чтобы сэкономить на использовании чрезмерного объема памяти. Я прочитал эту статью об использовании и управлении памятью String . С помощью Bytes вы можете легко переносить данные, не оставляя массивного следа на памяти.

Для отображения изображений я все же избегаю преобразования байтов в String с помощью библиотеки изображений Glide . Они позволяют вам перейти в byte[] который был массивным удобством.