0

Help! I'm trying to combine images using canvas but the output always comes out as a blank box. I can't figure out what is going wrong, my code is below:

const Canvas = require('canvas'); const theLayers=['https://raw.githubusercontent.com/Iceee1000/SpaceVizsla/main/MediaAssets/pixelVizsla/testing_01.png', 'https://raw.githubusercontent.com/Iceee1000/SpaceVizsla/main/MediaAssets/pixelVizsla/B_02.png', 'https://raw.githubusercontent.com/Iceee1000/SpaceVizsla/main/MediaAssets/pixelVizsla/testing_02.png']; //not-working function to combine multiple layers of images from the web. const CombineLayers = async(layers) => { console.log('combining layers') let canvas=Canvas.createCanvas(250, 250); let context=canvas.getContext('2d'); for (let layer of layers){ var img = new Image(); img.origin = 'anonymous'; img.src = layer; img.onload = function(){ context.drawImage(img, 0, 0, 250, 250); } } return canvas.toDataURL("image/png"); }; const dothings=async()=>{ const result= await CombineLayers(theLayers); console.log(result); } dothings(); 
3
  • What do you mean by "combine images" exactly? drawImage overwrites the existing canvas. Commented Apr 12, 2022 at 18:13
  • using "drawImage" to combine the images by drawing one on top of the other. Solved below. Commented Apr 12, 2022 at 18:40
  • Thanks for the self-answer. You can load from a URL without axios, but you'll need to await the onloads with promises (or, less ideally, chain callbacks) before running canvas.toDataURL("image/png"). See Loading images before rendering JS canvas Commented Apr 12, 2022 at 19:03

1 Answer 1

0

Solved my issue: Can not just image data directly from a URL, I needed to load/buffer it first. Solved below with axios:

const Canvas = require('canvas'); const axios = require('axios') function getBase64(url) { return axios .get(url, { responseType: 'arraybuffer' }) .then(response => Buffer.from(response.data, 'binary').toString('base64')) } const theLayers=['https://imageURL.png', 'https://imageURL.png', 'https://imageURL.png']; const CombineLayers = async(layers) => { console.log('combining layers') let canvas=Canvas.createCanvas(250, 250); let context=canvas.getContext('2d'); for (let layer of layers){ const data = await getBase64(layer); let datastring='data:image/png;base64,'+data const img = await Canvas.loadImage(datastring); context.drawImage(img, 0, 0, 250, 250); } return canvas.toDataURL("image/png"); }; const dothings=async()=>{ const result= await CombineLayers(theLayers); console.log(result); } dothings(); 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.