Anyway I came across this http://www.codeproject.com/Articles/616 ... a-Blurring (original author Matthew Hazlett, 22 Feb 2004) and it looked tantalizingly simple, just begging me to try porting it so I had a go and it was painless enough heehee. In feedback to the code somebody clarified that it's a median filter. The author describes it as
The quality of the blur seems quite good, it supports full RGBA, and it has variable width+height kernel matrix (but unweighted unlike true gaussian) so you can also do vertical and horizontal blurs (motion blurs?)The reason it isn't exactly the same as the real mccoy (gaussian) is it doesn't take into account a transform matrix, so as a result the colors all have the same weighted values (but you can't really tell a difference).
Here is 1) original, 2) blur x2 (smallest), 3) blur x8 - it doesnt seem to have a ceiling so you can go far beyond 8, 4) horizontal blur x8, 5) vertical blur x8

It's a direct port of the VB demo however, and I can see you all cringing now as you anticipate that yes - this uses Plot() & Point() to work one pixel at a time as per the original so it's quite slow, OUCH!
Code: Select all
;Based on http://www.codeproject.com/Articles/6162/Gaussian-And-Alpha-Blurring  (by Matthew Hazlett, 22 Feb 2004)
EnableExplicit
Structure _SIZE
  Height.i
  Width.i
EndStructure
Structure _SIZEF
  Height.f
  Width.f
EndStructure
Structure Color
  R.a
  G.a
  B.a
  A.a
EndStructure
Procedure.l Average(*Size._SIZE, *imageSize._SIZEF, PixelX, PixelY) 
  Dim pixel(Int(*imageSize\Height * *imageSize\Width))
  Protected pixels, x, y
  ;' Find the color for each pixel and add it to a new array.
  ;' Remember a 5X5 area on or near the edge will ask for pixels that don't exist in our image, this will filter those out. 
  For x = PixelX - (*Size\Width / 2) To PixelX + (*Size\Width / 2)
    For y = Pixely - (*Size\Height / 2) To Pixely + (*Size\Height / 2)
      If (x > 0 And x < *imageSize\Width) And (y > 0 And y < *imageSize\Height) 
        pixel(pixels) = Point(x, y)
        pixels+1
      EndIf
    Next
  Next  
  ;' Average the A, R, G, B channels reflected in the array
  Protected thisColor, alpha, red, green, blue
  For thisColor = 0 To pixels-1
    alpha + Alpha(pixel(thisColor))
    red + Red(pixel(thisColor))
    green + Green(pixel(thisColor))
    blue + Blue(pixel(thisColor))
  Next
  If pixels = 0: ProcedureReturn 0: EndIf
  ProcedureReturn RGBA(red/pixels, green/pixels, blue/pixels, alpha/pixels)  ;' Return the sum of the colors / number of colors (the avg)
EndProcedure
Procedure MedianBlur(hImg, *ImgSize._SIZEF, alphaEdgesOnly.i, *blurSize._SIZE)
  Protected PixelX, PixelY
  StartDrawing(ImageOutput(hImg))   
  For PixelY = 0 To *ImgSize\Height - 1
    For PixelX = 0 To *ImgSize\Width - 1
      If Not alphaEdgesOnly ;' Blur everything
        Plot(PixelX, PixelY,  Average(*blurSize, *ImgSize, PixelX, PixelY))
      ElseIf Alpha(Point(PixelX, PixelY)) <> 255   ;' Alpha blur channel check
        Plot(PixelX, PixelY,  Average(*blurSize, *ImgSize, PixelX, PixelY))
      EndIf
    Next
  Next
  StopDrawing()
EndProcedure
;-- TEST ----------------------------------------------------------------------------------------------------
Define blursize._SIZE, hImg = LoadImage(#PB_Any, #PB_Compiler_Home+"/Examples/Sources/data/purebasic.bmp")  ;500, 500,32, #PB_Image_Transparent) 
If hImg = 0:  MessageRequester("Error","Load file fail"): End: EndIf
Define ImgSize._SIZEF\Height = ImageHeight(hImg): ImgSize._SIZEF\Width = ImageWidth(hImg)
OpenWindow(0, 0, 0, ImgSize._SIZEF\Width, ImgSize._SIZEF\Height*5, "Blur", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
Define hBlurImg1 = CopyImage(hImg, #PB_Any)
blursize._SIZE\Height = 2:  blursize._SIZE\Width = 2    ;x2 blur (smallest)
MedianBlur(hBlurImg1, @ImgSize, #False, blursize)
Define hBlurImg2 = CopyImage(hImg, #PB_Any)
blursize._SIZE\Height = 8:  blursize._SIZE\Width = 8    ;x8 blur
MedianBlur(hBlurImg2, @ImgSize, #False, blursize)
Define hBlurImg3 = CopyImage(hImg, #PB_Any)
blursize._SIZE\Height = 2:  blursize._SIZE\Width = 8    ;x8 Horizontal blur
MedianBlur(hBlurImg3, @ImgSize, #False, blursize)
Define hBlurImg4 = CopyImage(hImg, #PB_Any)
blursize._SIZE\Height = 8:  blursize._SIZE\Width = 2    ;x8 Vertical blur
MedianBlur(hBlurImg4, @ImgSize, #False, blursize)
ImageGadget(0, 0, 0, ImgSize._SIZEF\Width, ImgSize._SIZEF\Height, ImageID(hImg)) 
ImageGadget(1, 0, ImgSize\Height, ImgSize._SIZEF\Width, ImgSize._SIZEF\Height, ImageID(hBlurImg1)) 
ImageGadget(2, 0, ImgSize\Height*2, ImgSize._SIZEF\Width, ImgSize._SIZEF\Height, ImageID(hBlurImg2)) 
ImageGadget(3, 0, ImgSize\Height*3, ImgSize._SIZEF\Width, ImgSize._SIZEF\Height, ImageID(hBlurImg3)) 
ImageGadget(4, 0, ImgSize\Height*4, ImgSize._SIZEF\Width, ImgSize._SIZEF\Height, ImageID(hBlurImg4)) 
Repeat
  Define Event = WaitWindowEvent()
  If Event = #PB_Event_CloseWindow: End: EndIf
ForEver




