Уменьшение размера изображения в памяти - PullRequest
6 голосов
/ 30 ноября 2010

Я ищу несколько советов о том, как создать программу с очень малым размером образа, которая будет запускаться как дочерний процесс моего приложения nodejs в linux.

Решение, которое я ищу, - это linuxисполняемый файл, который будет принимать строковое изображение base64 (загруженное с клиента) с помощью стандартного ввода, изменяя размер фотографии до указанного размера и затем перекачивая полученные данные изображения обратно через стандартный вывод.

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

Предложения библиотек или примеры предварительно скомпилированных исполняемых файлов на C / C ++ были бы весьма полезны.оценили.Также полезный ответ будет включать общие стратегии для изменения размера изображения с низким объемом памяти.

Спасибо

Ответы [ 6 ]

9 голосов
/ 30 ноября 2010

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

Стоит также отметить, что сокращение гигантских jpeg-файлов может быть эффективно выполнено путем простого пропуска высокочастотных коэффициентов и использования меньшего IDCT. Например, чтобы декодировать с половинной шириной и половинной высотой, отбросьте все, кроме верхнего левого квадранта коэффициентов (горизонтальная и вертикальная частота <4), и используйте для них IDCT 4x4 вместо обычных 8x8. И декодер <code>libjpeg, и декодер libavcodec поддерживают эту операцию для масштабирования степени 2 (1/2, 1/4 или 1/8). Этот тип подхода может сделать ненужным добавочное декодирование / масштабирование.

Вы можете попробовать это с djpeg -scale 1/4 < src.jpg | cjpeg > dest.jpg. Если вам нужен фиксированный выходной размер, вы, вероятно, сначала масштабируете в зависимости от того, какой из 1/2, 1/4 или 1/8 приблизит вас к желаемому размеру, не переходя к низкому, а затем выполните интерполяцию, чтобы перейти к последнему шагу например djpeg -scale 1/4 < src.jpg | convert pnm:- -scale 640x480 dest.jpg.

3 голосов
/ 06 января 2011

При работе с очень большими изображениями, такими как 0,25 GPix и более, ImageMagick использует ~ 2 ГБ оперативной памяти, даже при использовании djpeg для предварительного декодирования изображения JPEG.

Эта цепочка команд изменяет размеры изображений JPEG любого размера, используя только ~ 3 МБ ОЗУ:

djpeg my-large.jpg | pnmscale -xysize 16000 16000 | cjpeg > scaled-large.jpg
1 голос
/ 01 декабря 2010

Ничто не сравнится с Intel Integrated Performance Primitives с точки зрения производительности.Если вы можете себе это позволить, я настоятельно рекомендую использовать его.

В противном случае просто реализуйте свою собственную процедуру изменения размера.Lanczos дает неплохие результаты, хотя и не будет очень быстрым.

Редактировать: Я настоятельно рекомендую вам НЕ использовать Image Magick или Graphics Magick.Обе они являются отличными библиотеками, но предназначены для совершенно разных целей - обработки множества форматов файлов, глубины, форматов пикселей и т. Д. Они жертвуют производительностью и эффективностью памяти для вещей, о которых я упоминал.

1 голос
/ 30 ноября 2010

во всяком случае, это всего лишь пример, следующий за тем, что он описал:

import sys
from PIL import Image
import binascii
import cStringIO
x,y = sys.stdin.readline().strip().split(' ')
x,y = int(x), int(y)
img = Image.open(cStringIO.StringIO(binascii.b2a_base64(sys.stdin.read())).resize(x,y)
img.save(sys.stdout, format="png")

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

1 голос
/ 30 ноября 2010

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

0 голосов
/ 01 марта 2013

Возможно, вам понадобится: https://github.com/zhangyuanwei/node-images

Межплатформенный декодер изображений (png / jpeg / gif) и кодировщик (png / jpeg) для Nodejs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...