Java2D Graphics Anti-Aliased

How can I use Graphics2D.drawline with anti-aliasing on a BufferedImage?

I ran your sample and both methods of drawing seemed to apply the antialiasing. It may be a bug in the version of the jdk you're using. I'm running on Windows with jdk 1.8.0_77 and also tried with jdk 1.7.0_79.

Antialias height map edge using Java 2D

Some ideas:

  • Draw an anti-aliased line across the top by connecting the top point of each line to the top point of its neighbor. This might be easier to debug by just drawing the top line to see how it looks and then filling in the vertical lines if you like its look.

  • Try to work out some algorithm similar to the way antialiasing works by taking into account the positions of the tops of the previous and next ones when drawing this one. So, if the current one is lower or higher than the one before and the one after, add a grey dot to the top. If its the same, no dot is added. make the dot lighter or darker depending on how much higher the adjacent ones.

  • Smooth the data using a linear averaging or some sort of curve smoothing before plotting. This won't really anti-alias but may make the graph more appealing.

How to draw a decent looking Circle in Java

As it turns out, Java2D (which I'm assuming is what you're using) is already pretty good at this! There's a decent tutorial here: http://www.javaworld.com/javaworld/jw-08-1998/jw-08-media.html

The important line is:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

Java2D/Swing: Rendering a component with text anti aliasing to a BufferedImage

This is a JVM bug

I have encountered the same problem as you. And I have concluded that the problem is indeed with drawing to a translucent bitmap. I'm fairly certain that we're hitting: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6749069

Workaround

For now I draw into an opaque bitmap and blit it into my destination bitmap. If the background color behind your text is plain, this should work:

private void drawString(String text, int x, int y, Graphics2D g, Color bg){    
// Prepare an off-screen image to draw the string to
Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g);
BufferedImage image = configuration.createCompatibleImage(
(int)(bounds.getWidth() + 1.0f),
(int)(bounds.getHeight() + 1.0f),
Transparency.OPAQUE);
Graphics2D ig = image.createGraphics();

// Fill the background color
ig.setColor(bg);
ig.fillRect(0, 0, image.getWidth(), image.getHeight());

// Draw the string
int x0 = 0;
int y0 = ig.getFontMetrics().getAscent();
ig.setColor(g.getColor());
ig.setRenderingHints(g.getRenderingHints());
ig.setFont(g.getFont());
ig.drawString(text, x0, y0);
ig.dispose();

// Blit the image to the destination
g.drawImage(image, x-x0, y-y0, null);
}

If your background is not a plain color, you'll have to render the text as white on black to a bitmap, A. Then fill another bitmap with your text color C. Then blit that to your destination image, D as: D += A*C or D = D*(1-A)+A*C or some other suitable blending function.



Related Topics



Leave a reply



Submit