1
// Set colour of light bulb
function set_bulb_colour(img_id, rgb_colour) {
  var img = new Image();

  img.onload = function() {
    var canvas = document.createElement('canvas');

    canvas.width = img.width;
    canvas.height = img.height;

    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0);

    var image_data = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var data = image_data.data;

    for (var i = 0; i < data.length; i += 4) {
      if (data[i + 3] == 0) {
        continue;
      }

      // If the pixel is yellow set it to the new colour
      if (data[i] > 200 && data[i + 2] < 100) {
        data[i] = rgb_colour[0];
        data[i + 1] = rgb_colour[1];
        data[i + 2] = rgb_colour[2];
      }
    }

    ctx.putImageData(image_data, 0, 0);

    $('img#living_room_light_emoji').attr('src', canvas.toDataURL());
  }

  img.src = 'images/light_bulb.png';
}

I have a question about the code i have above if anyone knows the answer. The code works. It changes all the yellow pixels in a light bulb image to a rgb colour passed in. I get an object from getImageData. I then get the data calling .data on that. I modify the pixels in the data variable. But when i redraw the image using putImageData, i put the object image_data back in instead of the ‘data’ that i was modifing. How does that work, does the data variable somehow point to the object in image_data?

So what im asking is, by reading that code it looks like you take a copy of image_data’s data by calling .data and store it in a variable called data. To me modifiying data would not modify image_data. But it does. How does this work? When you use image_data to redraw it has the modified data. Does data point to image_data? I know how you could make this happen in C but didn't think it would work like this in javascript

ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
av4625
  • 303
  • 1
  • 11
  • 1
    Indeed, `var data = image_data.data;` does not create a copy. The variable `data` and the property `image_data.data` refer to the same object. – Sebastian Simon May 14 '18 at 23:24
  • There are tons of duplicates of this questions. All primirive values (number, strings, ...) are copied when passed around. All other types (arrays, objects, ...) are not, only a reference to their underlying data is passed. So `data` and `image_data.data` are both pointing to the same array in memory. Changes to one is reflected on the other. – ibrahim mahrir May 14 '18 at 23:29
  • ... the answer to the third duplicate question features a very interesting [**illustration**](https://stackoverflow.com/a/29050089/). – ibrahim mahrir May 14 '18 at 23:31
  • Thanks guys, I just do JavaScript at home for my own stuff so haven't a lot of experience, helpful comments, sorry about the duplicate – av4625 May 15 '18 at 07:49

1 Answers1

1

How does that work, does the ‘data’ variable somehow point to the object in ‘image_data’?

The short answer is yes.

The longer answer can be found here: Is JavaScript a pass-by-reference or pass-by-value language?

Basically, it's "call-by-sharing" (as opposed to pass-by-value or pass-by-reference). If you change the "original", the changes will not persist down but changes to "references" will persist back to the original.

Kurt
  • 1,868
  • 3
  • 21
  • 42