# Alternative to get() for faster performance?

**URL:** <https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228>\
**Category:** Coding Questions\
**Created:** [May 23, 2021, 12:21am UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228 "2021-05-23T00:21:03Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![codestruggles](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codestruggles/32/11537_2.png) [@codestruggles](https://discourse.processing.org/u/codestruggles)\
**Post date:** [May 23, 2021, 12:21am UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/1 "2021-05-23T00:21:03Z")

</div>

Hello, i was wondering how it would be possible to replace the get(x,y,w,h) function with something else to enhance performance… i’m currently working on a project where i have to “degrade the quality” of a webcam image in real time. I settled on an effect like this [here](https://editor.p5js.org/generative-design/sketches/P_4_1_2_02). i integrated the code as is and it works but it slows down the whole sketch and the webcam feedback becomes so slow it’s as if it freezed… i believe it’s because of this command `set(x2, y2, get(x1,y1,w,h));`, specifically the get() function?  
I read that another way to access pixels faster is by directly going after the pixel array like this

```auto
 myVideo.pixels[i], //r
 myVideo.pixels[i + 1], //g
 myVideo.pixels[i + 2], //b
 myVideo.pixels[i + 3], //a

```

but i’m already confused at how i’m supposed to get the position or change the scale.

so far this is the code i have in draw

```auto
myVideo.loadPixels();

for (let y = 0; y < myVideo.height; y ++) {
    for (let x = 0; x < myVideo.width; x ++) {
      
      var r = getQuick(myVideo, x, y)[0];
      var g = getQuick(myVideo, x, y)[1];
      var b = getQuick(myVideo, x, y)[2];
      var a = getQuick(myVideo, x, y)[3];

if (r < effect || g < effect || b < effect || a < effect ) {

        var x1 = random(myVideo.width);
        var y1 = random(myVideo.height);

        var x2 = round(x1 + random(-10, 10));
        var y2 = round(y1 + random(-10, 10));

        var w = 10;
        var h = 10;

        set(x2, y2, get(x1,y1,w,h));
       }
    }
  }
  myVideo.updatePixels();

```

Can someone help me solve this? I found that using the pixel array to simply manipulate the color of the pixels worked very well and allowed speed and fluidity. is it possible to do the same for position and scale and get a result as shown in [this example](https://editor.p5js.org/generative-design/sketches/P_4_1_2_02)? i already took a look at the references for set(), get(), and pixels[] but it did not help me understand how i’m supposed to execute what im trying to do ☹

by the way, i created this function though i am not sure it is entirely necessary, but anyway, putting this here in case i am actually making my life harder with useless stuff 😕

```auto
function getQuick(myVideo, x, y) {
  var i = (y * myVideo.width + x) * 4;
  return [
    myVideo.pixels[i], //r
    myVideo.pixels[i + 1], //g
    myVideo.pixels[i + 2], //b
    myVideo.pixels[i + 3], //a
  ];
}

```

---

<div class="post-metadata">

**Author:** ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)\
**Post date:** [May 23, 2021, 12:04pm UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/2 "2021-05-23T12:04:25Z")

</div>

have you tried [`copy`](https://p5js.org/reference/#/p5/copy)? if it’s still slow, you can give a shot with `context.drawImage`

> <https://github.com/processing/p5.js/issues/5237#issuecomment-836788895>
>
> \#### Most appropriate sub-area of p5.js?
> 
> \- \[x \] Core/Environment/Rendering
> 
> …
> \#### Details about the bug:
> 
> \- p5.js version: since v0.10.0
> \- Web browser and version: Edge v90
> \- Operating System: Windows 10
> \- Steps to reproduce this:
> 
> The framerate drops significantly (3fps), when using the copy() function in the context shown in the examples below. I tried to recreate the tutorial of Tim Rodenbröcker about kinetic typography in p5.js.
> This happens when p5 versions since 0.10.0 are used. It runs smoothly with versions before 0.9.0.
> 
> v0.9.0: https://editor.p5js.org/eriksiemund/sketches/ZD7V3\_qKM
> v.1.3.1: https://editor.p5js.org/eriksiemund/sketches/79w6n7V2W
> 
> The issue is already posted in the p5 forum, where micuat suggested a solution. He replaced copy() with context.drawImage and made a guess, that it might have something to do with the implementation of loadPixels since v0.10.0.
> 
> Fix by misuat: https://editor.p5js.org/micuat/sketches/XXyKscqN9
> 
> Link to forum thread: https://discourse.processing.org/t/p5-js-copy-function-slow-performance-since-version-0-10-0/30007
> 
> Thank you in advance!

---

<div class="post-metadata">

**Author:** ![th75](https://avatars.discourse-cdn.com/v4/letter/t/ebca7d/32.png) [@th75](https://discourse.processing.org/u/th75)\
**Post date:** [May 23, 2021, 6:26pm UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/3 "2021-05-23T18:26:04Z")

</div>

---- EDIT ----  
the answer below is wrong as it correspond to processing java and P5.js pixel array is different  
---- EDIT ----  
hi,  
in pixels[], each value of the array is one pixel

so the pixel (23 ; 32) of a 100x100 image is at the address 23+100 \* 32 (x+y\*image.width)  
(no need to multiply by 4 as in your code)  
then,for this pixel, you got one integer coding the 4 channel ARGB in one value  
so to copy the pixel , just copy this value to somewhere else,

the color is coded like that:this integer is 4 byte, each byte represent one of ARGB channels , so the 8 less significant bit are blue value (256 possibles value) then upper 8 bit are green… and so on  
tell me if you need more information on manipulating those color

---

<div class="post-metadata">

**Author:** ![codestruggles](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codestruggles/32/11537_2.png) [@codestruggles](https://discourse.processing.org/u/codestruggles)\
**Post date:** [May 23, 2021, 11:20pm UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/4 "2021-05-23T23:20:34Z")

</div>

hi! thanks for your reply! i tried using copy but i have the problem that the function expects integers but at some point, for

```auto
copy(sx, sy, sw, sh, dx, dy, dw, dh);

```

i need to replace 5th and 6th parameters with “effect”

```auto
function setup(){
let effect = 0;
}
function draw() {
let amplitude = 255;
effect = constrain(effect, 0, amplitude);
}

```

so it returns smth like “expected integer received number instead”. and i’m not sure if that contributes to slowing down the code but it did so i guess it does?  
I then tried your fix with context.drawImage but it doesn’t do anything… there are no errors though. but i have a few questions:  
what exactly do these for loops do?

```auto
for (let i = 0; i < tilesX; i++) {
      for (let j = 0; j < tilesY; j++) {}
}

```

it doesn’t seem like it would give us access to the pixels of the video but does it still serve to replace a loop such as

```auto
for (let y = 0; y < myVideo.height; y ++) {
    for (let x = 0; x < myVideo.width; x ++) {}
}

```

could that be why it’s not working? must i still do something like this for it to work?

```auto
for (let y = 0; y < myVideo.height; y ++) {
    for (let x = 0; x < myVideo.width; x ++) {

      var r = getQuick(myVideo, x, y)[0];
      var g = getQuick(myVideo, x, y)[1];
      var b = getQuick(myVideo, x, y)[2];
      var a = getQuick(myVideo, x, y)[3];

      if (r < effect || g < effect || b < effect || a < effect ) {

        for (let i = 0; i < tilesX; i++) {
            for (let j = 0; j < tilesY; j++) {

        let wave = int(sin(frameCount * 0.05 + ( i * j ) * 0.07) * 100);

        let sx = i * tileW + wave;
        let sy = j * tileH;
        let sw = tileW;
        let sh = tileH;

        let dx = i * tileW;
        let dy = j * tileH;
        let dw = tileW;
        let dh = tileH;

        drawingContext.drawImage(
              pg.canvas,
              sx,
              sy,
              sw,
              sh,
              dx,
              dy,
              dw,
              dh
            );
          }
        }

```

i tried it like that too but now it makes it buffer and still nothing happens, no errors either…  
i am sadly very lost. i hope i exposed my problem clearly enough 😓  
in any case, thank you very much for your response!

---

<div class="post-metadata">

**Author:** ![codestruggles](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codestruggles/32/11537_2.png) [@codestruggles](https://discourse.processing.org/u/codestruggles)\
**Post date:** [May 23, 2021, 11:50pm UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/5 "2021-05-23T23:50:00Z")

</div>

hello! thank you for your reply!  
i think i understand how pixels[] work in general… so you can control the position individually by using functions such as copy for example, but using a method like

```auto
      var r = getQuick(myVideo, x, y)[0];
      var g = getQuick(myVideo, x, y)[1];
      var b = getQuick(myVideo, x, y)[2];
      var a = getQuick(myVideo, x, y)[3];

```

can only control the colors?  
then, would it be possible to get the color values from one pixel and exchange it with those of another?

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [May 24, 2021, 12:45am UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/6 "2021-05-24T00:45:44Z")

</div>

Color values are accessed as follows

```auto
float br = brightness(pixels[i]);
float r = red(pixels[i]);
float g = green(pixels[i]);
float b = blue(pixels[i])

```

Where i is the index of the pixel required.

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [May 24, 2021, 2:22am UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/7 "2021-05-24T02:22:04Z")

</div>

> [@paulgoux](#):
>
> Color values are accessed as follows

I’m pretty sure this is incorrect @paulgoux. the `pixels` array contains individual number values for the different color components. The `get()` function has the virtue over this of returning the `p5.Color` value of the pixel from which you can get the components with the functions you’ve specified. More info can be found on the [p5js.org reference page for pixels](https://p5js.org/reference/#/p5/pixels).

---

<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:** [May 30, 2021, 3:04pm UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/8 "2021-05-30T15:04:48Z")

</div>

Hello,

This topic inspired me!

Something I worked on:

> **Example of random tiling \< Click here to see code!**
>
> ```auto
> // Pixel Manipulation 
> // v1.0.0
> // GLV 2021-05-30
> 
> let img;
> let cap;
> 
> function setup() 
> {
> createCanvas(640, 480); // Set to video size
>   
> img = createGraphics(width, height);
> 
> pixelDensity(1);    
> img.pixelDensity(1);
>   
> cap = createCapture(VIDEO);
> cap.hide(); 
>   
> //d = pixelDensity(); // Future! See references.
> }
> 
> function draw() 
> { 
> cap.loadPixels();
> img.loadPixels();
>   
> tilesX = 10;
> tilesY = 10;
>   
> //samples = map(mouseX, 0, width, 0, 2000);
> samples = 200; 
>   
> for (let i = 0; i<samples; i++)
> {
> x = (random(width))| 1; // Converts to int
> y = int(random(height)); // Converts to int 
>       
> let loc = x + y*cap.width;
>   
> // Copy a tile from capture to pixels     
> for (let xt = x; xt < x+tilesX; xt++) 
> {
> for (let yt = y; yt < y+tilesY; yt++) 
> {        
> let loct = (xt + yt*cap.width)*4;
>         
> img.pixels[loct + 0] = cap.pixels[loct + 0]; //r
> img.pixels[loct + 1] = cap.pixels[loct + 1]; //g
> img.pixels[loct + 2] = cap.pixels[loct + 2]; //b
> img.pixels[loct + 3] = cap.pixels[loct + 3]; //a
> }
> }
> }    
>     
> img.updatePixels();
> image(img, 0, 0);
>   
> // Display data
> fill(255);
> stroke(1);
> textSize(18);
> text(frameRate()|1, 10, 20);
> text(samples, 10, 40);
> }
> 
> ```

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/ddeb789c459bad19139d8c2b058fd3e41c31ccc9.jpeg)

A very cool effect!

`:)`

---

<div class="post-metadata">

**Author:** ![Sarahjjt](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@Sarahjjt](https://discourse.processing.org/u/Sarahjjt)\
**Post date:** [June 8, 2021, 5:41pm UTC](https://discourse.processing.org/t/alternative-to-get-for-faster-performance/30228/9 "2021-06-08T17:41:18Z")

</div>

Wow, that’s super cool! Thank you 🙂
