I found this box blur argorithm:
// Super Fast Blur v1.1
// by Mario Klingemann <http://incubator.quasimondo.com>
//
// Tip: Multiple invovations of this filter with a small
// radius will approximate a gaussian blur quite well.
//
BImage a;
BImage b;
void setup()
{
a=loadImage("dog.jpg");
size(a.width, a.height);
b=new BImage(a.width, a.height);
fill(255);
noStroke();
framerate(25);
}
void loop()
{
System.arraycopy(a.pixels,0,b.pixels,0,a.pixels.length);
fastblur(b,mouseY/8);
image(b, 0, 0);
}
void fastblur(BImage 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 r[]=new int[wh];
int g[]=new int[wh];
int b[]=new int[wh];
int rsum,gsum,bsum,x,y,i,p,p1,p2,yp,yi,yw;
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++){
rsum=gsum=bsum=0;
for(i=-radius;i<=radius;i++){
p=pix[yi+min(wm,max(i,0))];
rsum+=(p & 0xff0000)>>16;
gsum+=(p & 0x00ff00)>>8;
bsum+= p & 0x0000ff;
}
for (x=0;x<w;x++){
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]];
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++){
rsum=gsum=bsum=0;
yp=-radius*w;
for(i=-radius;i<=radius;i++){
yi=max(0,yp)+x;
rsum+=r[yi];
gsum+=g[yi];
bsum+=b[yi];
yp+=w;
}
yi=x;
for (y=0;y<h;y++){
pix[yi]=0xff000000 | (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];
rsum+=r[p1]-r[p2];
gsum+=g[p1]-g[p2];
bsum+=b[p1]-b[p2];
yi+=w;
}
}
}
and i wanted to convert it to blitzmax code,here is what i've done:
SuperStrict
Graphics 800,600
Global a:TPixmap
Global b:TPixmap
a=LoadPixmap("dog.PNG")
b=fastblur(a,3)
DrawImage(LoadImage(b),0,0)
Repeat
Flip
Until KeyDown(key_enter)
Function fastblur:TPixmap(img:TPixmap,radius:Int)
If radius<1 Return img
Local blur:TPixmap=CopyPixmap(img)
Local w:Int=blur.width
Local h:Int=blur.height
Local wm:Int=w-1
Local hm:Int=h-1
Local wh:Int=w*h
Local div:Int=radius+radius+1
Local r:Int[]=New Int[wh]
Local g:Int[]=New Int[wh]
Local b:Int[]=New Int[wh]
Local rsum:Int,gsum:Int,bsum:Int,x:Int,y:Int,y1:Int,y2:Int,i:Int,p:Int,p1:Int,p2:Int,yp:Int,yi:Int,yw:Int
Local vmin:Int[]=New Int[Max(w,h)]
Local vmax:Int[]=New Int[Max(w,h)]
Local pix:Byte Ptr=blur.pixels
Local dv:Int[]=New Int[256*div]
For i=0 To 256*div-1
dv[i]=(i/div)
Next
yw=0
yi=0
For y=0 To h-1
rsum=0
gsum=0
bsum=0
For i=-radius To radius
p=blur.ReadPixel((yi+Min(wm,Max(i,0))) Mod blur.width,Floor((yi+Min(wm,Max(i,0)))/blur.width))
Print rsum
Print gsum
Print bsum
Print (p And $ff000000) Shr 24
rsum:+(p And $ff0000) Shr 16
gsum:+(p And $00ff00) Shr 8
bsum:+p And $0000ff
Next
For x=0 To w-1
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)
EndIf
p1=blur.ReadPixel((yw+vmin[x]) Mod blur.width,Floor((yw+vmin[x])/blur.width))
p2=blur.ReadPixel((yw+vmax[x]) Mod blur.width,Floor((yw+vmax[x])/blur.width))
rsum:+((p1 And $ff0000)-(p2 And $ff0000)) Shr 16
gsum:+((p1 And $00ff00)-(p2 And $00ff00)) Shr 8
bsum:+(p1 And $0000ff)-(p2 And $0000ff)
yi:+1
Next
For x=0 To w-1
rsum=0
gsum=0
bsum=0
yp=-radius*w
For i=-radius To radius
yi=Max(0,yp)+x
rsum:+r[yi]
gsum:+g[yi]
bsum:+b[yi]
yp:+w
Next
yi=x
For y1=0 To h-1
blur.WritePixel(yi Mod blur.width,Floor(yi/blur.width),$ff000000 + (dv[rsum] Shl 16) + (dv[gsum] Shl 8) + dv[bsum])
If x=0
vmin[y1]=Min(y1+radius+1,hm)*w
vmax[y1]=Max(y1-radius,0)*w
EndIf
p1=x+vmin[y1]
p2=x+vmax[y1]
rsum:+r[p1]-r[p2]
gsum:+g[p1]-g[p2]
gsum:+b[p1]-b[p2]
yi:+w
Next
Next
Next
Return blur
EndFunction
But,no matter what i try,it doesn't work. Once it gives me boundary error,other time only fills image blue. Can anyone take a look at this and show me what am i doing wrong ?
|