How to properly shuffle a pixelArray

edited May 2017 in Questions about Code

Finally decided to join this forum since I rely so much on other's people's questions/answers.

My question today is how to randomly place a pixel after loading it. I'm not interested in manipulating it's colors just the pixels. Here is my function:

void glitch () {
  if (!glitchComplete) {

    // load the image's pixels into .pixel array 
    img.loadPixels();
    //iterate through each pixel row and column and apply the desired changes
    for (int x = 0; x < img.width; x++) {

      for (int y = 0; y < img.height; y++) {

        color pixelColor = img.pixels[y + x * img.height];
        //the formula I learned from the processing docs

        int loc = y + x * img.height;

        int randomOffset = int(random(5,20));

        //slight shift in their original location
        loc = loc + randomOffset;

        img.pixels[loc] = pixelColor;
      }
    }//end of double loop

    img.updatePixels();
    glitchComplete = true;

    // load updated image onto surface
    image(img, 0, 0, img.width, img.height);
  }

For anyone new to processing, just a heads up: " loc = loc + randomOffset;" will NOT work because this position technically doesnt exist in the pixel array. If you want to place a pixel in a random location, it must be a random location within the bounds of the pixel array (hope im using the right terminology here) .

My thinking here was I wanted to redraw the pixel at it's original location & color and simply shift it over a few pixels to produce something close to a glitch effect(instead of re-colouring the image). So can anyone suggest another method that can achieve the same results.

Your time and input is very much appreciated.

Tagged:

Answers

  • edited May 2017 Answer ✓

    Just limit that new location so it's sure to have a destination pixel, and it works fine:

    boolean clear = true;
    boolean glitch = false;
    
    void setup() { 
      size(500, 500); 
      frameRate(4);
      background(255);
    }
    
    void draw() { 
      if (clear) { 
        background(255);
      }
      translate(width/2, height/2);
      rotate(random(TWO_PI));
      float a, d, gap;
      int num_points = int(random(3, 20));
      gap = TWO_PI/float(num_points);
      fill(random(255), random(255), random(255));
      beginShape();
      for ( int i = 0; i < num_points; i++) {
        a = random(i*gap, (i+1)*gap);
        d = random(10, 200);
        vertex(d*cos(a), d*sin(a));
      }
      endShape(CLOSE);
      if (glitch) { 
        drawGlitch();
      }
    } 
    
    void mousePressed() {
      clear = !clear;
    }
    
    void keyPressed() {
      if ( key == ' ' ) {
        glitch = !glitch;
      }
    }
    
    void drawGlitch() {
      // load the image's pixels into .pixel array 
      loadPixels();
      //iterate through each pixel row and column and apply the desired changes
      for (int x = 0; x < width; x++) { 
        for (int y = 0; y < height; y++) {
    
          color pixelColor = pixels[y + x * height];
    
          int loc = y + x * height;
    
          int randomOffset = int(random(5, 20));
    
          //slight shift in their original location
          loc = loc + randomOffset;
          if (loc < pixels.length) {
            pixels[loc] = pixelColor;
          }
        }
      }//end of double loop
      updatePixels();
    }
    

    Press space for the glitching. Are you asking for more ways of doing glitch effects?

  • Answer ✓

    Same code as @TfGuy44.

    Kf

    void drawGlitch() {
      // load the image's pixels into .pixel array 
      loadPixels();
      //iterate through each pixel row and column and apply the desired changes
      int n=width*height;
      for (int i = 0; i < n; i++) {
        color pixelColor = pixels[i];
        int randomOffset = int(random(5, 20));
        pixels[constrain(i+randomOffset,0,n-1)] = pixelColor;
      }
      updatePixels();
    }
    
  • edited May 2017

    Thank you @TfGuy44 and @kfrajer for your fast responses! I did end up using @kfrajer answer simply because it was minimal effort to add and I didn't need to modify my existing code.

    So I see the magic line that I was missing is pixels[constrain(i+randomOffset,0,n-1)] = pixelColor; Do you mind explaining why you wrote that? I dont know what the constrain function does or why your code doesn't throw an out of bounds error.

  • Oh okay, then in that case I see how the constrain function is extremely useful in this case.

Sign In or Register to comment.