set() function does not seem to work

Hello:

This is a beginning to a generative art program. I plan to have it so that rows of pixels are moved left and right based upon their "color distances" from the averages of their top and bottom neighbor rows. The part I am concentrating on is the moveRow function. The programmer can provide it a row to move and how many pixels to move it to the left (negative numbers) or the right (positive numbers) as parameters. Note that moved row wraps around the screen. I try the program and nothing moves! I think it may have to do with the background image "neon-smoke" not being updated somehow. Note that the set() function is supposed to do that, in my opinion. Threw in img.updatePixels() for good measure.

PImage img;

void setup()
{
    size(500,500);
    img = loadImage("neon-smoke.jpg");
    img.resize(width,height);
    image(img,0,0);
}

void draw() {
  image(img,0,0);
  moveRow(10,1);
}

void moveRow(int row, int offset) {
   
   color[] c = new color[width];
   int targetPos = 0;
   for (int i = 0; i < width; i++) {
     if ((i+offset) > width)
       targetPos = (i+offset)-width;
     else if ((i+offset) < 0)
       targetPos = width+offset+i;
     else
       targetPos = i+offset;
      c[i] = img.get(row,targetPos);
      //println(i,offset,i+offset,targetPos,img.get(row,targetPos),c[i]);
   }
   
   for (int i = 0; i < width; i++)
     img.set(row,i,c[i]);
   img.updatePixels();
}

Tagged:

Answers

  • Oh, by the way, feel free to experiment and use your own image if you want!

  • I try the program and nothing moves!

    I try the program and am more observant :P

    I don't have your source image so maybe it was more obvious with the image I used. You're only moving pixels in a single column of your image so the effect is very subtle. Try applying it to all pixels and you'll see it's doing something. I'm not sure if this is what you actually intend as your description is hard to read since it's been formatted as code :/

    PImage img;
    
    void setup()
    {
        size(500,500);
        img = loadImage("neon-smoke.jpg");
        img.resize(width,height);
        image(img,0,0);
    }
    
    void draw() {
      image(img,0,0);
      // apply the effect to all rows:
      for (int i = 0; i < height; i++){
        moveRow(i,1);
      }
    }
    
    void moveRow(int row, int offset) {
    
       color[] c = new color[width];
       int targetPos = 0;
       for (int i = 0; i < width; i++) {
         if ((i+offset) > width)
           targetPos = (i+offset)-width;
         else if ((i+offset) < 0)
           targetPos = width+offset+i;
         else
           targetPos = i+offset;
          c[i] = img.get(row,targetPos);
          //println(i,offset,i+offset,targetPos,img.get(row,targetPos),c[i]);
       }
    
       for (int i = 0; i < width; i++){
           img.set(row,i,c[i]);
       }
    }
    
  • edited September 2015 Answer ✓

    Hmn... your code is actually working, although it might not work as desired.

    moveRow is currently shifting rows from top to bottom and vise versa and targetPos does not "wrap" around screen corners. I modified moveRow to work horizontal and made it "wrap":

    PImage img;
    
    void setup() {
        size(500, 500);
        img = loadImage("http" + "://www.gravatar.com/avatar.php?gravatar_id=d1b9ee5537bb75d0e375fe03dfe7b74f&size=50&default=http%3A%2F%2Fvanillicon.com%2Fd1b9ee5537bb75d0e375fe03dfe7b74f.png");
        img.resize(width, height);
    }
    
    void draw() {
        image(img, 0, 0);
        for(int y = 0; y < height; y++) // Funky distortion :D
            moveRow(y, (int)(sin((frameCount + y) * 0.01) * 10));
    }
    
    void moveRow(int row, int offset) {
    
        int[] c = new int[height]; // color is basically just a wrapper around an int
        offset += height; // Get a positive offset as modulo won't "wrap" negative values as you might expect
        for (int x = 0; x < height; x++)
            c[x] = img.get((x + offset) % height, row); // Use % (modulo) operator to make sure the (x + offset) "wraps" around the screen
    
        for (int x = 0; x < width; x++)
            img.set(x, row, c[x]);
    
    }
    

    This should get you started. The averageRow function is up to you. :)

Sign In or Register to comment.