# Pushing a 7712x960 Binary image to p5.js is Super slow. Is there a better way?

**URL:** <https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371>\
**Category:** Coding Questions\
**Created:** [May 25, 2018, 10:45am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371 "2018-05-25T10:45:17Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rosaku](https://avatars.discourse-cdn.com/v4/letter/r/ebca7d/32.png) [@Rosaku](https://discourse.processing.org/u/Rosaku)\
**Post date:** [May 25, 2018, 10:45am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/1 "2018-05-25T10:45:18Z")

</div>

Hi, first of all this is my first post, so go easy on me if i am posting in the wrong place 🙂

So what i am trying to do is render an image that is stored as a raw byte array. I am able to do that but its SUUUPER slow.In the code below i am even scaling the image by 1/4.

The image is 7712x920 about 7.1 MB

The reason i am quite positive there must be a better way is because if a store the pictures as bmp and use img = loadImage(“assets/my.bmp”); it works fine and the performance is good.

And no i can’t store all the images as bmp because the camera is running on an embedded device and storing the pixel data raw

There must be a better way!  
looking forward to hearing you suggestions 😃

```auto
//load image from server (works fine)
loadBytes(data.nextFrame,function(data){
      updateImage(data);
    });

//create and render image
function updateImage(data){
  var counter = 0;
  var itr = 0;
  console.log("image W: "+ img.width + " \n image H "+img.height);
  if(data.bytes.length>1){
    img.loadPixels();
    for(var h = 0; h < img.height;h++){
      for(var w= 0; w< img.width;w++){
        img.set(w, h, color(data.bytes[counter], data.bytes[counter], data.bytes[counter]));
        counter += scaleFactor;
        itr++;
      }
    }
    console.log("PixelValue " + counter);
    console.log("itr " + itr);
    img.updatePixels();
    image(img,0 , 0);
  }
}

```

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [May 25, 2018, 11:35am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/2 "2018-05-25T11:35:36Z")

</div>

Hi, take a look at the `loadPixels` example in the reference:

[https://p5js.org/reference/#/p5/loadPixels](https://p5js.org/reference/#/p5/loadPixels)

Your program currently uses `.set()` to set the pixels which is slow.  
Using the `pixels[...]` array should be much faster.  
Do you know how to do that?

---

<div class="post-metadata">

**Author:** ![Rosaku](https://avatars.discourse-cdn.com/v4/letter/r/ebca7d/32.png) [@Rosaku](https://discourse.processing.org/u/Rosaku)\
**Post date:** [May 26, 2018, 12:01am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/3 "2018-05-26T00:01:42Z")

</div>

Thank you for replying!

I have never used the pixels function before, but let med give it a shot.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [May 26, 2018, 7:28am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/4 "2018-05-26T07:28:09Z")

</div>

I gave it a try. For a 1000x1000 image, it takes my laptop 25 milliseconds to randomize all the pixel colors using the `pixels[]` array, and the same operation takes 650 milliseconds when using `set()`. That’s about 26 times slower.

One thing to note is that `set()` sets R, G and B at the same time, while the pixels array has R, G, B and A stored as four consecutive values, so my example images contains 4.000.000 elements (not 1.000.000).

In your program you are setting the same value three times to build a color. Is that on purpose? That will make a gray scale color…

Update: actually, if you really want to use gray scale values it would be even faster, 13 milliseconds in my test program, because I would not need to call `random()` three times per pixel but just once, so 50 times faster than with `set`.

---

<div class="post-metadata">

**Author:** ![Rosaku](https://avatars.discourse-cdn.com/v4/letter/r/ebca7d/32.png) [@Rosaku](https://discourse.processing.org/u/Rosaku)\
**Post date:** [May 26, 2018, 9:02am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/5 "2018-05-26T09:02:43Z")

</div>

Hi Then you again 🙂

That sounds like exactly what i need!  
I am struggling to update my function to use `pixels[]` instead of `.set`  
could you maybe share your test code?

The image is gray scale (forgot to say that) nice catch!

Again thank you! 😃

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [May 26, 2018, 1:37pm UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/6 "2018-05-26T13:37:10Z")

</div>

```auto
function setup() {
  createCanvas(400, 400);
	background(20,180, 10);
	
	var img = createImage(200, 200);
	img.loadPixels();
	for(var i=0; i<img.pixels.length; i+=4) {
		var c = random(255);
		img.pixels[i] = c;
		img.pixels[i+1] = c;
		img.pixels[i+2] = c;
		img.pixels[i+3] = 255;
	}
	img.updatePixels();
	image(img, 0, 0);
}

```

Run it here: [http://alpha.editor.p5js.org/abe/sketches/rkPTGyvyX](http://alpha.editor.p5js.org/abe/sketches/rkPTGyvyX)

This example doesn’t take into account pixelDensity. But the third one here does:  
[https://p5js.org/reference/#/p5/createImage](https://p5js.org/reference/#/p5/createImage)

I think that example has an error though (`width` and `height` should be `img.width` and `img.height` instead. I sent a [pull request](https://github.com/processing/p5.js/pull/2950/files))

---

<div class="post-metadata">

**Author:** ![Rosaku](https://avatars.discourse-cdn.com/v4/letter/r/ebca7d/32.png) [@Rosaku](https://discourse.processing.org/u/Rosaku)\
**Post date:** [May 26, 2018, 5:10pm UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/7 "2018-05-26T17:10:44Z")

</div>

Thank you very much Hamoid!  
Its working now! 😃

Have a nice weekend!

---

<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:** [May 26, 2018, 9:47pm UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/8 "2018-05-26T21:47:19Z")

</div>

Made my own version using a DataView + its method **setInt32()** as a wrapper to write to _pixels[]_ 4 bytes (RGBa) at once: 😀

> **[DataView](https://Developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView)**
>
> The DataView view provides a low-level interface for reading and writing multiple number types in a binary ArrayBuffer, without having to care about the platform's endianness.

  

> **[DataView.prototype.setInt32()](https://Developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt32)**
>
> The setInt32() method stores a signed 32-bit integer (long) value at the specified byte offset from the start of the DataView.

Dunno whether it’s faster or not, but you can check it out online here: 🤡

> **[Fill Image with Random Gray](https://Bl.ocks.org/GoSubRoutine/dd290c28663ef13aaf2f1b5e8d0adffa)**
>
> GoSubRoutine’s Block dd290c28663ef13aaf2f1b5e8d0adffa

```javascript
/**
 * Fill Image with Random Gray (v1.0.3)
 * GoToLoop (2018-May-26)
 *
 * https://Discourse.Processing.org/t/
 * pushing-a-7712x960-binary-image-to-p5-js-
 * is-super-slow-is-there-a-better-way/371/8
 *
 * Bl.ocks.org/GoSubRoutine/dd290c28663ef13aaf2f1b5e8d0adffa
 */

"use strict";

let img;

function setup() {
  createCanvas(400, 300).mousePressed(redraw);
  noLoop();
  img = createImage(width >> 1, height >> 1);
}

function draw() {
  background(top.document.title = '#' + hex(~~random(0x1000), 3));
  fillImgRndGray(img);
  set(width - img.width >> 1, height - img.height >> 1, img);
}

function keyPressed() {
  return !!redraw();
}

function fillImgRndGray(img) {
  if (!img) img = createImage(width, height);
  img.pixels.buffer || img.loadPixels();

  const pix = new DataView(img.pixels.buffer),
        len = pix.byteLength,
        bytes = Int32Array.BYTES_PER_ELEMENT,
        range = 0x100;

  for (let i = 0; i < len; i += bytes) {
    const gray = ~~random(range),
          RGBa = gray<<0o30 | gray<<0o20 | gray<<0o10 | 0xff;

    pix.setInt32(i, RGBa);
  }

  img.updatePixels();
  return img;
}

```

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [May 27, 2018, 11:17am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/9 "2018-05-27T11:17:38Z")

</div>

It’s cool that you know how to do this @GoToLoop but I think the syntax is unnecessarily hard to understand considering the audience of this forum.

Maybe if you share such an example it would be nice to explain why you choose to use octal, hexadecimal, bitwise operations, double negatives, `let`, `strict`, `const` etc, is there any advantage of using such and explaining how they work so others can learn from that.

---

<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:** [May 28, 2018, 5:25am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/10 "2018-05-28T05:25:09Z")

</div>

> [@hamoid](#):
>
> … but I think the syntax is unnecessarily hard to understand considering the audience of this forum.

Yup, a lil’ harder indeed. However, I’ve made this example as a bonus over your already accepted & thanked example! So it’s on purpose it’s more “technical” than yours. 😋

> [@hamoid](#):
>
> … it would be nice to explain why you choose to use octal, hexadecimal, bitwise operations, double negatives, `let` , `strict` , `const` etc, …

Whoa! What a big list to explain each item of it! 😵

I believe if some1 really wants an explanation about some part of my code, they can ask about it here, pinpointing exactly what they hadn’t understood. 🤒

I don’t feel like pre-explaining how my code works line-by-line before some1 had even asked for it 1st! 😲

Actually, ~80% (or even 100%) you had listed can be easily found here: 😇

> **[JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript)**
>
> JavaScript (JS) is a lightweight interpreted (or just-in-time compiled) programming language with first-class functions. While it is most well-known as the scripting language for Web pages, many non-browser environments also use it, such as Node.js,...

By `strict`, I guess you’ve meant `"use strict";` ,right? 🤔

This is a very old ES5 standard btW. 👴  
And IMO, every single “.js” file should have that as its 1st executable statement: 🗄

> **[Strict mode - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)**
>
> JavaScript's strict mode is a way to opt in to a restricted variant of JavaScript, thereby implicitly opting-out of "sloppy mode". Strict mode isn't just a subset: it intentionally has different semantics from normal code. Browsers not supporting...

Ditto for the ES6 `let` & `const` keywords. They’ve replaced the semi-deprecated `var` for ordinary usage: 💪

> **[let - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)**
>
> The let declaration declares re-assignable, block-scoped local variables, optionally initializing each to a value.

> **[const - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)**
>
> The const declaration declares block-scoped local variables. The value of a constant can't be changed through reassignment using the assignment operator, but if a constant is an object, its properties can be added, updated, or removed.

---

<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:** [May 28, 2018, 6:58am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/11 "2018-05-28T06:58:42Z")

</div>

> [@hamoid](#):
>
> … why you choose to use octal, hexadecimal, bitwise operations, …

These are the hexadecimal & octal values I’ve used on my sketch: 😒  
`0x1000, 0x100, 0xff, 0o30, 0o20, 0o10`

Frankly, if n1 wishes to know those corresponding base10 values can open their browser’s console by hitting CTRL + SHIFT + J (or just F12) and copy & paste this: ⌨  
`console.log(0x1000, 0x100, 0xff, 0o30, 0o20, 0o10);`  
Add get this following output:  
`4096 256 255 24 16 8`

Now I ask you: Is `'#' + hex(~~random(4096), 3)` actually more understandable than `'#' + hex(~~random(0x1000), 3)`? 🤔

Or would `RGBa = gray<<24 | gray<<16 | gray<<8 | 255;` enlighten us more than `RGBa = gray<<0o30 | gray<<0o20 | gray<<0o10 | 0xff;`? 🔦

Would n1 who still doesn’t understand how computers store data in RAM comprehend how the value 4096 (0x1000) could possibly be used to pick all main colors? 💻

Why not just 4000 or 4100? Or for picking a random gray, why not 250 or 260?

The `>> 1` is just a faster way to get the half of a value w/ its result truncated (no fractional part). 🤑

The `RGBa = gray<<24 | gray<<16 | gray<<8 | 255;` is for composite-placing the randomly picked gray color at the Red, Green & Blue byte-octet-position within the 32-bit (4-byte) color value. Of course, the tail `255` is for a 100% opaque alpha. 😉

For example, `gray<<24` bit-shifts the gray value 24 bits (3 bytes) to the left.  
The octal form `gray<<0o30` implies those 3 bytes for those in the know. 😛

In order to facilitate general comprehension, I’ve turned all those “mysterious” values into constants.  
Therefore that statement is now: 🕶  
`RGBa = gray<<THREE_BYTES | gray<<TWO_BYTES | gray<<ONE_BYTE | MAX_BYTE;`

So now you folks can focus more on what the code is doing rather than how it is doing it if u choose so! 😸

> <https://gist.github.com/GoSubRoutine/dd290c28663ef13aaf2f1b5e8d0adffa>

```javascript
/**
 * Fill Image with Random Gray (v1.1.1)
 * GoToLoop (2018-May-26)
 *
 * https://Discourse.Processing.org/t/
 * pushing-a-7712x960-binary-image-to-p5-js-
 * is-super-slow-is-there-a-better-way/371/11
 *
 * Bl.ocks.org/GoSubRoutine/dd290c28663ef13aaf2f1b5e8d0adffa
 */

"use strict";

const WEBCOLOR_RANGE = 0x1000, GRAY_RANGE = 0x100,
      NUM_COLOR_BYTES = Int32Array.BYTES_PER_ELEMENT,
      ONE_BYTE = 0o10, TWO_BYTES = 0o20, THREE_BYTES = 0o30, MAX_BYTE = 0xff;

let img;

function setup() {
  createCanvas(400, 300).mousePressed(redraw);
  noLoop();
  img = createImage(width >> 1, height >> 1);
}

function draw() {
  background(top.document.title = randomColor());
  fillImgRndGray(img);
  set(width - img.width >> 1, height - img.height >> 1, img);
}

function keyPressed() {
  return !!redraw(); // returns false as preventDefault()
}

function randomColor() {
  return '#' + hex(~~random(WEBCOLOR_RANGE), 3);
}

function fillImgRndGray(img) {
  if (!img) img = createImage(width, height);
  img.pixels.buffer || img.loadPixels();

  const pix = new DataView(img.pixels.buffer), len = pix.byteLength;

  for (let i = 0; i < len; i += NUM_COLOR_BYTES) {
    const gray = ~~random(GRAY_RANGE),
          RGBa = gray<<THREE_BYTES | gray<<TWO_BYTES | gray<<ONE_BYTE | MAX_BYTE;

    pix.setInt32(i, RGBa);
  }

  img.updatePixels();
  return img;
}

```

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [May 28, 2018, 9:52am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/12 "2018-05-28T09:52:35Z")

</div>

> [@GoToLoop](#):
>
> The `>> 1` is just a faster way to get the half of a value

There are reasons to use bitwise operations but speed is no longer one of them. Modern compilers choose the fastest way to achieve what you ask for. [Browserscope shows](https://jsperf.com/bitshift-vs-divide-by-2) that the normal division is actually faster in Chrome, Firefox and Opera.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [May 28, 2018, 9:55am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/13 "2018-05-28T09:55:29Z")

</div>

> [@GoToLoop](#):
>
> Now I ask you: Is `'#' + hex(~~random(4096), 3)` actually more understandable than `'#' + hex(~~random(0x1000), 3)` ?

Both are quite unreadable. Maybe this shows more the intention:

```javascript
// Set the page title to a random color-code.
// Color R, G and B values can be between 0 and 255,
// so 256 different levels. 256 * 256 * 256 equals
// 16.777.216, which is the total number of different colors
// most current computers can display.
top.document.title = '#' + hex(random(256*256*256), 6);
background(top.document.title);

```

---

<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:** [May 29, 2018, 4:53am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/14 "2018-05-29T04:53:10Z")

</div>

> [@hamoid](#):
>
> … that the normal division is actually faster in Chrome, Firefox and Opera.

For me they were about the same for 32-bit SlimJet (Chromium 64.0.3282.119) & 32-bit SRWare Iron (Chromium 66.0.3450.0) under my Win8.1 AMD laptop. 🙄

But surprisingly bitshifting was slower on 64-bit Waterfox (Firefox 56.2.0)! 😵

However, if I go w/ latest 64-bit Firefox Dev Edition 61.0b8, bitshifting is back at the top again! 💪

Given that future Firefox bitshifting is faster again; and in Chromium they’re mostly about the same; plus `width >> 1` is clearly much shorter than `Math.floor(width >> 1)` or even `floor(width >> 1)`, I’ll keep on doing bitshifting all the way! 😹

BtW, I’ve setup another [JsPerf.com](http://JsPerf.com) w/ 5 tests now: 🏁  
[https://JsPerf.com/bitshift-vs-divide-by-2-vs-multiply-by-half-ii](https://JsPerf.com/bitshift-vs-divide-by-2-vs-multiply-by-half-ii)

---

<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:** [May 29, 2018, 5:00am UTC](https://discourse.processing.org/t/pushing-a-7712x960-binary-image-to-p5-js-is-super-slow-is-there-a-better-way/371/15 "2018-05-29T05:00:49Z")

</div>

![FF-Shift-Test](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/1X/7ca1313eeaae3f7ccd8598d7569bb45963cf8a77.jpg) ![Chrome-Shift-Test](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/1X/1e124f31b6e55df5e8996efcbfd0e8fd2a65495d.jpg)
