2013 – Human Rights Poster

This poster was created using Gimp, Processing, and Flickr’s creative commons search engine. This work and the code used to create it are released under the creative commons, non-commercial, attribution license (cc-by-nc). The license holders for the faces are listed on the poster.

FinalPoster

This is a cell packing algorithm that isn’t really the most efficient. It requires a source image with text on it for the rest of the code to refer to. The dots are then coloured based on the brightness of source image. There is a bit of white space around the characters still, and I manually controlled the size of the dots instead of adjusting it dynamically, but the printed version looks alright, so I’m happy with it. Also I’m sure some of the functions at the end weren’t used, but I tend to just grab that big block of code and pop it into any sketch where I need to save an image.
CODE:

ArrayList cells;

PGraphics iBuff; // IMAGE BUFFER
PGraphics cBuff; // CELL BUFFER

PImage words;
PImage face;
PImage mask;
int numberOfFaces = 270;
int faceIndex = 0;

int cellMin;// = 30;//60;
int cellMax;// = 60;//120;

void setup() {
size(850, 550);
colorMode(HSB);

words = loadImage("words2.jpg");
mask = loadImage("mask.jpg");
nextFace();
cells = new ArrayList();
iBuff = createGraphics(1700, 1100);
iBuff.beginDraw();
iBuff.colorMode(HSB);
iBuff.image(words,0,0,iBuff.width,iBuff.height);
iBuff.endDraw();
//cBuff = createGraphics(5950, 3850);
cBuff = createGraphics(6800, 4400);
cBuff.beginDraw();
cBuff.colorMode(HSB);
cBuff.ellipseMode(CENTER);
cBuff.smooth();
//cBuff.imageMode(CENTER);
cBuff.background(255);
cBuff.endDraw();

cellMin = 20;
cellMax = 30;

for (int i=0; i<500; i++) {
cells.add(new Cell());
println(i + " of " + cells.size());
}

cellMin = 17;
cellMax = 27;

for (int i=0; i<800; i++) {
cells.add(new Cell());
println(i+500 + " of " + cells.size());
}
cellMin = 12;//30;
cellMax = 22;//60;

for (int i=0; i<600; i++) {
cells.add(new Cell());
println(i+1300 + " of " + cells.size());
}

cellMin = 9;
cellMax = 17;

for (int i=0; i<2300; i++) {
cells.add(new Cell());
println(i+2100 + " of " + cells.size());
}

cellMin = 5;
cellMax = 13;

for (int i=0; i0; i--)
{
Cell cell = (Cell) cells.get(i);
if(cell.cellSize == 0)
cells.remove(i);
}

for (int i=0; i50) {
//RED
H = (int)random(12) + 18;
S = (int)random(18) + 52;
B = 255;
}
else {
//GREEN
H = (int)random(10) + 73;
S = (int)random(27) + 27;
B = 220; //(int)((random(3)+1)*64);
}
color C = color(H, 200, B);
cellColour = C;

}

PVector getLocation() {
PVector result = new PVector(0, 0);
int tries = 0;
while (!OK && tries 1) {
checkCells(result);
}
checkLetters(result);
if (closestCellDist > cellMin) {
OK = true;
cellSize =(int) (((closestCellDist* 1.3 < cellMax) ? closestCellDist* 1.3 : cellMax) );
}
tries++;
}
if(tries == 40000) println("TOO MANY TRIES");
return result;
}

void checkLetters(PVector test) {
color C = iBuff.get((int)test.x,(int)test.y);
float dist = 1000;
if(brightness(C) 128)
dist = closestPixel(test,false);
if((dist*3) < closestCellDist)
closestCellDist = dist*3;

}

float closestPixel(PVector pixel, boolean inLetter) {

float result = 1000;
int x,y;
for(int i=0; i<cellMax; i++) {
for(int j=0; j 128){
float Dist = pixelDist((int)pixel.x,(int)pixel.y,x,y);
if(Dist < result) {
result = Dist;
//println("EdgeClipped");
}
}
}
else {
if(brightness(D) < 128){
float Dist = pixelDist((int)pixel.x,(int)pixel.y,x,y);
if(Dist < result) {
result = Dist;
//println("EdgeClipped");
}
}
}
}
}
return result;
}

float pixelDist(int p1x, int p1y, int p2x, int p2y) {
float result;
result = sq(p2x - p1x) + sq(p2y - p2y);
return result;
}

void checkCells(PVector test) {
for (int i=0;i<cells.size();i++) {
Cell cell = (Cell) cells.get(i);
if(closestCellDist < cellMin) {
i = cells.size();
}
else if((cellDist(test,cell)) < closestCellDist) {
closestCellDist = (cellDist(test,cell));
}
}
}

float cellDist(PVector v1, Cell v2) {
float dist = v1.dist(v2.cellLocation) - cellSize/2 - v2.cellSize/2;
return dist;
}

void drawCell() {
cBuff.beginDraw();
cBuff.fill(cellColour);
cBuff.noStroke();
float SCALE = 4;
//cBuff.ellipse(cellLocation.x*SCALE, cellLocation.y*SCALE, cellSize*SCALE, cellSize*SCALE);
cBuff.tint(hue(cellColour),saturation(cellColour),brightness(cellColour));
face.mask(mask);
//cBuff.blendMode(MULTIPLY);
cBuff.image(face,(cellLocation.x - (cellSize/2))*SCALE,(cellLocation.y-(cellSize/2))*SCALE,cellSize*SCALE,cellSize*SCALE);
cBuff.endDraw();
nextFace();
}
}

float polarToX(float theta, float rad) {
float x = rad * cos(theta);
return x;
}

float polarToY(float theta, float rad) {
float y = rad * sin(theta);
return y;
}

void saveImage(PImage IMG,String fileName) {
IMG.save(fileName);
println("IMAGE SAVED: "+fileName);
}
void saveImage(PImage IMG)
{
// you can use .tif .jpg .tga and .png files, just change the end of the next line
String fileName = getName()+".tif";
IMG.save(fileName);
println("IMAGE SAVED: "+fileName);
}
void saveImage(PImage IMG,int page)
{
// you can use .tif .jpg .tga and .png files, just change the end of the next line
String fileName = getName(page)+".jpg";
IMG.save(fileName);
println("IMAGE SAVED: "+fileName);
}

String getName(int page) {
String pageName = "Page";
String name;
if(page<10) {
name = pageName + "00" + page;
} else if(pagewidth || H>height) {
scl = (width/float(W)<(height/float(H)))
? width/float(W) : height/float(H);
} else {
scl = 1;
}
return scl;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s