Сжатие растрового изображения с камеры - PullRequest
4 голосов
/ 31 марта 2011

Мне нужно отправить изображение, снятое с камеры, по сети. Изображение слишком большое, чтобы создать растровое изображение, необходимое для использования bitmap.compress (); Похоже, что приложение Gmail может прикреплять изображения с камеры, сохраняя при этом их большой размер в пикселях, но с большим уменьшением их размера файла.

Это не сработает, потому что я получаю getBitmap (), который будет возвращать Image для большого размера, и я не хочу делать сэмплы до меньшего размера.

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    getBitmap().compress(Bitmap.CompressFormat.JPEG, 70, baos);

Любые идеи о том, как я могу сделать то же самое, не превышая общую память?

Обновление:

Для тех, кто возвращается в эту ветку, я последовал ответу Фила и использовал Apache MultiPartEntity, чтобы легко выполнить работу. (Он обрабатывает потоковые файлы с диска в сеть для вас) http://hc.apache.org/httpcomponents-client-ga/httpmime/apidocs/org/apache/http/entity/mime/MultipartEntity.html

Ответы [ 5 ]

3 голосов
/ 31 марта 2011

Возможно, имеет смысл использовать архивирование перед отправкой по сети? InflaterInputStream на стороне отправителя и DeflaterOutputStream на принимающей стороне выглядит как рабочая комбинация.

ADDENDUM Попробуйте использовать другой подход:

FileOutputStream fos = new FileOutputStream(file); //intermediate file to store compressed image
InputStream is=this.getStream(imageUri); //image uri taken from camera
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize=2; //try to decrease decoded image
options.inPurgeable=true; //purgeable to disk
Bitmap bitmap=BitmapFactory.decodeStream(is, null, options);
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos); //compressed bitmap to file
2 голосов
/ 15 апреля 2011

Поскольку вы еще не определили, что именно здесь означает «отправка по сети», сложно дать конкретный совет.

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

Если вам просто нужно отправить по сети,тогда почему бы просто не открыть InputStream и не буферизовать данные непосредственно в сети?

Надеюсь, это поможет - если вы сможете предоставить более подробную информацию, я обновлю ответ.

С наилучшими пожеланиями,

Фил Лелло

0 голосов
/ 14 апреля 2011

Возможно, предварительно разделив изображение; сжатие каждого отдельного и восстановление в конце звучит логично.

Вот несколько попыток,

http://kalanir.blogspot.com/2010/02/how-to-split-image-into-chunks-java.html

И

http://www.anddev.org/multimedia-problems-f28/chunk-of-a-big-big-image-t6211.html

0 голосов
/ 13 апреля 2011

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

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

Если вы не знаете C и не играли с JNI и Android NDK , это будет непросто.В частности, компиляция сторонних библиотек для Android иногда бывает непростой задачей.

Но я полагаю, что использование единственного решения здесь - единственное решение.

0 голосов
/ 12 апреля 2011

Вы можете использовать нижнюю версию изображения, то есть с разрешением 512x384 (миниатюра). Отметьте этот ответ о том, как получить миниатюры.

Миниатюры уже сжаты до 80%.

...