AffineTransforms, that arbitrary paths can be constructed and shapes filled using GeneralPaths, and that text strings are drawn and operated on just like any other shape in Java 2D. This month, I'll continue the discussion
by presenting the solution to last month's aliasing problem. I'll also illustrate how to use one shape to clip another, and delve into the new image-manipulation capabilities provided by Java.Aliasing occurs when a signal (in this case, a 2D graphics signal) is sampled and quantized from a continuous space into a discretized space. Sampling is the process of reading a value from a continuously varying signal. Quantization is the process by which these continuous sampled values are assigned a discrete value in the finite space represented by digital (binary-based) systems.
Aliasing is a by-product of this quantization. Humans perceive this by-product visually as abrupt changes in color from pixel to pixel. Graphics professionals often refer to these jagged edges as jaggies.
In general, aliasing is a bad thing. It leads to lower-quality signals of all kinds. In fact, if you look closely at the examples in last month's column, especially those with slanted and curved edges, you can see aliasing effects all the way back to Example02. (Example01's lines are drawn parallel and perpendicular to the scan-line direction of the computer screen, so there are no quantization errors.)
If you are not familiar with aliasing effects, you can refer to any decent graphics or signal processing textbook for much more in-depth information. Charles Poynton's A Technical Introduction to Digital Video (John Wiley & Sons; ISBN: 047112253X) gives a particularly good description of aliasing as it pertains to video signals. If you are familiar with aliasing, but would like a quick refresher, see the Resources section for a link to "The Truth about Antialiasing" by Jonathan Knudsen.
So, how do you handle aliasing? Java 2D lets you set one of several rendering hints to indicate that you would like for your 2D graphics to be drawn using antialiasing algorithms -- which smoothes the edges. Note that I said hints: Whichever Java 2D implementation you're using, it is allowed to decide whether or not to follow the hint and carry out the antialiasing as requested.
Let's compare the aliased output from last month's Example04 to some antialiased output, generated from Example05.
001 /**
002 * In previous examples, we saw some jagged edges due to aliasing.
003 * Example05 illustrates how to use rendering hints to request
004 * an anti-aliased render from Graphics2D.
005 **/
006 public void paint(Graphics g) {
007 Graphics2D g2d = (Graphics2D) g;
008
009 //This time, we want to use anti-aliasing if possible
010 //to avoid the jagged edges that were so prominent in
011 //our last example. With ask the Java 2D rendering
012 //engine (Graphics2D) to do this using a "rendering hint".
013 g2d.setRenderingHints(Graphics2D.ANTIALIASING,
014 Graphics2D.ANTIALIAS_ON);
015
016 //We reuse our GeneralPath filled shape. We translate
017 //and rotate this shape as we did before.
018 GeneralPath path = new GeneralPath(GeneralPath.EVEN_ODD);
019 path.moveTo(0.0f,0.0f);
020 path.lineTo(0.0f,125.0f);
021 path.quadTo(100.0f,100.0f,225.0f,125.0f);
022 path.curveTo(260.0f,100.0f,130.0f,50.0f,225.0f,0.0f);
023 path.closePath();
024
025 AffineTransform at = new AffineTransform();
026 at.setToRotation(-Math.PI/8.0);
027 g2d.transform(at);
028 at.setToTranslation(0.0f,150.0f);
029 g2d.transform(at);
030
031 g2d.setColor(Color.green);
032 g2d.fill(path);
033
034 Font exFont = new Font("TimesRoman",Font.PLAIN,40);
035 g2d.setFont(exFont);
036 g2d.setColor(Color.black);
037 g2d.drawString("JavaWorld",0.0f,0.0f);
038 }
The effects of the antialiasing are shown below.
TextLayout for internationalization support in the 1.2 Java platform. Accompanied by excellent illustrations that help to simplify the
more convoluted concepts in the text. http://www.ibm.com/java/education/international-text/
Font.properties file. http://www.alumni.caltech.edu/~dank/javafont.htm
Try thisBy Anonymous on March 5, 2009, 11:37 amimport java.awt.RenderingHints; // Anti Aliasing RenderingHints rh = g.getRenderingHints(); rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); ...
Reply | Read entire comment
Compilation errorsBy Anonymous on March 3, 2009, 7:05 amImport, import java.awt.RenderingHints; and change: g2d.setRenderingHints(Graphics2D.ANTIALIASING,Graphics2D.ANTIALIAS_ON); to: g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
Reply | Read entire comment
Compilation errorsBy Anonymous on November 16, 2008, 9:40 amExample05.java:67: cannot find symbol symbol : variable ANTIALIASING location: class java.awt.Graphics2D g2d.setRenderingHints(Graphics2D.ANTIALIASING, ...
Reply | Read entire comment
View all comments