Firebase потрясающая. Как написано в предыдущей статье JSMonday, он позволяет нам писать бессерверные приложения, аутентифицировать пользователей и многое другое.
Firebase также предлагает услугу Firebase Storage, которая чем-то похожа на AWS S3. Вы можете создать ведро, а затем вставить в него любой файл. Обычно он используется для хранения изображений, но здесь возникает проблема: что, если пользователь загружает невероятно тяжелое изображение? Вы можете изменить его размер!
Давайте посмотрим, как это сделать с помощью функций Firebase.
Прежде всего, давайте инициализируем новый проект Firebase Functions.
Затем давайте установим пару пакетов npm:
Как видите, мы устанавливаем эти три пакета:
@google-cloud/storage
позволяет получать изображения из Firebase Storage.fs-extra
, который включает в себя модульfs
по умолчанию для Node.js и предоставляет его функции с помощью обещаний.sharp
, потрясающая и высокопроизводительная библиотека для работы с изображениями для Node.js
Теперь мы готовы написать наш инструмент для изменения размера изображения!
Давайте перейдем к нашему functions/index.js
файлу и начнем импортировать необходимые нам зависимости:
Большой! Теперь мы можем начать писать наш обработчик функции:
Как видите, мы сообщаем нашей функции Firebase, что нам нужно как минимум 2 ГБ памяти и максимум 120 секунд времени для выполнения нашей функции. Мы также заявляем, что нам нужно активировать эту функцию после того, как изображение будет загружено в нашу корзину (storage.object().onFinalize
).
Напишем функцию handler
:
Нам нужно получить кучу информации из нашего аргумента object
(который на самом деле является объектом, описывающим, куда было загружено наше изображение):
- Bucket: сегмент, в который мы загрузили изображение.
- Путь к файлу: путь к файлу внутри нашего сегмента.
- Имя файла: имя загруженного файла.
- Bucket Directory: имя каталога, в который мы загрузили наше изображение.
Теперь мы можем создать временный каталог, в котором мы будем выполнять наш код изменения размера. Мы также создадим временный файл, с которым будем выполнять наши манипуляции.
Теперь возникает проблема: наша функция запускается каждый раз, когда в нашем Bucket создается новый файл ... но на самом деле мы создаем новое изображение с измененным размером, так как же нам избежать бесконечного цикла изменения размера?
Мы зададим имя типа myImage@s_1920.jpg
для нашего изображения с измененным размером (где s_
означает «размер»), чтобы мы могли проверить, является ли вновь созданное изображение результатом изменения размера или нет.
image само по себе является изображением с измененным размером, мы выйдем из нашей функции.
Теперь нам просто нужно скачать только что созданный образ. Мы загрузим его по ранее созданному пути временного файла:
Теперь мы готовы приступить к изменению размера! Допустим, нам нужно создать три разных размера: 1920 пикселей, 720 пикселей, 100 пикселей. Давайте превратим эти значения в массив:
Теперь нам нужно запустить средство изменения размера, поэтому мы создадим обещание для каждого размера внутри нашего массива:
Как видите, процесс довольно простой:
- Получите расширение изображения.
- Получите исходное имя изображения.
- Создайте окончательное имя изображения.
- Получите свой путь.
- Теперь давайте запустим
sharp
и изменим размер изображения, а затем сохраним его в файл. - И последнее, но не менее важное: загрузите изображение в исходную корзину с новым именем файла.
Теперь нам просто нужно выполнить эти три обещания ... но мы не хотим запускать их последовательно, это может занять слишком много времени! Поэтому мы будем использовать Promise.all
, чтобы запускать их одновременно:
Готово!
Давайте развернем функцию и протестируем ее, загрузив файл в Firebase Storage:
Теперь мы готовы запустить наше средство изменения размера!
В JSMonday мы фактически используем приведенный выше код для изменения размера наших изображений:
Не стесняйтесь повторно использовать приведенный выше код для изменения размера изображения!