Project 09: Computational Portrait

My process: I chose a picture of me on my 3rd birthday. I wanted to incorporate the number 3 into my custom pixel portrait. So I started there. My first custom pixels are made of 3s. Then I started to play with the other ways I could deconstruct, rebuild, and recolor play with the other ways I could deconstruct, rebuild, and recolor my portrait. I have created a 5 Portrait Series.

Portrait 1 – Made of Threes, Portrait 2 – Made of Ovals – inspired by thumbprint art, Portrait 3 – Made of Squares, Portrait 4 – Made of Legos – inspired by Legos, Portrait 5 – Made of Warhol – inspired by Andy Warhol

Press the space bar to see the various portraits I created. Click the mouse to freeze the creation of a portrait. Click again to resume.

sketch
/* Evan Stuhlfire
 * estuhlfi@andrew.cmu.edu section B
 * Project-09: Computational Portrait */

/* My process: I chose a picture of me on my 3rd 
 * birthday. I wanted to incorporate the number 3 into
 * my custom pixel portrait. So I started there. My first custom pixels
 * are made of 3s. Then I started to 
 * play with the other ways I could deconstruct, rebuild, and recolor
 * my portrait. I have created a 5 Portrait Series. */

 /* Portrait 1 - Made of Threes
  * Portrait 2 - Made of Ovals - inspired by thumbprint art
  * Portrait 3 - Made of Squares
  * Portrait 4 - Made of Legos - inspired by Legos
  * Portrait 5 - Made of Warhol - inspired by Andy Warhol */

/* Press the space bar to see the various portraits I created.
 * Click the mouse to freeze the creation of a portrait. Click again
 * to resume. This way portraits can be saved in different states. */

var img; // image variable
var scaleCanvas = 1.4; // factor to make canvas bigger than image

// booleans to determin which portrait to draw
var dThrees = true;
var dEllipses = false;
var dSquares = false;
var dLines = false;
var dOutline = false;

// used with a mouse click to freeze and resume dynamic portraits
var freeze = false; 

function preload() {
    img = loadImage("https://i.imgur.com/FRtQdiE.jpg");
}

function setup() {
    // create canvas 1.4 times the size of the original image
    createCanvas(img.width * scaleCanvas, img.height * scaleCanvas);
    background(230);

    textAlign(CENTER);
}
    
function draw() {
    // randomly generate x and y to get color from

    // use randomGaussian so image appears in center first
    var xPos = Math.floor(randomGaussian(img.width/2, 100));
    var yPos = Math.floor(randomGaussian(img.height/2, 100));

    // remap coordinates of image to the canvas size
    var xMap = map(xPos, 0, img.width, 0, width);
    var yMap = map(yPos, 0, img.height, 0, height);

    // get pixel color
    var pixCol = img.get(xPos, yPos);

    // test which syle to draw
    if(dThrees & !freeze) {
        drawThrees(xMap, yMap, pixCol);
    } else if(dEllipses & !freeze) {
        drawEllipses(xMap, yMap, pixCol);
    } else if(dSquares & !freeze) {
        rectMode(CENTER);
        drawSquares(xMap, yMap, pixCol);
    } else if(dLines & !freeze) {
        drawLines();
    } else if(dOutline & !freeze) {
        rectMode(CORNER);
        drawOutline();
    }
}

function keyPressed() {
    // switch between portait drawings when
    // the space bar is pressed
    if(key != " ") {
        // key was not space bar, return
        return;
    }

    if(dThrees){
        dThrees = false;
        dEllipses = true;
        dSquares = false;
        dLines = false;
        dOutline = false;
    } else if(dEllipses) {
        dThrees = false;
        dEllipses = false;
        dSquares = true;
        dLines = false;
        dOutline = false;
    } else if(dSquares) {
        dThrees = false;
        dEllipses = false;
        dSquares = false;
        dLines = true;
        dOutline = false;
    } else if(dLines) {
        dThrees = false;
        dEllipses = false;
        dSquares = false;
        dLines = false;
        dOutline = true;
    } else if(dOutline) {
        dThrees = true;
        dEllipses = false;
        dSquares = false;
        dLines = false; 
        dOutline = false; 
    }
    // reset background, unfreeze if frozen
    background(230);
    freeze = false;
}

function mousePressed() {
    // toggle the freeze boolean to freeze drawing
    freeze = !freeze;
}

function colorShift(pc, shiftType) {
    // read the pixel color variable and shift the color
    // based on shiftType specified
    var r, g, b, t;

    // read colors
    r = pc[0];
    g = pc[1];
    b = pc[2];
    t = pc[3];

    if(shiftType == "green") {
        // shift colors towards green
        r = constrain(r - 10, 5, 200);
        g = constrain(g + 50, 50, 230);
        b = constrain(b + 10, 10, 200);  
    } else if(shiftType == "blue") {
        // shift colors towards blue
        r = constrain(r - 10, 5, 200);
        g = constrain(g + 10, 10, 200);
        b = constrain(b + 50, 50, 230);        
    }

    // map mouse to change trasparancy as it moves vertical
    var my = map(mouseY, 0, height, 50, 180);
    t = my;

    return color(r, g, b, t);
}

