creyes1-Project-09-Portrait

creyes1 Project-09 (Portrait)

//Christopher Reyes
//Section D
//creyes1@andrew.cmu.edu
//Project-09 (Custom Pixel)

var underlyingImage;

function preload() {
    underlyingImage = loadImage('https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/10/creyes1_15104pic.jpg');
}

function setup() {

    createCanvas(480, 480);
    background(255);

    underlyingImage.loadPixels(); //Loads pixel data
    frameRate(60);

}

function draw() {
    //Creates randomly spawning rectangles with color according to underlyingImage
    var px = random(width);
    var py = random(height);
    var ix = constrain(floor(px), 0, width-1);
    var iy = constrain(floor(py), 0, height-1);

    var theColorAtLocationXY = [red(underlyingImage.get(ix, iy)) + 20,
                                green(underlyingImage.get(ix, iy)),
                                blue(underlyingImage.get(ix, iy)),
                                70];

    var rectSize = random(10, 20);

    rectMode(CENTER);
    noStroke();
    fill(theColorAtLocationXY);
    rect(px, py, rectSize, rectSize*3);

    //Draws smaller squares for more detail...
    //At eyes
    drawDetailPixel(width/2, 50, 145, 200, 10);
    //At mouth
    drawDetailPixel(width/2 - 10, 50, 240, 300, 10);

}

//Samples underlying image data for pixel color, then draws a rectangle
//in a random position with a Gaussian distribution
function drawDetailPixel(xmin, xmax, ymin, ymax, pixelSize) {
    var dpx = randomGaussian(xmin, xmax);
    var dpy = random(ymin, ymax);
    var dix = constrain(floor(dpx), 0, width-1);
    var diy = constrain(floor(dpy), 0, height-1);
    var detailColXY = [red(underlyingImage.get(dix, diy)) + 20,
                                      green(underlyingImage.get(dix, diy)),
                                      blue(underlyingImage.get(dix, diy)),
                                      35];
    fill(detailColXY);
    rect(dpx, dpy, pixelSize, pixelSize);
}

//Draws a large transparent ellipse according to underlying image color
function mousePressed() {
    fill(red(underlyingImage.get(mouseX, mouseY)) + 20,
         green(underlyingImage.get(mouseX, mouseY)),
         blue(underlyingImage.get(mouseX, mouseY)),
         35);
    stroke(255, 255, 255, 35);
    strokeWeight(1);
    ellipse(mouseX, mouseY, random(150, 250));
}

While I didn’t run into too many issues with this project in terms of implementation, I did have some issues with finding a balance between keeping it visually interesting while avoiding having too much visual noise that it becomes confusing to look at. I really liked the idea that this was a program that would continue to loop and build upon itself, and so opted for various degrees of transparency so that the image would become more clear as the program ran. I also made it a point to highlight certain areas of the image, such as the eyes and mouth, with smaller transparent squares to build up some more defined shapes so that it would be easier to pick out a face from the constantly layering rectangles. I really like the interaction between the analog brush marks in the portrait with the computational pixels in the program, where it creates something almost painterly, yet not quite glitch art, but a really interesting in-between.


Original Self Portrait



Development of the portrait as the program runs and manual mouse clicks are introduced

Leave a Reply