/* @pjs globalKeyEvents=true; preload="headshot.jpg"; */ PImage img; // From a Ben Fry example: All ASCII characters, sorted according to their visual density String letterOrder = " .`-_':,;^=+/\"|)\\<>)iv%xclrs{*}I?!][1taeo7zjLu" + "nT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q"; char[] letters; PFont f; float sz = 8.0; void setup() { size(600, 800); img = loadImage("headshot.jpg"); f = createFont("monospace", 48); // also from a Ben Fry example: for the 256 levels of brightness, distribute the letters across // the an array of 256 elements to use for the lookup letters = new char[256]; for (int i = 0; i < 256; i++) { int index = int(map(i, 0, 256, 0, letterOrder.length())); letters[i] = letterOrder.charAt(index); } // we want black on white not the white on black of the example letters = reverse(letters); } void draw() { background(255); textFont(f); textSize(sz); float prev = 0; img.loadPixels(); for (int y = 1; y < height; y+= int(1 * sz)) { for (int x = 0; x < width; x+=prev) { int pixelColor = img.pixels[x+y*img.width]; // Faster method of calculating r, g, b than red(), green(), blue() int r = (pixelColor >> 16) & 0xff; int g = (pixelColor >> 8) & 0xff; int b = pixelColor & 0xff; int pixelBright = max(r, g, b); fill(0); text(letters[pixelBright], x, y); prev = textWidth(letters[pixelBright]); } } noLoop(); } void keyPressed() { switch (key) { case 'f': sz *= .95; sz = constrain(sz, 4, 15); break; case 'F': sz *= 1.05; sz = constrain(sz, 4, 15); break; } loop(); }