function drawThrees(xMap, yMap, pixCol) {
    // draw portrait out of 3s
    var maxSize = 40;

    // green shift colors from original image
    pixCol = colorShift(pixCol, "green");
    stroke(pixCol);
    strokeWeight(1);
    fill(pixCol);
    // map mouse x to new range to control text size
    var mx = map(mouseX, 0, width, 10, maxSize);
    textSize(min(mx, maxSize));

    // draw 3s on canvas
    text("3", xMap, yMap);
}

function drawEllipses(xMap, yMap, pixCol) {
    // draw portrait out of random ellipses

    // blue shift colors from original image
    pixCol = colorShift(pixCol, "blue");
    // use color for fill
    fill(pixCol);
    stroke(pixCol);
    strokeWeight(1);
    ellipse(xMap, yMap, random(5, 35), random(5, 15));
}

function drawSquares(xMap, yMap, pixCol) {
    // create portrait from squares
    // square size is based on the darkness of the pixel color
    var maxColor = 140;
    var midColor = 100;
    var midColor2 = 70;

    // make color more or less transparent with movement of mouseY
    var transColor = colorShift(pixCol, "");
    // set colors
    stroke(transColor);
    fill(transColor);

    // Check pixel color and adjust square size based on how dark color is
    if(pixCol[0] > maxColor & pixCol[1] > maxColor && pixCol[3] > maxColor) {
        square(xMap, yMap, 30);
        fill(pixCol);
        circle(xMap, yMap, 5);
    } else if(pixCol[0] > midColor & pixCol[1] > midColor && pixCol[3] >
        midColor) {
        square(xMap, yMap, 20);
        fill(pixCol);
        circle(xMap, yMap, 5);
    } else if(pixCol[0] > midColor2 & pixCol[1] > midColor2 && pixCol[3] >
        midColor2) {
        square(xMap, yMap, 15);
        fill(pixCol);
        circle(xMap, yMap, 5);
    }else {
        square(xMap, yMap, 20);
        fill(pixCol);
        circle(xMap, yMap, 5);
    }
}

function drawLines() {
    // lego like circles and square in rows and columns
    for(var y = 5; y < img.height; y += 5) {

        for(var x = 5; x < img.width; x += 5) {
            var c = img.get(x, y);

            // map x from img to x from canvas
            var mx = map(x, 0, img.width, 0, width);
            // map y from img to y from canvas
            var my = map(y, 0, img.height, 0, height);

            // fill and draw 
            // shift to lego colors   
            if(c[0] > 180) {
                c = color(255, 255, 0);
            } else if(c[0] > 80) {
                c = color(0, 255, 0);
            } else if(c[0] > 50) {
                c = color(255, 0, 0);
            } else {
                c = color(0, 0, 255);
            }
            fill(c);
            noStroke();
            rect(mx, my, 10, 10);
            stroke(50);
            circle(mx, my, 5);
        }
    }
}

function drawOutline() {
    // draw an Andy Warhol style grid of pixel faces
    // draw four color quadrants
    fill(0, 255, 0); // green
    rect(0, 0, width/2, height/2);
    fill(255, 255, 77); // yellow
    rect(width/2, 0, width, height/2);
    fill(77, 255, 255); // blue
    rect(0, height/2, width/2, height);
    fill(255, 148, 77); // orange
    rect(width/2, height/2, width, height);

    // draw monochrome points at points of color change
    for(var y = 0; y < img.height; y += 3) {
        // get color from image
        var c = img.get(0, y);

        // look ahead to see when to change line color
        for(var x = 0; x < img.width; x += 2) {
            var dc = img.get(x, y);

            // color is different, draw this point
            if(dc[0] - c[0] > 10 || c[0] - dc[0] > 10 || 
                x == img.width - 1) {
                // map x from img to x from canvas
                var mx = map(x, 0, img.width, 0, width);
                // map y from img to y from canvas
                var my = map(y, 0, img.height, 0, height);

                if(c[0] > 60) {
                    drawPointImg(mx, my, color(0, 0, 230), 1);
                    drawPointImg(mx, my, color(230, 0, 230), 2);
                    drawPointImg(mx, my, color(255, 0, 0), 3);
                    drawPointImg(mx, my, color(255, 216, 204), 4);
                }

                // set color variable to new color
                c = dc;
            }
        }
    }
}

function drawPointImg(mx, my, pc, quad) {
    // draw set of points for specified quadrant 
    // map to specified quad
    if(quad == 1) {
        // map points to first quadrant
        qmx = map(mx, 0, width, 0, width/2);
        qmy = map(my, 0, height, 0, height/2);
    } else if (quad == 2) {
        // map points to second quadrant
        qmx = map(mx, 0, width, width/2, width);
        qmy = map(my, 0, height, 0, height/2);
    } else if (quad == 3) {
        // map points to third quadrant
        qmx = map(mx, 0, width, 0, width/2);
        qmy = map(my, 0, height, height/2, height);
    } else if (quad == 4) {
        // map points to fourth quadrant
        qmx = map(mx, 0, width, width/2, width);
        qmy = map(my, 0, height, height/2, height);
    }

    // set color of point
    stroke(pc);
    strokeWeight(.25);

    // draw point
    point(qmx, qmy);
}


Project Notes

Leave a Reply