P5 pixel array to copy canvas region to Image object

Working on a project that uses the webcam, lays some graphics on top of the cam image, then I need to store the cam image with the overlayed graphics in an Image object variable. Currently, my code works but the resulting image is just the upper left corner of what I need to capture.


let cam, selfy;

let showImg = false;

let margin, topMargin;

function setup() {
  createCanvas(windowWidth, windowHeight);
  cam = createCapture(VIDEO);
  cam.hide();
  textSize(48);
  margin = 50;
  topMargin = 50;
//console.log(pixelDensity());
}

function draw() {
  background(0);
  image(cam, margin,topMargin);
  fill(255,255,0);
  text("SELFY",65,50+cam.height-15);
  fill(255,0,0);
  noStroke();
  circle(75,75,30);

  if(showImg){
    image(selfy, width/2,height/2);
  }
}


function touchEnded(){
  resizeCanvas(cam.width,cam.height);//resize the canvas to easier deal with this
  selfy = createImage(cam.width,cam.height);//same size as the cam
  selfy.loadPixels();
  let d = pixelDensity();

    loadPixels(); //load pixels of the entire canvas

   for (let x=0; x<width; x++){//x axis section of the canvas i wish to capture
      for (let y=0; y<height; y++){//y axis section of the canvas i wish to capture
        let index = x + y * (width*d) * 4; //index for the canvas pixel array
        //copy the pixels from the canvs to an Image
          selfy.pixels[index] = pixels[index];
          selfy.pixels[index+1] = pixels[index+1];
          selfy.pixels[index+2] = pixels[index+2];
          selfy.pixels[index+3] = pixels[index+3];
      }
    }

  selfy.updatePixels();
    showImg = true;
resizeCanvas(windowWidth,windowHeight);
}

Hi! Welcome to the forum!

I think the index should be

let index = (x + y * (width*d)) * 4;

I suggest using pixelDensity(1) in setup to avoid complicated things. Also you can use get(x, y, w, h) to make it easier… in fact the copying part can be compressed to

selfy = get(0, 0, width, height)

(with get you shouldn’t have issues with any pixelDensity)

2 Likes

@micuat! thank you very much. I was avoiding get() because all the documentation claims it to be so much slower than working with the pixels[] array. This will work.

MO

1 Like

If you just wanna copy the contents from 1 array to the other you could simply invoke method set(): :bulb:

loadPixels();
selfy.loadPixels();
selfy.pixels.set(pixels);
selfy.updatePixels();
2 Likes

ahh yes. this is interestingly easy as well. thank you @GoToLoop!

1 Like