The animation of contrast enhancement is like cut glass

Generative art example : Cut glass.


How to enhance the contrast like a cut glass.

It's a creative coding animation example made with the 'Processing'.

I wondered how to enhancement a contrast like cut glass. And I got an answer using blendMode(MULTIPLY) and blendMode(ADD).


How to enhancement a contrast like cut glass.

And I used PImage to draw many frames with just one picture. Economical programming!

This code does not display any images on the screen but generates image files in frames directory. You can make an animation with these files.







 

The 'Processing' code example.

Please feel free to use this example code of the 'Processing' under the terms of the GPL. To see other works based on my code is my pleasure. And my honor.

// In the Glass.
// Processing 3.2.1
// 2018.04.29
// 20fps x 6s

void setup() {

  size(720, 720);
  colorMode(HSB, 360, 100, 100, 100);
  smooth();
  rectMode(CENTER);
  noLoop();

}

void draw() {

  int frameCountMax = 20 * 6; // whole video frames
  int stillFrames   = 20 * 2; // fix size still image frames

  background(0, 0, 0, 100);
  translate(width / 2, height / 2);

  // draw glass image and put it in PImage for later use
  drawGlass();
  PImage picInit = get();

  blendMode(BLEND);
  for (int i = 1; i <= frameCountMax - stillFrames; ++i) {
    // easing motion
    float easeRate = 1 / max(0.05, easeInOutCubic(map(i, 1, frameCountMax - stillFrames, 0.1, 1.0)));

    // save animation frames
    background(0, 0, 0, 100);
    PImage picWork = picInit.copy();
    picWork.resize(floor(width * easeRate), floor(height * easeRate));
    pushMatrix();
    rotate(PI * easeRate);
    image(picWork, -width * easeRate / 2, -height * easeRate / 2);
    popMatrix();
    casing();

    saveFrame("frames/" + String.format("%04d", i) + ".png");
  }

  // save fix size frames
  for (int i = 1 + frameCountMax - stillFrames; i <= frameCountMax; ++i) {
    image(picInit, -width / 2, -height / 2);
    casing();
    saveFrame("frames/" + String.format("%04d", i) + ".png");
  }

  // save Twitter thumbnail frame
  saveFrame("frames/0000.png");
  exit();

}

void drawGlass() {

 // magic numbers  
  float decrement    = random(0.92, 0.96);
  int   surfaceCount = 8;
  int   numberX      = floor(random(8, 12));

  int   numberY   = numberX;
  float baseSizeX = width / 2;
  float baseSizeY = height / 2;
  float baseHue   = random(360);
  int   baseSeed  = floor(random(100));

  for (int surface = surfaceCount; surface > 0; --surface) {
    // contrast enhancement
    if (surface % 2 == 0) {
      blendMode(ADD);
    } else {
      blendMode(MULTIPLY);
    }

    // surface size
    baseSizeX *= decrement;
    baseSizeY *= decrement;
    int divX   = floor(baseSizeX / numberX);
    int divY   = floor(baseSizeY / numberY);
    int sizeX  = divX * numberX;
    int sizeY  = divY * numberY;

    // draw glass pieces
    noiseSeed(baseSeed + surface);
    float nsX = 0;
    for (int x = -sizeX; x <= sizeX; x += divX) {
      float nsY  = 0;
      for (int y = -sizeY; y <= sizeY; y += divY) {

        float strokeSat = map(noise(x * surface, y), 0, 1, 20, 100);
        float strokeBri = map(noise(x, y * surface), 0, 1, 0, 50);
        float fillSat   = map(noise(x, y * surface), 0, 1, 20, 100);
        float fillBri   = map(noise(x * surface, y), 0, 1, 0, 100);

        pushMatrix();
        translate(x, y);

        noFill();
        strokeWeight(0.2);
        stroke(
               (baseHue + (noise(x) + noise(y)) * 30) % 360,
               strokeSat,
               strokeBri,
               100
               );
        rect(0, 0, divX*0.8, divY*0.8);

        noStroke();
        fill(
             (baseHue + (noise(x) + noise(y)) * 60) % 360,
             fillSat,
             fillBri,
             100
             );
        rotate(PI/4.0);
        rect(0, 0, divX*0.6, divY*0.6);

        popMatrix();

        nsY += 0.8;
      }
      nsX += 0.8;
    }
  }

}

float easeInOutCubic(float t) {

  t *= 2.0;
  if (t < 1.0) {
    return pow(t, 3) / 2.0;
  }

  t -= 2.0;
  return (pow(t, 3) + 2.0) / 2.0;
  
}

void casing() {

  fill(0, 0, 100, 0);
  strokeWeight(80);
  stroke(0, 0, 0, 100);
  rect(0, 0, width, height);
  strokeWeight(50);
  stroke(0, 0, 100, 100);
  rect(0, 0, width, height);

}

/*
Copyright (C) 2018 deconbatch

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>
*/



 

Yet another example image.


Generative art example : Cut glass.

 

Next Post Previous Post
No Comment
Add Comment
comment url