modifying the color of a png image

Hello everybody,

I am at a loss trying to change the color of a png image. Nothing I have tried seems to be working. Here is my code so far (the image (note.png is just a black music eight on a transparent background which you can easily recreate). I want the black color of the note to change, not the background.

var img;

function setup() {
  createCanvas(100, 100);
  img = loadImage("../data/note.png");

function draw() {
  background(255, 0, 0, 50);      // pinkish
  image(img, 25, 0, 50, 90);


  for (var x = 0; x < img.width; x++) {
      for (var y = 0; y < img.height; y++) {
             var index = (x + y * width)*4;
         var pixC = img.get(index);
    //     console.log(pixC);
         if (pixC !=  color('255, 0, 0, 50'))    // background color   // I also tried "if (pixC ==  color('0, 0, 0'))" 
            pixels[index+0] = 0;
            pixels[index+1] = 255;
            pixels[index+2] = 0;
            pixels[index+3] = 255;           

  image(img, 25, 0, 50, 90);

Thanks for your help.


  • Please format your code. Edit your post (gear on top right side of any of your posts), select your code and hit ctrl+o. Leave an empty line above and below your block of code. Details here:


  • editing done!

  • edited April 2018

    comment deleted. um, apparently java pixels is different from javascript pixels...

  • So? What should I do? I tried to imitate some of Shiffman's code, to no avail!

  • is line 20 working? do you see 'OK'?

    try it with a tiny image, like 10x10 pixels. that way you can print out the values you are getting without being overwhelmed by output. does the output differ from what you are expecting.

  • edited April 2018
    1. Load assets in preload() instead: :-c
    2. Method get() is either 0, 2, or 4 parameters:
    3. Therefore var pixC = img.get(index); @ line #18 w/ 1 parameter is wrong! :-&
    4. Instead, access pixels[] for both read & write:
    5. color() returns a p5.Color object, not an array[]: L-) -->
    6. The RGBa pixels[] is of datatype Uint8ClampedArray: :-B
    7. If you prefer to access the RGBa pixels[] as a whole 32-bit value rather than 4 8-bit separate values, you can create an Int32Array (or an Uint32Array) buffer view of pixels[]: *-:)
      const pixels32 = new Int32Array(img.pixels.buffer);
    8. That'll greatly simplify traversing, reading, comparing & writing to pixels[], given each index is now 1 RGBa value rather than split across 4 indices. \m/
  • @koogs Do NOT delete your comments! =))

    Also, make sure that you realize that the plain loadPixels() deals with the pixels for the main sketch window, but img.loadPixels() works with img.pixels, which is the pixels of a specific image.

  • edited April 2018

    @GoToLoop - Thank you so much for your detailed answer. Unfortunately, I still cannot get it to work. If I put the image on a larger canvas, the whole image (square) gets colored, not just the drawings on it. If the canvas is the same size, nothing happens. In fact, the console.log for img.loadPixels() gives me 'undefined', therefore, it is not surprising that nothing happens. It makes me angry as I managed to get this same kind of code working in Hype and Processing in seconds. I wanted to port it to P5.js, and just can't do it! I just want my little notes to get colored when they come out of my trumpet!!

    @TfGuy44 - Thank you for your comment, but I knew that already, and as I said above, img.loadPixels() gives me no positive result.

  • is loadPixels() a void method? ie it doesn't return anything, but it does fix the pixels array.

  • I can only suggest to use the latest p5.js libs. If you are using the latest, then place a ticket in github as this should get some attention.


  • edited April 2018

    ... as I managed to get this same kind of code working in Hype and Processing in seconds.

    According to Hype's site:
    Its Hype library is also compatible w/ Pjs:

    Here's an example running online:

    If you take its whole ".pde" file:

    And paste it in Processing under Java Mode, the code is gonna work there too! :)>-

    If you do the same at:
    Switch to its Processing.js Mode and click at its play button, that very same ".pde" runs there as well. \m/

  • I wanted to port it to P5.js, and just can't do it!

    If you had an already running code, why didn't you post that as well? :-/
    Both the original code & the converted attempt should be posted. :-\"

    Also, you should keep posting your most recent attempts, so we can track your progress on solving your issue. O:-)

  • Sorry @GoToLoop, but Hype is not compatible with P5.js. Hype is a Java library, so it does not work with Javascript. Joshua Davis had mentioned porting it to P5.js a while ago, but he now says that they are concentrating on Processing for now. I think I am going to give up my idea of rewriting it in P5. I was just doing that as an exercise. Thanks for your king cooperation anyway.

  • @sillyfrog -- GoToLoop was pointing out that Hype claims to work with the older ProcessingJS -- not the newer P5.js. This makes sense, because there are live demos running on the Hype website -- if they aren't running in JavaScript, then how is that happening...? It is Java code written so that it can be transpiled into JavaScript -- rather than written in native JavaScript.

  • ... but Hype is not compatible with P5.js.

    In general, any regular JS library can be used in p5.js.
    Although there are some which are specifically written as a p5.js extension:

    Hype is a Java library, so it does not work with Javascript.

    That's true. But Pjs can automatically transpile it to JS syntax! :ar!
    That's why we can see Hype sketches running inside a browser: \m/

  • edited May 2018

    Joshua Davis had mentioned porting it to p5.js a while ago, ...

    Given his library Hype uses just a small fraction of Java stuff that Pjs is fully able to transpile to JS syntax, it shouldn't be that hard to convert it to a p5.js extension library. ~O)

    But I've spotted some technicalities in Hype which makes converting it to JS a real challenge. :-SS

    It is its usage of operator instanceof. Well, JS got that operator too. :>
    However, Hype relies on instanceof in order to check whether an object is affiliated to some interface.

    But JS doesn't have interfaces. We can attempt to solve that by reifying a Java interface as an actual JS class.

    But then we'd need to replace implements w/ extends when defining subclasses of it. ~:>
    But Hype got classes that implements more than 1 interface.

    But if those interfaces are classes now, we gotta use extends instead.
    And only 1 class can be specified by extends, even in JS! #-o

    Dunno exactly which voodoo tricks Pjs pulled off in order to transpile Hype Java into Hype JS. :-$

    But to make a multi-inheritance in JS, we gotta use a programming technique called mixin.
    It's not a JS builtin facility though. :(

    And Pjs had to do mixins in such a way that instanceof would detect the "mixed" interface as a parent of the object being tested. :ar!

  • edited May 2018

    @GoToLoop Thanks for all your anwsers. I am away on vacation for 2 weeks and using my laptop (Windows 10), and guess what? I managed to get the program working! :)

    I will have to test that same code on my iMac Retina when I go back. I'll keep you posted.

    Bye for now and thanks again.

    I will try the Hype library on P5. Not sure how to do that, but I'll give it a try. Not sure either how P5 can transpile it to Js, but I'll try anyway.

Sign In or Register to comment.