1. Предпосылки
В бизнес-требованиях обычным сценарием является динамическое создание общего доступа к изображениям на основе возвращенных данных. Например, в апплете чтения с начальной точки каждая книга должна генерировать динамическое изображение, включая: название книги, автора, категорию и код апплета текущей страницы, которые будут динамически изменяться.
Так как же абстрагироваться и реализовать такие требования с высокой производительностью? Давайте вместе обсудим схему генерации динамических картинок.
Во-вторых, сравнение программ
В настоящее время в отрасли существует множество решений для реализации динамических изображений, которые в основном делятся на два типа: реализация на стороне клиента и реализация на стороне сервера.Основываясь на наших исследованиях и практическом опыте, следующие два метода реализации и их преимущества и недостатки вводятся соответственно.
2.1 Реализация клиента — html2canvas
Студенты, реализовавшие функцию генерации динамических картинок, должны быть знакомы с html2canvas.Одна функция может рисовать html на холсте, а затем информацию о картинке можно получить через метод toDataUrl холста. Общий процесс примерно такой:
Но раз уж вы использовали html2canvas, то должны знать, что этот процесс не так уж и гладок. Как говорится в файле readme, он не обязательно на 100% восстанавливает внешний вид html-элементов на веб-страницах. Проявляется множество проблем:
а. Совместимость: несоответствие на разных концах,Некоторые свойства не поддерживаются
б) сгенерированное изображение неполное из-за медленной загрузки ресурсов
в) слишком долго
г. Комплексная отладка
Проще говоря, его основной принцип состоит в том, чтобы пройти и проанализировать элемент dom, а затем использовать метод рисования холста, чтобы максимально восстановить внешний вид элемента dom на веб-странице. Хотя он проделал большую работу, он все еще не может восстановить все css с полной точностью.
2.2 Реализация сервера: Puppeteer
Поскольку у html2canvas так много ям, можем ли мы отказаться от схемы рендеринга в Canvas, но напрямую отображать html в веб-странице, а затем напрямую делать скриншот. Кукольник может сделать это за нас.
На самом деле Puppeteer — это браузер Chrome, которым можно управлять с помощью кода.Вы можете открыть вкладку Chrome через API Puppeteer, отобразить Html и сделать снимок экрана. Таким образом мы унифицируем среду генерации образов и решаем проблему совместимости.
выглядит неплохо? Тем не менее, производительность Puppeteer действительно беспокоит в наших реальных измерениях, поскольку Puppeteer должен создавать новую вкладку браузера каждый раз, когда он создает изображение, а затем ему нужен соответствующий процесс для рендеринга веб-страницы и создания скриншотов, когда есть много запросов, он будет занимают много серверных ресурсов, его QPS трудно оправдать наши ожидания.
Мы испробовали некоторые схемы оптимизации, в том числе оптимизацию элементов автозагрузки, повторное использование экземпляров браузера, инициализацию нескольких экземпляров браузера и т. д., но вычислительные затраты по своей природе довольно велики, а окончательный QPS по-прежнему неудовлетворителен.
2.3 Другие реализации сервера
Мы также провели некоторые исследования других серверных решений (на основе NodeJS):
- Инструменты для работы с изображениями (Jimp/Sharp):Этот тип инструмента представляет собой инструмент обработки графики, который в основном может выполнять такие операции, как растяжение, обрезка и наложение изображений.
- Рисунок холста на стороне сервера (domjs+canvas-node/fabric.js):Такое решение похоже на процесс html -> canvas -> изображение, но теперь этот процесс обрабатывается на стороне сервера.
- webshot (инструмент, похожий на Puppeteer):Он работает как безголовый браузер.
После тестирования производительности их производительность аналогична производительности puppeteer, но они все еще не соответствуют требованиям производственной среды.
2.4 Окончательное решение: Голанг
Проанализировав приведенные выше различные схемы динамической генерации изображений, мы обнаружили, что будь то генерация на стороне клиента или генерация на стороне сервера через Nodejs + Puppeteer и т. д., совместимость и производительность не очень хороши. Итак, можем ли мы вырваться из присущего интерфейсу образа мышления, выбрать внутренний язык, преодолеть ограничения, налагаемые NodeJ (не подходит для операций с интенсивным использованием ЦП), и эффективно генерировать изображения?
Благодаря исследованиям большинство языков программирования имеют библиотеки, поддерживающие синтез изображений (например, imagemagick), учитывая, что Nodejs не подходит для таких ресурсоемких задач, мы наконец принялиРендеринг Golang + хранилище данных NodeJsдля генерации изображений. Почему стоит выбрать Golang: Причина очень проста, главная причина в том, что относительно просто ознакомиться с синтаксисом, интерфейс можно использовать быстро, а принцип можно напрямую скомпилировать вМашинный код, не зависит от других библиотек, быстрое время компиляции, высокая эффективность разработки и работы, а также некоторые концепции сопрограмм;
3. Конкретные решения
Для выбранной нами схемы сначала определимКак генерировать картинки: Обратитесь к функции экспорта изображений в Photoshop, которая объединяет все слои для создания единого изображения.
Для большинства сценариев, как показано на рисунке ниже, динамически изменяющимися частями являются изображения и текст.Если сервер может реализовать наложение и синтез изображений и текста, эти сценарии могут быть удовлетворены.
3.1 Общий дизайн
В настоящее время проект создания изображения должен пройти следующие части, мы разделили его на 3 слоя:
платформа визуализации: Создайте новый проект и используйте слои для создания желаемого изображения;
сервисный уровень nodejs: Сохранение, чтение и другие операции с данными слоя;
слой рендеринга изображений golang: Слой данных для создания изображений;
Глядя на приведенное выше изображение слева направо, слева показан процесс генерации внешнего изображения, а справа — промежуточный процесс управления внутренним слоем изображения. Оба читают данные через нижнюю базу данных, а наши данные - это информация слоя, хранящаяся в формате json. Вся система (и внешняя, и внутренняя) читает и модифицирует эти данные слоя. Формат данных Вероятно, следующий:
[
{
"type": "image", // 类型。比如:image、text、canvas
"name": "画布", // 自定义的名称
"w": 251, // 宽度
"h": 323, // 高度
"x": 0, // x 偏移量
"y": 0, // y 偏移量
"paramName": "", // 绑定的变量名
"content": "xxx", // 内容
"color": null, // 颜色
"opacity": 1, // 透明度
"bgColor": "rgba(255, 255, 255, 0)", // 背景色
"contentType": "img", // 内容的类型
...
}
]
3.2. Внутреннее — визуальная платформа конфигурации
Мы разработали платформу визуализации для управления и создания изображений. Пользователи могут комбинировать окончательные желаемые изображения в виде перетаскивания, что значительно снижает стоимость разработки. Как показано ниже:
Возможности, предоставляемые платформой: Обеспечьте встроенные компоненты: компонент изображения, компонент текста, компонент QR-кода
Перетаскивание компонентов: вы можете быстро изменить положение компонентов, перетащив их
Настройки свойств: вы можете установить различные свойства для компонентов, такие как ширина и высота, цвет, выравнивание
Настройки параметров: вы можете привязывать параметры к компонентам и изменять параметры в URL-адресе при их использовании для динамического отображения.
Режим разработчика: когда встроенные функции платформы не могут удовлетворить потребности, вы можете использовать режим разработчика для достижения
Сгенерируйте json, описывающий информацию о слоях для серверной генерации изображений.
Функция автоматического сохранения
3.3 Внешнее — генерация изображений Golang
Golang предоставляет базовую библиотеку изображений для обработки изображений.Основываясь на некоторых существующих возможностях обработки графики, текста и изображений, мы расширили весь набор методов процесса генерации изображений. Общий процесс выглядит следующим образом:
- Сборка данных: синтез данных слоя и переменных параметров для получения данных слоя графика.
- Генерация слоя: в настоящее время существует три типа слоев (в будущем их будет больше), которые обрабатываются по-разному:
- Текстовый слой: создание текстового слоя в соответствии с данными слоя (шрифт, размер шрифта, насыщенность, цвет...)
- Слой изображения: изображение будет кэшировано локально, если кеш есть, то оно будет прочитано из кеша, в противном случае оно будет получено из сети. Затем создайте слой изображения на основе данных слоя (прозрачность, закругленные углы...)
- Слой QR-кода: используйте инструмент генерации QR-кода, чтобы преобразовать URL-адрес в слой изображения QR-кода.
- Состав слоя: слой изображения и текстовый слой накладываются друг на друга по порядку, и, наконец, создается и возвращается изображение.
Кроме того, мы используем Serverless для развертывания сервисов Golang, используем Serverless, чтобы воспользоваться преимуществами его автоматического масштабирования, повысить производительность службы и оптимизировать затраты, мы можем снизить затраты на эксплуатацию и обслуживание и повысить производительность.
Наконец, мы протестировали его: QPS текущей схемы примерно в десять раз выше, чем у схемы кукловода.
4. Резюме и перспективы
строить планы | совместимость | представление | Эффективность разработки |
---|---|---|---|
Интерфейс canvas2html генерирует изображения | Низкий | высоко | Низкий |
Генерация сервера Puppeteer+Nodejs | высоко | Низкий | Низкий |
Окончательный план реализации Golang + Nodejs | высоко | высоко | высоко |
Текущее решение Golang + Nodejs повышает эффективность требований к генерации изображений для менее сложных динамических изображений, экономит время разработки и гарантирует производительность. В будущем мы надеемся добавить больше встроенных компонентов, таких как компоненты, похожие на диаграммы, для выполнения более сложных задач по созданию изображений.
Надеюсь, эта статья поможет вам.