技术宅的圣诞礼物
by
at 2012-01-08 12:29:27
original http://item.feedsky.com/~feedsky/heikezhi/~8608072/592583106/6713895/1/item.html
如果你是个技术宅,正在发愁圣诞送什么礼物给女友,那你不妨学学Scott MacDonald,用骰子为她制作一副肖像画,下面就让我们看看Scott是如何完成这幅重达100磅(约45公斤)的骰子肖像画的吧。

首先第一步就是图像处理,我们需要将全彩图像转换为骰子灰度,首先将图像转换为6阶灰度图,然后将这6个灰度对应到骰子的6个点,1代表黑色,6代表白色,帖子结尾附有Processing转换程序(如果你是PS宅,这里是一篇PS转换教程)。
接下来就是材料准备了,这是Scott购买的3000颗骰子,他计划制作一幅64 x 102.4厘米的画作,如果以骰子为单位,那就是40 x 64平方骰子,总共需要2560颗骰子,这个尺寸的高宽比为1.6,接近黄金比例。

spmacdonald的工作台,他花了4个小时完成组装:

下面是最后的成品:

大图:

转换程序:
PImage img;
PImage cropped_img;
PImage patch;
int _width = 640;
int _height = 1024;
int patch_w = 16;
int patch_h = 16;
int pip_size = 4;
void setup() {
size(_width, _height);
img = loadImage("Caroline.jpg");
img.resize(1536, 1024);
cropped_img = img.get(250, 0, _width, _height);
}
// Draw quantized image
void draw() {
// Array to hold the gray values of a patch
int[] x = new int[patch_w * patch_h];
// Quantize the image
for (int i=0; i < (_width/patch_w); ++i) {
for (int j=0; j < (_height/patch_h); ++j) {
patch = cropped_img.get(i*patch_w,
j*patch_h,
patch_w,
patch_h);
patch.loadPixels();
for (int k=0; k < patch.pixels.length; ++k) {
x[k] = rgb2gray(patch.pixels[k]);
}
int dice_num = six_step_gray(mean(x));
if (dice_num == 1) draw_one(i, j);
if (dice_num == 2) draw_two(i, j);
if (dice_num == 3) draw_three(i, j);
if (dice_num == 4) draw_four(i, j);
if (dice_num == 5) draw_five(i, j);
if (dice_num == 6) draw_six(i, j);
}
}
}
void draw_one(int i, int j) {
fill(0);
rect(i*patch_w, j*patch_h, 16, 16);
fill(255);
ellipse(i*patch_w+8, j*patch_h+8, pip_size, pip_size);
}
void draw_two(int i, int j) {
fill(0);
rect(i*patch_w, j*patch_h, 16, 16);
fill(255);
ellipse(i*patch_w+3, j*patch_h+3, pip_size, pip_size);
ellipse(i*patch_w+13, j*patch_h+13, pip_size, pip_size);
}
void draw_three(int i, int j) {
fill(0);
rect(i*patch_w, j*patch_h, 16, 16);
fill(255);
ellipse(i*patch_w+3, j*patch_h+3, pip_size, pip_size);
ellipse(i*patch_w+8, j*patch_h+8, pip_size, pip_size);
ellipse(i*patch_w+13, j*patch_h+13, pip_size, pip_size);
}
void draw_four(int i, int j) {
fill(0);
rect(i*patch_w