Image array For loop position variation


#1

Pretty simple, I want to create subtle variation in position in the X and Y axis using noise() on a PImage. I’ve messed around with the pull and pop matrix with no luck. Any help is appreciated.

void noize(){
  jpg.loadPixels();
  
  noiseFloatx = noise(5);
  noiseFloaty = noise(0,5);
  
  noiseIntx = (round(noiseFloatx)); 
  noiseInty = (round(noiseFloaty)); 
  
  for (int gridX=0; gridX<jpg.width; gridX++){
    for (int gridY=0; gridY<jpg.height; gridY++){  
      int cgetN = (jpg.get(gridX,gridY));
      fill(cgetN);
   ellipse(gridX+boarder+noiseIntx, gridY+boarder+noiseFloaty, rs, rs);
    }
  }
  jpg.updatePixels();
  noLoop();
}

#2

i do a little test
you can do

draw()
  ellipse

or

draw()
  loadPixels();  
  pixels[x]=color(0,0,200); 
  updatePixels();

example

void setup() {
}
void draw() {
  background(200,200,0);
  loadPixels();
  int line = height/2;
  for ( int i = width*line; i< width*(line+1);i++) pixels[i]=color(0,0,200);   // make a line at line
  //_____________________________________________________now inhere can draw what you want
  rect (20,20,20,20);
  //_____________________________________________________but when you do
  updatePixels();
  //_____________________________________________________it's gone
}

#3

I hope you found a solution that worked for you.

This was unclear to me. Did you mean that you want to:

  1. move the cells – drift each pixel of the image in a random direction – so that it is “scattered”, like powder, and some parts display outside the bounding rectangle, and some overlap, and some have no image data at all in them.

or

  1. sample into the cells – populate each pixel of the image from a random nearby pixel – but still end up with a grid of color in a rectangular bounding box, and each has a color.

#4

This was the aim, yes. I’m hoping to do this with the pushMatrix + translate. I’ve simplified my code as a basis to start with but even that isn’t working:

PImage source;

int loc;

color c;

float h;
float s;
float b;

int x;
int y;

void setup(){
  colorMode(HSB);
  source = loadImage("source.jpg");
  size(source.width,source.height);
  background(0);
  
  source.loadPixels();
  
  int loc = y*source.width+x; // Map pixel array to cordernates in 2d space
  color c = (source.pixels[loc]); //Assigns c color to pixel array
  
  float h = hue(source.pixels[loc]);
  float s = saturation(source.pixels[loc]);
  float b = brightness(source.pixels[loc]);
  source.updatePixels();
}
 
void draw(){
  source.loadPixels();
  float scale = 0.01;
 
  for(int x = 0; x<width;x++){
    for(int y = 0; y<height;y++){
      ellipse(x,y,10,10);
      fill(h,s,(b*noise(scale*x,scale*y)));
    }
  }
  source.updatePixels();
}

#5

I don’t recommend pushing and popping the matrix for every pixel – that is going to be really, really inefficient. I wouldn’t even use PImage.get(). Instead, I would recommend a for loop iterating over jpg.pixels[].

Getting the color of a single pixel with get(x, y) is easy, but not as fast as grabbing the data directly from pixels[]. The equivalent statement to get(x, y) using pixels[] is pixels[y*width+x] . See the reference for pixels[] for more information.

Do you want your pixels to be jumping around every frame, or do you want the scattered values to be stable / static? If static you could pre-generate a list of 2*pixels noise values and store them in 1 or 2 arrays, for your x and y offsets.


#6

Here is a little toy for playing with noise over image pixels.

It is not optimized yet in any way – it recalculates every value for every pixel each frame. But this keeps the code very simple for experimenting.

// ImagePixelNoiseShift
// 2019-01-12 Jeremy Douglass - Processing 3.4
// See: discourse.processing.org/t/image-array-for-loop-position-variation/6938/4
//
// Use noise to shift the locations of individual image pixels, warping the image
// like a Perlin 2D noise field.
// -  Move mouse up-down to increase the noise step value.
// -  Move mouse left-right to increase the effect per pixel.
// -  Press any key to use a new noise field.

OffsetImage oImg;

void setup() {
  size(480, 480);
  frameRate(4);
  PImage img = loadImage("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Processing_3_logo.png/240px-Processing_3_logo.png");
  oImg = new OffsetImage(img);
}

void draw() {
  background(255, 0, 0);
  translate(width/2 - oImg.img.width/2, height/2 - oImg.img.height/2);
  oImg.warp(mouseY/((float)height) * 0.02, 1.5);
  oImg.render(mouseX);
}

void keyReleased(){
  noiseSeed(millis());
}

class OffsetImage {
  PImage img;
  float[][][] offsets;
  OffsetImage(PImage img) {
    this.img = img;
    offsets = new float[img.height][img.width][2];
  }
  void render(){
    this.render(1);
  }
  void render(float scale){
    this.img.loadPixels();
    pushStyle();
    for (int y=0; y<img.height; y++) {
      for (int x=0; x<img.width; x++) {
        int idx = y*img.width+x;
        stroke(img.pixels[idx]);
        point(x + offsets[x][y][0] * scale, y + offsets[x][y][1] * scale);
      }
    }
    popStyle();
  }
  void warp(float noiseStep, float ylayer){
    for (int y=0; y<img.height; y++) {
      for (int x=0; x<img.width; x++) {
        this.offsets[x][y][0] = (noise(x*noiseStep, y*noiseStep, 0) - 0.5);
        this.offsets[x][y][1] = (noise(x*noiseStep, y*noiseStep, ylayer) - 0.5);
      }
    }
  }
}