Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

Antialiasing, images, and alpha compositing in Java 2D

Java 2D adds support for antialiased rendering, image transforms, and alpha compositing

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Last month, I introduced some basic notions of Java 2D: that all 2D objects can be manipulated using 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.

What is aliasing, and how do you avoid it?

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.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (3)
Login
Forgot your account info?

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

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources
  • An introduction to drawing text in JDK 1.0 and 1.1 environments. Figure 4 examines imported concepts related to text placement. If you have ever wondered what a typographer meant by advance and descent, this article can help. http://www.javaworld.com/javaworld/jw-01-1997/jw-01-howto.html
  • Information on using 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/
  • Everything you wanted to know but were afraid to ask about fonts and internationalization in Java. This site includes separate sections on Java 1.0, 1.1, and 1.2 platforms, for those of us that have to work in multiple releases (a great many of us, I suspect). Includes information on the dreaded Font.properties file. http://www.alumni.caltech.edu/~dank/javafont.htm
  • Charles Poynton's A Technical Introduction to Digital Video covers a variety of analog and digital video topics. It includes a very good chapter on signal filtering and sampling, which gives in-depth information on aliasing effects. http://www.amazon.com/exec/obidos/ASIN/047112253X/billday/
  • The article "Put This in Your Pipe" walks through the process by which Graphics2D actually renders out 2D graphics. It discusses the pipeline nature of Graphics2D, and how this affects the order of operations in Java 2D code. http://java.oreilly.com/news/knudsen/java_0498.html
  • Another one of Knudsen's Java 2D articles, "The Truth about Antialiasing," gives more details about how and why aliasing occurs, and another example showing how to deal with aliasing in Java 2D. http://java.oreilly.com/news/knudsen/java_0598.html
  • Sun API specification for Java 2D. This javadoc-generated documentation is updated with each new release of the Java 1.2 platform. http://java.sun.com/products/jdk/1.2/docs/guide/2d/index.html
  • "How Do I Process Images with Java," by Aaron Michael Cohen, Dr. Dobb's Journal, July 1998. This article discusses the producer-consumer model from Java 1.0 and 1.1 in more depth. Source code is available online. http://www.ddj.com/ddj/1998/1998_07/index.htm
  • JavaOne 1998 presentation materials for "Developing Imaging Applications Using the Java 2D API and Java Advanced Imaging API." Provides a good comparison of JDK 1.0 and 1.1's Push Model supported by ImageProducers and ImageConsumers to the Immediate Mode image buffer model supported by Java 2D BufferedImages and the Pull Model to be supported by Java 2D and Java Advanced Imaging. This session can show you how all three models fit together and what trade-offs you should consider when you decide which to use. http://java.sun.com/javaone/javaone98/sessions/T606/index.html
  • "The Care and Handling of Color," another nice Java 2D article by Knudsen. Gives a good explanation of how difficult color management is in general, then goes on to explain how Java 2D provides a uniform way to manage color spaces for display as well as hard copy output. http://java.oreilly.com/news/knudsen/java_1097.html
  • This Java Developer Connection article on color management in the Java 1.2 environment, "New Color ClassesA Programmer's Palette of Color," complements Knudsen's article fairly well. It contains a list of the types of color spaces supported in the JDK 1.2. (Accessing this article requires a free username and password.) http://developer.java.sun.com/developer/technicalArticles/monicap/2DGraphics/Color/color.html
  • If you are having problems and are beginning to wonder if you might have a Java 2D bug on your hands, you can search the Java bug database at Sun. Select "java bugs" from the pull down menu, then search for "general:classes_2D". (Accessing this page also requires a free username and password.) http://developer.java.sun.com/developer/search.shtml
  • Bill's other Media Programming columns /javaworld/topicalindex/jw-ti-media.html
  • Bill archives Media Programming resources on his Web site. This archive contains the up-to-date media.jar file with code fixes for all of the examples in the column. http://reality.sgi.com/bday/Work/index.html