Note that our non-AA renderers should be better able to multi-thread.
Another alternative would be to perform AA using over-sampling. If your
server has a decent amount of memory then it may be faster and provide
higher quality to render the image at a larger size and then use
interpolated scaling to reduce it down to the desired size.
For example - to use 2x2 over-sampling, you would use:
int scalebits = 1; // 1 bit == x2 oversampling
int scaledw = w << scalebits;
int scaledh = h << scalebits;
BufferedImage scaledbimg =
new BufferedImage(scaledw, scaledh, TYPE_INT_RGB);
Graphics2D g2d = scaledbimg.createGraphics();
g2d.scale(1<<scalebits, 1<<scalebits);
// Note - do not turn on AA...
render(g2d);
g2d.dispose();
BufferedImage bimg =
new BufferedImage(scaledw >> 1, scaledh >> 1,
TYPE_INT_RGB);
while (scalebits > 0) {
// Scale it N times by a factor of 0.5 at each step.
// If we scale it more than that on a given step we may
// lose some of the data due to the filtering.
g2d = bimg.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATE_BILINEAR);
// Or use RenderingHints.VALUE_INTERPOLATE_BICUBIC, but
// BILINEAR should be fine here.
g2d.drawImage(scaledbimg,
0, 0, scaledw >> 1, scaledh >> 1,
0, 0, scaledw, scaledh, null);
g2d.dispose();
scaledw >>= 1;
scaledh >>= 1;
BufferedImage tmp = bimg;
bimg = scaledbimg;
scaledbimg = tmp;
}
return scaledbimg;
// Only use the topmost w,h of the image...or
// return scaledbimg.getSubImage(0, 0, w, h);
// INT_RGB (or INT_ARGB) formats are the best to use for the
// above operations.
// If you need to use a format other than INT_RGB, it is best
// to perform all of the above with INT_RGB images and then
// convert to the desired image format once at the end.
This uses 2 buffers since it isn't defined if scaling from one image to
itself is a valid operation. Also, the final image being returned may
be larger than the requested w,h. If you can control the subsequent
code so that it only uses the topmost wxh pixels then you are fine,
otherwise use BufferedImage.getSubImage() to trim it down. If the
server requests tend to be for images of a standard size, then each
rendering thread in the server could just create a single pair of
oversized images and reuse them for each request...
...jim
[EMAIL PROTECTED] wrote:
Hi,
I am currently profiling a server-side application which generates images based
on a SVG document. The image has roughly 1500 points which are displayed using
a symbol stored in a GIF image.
The profiling test uses 15 clients, requesting exactly the same image on the
server.
JProfiler shows that the 15 threads are blocked most of the times. Further
investigations show that they need a lock somewhere in Graphics2D.drawImage.
If we return only the SVG document to the client (i.e. we bypass the image
generation) all goes well.
Does anyone already experienced this? Anyone has reccomendations or tips&tricks
regarding the server-side generation of images in multithread?
Tested with JDK 1.4.2, 1.5 and 1.6
Thanks,
Stéphane
[Message sent by forum member 'stephanenicoll' (stephanenicoll)]
http://forums.java.net/jive/thread.jspa?messageID=188043
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".