Loading...
Logo
Processing Forum
Hello. I'm new to processing. I'm trying to draw an image to the window pixel by pixel with a short delay between each pixel. My code is below. I feel like this should work based on other forum posts I've seen but I just get a gray square when I run it. Thanks for any help!

Copy code
  1. PImage img0; 
  2. int y;
  3. int z;

  4. String[] images = {
  5.   "1.jpg",
  6.   "2.jpg",
  7.   "3.jpg",
  8. };

  9. void setup() {
  10.   size(200,133);
  11. }

  12. void myDelay(int ms) {
  13.   try {    
  14.     Thread.sleep(ms);
  15.   }
  16.   catch(Exception e){}
  17. }

  18. void draw() {
  19.     loadPixels();
  20.     y = random(0,3);
  21.     // turn float into int (there must be a better way to do this)
  22.     z = int(y * 1);
  23.     
  24.     img0 = loadImage(images[z]);
  25.     img0.loadPixels();
  26.     for (int y = 0; y < height; y++) {
  27.       for (int x = 0; x < width; x++) {
  28.         int loc = x + y*width;
  29.       
  30.         // The functions red(), green(), and blue() pull out the 3 color components from a pixel.
  31.         float r = red(img0.pixels[loc]);
  32.         float g = green(img0.pixels[loc]);
  33.         float b = blue(img0.pixels[loc]);
  34.         
  35.         color c = color(r,g,b);
  36.         set(x,y,c);
  37.         myDelay(100);
  38.       }
  39.     }
  40. }

Replies(7)

You can't easily do any updates to the display from within a for loop because the entire thing is executed before draw finishes and displays a frame. You can change the code a little to increment the index of the pixel you are getting and setting and set it each frame. The following should do this and switch the image each time it has filled the canvas. I've shown how to get the next x and y position of the pixel, but it is not necessary. You can use Processing's pixels array with a direct index instead of set.

PImage img0;

String[] images = {
  "1.jpg",
  "2.jpg",
  "3.jpg",
};

void setup() {
  size(200,133);
  loadPixels();
}

void myDelay(int ms) {
  try {    
    Thread.currentThread().sleep(ms);
    updatePixels();
  }
  catch(Exception e){}
}

void draw() {
  int loc = frameCount%(width*height);
//  int x = loc%width;
//  int y = floor(loc/width);
  
  if(loc == 0) {
    img0 = loadImage(images[(int)random(3)]);
    img0.loadPixels();
  }

  // The functions red(), green(), and blue() pull out the 3 color components from a pixel.
  float r = red(img0.pixels[loc]);
  float g = green(img0.pixels[loc]);
  float b = blue(img0.pixels[loc]);
  
  color c = color(r,g,b);
//  set(x,y,c);
  pixels[loc] = c;
  myDelay(10);
}


When making a suggestion to not use something it might be nice to explain why. I don't think there is anything inherently wrong with sleep()ing threads except that it may get confusing especially for new users and in code more complex then the example. There are various other ways to do timing. I thought about suggesting the use of frameRate(10), but I guess I usually lean towards modifying OP's code as little as possible and letting them discover the alternatives themselves.

By the way, I just realized it is better to write it Thread.sleep(...) like OP did instead of the way I did.
rbauer: thanks for your help! This works. But, even with ms set to 1 it is much slower than I want. I'm trying frameRate() to see if that will work. Is there any theoretical issue with setting frameRate to 2000? That's much higher than the default but seems to be about the speed I want.



" When making a suggestion to not use something it might be nice to explain why"
The articles linked in my answer explains this at length. Or are supposed to explain it (maybe I just failed at being clear). That's the point of the FAQ: to avoid repeating the same info over and over in the forum...

" I don't think there is anything inherently wrong with sleep()ing threads"
Sure, except when it is the main thread sleeping for several seconds, as seen too often.
I don't see the point here (in the original message, which was my target), anyway, since the delays just cumulate in draw(), and doesn't help in making a progressive draw, as intended.
It seems OP didn't need a delay after all and, yes it should be fine to do frameRate(2000). You could also set more than one pixel per frame.
Sure, except when it is the main thread sleeping for several seconds, as seen too often.
You still haven't explained specifically why it is bad to sleep the main thread as far as I can tell. I glanced at your wiki pages and they seem fine, but not directly related to threads or sleep(...). A short summary along with your links might have been more helpful. Something like, "Often a better way to handle timing involves using the millis() method."

Its a little off topic, but if I could give some input for those pages I would suggest perhaps combining them under a more general title and mentioning Threads and sleep(...) even if you would like to steer people away from that since it seems at least some beginners tend to go that direction when trying something like that.

EDIT
Ah I see they have a category on the FAQ. By the way I'm not trying to discount your advice, PhiLho, just kind of trying to see the situation through the eyes of a typical forum user who may be looking for quick specific advice and also trying to promote learning by doing. If something works for a small example someone will soon enough learn its pitfalls by continuing to use it as they expand the code and it gets more complicated.
Thanks for the advices, rbrauer, constructive feedback is always welcome.