-1

I am stitching 2 images together to create a single image. Overlaying might be a better term. The first image is the following.

first image The second image is the following: second image

After doing some canvas magic, I am able to overlay the final image using TWO canvas elements which looks like this

two canvas overlay

I then grab the image data of both images and "stitch" together the image data to re-create the illusion of a single image from 2 canvas elements overlaid into a single canvas using the following technique

let r, g, b, a;
let r_, g_, b_, a_;

let stitched_data = [];

for (let i = 0; i + 3 < background.data.length; i += 4) {
  r = background.data[i];
  g = background.data[i];
  b = background.data[i];
  a = background.data[i];

  r_ = foreground.data[i];
  g_ = foreground.data[i];
  b_ = foreground.data[i];
  a_ = foreground.data[i];

  let _r, _g, _b, _a;

  if (a_ != 0) {
    console.log(a, a_);
    _r = r_;
    _g = g_;
    _b = b_;
    _a = 255;
  } else {
    _r = r;
    _g = g;
    _b = b;
    _a = 255;
  }

  if(_r)

  stitched_data.push(_r);
  stitched_data.push(_g);
  stitched_data.push(_b);
  stitched_data.push(_a);
}

let stitched = Uint8ClampedArray.from(stitched_data);
let stiched_ = new ImageData(stitched, canvas.width, canvas.height);
ctx.putImageData(stiched_, 0, 0);

Both the foreground and background are ImageData using the ctx.getImageData function built into the canvas API. I then recreate a new image data from a new Uint8ClampedArray, and feed that into the constructor function for a new ImageData. The result is exactly what I want, EXCEPT it is black and white only!!! Why don't the RGB values carry over?? This doesn't make sense to me, can someone please explain why, despite me carrying over the image data, it only saves it to black and white??

This is the final result

enter image description here

ChannelJuanNews
  • 406
  • 3
  • 11
  • Why... are you copying individual pixels? Just draw the "head" image with `drawImage()` with the x/y/width/height you need? This is what alpha channels are _for_: so that when you layer the image, the right thing happens =) – Mike 'Pomax' Kamermans Jan 07 '21 at 02:14
  • since both images are the same dimension, it is my intuition that drawImage or putImageData will overwrite the image data underneath. am I wrong? – ChannelJuanNews Jan 07 '21 at 02:16
  • I was unaware that this is what alpha channels were for Mike. Could you point me to some resources so I can better understand what alpha channels are for? I would appreciate being able to read some material so I can better grasp these concepts. – ChannelJuanNews Jan 07 '21 at 02:27
  • Typo: `r = background.data[i]; g = background.data[i];` etc. should be `r = background.data[i]; g = background.data[i+1];` etc. here `r`,`g` and `b` all are the same and only red channel value. – Kaiido Jan 07 '21 at 03:55
  • MIND BLOWN. thank you Kaiido!!!! – ChannelJuanNews Jan 07 '21 at 06:51

1 Answers1

0

Thanks to @Mike 'Pomax' Kamermans, I was able to solve this issue very quickly. I was unaware that this is what alpha channels were for

var image1 = new Image();
image1.src = background_canvas.toDataURL();

var image2 = new Image();
image2.src = foreground_canvas.toDataURL();

ctx.drawImage(image1, 0, 0);
ctx.drawImage(image2, 0, 0);

return document.querySelector("body").appendChild(canvas);
ChannelJuanNews
  • 406
  • 3
  • 11