Get RGB values of a pixel on the canvas

I tried get() and pixels array, but they both didnt work cause get() is for when you load an image as I understand and pixels array for some reason just is full of the background color and no colors of lines I drew. How should I go about this? I just want to be able to check the RGB value of a given pixel on my canvas which has lines drawn on it with line()

The get() function and the pixel array is a little bit different than it is in Processing. The best way to understand the all the differences is to read the through the Image section in the documentation. But the way get() works is you give it an x and y to get a single pixel. You can get a section by giving it x, y, width, height and with no parameters you get the whole canvas. Here’s an example for what you’re asking about:

function setup() {
  createCanvas(400, 400);
  background(51);
  for (let i = 0; i < 100; i++) {
    stroke(random(255), random(255), random(255));
    line(random(width), random(height), random(width), random(height));
  }
  noStroke();
}

function draw() {
  let c = get(mouseX, mouseY);
  fill(c);
  square(0, 0, 20, 20);
}

you can just do this to iterate over all of the pixels

  loadPixels();
	for(let y = 0; y < height; y++) {
		for(let x = 0; x < width; x++) {
			let xy = (x + y * width) * 4;
			
			pixels[xy] = 255;
			pixels[xy + 1] = 0;
			pixels[xy + 2] = 255;
			pixels[xy + 3] = 255;
		}
	}
	updatePixels();

or you can setup your own get set something like

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  
  stroke(255, 0, 255);
  line(0, 0, width, height);
  
  //something to show the pixel color of the pixel
  //which the mouse is over
  stroke(255);
  fill(getPixel(mouseX, mouseY));
  rect(width / 2 - 10, height / 2 - 10, 20, 20);
}

function getPixel(x, y) {
  loadPixels();
  var xy = (x + y * width) * 4;
  return color(
  	pixels[xy],
    pixels[xy + 1],
    pixels[xy + 2],
    pixels[xy + 3]
  );
}
function setPixel(x, y, color) {
loadPixels();
  var xy = (x + y * width) * 4;
  pixels[xy] = red(color);
  pixels[xy + 1] = green(color);
  pixels[xy + 2] = blue(color);
  pixels[xy + 3] = alpha(color);
  updatePixels();
}

Thank you both… you made me realize how dumb i can be haha. I have it working now, though I must say it introduced some “lag” to my game. I mean, I used to see my “player” move smoothly but now with using either get() or pixel[] every frame, both make my player look a bit more clunky. when moving. Any ideas? I saw when I log the information of a specific pixel, it isn’t just 4 elements ‘r’ ‘g’ ‘b’ and brightness, but a whole bunch of other stuff. Maybe if there’s a way to only load the RGB values as that is all I need, this “lag” could be fixed

what is it that you are sampling the pixels for? without seeing some code it would be hard to say where the slow-down is originating.

well I’m making a snake game. I need pixels every frame because i was thinking it would be easier to check for collisions in the game if I can check the color of the pixels ahead of the snake. If it’s anything but the background color then it means there’s a collision. Perhaps there’s a smarter way to go about this?
edit: the thickness of the snake line kinda seemed to make harder to calculate collision by checking x and y positions since I only have the x and y position of the “middle” of the snake

yeh pixel collision will be costly. there is a p5js snake game example here which isn’t bad and might give you some insight on how to handle collisions

1 Like

yeah ive done it exactly as he does before, but yeah because of the thickness of the line it means that you can “enter” your own snake if you turn just at the right time.So like, if you come back to your own line and turn just 1 pixel above your old line, the snake itself will collide but because the head of the snake is 1 pixel above the old one, it will never detect collision and that is a big problem
edit: i move 2 pixels at a time, instead of 10, which is why stuff like that can happen (well 2 instead of 1 pixel above can happen but you get the point xd)

so you have the variable “diff” set to 2 and what is your strokeWeight? the visualisation isn’t directly tied to the, i guess you could call it step size or grid cell size, i imagine that is the drama.

my strokeweight is 9. I didn’t call it diff but called it speed, but yes, it is 2 and needs to stay so, as it’s supposed to be more “precise” to control
edit: i think i will get back to adding the next things i want to add to the game, and then meanwhile i can think of how to best approach this and maybe get new ideas we’ll see haha

the collision resolution and the visual resolution are different and so the collision function needs to be changed to account for that… i believe. i’m sure someone else can offer more help. best of luck with it all.

using more calculation power / risking slow down /
can check a bigger area instead one pix
https://editor.p5js.org/kll/sketches/FP-nEKU8T

In general, collision detection is done with geometry – not with pixels. Trying to detect collisions with pixels will usually cause you lots of problems – and as you solve them, more will come up. Without having seen your code, for snake I would recommend using line-line collision detection to see if the snake crosses a section of itself – or else point-rect collision detection on bounding boxes to see if the head collides with a tail segment, depending on the size and curvy-ness of your snake.