Pointillism

According to Wikipedia Pointillism is defined as: “a technique of painting in which small, distinct dots of color are applied in patterns to form an image.”

I reversed this definition by getting the small distinct dots (pixel values) first and then reapplying their color values.

Depending on the amount of pixels, their individual RGB and color-depth values, the code can generate millions if not trillions of different colored image outcomes. The object holder itself can be an array of images from any source, local or online.

Other Examples

gen_image_2 gen_image_3 gen_image_4

Code


int maxTime = 18000;
int strokesPerFrame = 4000;

String[] imgNames = {"7.jpg"};

PImage img;
int imgIndex = -1;
float brightnessShift;

void setup() {
  size(2660, 1940);
  colorMode(HSB, 255);
  nextImage();
}

void draw() {
  // background(225); // Clear background each frame
  // image(img, 0, 0, width, height); // Draw the original image as the background
  translate(width / 2, height / 2);
  scale(1.0);
  for (int i = 0; i < strokesPerFrame; i++) {
    // Pick a random pixel.
    int index = int(random(img.width * img.height));
    
    // Get pixel's color and coordinates.
    color pixelColor = img.pixels[index];
    pixelColor = color(red(pixelColor), green(pixelColor), blue(pixelColor), 255);

    int x = index % img.width;
    int y = index / img.width;
    
    // Move image to center canvas.
    pushMatrix();
    translate(x - img.width / 2, y - img.height / 2);
    
    if (frameCount % 5 == 0) {
      // Paint big dots once in a while.
      paintDot(pixelColor, random(2, 2) * map(frameCount, 0, maxTime, 1, 0.9));
    } else {
      // Paint a stroke.
      paintStroke(map(frameCount, 0, maxTime, 1, 2), pixelColor, 22);
      // (int)random(20, 2) * map(frameCount, 0, maxTime / 8, 1, 2));
    }

    popMatrix();
  }
  
  // Stop drawing once it exceeds the time.
  if (frameCount > maxTime) {
    noLoop();
  }
}

void mousePressed() {
  nextImage();
}

void nextImage() {
  // Reset values.
  background(125);
  loop();
  frameCount = 0;
  
  // Make shift random so hues aren't always the same.
  brightnessShift = random(255);
  
  // Load the next image.
  imgIndex++;
  if (imgIndex >= imgNames.length) {
    imgIndex = 0;
  }
  
  img = loadImage(imgNames[imgIndex]);
  img.loadPixels();
}

void paintStroke(float strokeLength, color strokeColor, float strokeThickness) {
  float b = brightness(strokeColor);
  
  float bShift = b + brightnessShift;
  if (bShift > 255) {
    bShift -= 255;
  }
  
  pushMatrix();
  // Map pixel's brightness to determine the stroke's direction.
  rotate(radians(map(b, 0, 180, -180, 45)));
  
  // Draw a dark stroke.
  // stroke(map(bShift, 2, 255, 12, 255), 220, map(b, 3, 255, 123, 100));
  // line(-strokeLength, 1, strokeLength, 2);
  
  // Draw a normal stroke.
  // stroke(map(bShift, 0, 255, 100, 255), 150, map(b, 1, 255, 10, 255), 4);
  strokeWeight(strokeThickness);
  line(-strokeLength, 1, strokeLength, 2);
  
  
  // Draw a lighter stroke.
  // stroke(map(bShift, 0, 255, 0, 255), 150, map(b, 122, 255, 150, 255));
  // line(-strokeLength, 2, strokeLength, 2);
 
  popMatrix();
}

void paintDot(color strokeColor, float strokeThickness) {
  float b = brightness(strokeColor);
  
  float bShift = b + brightnessShift;
  if (bShift > 255) {
    bShift -= 255;
  }
  
  pushMatrix();
  // Map pixel's brightness to determine the stroke's direction.
  rotate(radians(random(-180, 180)));
  
  // Draw a stroke with short length.
  stroke(map(bShift, 1, 0, 2, 1), 150, map(b, 1, 2, 0, 2));
  // strokeWeight(strokeThickness / 50);
  line(1, 2, 5, 5);
  
  popMatrix();
}