Как оптимизировать загруженные пользователем изображения, а также существующие изображения на сервере в Meteor - PullRequest
2 голосов
/ 15 апреля 2019

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

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

Моя вторая мысль заключалась в использовании HTML-холста для изменения размера изображений.Это будет работать, я думаю, для недавно загруженных изображений.Но я все еще ищу способ обработки существующих изображений.

Я подумал:

  • Возможно, в AWS есть встроенный способ их обработки.Я бы не отказался сделать это таким образом.
  • Какой-то пакет Meteor / node, который может помочь с этим.
  • Настройка другого сервера только для обработки изображений.
  • Использование сторонней обработки изображений.

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

Ответы [ 3 ]

2 голосов
/ 15 апреля 2019

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

Например, с изображением JPG размером 10 000 x 10 000 пикселей, я вижу:

$ vipsheader wtc.jpg 
wtc.jpg: 9372x9372 uchar, 3 bands, srgb, jpegload
$ /usr/bin/time -f %M:%e vipsthumbnail wtc.jpg -s 5000x5000 -o x.jpg
98720:0.65

Это 4-ядерный 8-ниточный i7. Он использует 98 МБ памяти и занимает 0,65 с реального времени. В документах есть глава , в которой вводится vipsthumbnail .

Для сравнения, с ImageMagick 6 я вижу:

$ /usr/bin/time -f %M:%e convert wtc.jpg -resize 5000x5000 x.jpg
1263232:2.02

1,3 ГБ памяти, что занимает 2 секунды реального времени - примерно в 10 раз больше памяти и в 3 раза медленнее.

Поскольку vipsthumbnail использует так мало памяти, вы можете объединить его с параллельной GNU, не требуя сервера с большим количеством ГБ памяти. На этом i7 я могу с пользой запустить четыре за раз и получить примерно 4-кратное ускорение, так что, возможно, в 12 раз быстрее, чем ImageMagick в целом.

sharp - популярное связывание узлов для libvips , что может быть более удобным. Также есть привязки для Python, Ruby, PHP, Go, Lua и т. Д. И т. Д.

(отказ от ответственности: я один из сопровождающих libvips, поэтому я не очень нейтрален)

1 голос
/ 16 апреля 2019

Я вижу два пути на два совершенно разных бюджета:

  1. Этот способ я не рекомендую, если у вас только 1-2 ГБ (https://transloadit.com/demos/file-importing/resize-all-images-in-an-s3-bucket/)

  2. Свяжите свой S3 с сервисом Cloudinary и выполните преобразования с помощью Cloudinary (вам не понравится ($$) за количество изображений, которые у вас есть).

  3. Я надеюсь, что в AWS вы используете Cloudfront для обслуживания своих активов. Независимо от технологии преобразования, вы в основном будете делать 2 вещи:

    • Создать 1 лямбда-функцию для преобразования всех вновь созданных активов в S3. Что я делаю, так это "отслеживаю" корзину S3, и все новые вещи запускают мою функцию Lambda, и я создаю ресурсы в 2 других папках, и я получаю: полное разрешение, половинное разрешение и разрешение большого пальца. В Meteor вы затем связываете каждый размер с тем, что вам нужно. Наиболее типичный случай - когда у вас есть изображение профиля пользователя, которое вам нужно видеть в виде полного заголовка, списка или небольшого большого пальца в чате.
    • Создайте 1 Lambda Edge (чуть больше $$, я полагаю) и присоедините его к своему Cloudfront Edge, чтобы отвечать на все вызовы. Если для текущего сохраненного тома стоимость хранения не слишком высока, вы можете преобразовывать изображения по мере их запроса и заменять старые большие изображения, а не запускать их массовым образом как однократный процесс.

Вместо Lambda Edge вы, вероятно, могли бы настроить машину EC2 с Node и запустить функцию, чтобы перебрать все ваши ресурсы S3 и выполнить преобразование.

В любом случае, я чувствую, что все, что вы хотите сделать, это все AWS, не связанные с вашим Метеором. Еще одна вещь, которую нужно сделать: оптимизировать изображения перед их загрузкой. Если вы используете React с Meteor, я мог бы предоставить вам необходимые компоненты, в противном случае я могу дать вам компоненты, и вы напишите слой представления Blaze или все, что вы можете использовать.

У меня есть функции лямбда-преобразования в производстве, основанные на ImageMagic, на случай, если вы захотите пойти по этому пути. Я также планирую «обновить» эту функцию, чтобы использовать Sharp (как в примере), но в настоящее время она отлично работает в производственном процессе и переключится, когда у меня будет некоторое время. Проверьте этот пример:

  Download the image from S3, transform, and upload to a different S3 bucket or folder.

  const dstKeyResizedHalf = `p-half/` + imageName
  s3.getObject({
    Bucket: srcBucket,
    Key: srcKey
  }).promise()
    .then(data => Sharp(data.Body)
      .jpeg({
        chromaSubsampling: '4:4:4',
        progressive: true
      })
      .resize(WEB_WIDTH_MAX)
      .toFormat('jpg')
      .toBuffer()
    )
    .then(buffer => s3.putObject({
      Body: buffer,
      Bucket: dstBucket,
      ContentType: 'image/jpg',
      Key: dstKeyResizedHalf,
      CacheControl: 'max-age=864000'
    }).promise())
    .catch(err => callback(err))
}
0 голосов
/ 16 апреля 2019

Я использую https://www.imagemagick.org/ для изменения размера, обрезки, поворота моих изображений.это работает с метеором.Это будет хорошей отправной точкой для изучения.https://github.com/CollectionFS/Meteor-CollectionFS

...