1

I have created some white noise, which I would like to decrease over time (change starting after 2 secs, intensifying after 10 secs etc), slowly tending towards a black screen.

What I can't figure out is, how can I make only some (say, 50% of all pixels) random pixels change colour, while the rest is just black, within the same frame?

So far, I could only make ALL of them change randomly, or ALL of them stay black. Any help would be much appreciated, thank you!!

void setup() {
  size(1000, 800);
}

void draw() {
  if (millis() < 2000) {
    loadPixels();
    for ( int i=0; i<pixels.length; i++)
      pixels[i] = color(random(255));
    updatePixels();
  }

  if (millis() > 2000) {
    loadPixels();
    if (random(1) >= 0.5) {
      for ( int i=0; i<pixels.length; i++)
        pixels[i] = color(random(255));
      updatePixels();
    } else {
      loadPixels();
      for ( int i=0; i<pixels.length; i++)
        pixels[i] = color(0);
      updatePixels();
    }
  }

  if (millis() > 10000) {
    loadPixels();
    for ( int i=0; i<pixels.length; i++)
      pixels[i] = color(random(255));
    updatePixels();
  }
}
Christopher Bottoms
  • 11,218
  • 8
  • 50
  • 99
elf
  • 13
  • 4

2 Answers2

1

A simple way would be to take into account that random() returns a random value within a range. If you give it a low value, you'll have a low random value. If you use that value as a colour, the lower the value, the closer to black you are which might work well in your case.

If you have a randomness to 255, you increase the changes of having bright pixels, otherwise(with low random values), pixels will be dark:

//noise image
PImage noise;
//amount of noise image image 0 = 0%, 255 = 100%
int noiseAmt = 255;

void setup(){
  noise = createImage(width,height,RGB);
}
void draw(){
  //decrease noise over time
  noiseAmt--;
  if(noiseAmt < 0) noiseAmt = 255;

  //apply noise based on noise amount
  noiseImage();
  //render image
  image(noise,0,0);
}

void noiseImage(){
  int numPixels = noise.pixels.length;
  for(int i = 0 ; i < numPixels; i++){
    //random(noiseAmt) is the key - low values = darker pixels
    noise.pixels[i] = color(random(noiseAmt));
  }
  noise.updatePixels();
}

To get a hang of this, here's a slightly modified version of the code which uses the UP/DOWN arrow keys to control noise:

//noise image
PImage noise;
//amount of noise image image 0 = 0%, 255 = 100%
int noiseAmt = 127;

void setup() {
  noise = createImage(width, height, RGB);
}
void draw() {
  //apply noise based on noise amount
  noiseImage();
  //render image
  image(noise, 0, 0);
}

void noiseImage() {
  int numPixels = noise.pixels.length;
  for (int i = 0; i < numPixels; i++) {
    //random(noiseAmt) is the key - low values = darker pixels
    noise.pixels[i] = color(random(noiseAmt));
  }
  noise.updatePixels();
}
void keyPressed(){
  if(keyCode == UP)   noiseAmt += 5;
  if(keyCode == DOWN) noiseAmt -= 5;
  noiseAmt = constrain(noiseAmt,0,255);
  println("noiseAmt: " + noiseAmt);
}

Back to the matter of time, you can have a look this answer which covers tracking time using millis(). The only extra part is mapping the fade time to the noise amount, which would be some ratio. It might be easier if we map the time passed as a normalised value (from 0.0 to 1.0) which can easily scale to 0.0 to 255.0 simply by multiplying by 255:

//noise image
PImage noise;
//amount of noise image image 0 = 0%, 255 = 100%
int noiseAmt = 255;

int timestamp,fadeTime = 10000;//fade to black in 10s

void setup(){
  noise = createImage(width,height,RGB);
  timestamp = millis();
}
void draw(){
  //decrease noise over time
  int now = millis();
  //if the difference between an initial timestamp and the current time is less than 10s
  if(now - timestamp <= fadeTime){
    //compute the ratio between the time difference and total fadeTime which will be from 0.0 to 1.0
    //subtract this difference from 1.0 to flip the ratio direction from 0.0 -> 1.0 to 1.0 -> 0.0 
    float fadeRatio = 1.0 - ((float)(now-timestamp)/fadeTime);
    //this ratio multiplied to 255 will be
    noiseAmt = (int)(fadeRatio * 255);
  } 

  //apply noise based on noise amount
  noiseImage();
  //render image
  image(noise,0,0);
}

void noiseImage(){
  int numPixels = noise.pixels.length;
  for(int i = 0 ; i < numPixels; i++){
    //random(noiseAmt) is the key - low values = darker pixels
    noise.pixels[i] = color(random(noiseAmt));
  }
  noise.updatePixels();
}

Processing has some nice functions for dealing with mapping and constraining number ranges:

//noise image
PImage noise;
//amount of noise image image 0 = 0%, 255 = 100%
int noiseAmt = 255;
int timestamp,fadeTime = 10000;//fade to black in 10s

void setup(){
  noise = createImage(width,height,RGB);
  timestamp = millis();
}
void draw(){
  //decrease noise over time
  int now = millis();
  //if the difference between an initial timestamp and the current time is less than 10s
  noiseAmt = (int)map(now - timestamp,0,fadeTime,255,0);
  noiseAmt = constrain(noiseAmt,0,255); 

  //apply noise based on noise amount
  int numPixels = noise.pixels.length;
  for(int i = 0 ; i < numPixels; i++){
    //random(noiseAmt) is the key - low values = darker pixels
    noise.pixels[i] = color(random(noiseAmt));
  }
  noise.updatePixels();

  //render image
  image(noise,0,0);
}

Note the fadeTime is set to 10s (10000 milliseconds). Feel free to tinker with the fadeTime value.

Community
  • 1
  • 1
George Profenza
  • 50,687
  • 19
  • 144
  • 218
  • Thank you very much for this! Sorry that I have to keep asking - how would I do exactly this process, but over the course of a certain time, connecting it to the 'millis()' if-statements I mentioned above? – elf Dec 07 '15 at 09:45
  • Have a look at the answer above. This is assuming you want to fade over time as opposed to jump from 100% noise, to 50% after 2 seconds, then suddenly to 0% after 10 seconds. – George Profenza Dec 07 '15 at 11:08
  • 1
    Awesome! Please vote for the answers if they were helpful ;) – George Profenza Dec 07 '15 at 15:34
  • you should accept an answer if it solves your issue. – v.k. Dec 08 '15 at 02:56
0

Instead of posting all of your code in an external website, boil your problem down to an MCVE and include it directly in your question.

That being said, you have two options:

Option 1: Store all of your pixels in some kind of data structure. You might have a 2D array of MyPixel objects, where MyPixel is a class you create that contains all of the information you need to know which instances in that array to change the color of.

Option 2: Draw directly to a PImage. Then you can iterate through that PImage to find a non-black pixel and change it.

Which approach you take is entirely up to you. I'd personally choose the first option, but that's just my personal preference. Try one of these approaches, and post an MCVE when you get stuck. Note that this should be as few lines as possible while still demonstrating the problem, not your whole sketch- we don't need to see your timing logic, for example.

Community
  • 1
  • 1
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • Thank you very much! Sorry about the newbie mistake, deadline stress made me a bit short-sighted. I can defo work with this! – elf Dec 04 '15 at 16:59