# "Get" as color detector?

**URL:** <https://discourse.processing.org/t/get-as-color-detector/19912>\
**Category:** Coding Questions\
**Created:** [April 18, 2020, 11:37pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912 "2020-04-18T23:37:58Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![mnoble](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnoble/32/99_2.png) [@mnoble](https://discourse.processing.org/u/mnoble)\
**Post date:** [April 18, 2020, 11:37pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/1 "2020-04-18T23:37:58Z")

</div>

Hello Forum 🙂

On Processing, I love this program for detecting colors:

```auto
color c;

void setup (){
  size (200,200);
}

void draw() {
  background (0);
  fill (255);
  rect (0,0,100,200); 
  c = get (mouseX,mouseY);
  
  if (c == -1){
    print ("the color is white ");
  } else if (c == -16777216){
    fill (0,255,0);
    print ("the color is black "); 
 }
}

```

But, I am seriously struggling to convert this simple program to p5js. It seems that ‘get’ works a bit differently with p5js.

Also, can anyone give me more context on what format the color codes are in this Processing sketch?

---

<div class="post-metadata">

**Author:** ![seanc4s](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@seanc4s](https://discourse.processing.org/u/seanc4s)\
**Post date:** [April 19, 2020, 2:46am UTC](https://discourse.processing.org/t/get-as-color-detector/19912/2 "2020-04-19T02:46:18Z")

</div>

I think you have use some of the functions like red( c),green( c),blue( c),brightness( c) to find out the exact color.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [April 19, 2020, 2:47am UTC](https://discourse.processing.org/t/get-as-color-detector/19912/3 "2020-04-19T02:47:31Z")

</div>

Hello,

get() in P5.js reads the color into an array:  
[https://p5js.org/reference/#/p5/get](https://p5js.org/reference/#/p5/get)

Some code I patched together to explore this:

> **Example**
>
> ```auto
> let c = [0, 0, 0, 0];
> let c1 = [255, 255, 255, 255];
> let c2 = [0, 0, 0, 255];
> 
> let state = false;
> 
> function setup() 
> {
> createCanvas(400, 400);
> print ("Begin...");    
> }
> 
> function draw() 
> {
> background (0);
> 
> fill (255);
> rect (0, 0, 200, 200); 
>   
> c = get(mouseX, mouseY);   
> print(c);
>   
> state = isEqual1();
> //print(state);
> if (state)
> {
> print ("the color is white ");
> state=false;  
> }
>     
> state = isEqual2();
> //print(state);
> if (state)
> {
> print ("the color is black ");
> state=false;  
> }    
> }
>   
> function isEqual1() 
> { 
> // comapring each element of array 
> for(var i=0;i<c.length;i++)
> {
> if(c[i] != c1[i]) 
> {
> return false; 
> }        
> return true; 
> } 
> }   
> 
> function isEqual2() 
> { 
> // comapring each element of array 
> for(var i=0;i<c.length;i++)
> {
> if(c[i] != c2[i]) 
> {
> return false; 
> }        
> return true; 
> } 
> }   
> 
> ```

> **Example Update - Better function**
>
> ```auto
> let c = [0, 0, 0, 0];
> let c1 = [255, 255, 255, 255];
> let c2 = [0, 0, 0, 255];
> 
> let state = false;
> 
> function setup() 
> {
> createCanvas(400, 400);
> print ("Begin...");    
> }
> 
> function draw() 
> {
> background (0);
> 
> fill (255);
> rect (0, 0, 200, 200); 
>   
> c = get(mouseX, mouseY);   
> print(c);
>   
> state = isEqual(c, c1);
> //print(state);
> if (state)
> {
> print ("the color is white ");
> state=false;  
> }
>     
> state = isEqual(c, c2);
> //print(state);
> if (state)
> {
> print ("the color is black ");
> state=false;  
> }    
> }
>   
> function isEqual(col1, col2) 
> { 
> // comparing each element of array 
> for(var i=0;i<c.length;i++)
> {
> if(col1[i] != col2[i]) //If any one is != then it is false
> {
> return false; 
> }        
> return true; 
> } 
> }   
> 
> ```

This was just an initial exploration and I compared arrays.  
This can be done much better…

Borrowed some elements from here:  
[How to compare two arrays in JavaScript? - GeeksforGeeks](https://www.geeksforgeeks.org/how-to-compare-two-arrays-in-javascript/)

`:)`

---

<div class="post-metadata">

**Author:** ![seanc4s](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@seanc4s](https://discourse.processing.org/u/seanc4s)\
**Post date:** [April 19, 2020, 2:50am UTC](https://discourse.processing.org/t/get-as-color-detector/19912/4 "2020-04-19T02:50:33Z")

</div>

## get()

"Get a region of pixels, or a single pixel, from the canvas.

Returns an array of [R,G,B,A] values for any pixel or grabs a section of an image."

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [April 19, 2020, 5:10am UTC](https://discourse.processing.org/t/get-as-color-detector/19912/5 "2020-04-19T05:10:30Z")

</div>

> [@mnoble](#):
>
> It seems that **get()** works a bit differently with p5js.

Actually very differently I’m afraid! 😰

Processing’s **get()** returns a 32-bit (4-byte) signed `int` aRGB color value:

> **[get() / Reference](https://processing.org/reference/get_.html)**
>
> Reads the color of any pixel or grabs a section of an image. If no parameters are specified, the entire image is returned. Use the x and y parameters to get the value of one pixel. Get a…

> **[color / Reference](https://processing.org/reference/color_datatype.html)**
>
> Datatype for storing color values. Colors may be assigned with get() and color() or they may be specified directly using hexadecimal notation such as #FFCC00 or 0xFFFFCC00.…

While in p5js **get()** returns an array containing 4 values ordered as RGBa:

> **[reference | p5.js](https://p5js.org/reference/#/p5/get)**
>
> p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.

If you don’t mind using _pixels[]_ in place of **get()**:

> **[reference | p5.js](https://p5js.org/reference/#/p5/pixels)**
>
> p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.

I’ve got this project which is already finished (but still untested & unpublished) where we can invoke **getProcessingPixels()** passing an image (or its corresponding _pixels[]_) as its argument, and then it returns an Int32Array proxy viewer of it:

> **[Int32Array - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array)**
>
> The Int32Array typed array represents an array of 32-bit signed integers in the platform byte order. If control over byte order is needed, use DataView instead. The contents are initialized to 0. Once established, you can reference elements in the...

> **[Proxy - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)**
>
> The Proxy object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object.

That returned Int32Array proxy viewer should behave just like a Processing’s aRGB _pixels[]_:

> **[pixels\[\] / Reference](https://processing.org/reference/pixels.html)**
>
> The pixels\[\] array contains the values for all the pixels in the display window. These values are of the color datatype. This array is defined by the size of the display window. For example, if…

So you can more easily convert Processing’s sketches relying on _pixels[]_ to p5js: 🥳

```javascript
// https://Discourse.processing.org/t/get-as-color-detector/19912/5
// GoToLoop (2020-Apr-19)

'use strict';

function getProcessingPixels(imgOrPixels) {
  const { buffer } = imgOrPixels.pixels && imgOrPixels.pixels || imgOrPixels;

  return new Proxy(
    new Int32Array(buffer), getProcessingPixels.INT32_aRGB_HANDLE
  );
}

getProcessingPixels.isLittleEndian = function () {
  return new Uint8Array(Uint32Array.of(0x12345678).buffer)[0] === 0x78;
};

getProcessingPixels.int32aRGBLittleEndianHandle = {
  set(obj, prop, val) { // aRGB -> aBGR (RGBa)
    const idx = +prop.toString();

    if (idx >= 0 && idx < obj.length && Number.isInteger(idx)) {
      const red = val >> 0o20 & 0xff, blue = (val & 0xff) << 0o20;
      val = val & 0xff00ff00 | red | blue;
    }

    return obj[prop] = val, true;
  },

  get(obj, prop) { // aBGR (RGBa) -> aRGB
    const idx = +prop.toString(), val = obj[prop];

    if (idx >= 0 && idx < obj.length && Number.isInteger(idx)) {
      const red = (val & 0xff) << 0o20, blue = val >> 0o20 & 0xff;
      return val & 0xff00ff00 | red | blue;
    }

    return typeof val === 'function' && val.bind(obj) || val;
  }
};

getProcessingPixels.int32aRGBBigEndianHandle = {
  set(obj, prop, val) { // aRGB -> RGBa
    const idx = +prop.toString();

    if (idx >= 0 && idx < obj.length && Number.isInteger(idx))
      val = val >>> 0o30 | val << 0o10;

    return Reflect.set(obj, prop, val);
  },

  get(obj, prop) { // RGBa -> aRGB
    const idx = +prop.toString(), val = Reflect.get(obj, prop);

    if (idx >= 0 && idx < obj.length && Number.isInteger(idx))
      return val << 0o30 | val >>> 0o10;

    return typeof val === 'function' && val.bind(obj) || val;
  }
};

getProcessingPixels.LITTLE_ENDIAN = getProcessingPixels.isLittleEndian();
getProcessingPixels.BIG_ENDIAN = !getProcessingPixels.LITTLE_ENDIAN;

getProcessingPixels.INT32_aRGB_HANDLE =
  getProcessingPixels.LITTLE_ENDIAN &&
  getProcessingPixels.int32aRGBLittleEndianHandle ||
  getProcessingPixels.int32aRGBBigEndianHandle;

```

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [April 19, 2020, 6:14pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/6 "2020-04-19T18:14:19Z")

</div>

Processing and p5.js color work very differently, and that is surprising. There is a lot of great information on how / why above, but here is a walkthrough of a solution to your students using `get()` as a color detector in their projects.

### In Processing (Java mode),

`get()` and `color()` return the same things (the [color datatype](https://processing.org/reference/color_datatype.html), a 32-bit int representing ARGB), which can be compared using `==`.

Let’s detect if the mouse is on white:

```auto
// check mouse color
void setup() {
  size(100,100);
  rect(25,25,50,50);
}

void draw() {
  int cwhite = color(255);
  int cmouse = get(mouseX, mouseY);
  if(cmouse==cwhite) {
    println(frameCount, cmouse);
  }
}

```

### In p5.js (JavaScript),

`get()` and `color()` return DIFFERENT things, AND, those things can’t be compared with equals – to each other, OR to themselves(!!). [`get()` returns an array](https://p5js.org/reference/#/p5/get) of floats [R, G, B, A]. `color()` returns a [p5.Color](https://p5js.org/reference/#/p5.Color) object, which contains multiple arrays, including one with four 0-255 values, called “levels”. In JavaScript, arrays and objects with the same contents are not found equal with `==`.

To adapt the Processing sketch to p5.js, we need two things:

1. define our color to check for as a flat array, [R, G, B, A], so it will match `get()`. Either declare it directly [] or use `color(my_arguments).levels`.
2. create an equals function to compare two colors. There are many ways to do this, but we’ll use one that is easy to read and fast.

```auto
// check mouse color
function setup() {
  createCanvas(100, 100);
  rect(25,25,50,50);
}

function draw() {
  let cmouse = get(mouseX, mouseY); // [R, G, B, A]
  let cwhite = [255,255,255,255];
  // let cwhite = color(255).levels; 
  if(eqcolor(cmouse, cwhite)) {
    print(frameCount, cmouse);
  }
}

function eqcolor(a, b) {
  return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3];
}

```

https://editor.p5js.org/jeremydouglass/sketches/JsVeospiC

```auto
<iframe src="https://editor.p5js.org/jeremydouglass/sketches/JsVeospiC" width="100%" height="510" allowfullscreen frameborder="0" marginwidth="0" marginheight="0"></iframe>

```

---

<div class="post-metadata">

**Author:** ![mnoble](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnoble/32/99_2.png) [@mnoble](https://discourse.processing.org/u/mnoble)\
**Post date:** [April 19, 2020, 6:25pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/7 "2020-04-19T18:25:37Z")

</div>

Thank you so much everyone!!! Wow!!!

---

<div class="post-metadata">

**Author:** ![mnoble](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnoble/32/99_2.png) [@mnoble](https://discourse.processing.org/u/mnoble)\
**Post date:** [April 19, 2020, 6:32pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/8 "2020-04-19T18:32:06Z")

</div>

> [@jeremydouglass](#):
>
> create an equals function to compare two colors. There are many ways to do this, but we’ll use one that is easy to read and fast.

This is so tremendously helpful for teaching! Thank you!

---

<div class="post-metadata">

**Author:** ![mnoble](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnoble/32/99_2.png) [@mnoble](https://discourse.processing.org/u/mnoble)\
**Post date:** [April 19, 2020, 7:06pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/9 "2020-04-19T19:06:16Z")

</div>

Quick question about syntax/curly bracket structure 🙂

![brackets](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/7/72cca6bb529a215d1ff01d114f38edbeac8b1d83.png)

Does the use of “return” change the need for an opening curly bracket with the if conditional?

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [April 19, 2020, 7:07pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/10 "2020-04-19T19:07:49Z")

</div>

Sorry, `if` doesn’t need `{}` when the condition is only a single line. But that is confusing for learners – I’ll fix in the examples above.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [April 19, 2020, 7:09pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/11 "2020-04-19T19:09:54Z")

</div>

Also:

### How to do it without an equality function.

Instead of a custom equality function:

```auto
if(eqcolor(cmouse, cwhite))

```

drop `eqcolor` and use `.toString()` instead:

```auto
if(cmouse == cwhite.toString())

```

Example sketch:

[https://editor.p5js.org/jeremydouglass/sketches/wNZhvyugn](https://editor.p5js.org/jeremydouglass/sketches/wNZhvyugn)

This works because in JavaScript,

```auto
print([1,2] == [1,2]) // false
print([1,2] == '1,2') // true

```

Sigh. I honestly don’t like doing this because even though the code is shorter learners find it deeply, deeply confusing, so they forget the .toString() and get frustrated when it doesn’t work. But that might be a question of taste.

---

<div class="post-metadata">

**Author:** ![mnoble](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnoble/32/99_2.png) [@mnoble](https://discourse.processing.org/u/mnoble)\
**Post date:** [April 19, 2020, 7:10pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/12 "2020-04-19T19:10:10Z")

</div>

Awesome - got to keep things consistent for myself and my students. Much appreciated!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [April 19, 2020, 7:58pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/13 "2020-04-19T19:58:48Z")

</div>

> [@mnoble](#):
>
> Does the use of `return` change the need for an opening curly bracket with the `if` conditional?

Actually b/c the whole expression is evaluated as 1 `boolean`, we can simply use 1 `return` only for it:

```javascript
function eqColor(a, b) {
  return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3];
}

```

So there’s no need for 1-statement `if` nor `else` in this case.

Another alternative version using `for`:

```javascript
function eqColor(a, b) {
  for (var i = 0; i < a.length; ++i) if (a[i] != b[i]) return false;
  return true;
}

```

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [April 19, 2020, 8:41pm UTC](https://discourse.processing.org/t/get-as-color-detector/19912/14 "2020-04-19T20:41:48Z")

</div>

> [@GoToLoop](#):
>
> b/c the whole expression is evaluated as 1 `boolean` , we can simply use 1 `return`

Good point. I’ll going to update the examples with that.

The `for` version is more versatile, and also fails-fast – but I wanted to make it explicit for learners that we expect to match exactly four term pairs.
