动态效果演示
实现
part1
观察这张gif图片不难发现,它显然是基于一个已有的照片来实现的。因此整体的实现步骤分为导入和记录图片像素信息,每一帧创建若干随机圆,填充该圆所在位置的颜色。
导入图片,记录像素值
这里我首先创建了一个circle类,用来记录每个点的位置信息和颜色信息。然后在setup函数中导入图片,并显示出来,保存每个点的位置加颜色信息,再clear窗口。
class circles
{
int x,y,r;
circles()
{
x=int(random(0,750));
y=int(random(0,1000));
r=int(random(1,20));
}
}
void setup()
{
size(750,1000);
img_me=loadImage("me.JPG");
image(img_me,0,0,width,height);
for (int j=0;j<750;j++)
{
for (int k=0;k<1000;k++)
{
color colortemp=get(j,k);
colormap map=new colormap(colortemp,j,k);
colorlist.add(map);
}
}
clear();
每一帧随机创建圆
//全局变量
ArrayList<circles> circlelist=new ArrayList<circles>();
ArrayList<colormap> colorlist=new ArrayList<colormap>();
//20/flash
for(int j=0;j<100;j++)
{
circlelist.add(new circles());
i+=1;
}
for(int a=0;a<circlelist.size();a++)
{
circles circle_single=circlelist.get(a);
int b=circle_single.x;
int c=circle_single.y;
int r=circle_single.r;
color color_fill=colorlist.get(b*1000+c).color_me;
noStroke();
fill(color_fill);
ellipse(b,c,r,r);
}
part2
基本同第一部分,将圆改为倒三角
class Triangle
{
int x,y,x1,x2,x3,y1,y2,y3,r;
Triangle()
{
x=int(random(0,750));
y=int(random(0,1000));
r=int(random(1,20));
x1=int(x-pow(3,0.5)/2*r);
x2=int(x+pow(3,0.5)/2*r);
x3=x;
y1=int(y-r/2);
y2=int(y-r/2);
y3=int(y+r);
}
}
for(int j=0;j<100;j++)
{
tris.add(new Triangle());
i+=1;
}
for(int a=0;a<tris.size();a++)
{
Triangle trii=tris.get(a);
int b=trii.x;
int c=trii.y;
color color_fill=colorlist.get(b*1000+c).color_me;
noStroke();
fill(color_fill);
triangle(trii.x1,trii.y1,trii.x2,trii.y2,trii.x3,trii.y3);
//print(trii.x1);
}
part3
思路是将原图转为灰度图后获取每一部分灰度值,设置不同阈值赋以不同的颜色。
void draw_3()
{
//20/flash
for(int j=0;j<500;j++)
{
circlelist2.add(new circles2());
i+=1;
}
for(int a=0;a<circlelist2.size();a++)
{
circles2 circle_single=circlelist2.get(a);
int b=circle_single.x;
int c=circle_single.y;
int r=circle_single.r;
int color_fill=colorlist2.get(b*1000+c).color2;
color color_to_fill=color(0,0,0);
if(color_fill>=120&&color_fill<=180)
{
color_to_fill=color(244,225,197);
}
else if(color_fill>=200)
{
color_to_fill=color(255,197,197);
}
else if(color_fill>=50&&color_fill<=100)
{
color_to_fill=color(252,204,132);
}
noStroke();
fill(color_to_fill);
ellipse(b,c,r,r);
}
}
part4
思路:首先将原灰度图同过设立阈值,将黑色部分保存到一个列表中。
//在setup函数中
img_me2=loadImage("me4.jpg");
image(img_me2,0,0,width,height);
i=0;
for (int j=0;j<750;j++)
{
for (int k=0;k<1000;k++)
{
int colortemp=int(red(get(j,k)));
colormap2 map2=new colormap2(colortemp,j,k);
colorlist2.add(map2);
if(colortemp<=50)
{
point pointt=new point(j,k);
points.add(pointt);
}
}
}
clear();
创建point类保存位置信息
class point
{
int x,y;
point(int x1,int y1)
{
x=x1;
y=y1;
}
}
ArrayList<point> points=new ArrayList<point>();
遍历列表中的点,在画布上随机取点和列表中点一一对应,绘制两点之间的连线。并在每一帧绘制所有已经遍历的点,用ellipse。
void draw_4()
{
if(clip<points.size())
{
background(255);
for (int aa=0;aa<100;aa++)
{
if(clip<points.size())
{
point pointt=points.get(clip);
clip+=5;
//println(clip);
point pointr=new point(int(random(0,750)),int(random(0,1000)));
stroke(0);
line(pointr.x,pointr.y,pointr.x+int((1+flag_toadd)*(pointt.x-pointr.x)/10),pointr.y+int((1+flag_toadd)*(pointt.y-pointr.y)/10));
}
}
for (int a=0;a<clip;a+=5)
{
noStroke();
fill(0);
point pointtemp=points.get(a);
ellipse(pointtemp.x,pointtemp.y,2,2);
}
if(!(flag_toadd % 10==0))
{
clip-=500;
}
flag_toadd+=1;
}
else
{
for (int a=0;a<clip;a+=5)
{
noStroke();
fill(0);
point pointtemp=points.get(a);
ellipse(pointtemp.x,pointtemp.y,2,2);
}
}
}
part5
添加鼠标交互,每点一次切换绘制模式。
void mouseClicked()
{
total_flag+=1;
}
void draw()
{
if(total_flag%4==0)
{
clear();
draw_1();
}
if(total_flag%4==1)
{
clear();
draw_2();
}
if(total_flag%4==2)
{
clear();
draw_3();
}
if(total_flag%4==3)
{
clear();
draw_4();
}
}
总结
用processing每每都有意料之外的收获,在于其能十分快捷地得到反馈,即便写错了,也能获得和开始所想不一样的效果。期待下一次用processing做出更加炫酷的效果。