Objekte weichzeichnen zu können ist, ein Muss, will man ansprechende Graphiken erstellen. Die Processing eigene weichzeichen-Funktion blur() hat einen entscheidenden Nachteil. Sie ist sehr langsam. Will man Objekte in einer Animation (in Echtzeit) weichzeichnen ist sie somit obsolet.
Mario Klingemann hat einen sehr schnellen Weichzeichen-Algorithmus geschrieben, welcher wiederum von PhiLho erweitert wurde, so dass er nun auch mit dem Alpha Kanal umgehen kann. Damit hat man die Möglichkeit auch mit transparentem Hintergrund zu arbeiten.
// ==================================================
// fastblur, reworked by PhiLho from the Processing Forum
// by Mario Klingemann http://incubator.quasimondo.com/processing/superfast_blur.php
// ==================================================
void fastBlur(PImage img, int radius){
if (radius<1){
return;
}
int w=img.width;
int h=img.height;
int wm=w-1;
int hm=h-1;
int wh=w*h;
int div=radius+radius+1;
int a[]=new int[wh]; // i've added this
int r[]=new int[wh];
int g[]=new int[wh];
int b[]=new int[wh];
int asum,rsum,gsum,bsum,x,y,i,p,p1,p2,yp,yi,yw; // and the asum here
int vmin[] = new int[max(w,h)];
int vmax[] = new int[max(w,h)];
int[] pix=img.pixels;
int dv[]=new int[256*div];
for (i=0;i<256*div;i++){
dv[i]=(i/div);
}
yw=yi=0;
for (y=0;y<h;y++){
asum=rsum=gsum=bsum=0; // asum
for(i=-radius;i<=radius;i++){
p=pix[yi+min(wm,max(i,0))];
asum+=(p>>24) & 0xff;
rsum+=(p & 0xff0000)>>16;
gsum+=(p & 0x00ff00)>>8;
bsum+= p & 0x0000ff;
}
for (x=0;x<w;x++){
a[yi]=dv[asum];
r[yi]=dv[rsum];
g[yi]=dv[gsum];
b[yi]=dv[bsum];
if(y==0){
vmin[x]=min(x+radius+1,wm);
vmax[x]=max(x-radius,0);
}
p1=pix[yw+vmin[x]];
p2=pix[yw+vmax[x]];
asum+=((p1>>24) & 0xff)-((p2>>24) & 0xff); // asum
rsum+=((p1 & 0xff0000)-(p2 & 0xff0000))>>16;
gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8;
bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff);
yi++;
}
yw+=w;
}
for (x=0;x<w;x++){
asum=rsum=gsum=bsum=0;
yp=-radius*w;
for(i=-radius;i<=radius;i++){
yi=max(0,yp)+x;
asum+=a[yi]; // asum
rsum+=r[yi];
gsum+=g[yi];
bsum+=b[yi];
yp+=w;
}
yi=x;
for (y=0;y<h;y++){
pix[yi] = (dv[asum]<<24) | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
if(x==0){
vmin[y]=min(y+radius+1,hm)*w;
vmax[y]=max(y-radius,0)*w;
}
p1=x+vmin[y];
p2=x+vmax[y];
asum+=a[p1]-a[p2]; // asum
rsum+=r[p1]-r[p2];
gsum+=g[p1]-g[p2];
bsum+=b[p1]-b[p2];
yi+=w;
}
}
}
Wie setzt man den Algorithmus ein?
Wie wir der ersten Zeile entnehmen können, verlangt die Funktion beim Aufruf ein PImage und einen Integer als Parameter. Wir können nun also ein *.jpg laden und dieses, bevor wir es am Bildschirm ausgeben, mit dem Algorithmus weichzeichnen.
Beispiel FotoBlur: starte Applet
PImage img;
void setup() {
img=loadImage("blume.JPG");
size(img.width, img.height);
}
void draw() {
img=loadImage("blume.JPG");
fastBlur(img,mouseX/5);
image(img, 0, 0);
}
Wollen wir aber von Processing gezeichnete Objekte weichzeichen, müssen wir diese in einen sog. FrameBuffer zeichnen. Siehe hochauflösende Bilder ausgeben.
Beispiel Bluring selbst gezeichneter Objekte: Starte Applet
Hier wird ein Graphik-Objekt (ellipse()) in einen Offscreen Buffer gezeichnet und dieser dann mit fastBlur() weichgezeichnet.
/*---------------------------------------------------------
By Thomas Koberger
https://lernprocessing.wordpress.com/
---------------------------------------------------------*/
PImage img;
PGraphics pg;
void setup() {
img=loadImage("blume.JPG");
size(img.width, img.height);
}
void draw() {
image(img, 0, 0);
pg= createGraphics(width, height, P2D);
pg.beginDraw();
pg.noFill();
pg.strokeWeight(8);
pg.stroke(50, 100, 250);
pg.ellipse(width/2, height/2, 200, 200);
pg.loadPixels();
fastBlur(pg,mouseX/10);
pg.endDraw();
image(pg, 0, 0);
}
Beispiel Agenten weichzeichnen: starte Applet
Hier werden Agenten in kleine FrameBuffer gerendert, weichgezeichnet und dann angezeigt. Außerdem wird das ganze Bild, jeweils weichgezeichnet und im nächsten Frame als Hintergrund verwendet.
SourceCode siehe Applet!




