Слияние изображений с использованием Javascript / React - PullRequest
0 голосов
/ 20 марта 2019

Я создаю сайт, на котором у каждого пользователя есть «аватар». Аватар имеет различные аксессуары, такие как шляпы, выражения лица и т. Д. Я делал это ранее на сайте php, но я использую реагирование для создания этого нового сайта. Я загружаю в каждого пользователя аватар и ссылки на его пункты из firestore. я не хочу используйте абсолютное позиционирование или CSS, я хочу, чтобы аватар был одним изображением.

Пример того, чего я пытаюсь достичь: enter image description here

Я нашел эту библиотеку: https://github.com/lukechilds/merge-images, которая, кажется, именно то, что мне нужно, но я не могу загрузить внешние изображения, или я получаю эту ошибку:

error img

Будем весьма благодарны за любые решения этой ошибки или предложения по альтернативе.

Мой код:

render() {

mergeImages([
  'http://example.com/images/Avatar.png',
  'http://example.com/images/Hat.png',
])
.then((b64) => {
  document.querySelector('img.abc').src = b64;
})
.catch(error => console.log(error))
return (
  ...
      <img class="abc" src='' width={100} height={200} alt="avatar"/>
  ...
); }

Ответы [ 2 ]

1 голос
/ 23 марта 2019

Задача

Это проблема CORS. Изображения приходят из другого источника, это не ваш сервер.

Если вы посмотрите на источник библиотеки , вы заметите, что он использует <canvas> под колпаком для объединения изображений, а затем получает полученные данные. Canvas не может работать с изображениями, загруженными из другого домена. За этим стоит хорошая аргументация. По сути, загрузка изображения в холст - это способ извлечения данных, и, поскольку вы можете извлечь данные из холста как base64, злоумышленник может украсть информацию, сначала загрузив ее в <canvas>, а затем вытащив ее.

Вы можете прочитать об этом непосредственно из спецификации для элемента <canvas> .

Решение

Вам необходимо предоставить изображения либо из одного источника (по сути, из одного домена), либо включить Access-Control-Allow-Origin: ... в заголовки HTTP, которые обслуживают изображения. Есть способы сделать это в хранилище Firebase или в других серверных решениях, которые вы можете использовать.

0 голосов
/ 23 марта 2019

В пакете merge-images есть некоторые причуды. Одна из этих странностей заключается в том, что отдельные изображения будут обслуживаться с вашего локального сервера (например, http://localhost:3000/images/head.png, http://localhost:3000/images/eyes.png и http://localhost:3000/images/mouth.png) или , чтобы эти отдельные изображения были импортированы в одно файл.

Рабочий пример : https://github.com/mattcarlotta/merge-images-example (этот пример включает в себя первые три варианта, поясненные ниже, с четвертым вариантом, использующим конечный результат использования стороннего CDN)

Чтобы запустить пример, клонируйте репо:

git clone https://github.com/mattcarlotta/merge-images-example

Изменить каталог:

cd merge-images-example

Затем установите зависимости:

yarn install

Затем запустите сервер разработки:

yarn dev

Вариант 1 : Простейшей реализацией было бы импортировать их в AvatarFromFiles компонент. Однако, как написано, он не предназначен для повторного использования и не подходит для динамически выбранных аватаров.

Вариант 2 : Возможно, вы захотите обслуживать их с локального сервера, например, AvatarFromLocalServer с помощью Webpack Dev Config . Затем вы должны извлечь сохраненные строки из API и передать их из состояния в компонент . Еще раз, это все еще требует наличия изображений в папке images, но, что более важно, это не идеально для производственной среды, потому что папка images 1047 * должна быть размещена за пределами из src папка для обслуживания. Это также может привести к проблемам безопасности. Поэтому я вообще не рекомендую эту опцию.

Вариант 3: То же, что и в варианте 1, но загружается с отложенной загрузкой, как компонент AvatarFromLazyFiles , и, следовательно, гибкий. Вы можете загружать изображения по их имени ; однако все равно требуется, чтобы все образы присутствовали во время выполнения и во время производственной компиляции. Другими словами, у вас есть то, что вы получаете.

Вариант 4 : Итак ... идеальным вариантом было бы создать микросервис изображения или использовать CDN , который обрабатывает все изображения (загрузка, манипулирование / объединение и обслуживание изображений). Клиент сможет выбирать / загружать новые изображения только в этот микросервис / CDN, тогда как микросервис / CDN обрабатывает все остальное. Это может потребовать немного больше работы, но обеспечивает наибольшую гибкость , очень простую до реализацию и лучшую производительность - поскольку это снимает всю работу с клиента на выделенный сервис.

В заключение, если вы не планируете иметь установленное количество изображений, используйте опцию 3, в противном случае опцию 4.

enter image description here

...