Сжимайте изображения без чтения в память

У меня есть большой файл изображения на SD-карте, который я хочу сжать перед загрузкой на сервер. Но чтобы сжать изображение с помощью Bitmap.compress(CompressFormat format, int quality, OutputStream stream), нам нужно прочитать изображение в память и сохранить сжатую версию. Есть ли способ создать сжатую версию изображения без чтения растрового изображения в память.

Я использую следующий код для сжатия.

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;

Bitmap finalBitmap = BitmapFactory.decodeFile(originalFile.getAbsolutePath(), options);    

File local = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),  "/my_images");
local.mkdirs();
File compressedFile = new File(local, "test.jpg");
FileOutputStream out = new FileOutputStream(compressedFile);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 70, out);

person Ammar    schedule 28.03.2017    source источник
comment
Сохраните растровое изображение на диск и сожмите файл.   -  person Rod_Algonquin    schedule 28.03.2017
comment
Изображение уже сохранено на диске и весит около 100 МБ. Поэтому я не хочу загружать растровое изображение в память, так как это вызовет OOM. Мне нужно создать сжатую версию файла, чтобы оптимизировать время загрузки.   -  person Ammar    schedule 28.03.2017
comment
в каком формате вы загружаете свое изображение?   -  person Mohammed Atif    schedule 28.03.2017
comment
Есть ли вообще смысл в сжатии изображения на устройстве? Я имею в виду загрузить его на сервер и сжать его там, если это необходимо - у него наверняка будут намного превосходящие ресурсы?   -  person Mark Keen    schedule 28.03.2017
comment
100мб? какое разрешение изображения?   -  person Mohammed Atif    schedule 28.03.2017
comment
@MarkKeen Мне нужно оптимизировать время загрузки, поэтому на клиенте требуется сжатие.   -  person Ammar    schedule 28.03.2017
comment
@MohammedAtif Это файл JPG с разрешением 7787   ×   11601. На самом деле это тестовый файл, но ожидается, что мое приложение столкнется с огромными файлами в реальных случаях использования.   -  person Ammar    schedule 28.03.2017
comment
это слишком много для файла изображения. как насчет использования файла svg вместо большого jpeg?   -  person Mohammed Atif    schedule 28.03.2017
comment
Используйте процедуру сжатия zip для файла изображения, как было предложено. Не уверен, как вы сожмете его намного больше, если это уже jpeg - без существенной потери качества, то есть - также к тому времени, когда оно сжато, вы могли бы загрузить изображение - я предполагаю, что с изображениями такого размера вы будете использовать wi- фи.   -  person Mark Keen    schedule 28.03.2017
comment
@MohammedAtif мы не можем ограничивать типы входных изображений пользователем.   -  person Ammar    schedule 28.03.2017
comment
я никогда не видел ни одного идеального пользователя Android с 100-мегабайтным jpeg-файлом на своем телефоне. ваша текущая проблема больше связана с обработкой ввода, а не с загрузкой. не могли бы вы предоставить более подробную информацию об изображении. например, какие данные он содержит и как он генерируется и т. д.   -  person Mohammed Atif    schedule 28.03.2017


Ответы (1)


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

person greenapps    schedule 28.03.2017
comment
Я не хочу уменьшать изображение, вместо этого мне нужно иметь изображение в исходном масштабе с некоторым сжатием, чтобы уменьшить размер/время загрузки. - person Ammar; 28.03.2017
comment
jpeg — лучшее сжатие, которое вы можете сделать на мобильной стороне. даже после этого, если это 100 МБ, то что-то не так с тем, как вы создаете изображение @Ammar - person Mohammed Atif; 28.03.2017
comment
I need to have original scale image with some compression to reduce size/upload time. . Невозможно. А jpg уже максимально сжат. Размер может быть уменьшен только для более низкого качества. Но для этого вам сначала нужно создать это невозможное растровое изображение. Ужасно, как вы сформулировали свою проблему. - person greenapps; 28.03.2017
comment
@MohammedAtif Я обновил вопрос, чтобы включить код, который я использую для сжатия изображения. Вопрос не в том, какой метод сжатия лучше. Вопрос в том, как сжать jpeg без загрузки растрового изображения из файла изображения. - person Ammar; 28.03.2017
comment
@greenapps Входное изображение может быть любым, не обязательно JPG. - person Ammar; 28.03.2017
comment
@ Аммар, мой вопрос: где вам удалось найти файл изображения размером 100 МБ на устройстве Android? Я знаю, что у вас уже есть некоторые предположения относительно решения, но вы не найдете идеального решения, если не перестанете защищать свой имидж и не начнете предоставлять больше информации о нем. - person Mohammed Atif; 29.03.2017