Fast Real-Time blur for applet

hi guys!
i’m new here and i guess that i will learn a lot reading deep into this forum ;D

but now a question… i’m trying to build a library to handle the animation and effects of my applets and i’m getting some problems with performance :(… i’m using Java2D api to avoid problem of compatibility and i’m becoming crazy finding a fast way to implement a blur algorithm that i will use in animation… the first try was with a ConvolveOp class but it’s too much slow with a 8x8 kernel…

so any suggestion??
thanks :smiley:

… forgive me for my inglish i’m italian :persecutioncomplex:

this is really fast:

I think Pulpcore uses a similar approach, you can browse the source code.

thaks a lot for helping me :smiley:

i will try to implement this trick, they seam good and fast ::slight_smile:

I’ve implemented the second one before, operating on an int[] raster. I think the fastest I managed to get it after a couple of days of optimisation was 20 blurs per second of 640x480 RGB on a 2006-era mid-range desktop.

can you post some code?
i’m not very good in math :-X

I’d have to write it from scratch. When I did it before it was for a company (and I can’t even violate my contract to post it :wink: because I no longer work there).

Do you want it done in place, or output to a different int[] to the input?

There is C source code in that Gamasutra article, converting it to Java (and extending to ARGB) should not be difficult.

this could help you too (but I think converting the C code is easier):
http://code.google.com/p/pulpcore/source/browse/src/pulpcore/image/filter/Blur.java

EDIT: double post sorry :-\

i work with BufferedImage :stuck_out_tongue:

i will take a look at the source code in C, i will try ::slight_smile:

Depending on how the BufferedImage was constructed, you can get a significant speed up with:

DataBuffer imageData = myBufferedImage.getRaster().getDataBuffer();

and modify the DataBuffer directly with getElem() and setElem().

Edit: I just realised that doesn’t really solve your problem. The WritableRaster you get from getRaster() has a method for setting all the image data from an array: setPixels(x,y,w,h,iArray)

Even faster if you cast the DataBuffer to a DataBufferInt, and use DataBufferInt#getData() to obtain the underlying int[].
You are then manipulating the Image’s data array directly - no copying necessary.

Obviously you need to ensure your BufferedImage is of a suitable type.

thaks for the reply ! :slight_smile:

but i still don’t understand exactly the algorithm…
for example what means “each destination pixel is simply the average of a short horizontal line of pixels in the source image”?
means the average of all color component?

(i’m trying to implement the second trick because is more flexible i think…)

Yes, you do red, green, and blue separately.

really ? arf… as long as it is bunch or little piece of code I really really will never care…

@OP (andre90boss ):

you could use something like that :

int pixels[];
Image image;

BufferedImage BIImage;
BIImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
pixels=((DataBufferInt)(BIImage.getRaster().getDataBuffer())).getData(); 
image=(Image)BIImage;

then later modify pixels array to access image pixels and use regular graphics.drawImage( … ) when requiered to draw.

About pixels manipulation you can have a look here http://dzzd.net/SimpleParticle/ source code here http://dzzd.net/SimpleParticle/sources.zip there is similar pixels processing than bluring (as I remember it use MemoryImageSource but you can easily (with the above code) convert it to use BufferedImage)

It wasn’t particularly small. 200 or 300 lines of code because of unrolled loops, extracted special cases, etc.

Wouldn’t it be fastest (least cache misses) to only work on scanlines (no columns)

  1. blur on scanline
  2. transpose pixels
  3. blur on scanline
  4. transpose pixels

as working with scanline is always a lot faster I suppose you are right, sure it will.

like a common error when dealing with int buffer Image wich is : (EDIT: or any two dimensional array using “a single dimensional array.”…)

for(x=0;x<w;x++)
 for(y=0;y<h;y++)
  pix[x+y*w]=something

;

instead of

for(y=0;y<h;y++)
   for(x=0;x<w;x++)
    pix[x+y*w]=something;

thanks for the replies!

i will try to follow yours suggestions :wink:
in the worst case i will post again ;D

Why? You’re going to get your cache misses in the transpose operations rather than the blurring, aren’t you?

Lets say the image is 1024 pixels wide, so each scanline is exactly one page (4K).

If you blur ‘radius’ is 4 pixels, you need 4+1+4=9 pixel reads for each pixel write. When reading/writing columns, you have to continuously read from 9 different pages for each pixel write. Something tells me the CPU (or JVM) won’t find the ‘fast path’ for such code.

Anyway, I’ll benchmark it properly.