最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Merging Images Using JavascriptReact - Stack Overflow

programmeradmin1浏览0评论

I am creating a website in which each user has an "avatar". An avatar has different accessories like hats, facial expressions, etc. I have made this previously on a php website but I am using react to create this new website. I am loading in each users avatar and its item links from firestore. I do not want to use absolute positioning or css, I want the avatar to be one image.

Example of what I am trying to achieve:

I found this library: which seems to be exactly what I need but I cannot load in external images or I get this error:

Any solutions to this error or suggestions to an alternative would be greatly appreciated.

My code:

render() {

mergeImages([
  '.png',
  '.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"/>
  ...
); }

I am creating a website in which each user has an "avatar". An avatar has different accessories like hats, facial expressions, etc. I have made this previously on a php website but I am using react to create this new website. I am loading in each users avatar and its item links from firestore. I do not want to use absolute positioning or css, I want the avatar to be one image.

Example of what I am trying to achieve:

I found this library: https://github./lukechilds/merge-images which seems to be exactly what I need but I cannot load in external images or I get this error:

Any solutions to this error or suggestions to an alternative would be greatly appreciated.

My code:

render() {

mergeImages([
  'http://example./images/Avatar.png',
  'http://example./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"/>
  ...
); }
Share Improve this question asked Mar 20, 2019 at 18:26 PerniferousPerniferous 6111 gold badge7 silver badges20 bronze badges 2
  • are the images ing from a different domain than yours? that's probably what's happening – azium Commented Mar 20, 2019 at 18:36
  • Yes they would be ing from a different domain, most likely firebase cloud storage. In these tests though I am just using random images from other sites. This is one of the main difficulties. – Perniferous Commented Mar 20, 2019 at 18:37
Add a ment  | 

2 Answers 2

Reset to default 4 +100

The merge-images package has some quirks. One of those quirks is that it expects individual images to either be served from your local server (example: http://localhost:3000/images/head.png, http://localhost:3000/images/eyes.png, and http://localhost:3000/images/mouth.png) or that those individual images be imported into a single file.

Working example: https://github./mattcarlotta/merge-images-example (this example includes the first three options explained below with the fourth option utilizing the end result of using a third party CDN)

To run the example, clone the repo:

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

Change directory:

cd merge-images-example

Then install dependencies:

yarn install

Then run the development server:

yarn dev

Option 1: The simplest implementation would be to import them into a AvatarFromFiles ponent. However, as written, it isn't reusable and isn't suitable for dynamically selected avatars.

Option 2: You may want to serve them from the local server like the AvatarFromLocalServer ponent with a Webpack Dev Config. Then you would retrieve stored strings from an API and pass them down into from state into the ponent. Once again, this still requires the images to be present in the images folder, but more importantly, it isn't ideal for a production environment because the images folder must be placed outside of the src folder to be served. This could also lead to security issues. Therefore, I don't remend this option at all.

Option 3: Same as Option 1, but lazy loaded like the AvatarFromLazyFiles ponent and therefore flexible. You can load images by their name; however, it still requires that all of the images be present upon runtime and during production pilation. In other words, what you have on hand is what you get.

Option 4: So... the ideal option would be to build an image microservice or use a CDN that handles all things images (uploading, manipulating/merging, and serving images). The client would only be able to select/upload new images to this microservice/CDN, while the microservice/CDN handles everything else. This may require a bit more work but offers the most flexibility, super easy to implement, and best performance -- as it offloads all the work from the client to the dedicated service.

In conclusion, unless you plan on having a set amount of images, use option 3, otherwise option 4.

Problem

This is a CORS issue. The images are ing from a different origin that's not your server.

If you look at the source of the library, you'll notice it's using a <canvas> under the hood to merge the images, and then getting the resulting data. Canvas cannot work with images loaded from another domain. There's good reasoning behind this. In essence, loading an image into a canvas is a way to fetch data, and since you can retrieve the data from the canvas as base64, a malicious one could steal information by first loading it into a <canvas> and then pulling it out.

You can read about it directly from the spec for the <canvas> element.

Solution

You need to serve the images either from the same origin (essentially, the same domain) or include Access-Control-Allow-Origin: ... on the HTTP headers that serve the images. There's ways to do this in firebase storage, or other server solutions you might use.

发布评论

评论列表(0)

  1. 暂无评论