Rendering Hints


In the preceding sections you have seen that the rendering process is quite complex. Though the Java 2D API is surprisingly fast in most cases, there are cases when you would like to have control over trade-offs between speed and quality. You achieve this by setting rendering hints. The setRenderingHint method of the Graphics2D class lets you set a single hint. The hint keys and values are declared in the RenderingHints class. Table 7-2 summarizes the choices.

Table 7-2. Rendering Hints

Key

Values

Explanation

KEY_ANTIALIASING

 VALUE_ANTIALIAS_ON VALUE_ANTIALIAS_OFF VALUE_ANTIALIAS_DEFAULT 

Turn antialiasing for shapes on or off.

KEY_RENDERING

 VALUE_RENDER_QUALITY VALUE_RENDER_SPEED VALUE_RENDER_DEFAULT 

When available, select rendering algorithms for greater quality or speed.

KEY_DITHERING

 VALUE_DITHER_ENABLE VALUE_DITHER_DISABLE VALUE_DITHER_DEFAULT 

Turn dithering for colors on or off. Dithering approximates color values by drawing groups of pixels of similar colors.

KEY_TEXT_ANTIALIASING

 VALUE_TEXT_ANTIALIAS_ON VALUE_TEXT_ANTIALIAS_OFF VALUE_TEXT_ANTIALIAS_DEFAULT 

Turn antialiasing for fonts on or off.

KEY_FRACTIONALMETRICS

 VALUE_FRACTIONALMETRICS_ON VALUE_FRACTIONALMETRICS_OFF VALUE_FRACTIONALMETRICS_DEFAULT 

Turn the computation of fractional character dimensions on or off. Fractional character dimensions lead to better placement of characters.

KEY_ALPHA_INTERPOLATION

 VALUE_ALPHA_INTERPOLATION_QUALITY VALUE_ALPHA_INTERPOLATION_SPEED VALUE_ALPHA_INTERPOLATION_DEFAULT 

Turn precise computation of alpha composites on or off.

KEY_COLOR_RENDERING

 VALUE_COLOR_RENDER_QUALITY VALUE_COLOR_RENDER_SPEED VALUE_COLOR_RENDER_DEFAULT 

Select quality or speed for color rendering.

KEY_INTERPOLATION

 VALUE_INTERPOLATION_NEAREST_NEIGHBOR VALUE_INTERPOLATION_BILINEAR VALUE_INTERPOLATION_BICUBIC 

Select a rule for interpolating pixels when scaling or rotating images.

KEY_STROKE_CONTROL

 VALUE_STROKE_NORMALIZE VALUE_STROKE_PURE VALUE_STROKE_DEFAULT 

Select a rule for combining strokes.


The most useful of these settings involves antialiasing. This technique removes the "jaggies" from slanted lines and curves. As you can see in Figure 7-27, a slanted line must be drawn as a "staircase" of pixels. Especially on low-resolution screens, this line can look ugly. But if, rather than drawing each pixel completely on or off, you color in the pixels that are partially covered, with the color value proportional to the area of the pixel that the line covers, then the result looks much smoother. This technique is called antialiasing. Of course, antialiasing takes a bit longer because it takes time to compute all those color values.

Figure 7-27. Antialiasing


For example, here is how you can request the use of antialiasing.

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

It also makes sense to use antialiasing for fonts.

[View full width]

g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints .VALUE_TEXT_ANTIALIAS_ON);

The other rendering hints are not as commonly used.

You can also put a bunch of key/value hint pairs into a map and set them all at once by calling the setRenderingHints method. Any collection class implementing the map interface will do, but you may as well use the RenderingHints class itself. It implements the Map interface and supplies a default map implementation if you pass null to the constructor. For example,

 RenderingHints hints = new RenderingHints(null); hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setRenderingHints(hints); 

That is the technique we use in Example 7-8. The program draws an image that we thought might benefit from some of the hints. You can turn various rendering hints on or off. Not all platforms support all the hints, so you should not expect every one of the settings to have an effect. On Windows and Linux, antialiasing smooths out the ellipse, and text antialiasing improves the look of the italic font. The other hints seemed to have no effect, but they might with other platforms or with more complex images.

Figure 7-28 shows a screen capture of the program.

Example 7-8. RenderQualityTest.java

[View full width]

   1. import java.awt.*;   2. import java.awt.event.*;   3. import java.awt.geom.*;   4. import java.io.*;   5. import java.util.*;   6. import javax.imageio.*;   7. import javax.swing.*;   8.   9. /**  10.    This program demonstrates the effect of the various  11.    rendering hints.  12. */  13. public class RenderQualityTest  14. {  15.    public static void main(String[] args)  16.    {  17.       JFrame frame = new RenderQualityTestFrame();  18.       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  19.       frame.setVisible(true);  20.    }  21. }  22.  23. /**  24.    This frame contains buttons to set rendering hints  25.    and an image that is drawn with the selected hints.  26. */  27. class RenderQualityTestFrame extends JFrame  28. {  29.    public RenderQualityTestFrame()  30.    {  31.       setTitle("RenderQualityTest");  32.       setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);  33.  34.       buttonBox = new JPanel();  35.       buttonBox.setLayout(new GridBagLayout());  36.       hints = new RenderingHints(null);  37.  38.       makeButtons("KEY_ANTIALIASING", "VALUE_ANTIALIAS_ON", "VALUE_ANTIALIAS_OFF");  39.       makeButtons("KEY_RENDERING", "VALUE_RENDER_QUALITY", "VALUE_RENDER_SPEED");  40.       makeButtons("KEY_DITHERING", "VALUE_DITHER_ENABLE", "VALUE_DITHER_DISABLE");  41.       makeButtons("KEY_TEXT_ANTIALIASING", "VALUE_TEXT_ANTIALIAS_ON",  "VALUE_TEXT_ANTIALIAS_OFF");  42.       makeButtons("KEY_FRACTIONALMETRICS",  43.          "VALUE_FRACTIONALMETRICS_ON", "VALUE_FRACTIONALMETRICS_OFF");  44.       makeButtons("KEY_ALPHA_INTERPOLATION",  45.          "VALUE_ALPHA_INTERPOLATION_QUALITY", "VALUE_ALPHA_INTERPOLATION_SPEED");  46.       makeButtons("KEY_COLOR_RENDERING", "VALUE_COLOR_RENDER_QUALITY",  "VALUE_COLOR_RENDER_SPEED");  47.       makeButtons("KEY_INTERPOLATION",  48.          "VALUE_INTERPOLATION_NEAREST_NEIGHBOR", "VALUE_INTERPOLATION_BICUBIC");  49.       makeButtons("KEY_STROKE_CONTROL", "VALUE_STROKE_NORMALIZE", "VALUE_STROKE_PURE");  50.       canvas = new RenderQualityPanel();  51.       canvas.setRenderingHints(hints);  52.  53.       add(canvas, BorderLayout.CENTER);  54.       add(buttonBox, BorderLayout.NORTH);  55.    }  56.  57.    /**  58.       Makes a set of buttons for a rendering hint key and values  59.       @param key the key name  60.       @param value1 the name of the first value for the key  61.       @param value2 the name of the second value for the key  62.    */  63.    void makeButtons(String key, String value1, String value2)  64.    {  65.       try  66.       {  67.          final RenderingHints.Key k  68.             = (RenderingHints.Key) RenderingHints.class.getField(key).get(null);  69.          final Object v1 = RenderingHints.class.getField(value1).get(null);  70.          final Object v2 = RenderingHints.class.getField(value2).get(null);  71.          JLabel label = new JLabel(key);  72.  73.          buttonBox.add(label, new GBC(0, r).setAnchor(GBC.WEST));  74.          ButtonGroup group = new ButtonGroup();  75.          JRadioButton b1 = new JRadioButton(value1, true);  76.  77.          buttonBox.add(b1, new GBC(1, r).setAnchor(GBC.WEST));  78.          group.add(b1);  79.          b1.addActionListener(new  80.             ActionListener()  81.             {  82.                public void actionPerformed(ActionEvent event)  83.                {  84.                   hints.put(k, v1);  85.                   canvas.setRenderingHints(hints);  86.                }  87.             });  88.          JRadioButton b2 = new JRadioButton(value2, false);  89.  90.          buttonBox.add(b2, new GBC(2, r).setAnchor(GBC.WEST));  91.          group.add(b2);  92.          b2.addActionListener(new  93.             ActionListener()  94.             {  95.                public void actionPerformed(ActionEvent event)  96.                {  97.                   hints.put(k, v2);  98.                   canvas.setRenderingHints(hints);  99.                } 100.          }); 101.          hints.put(k, v1); 102.          r++; 103.       } 104.       catch (Exception e) 105.       { 106.          e.printStackTrace(); 107.       } 108.    } 109. 110.    private RenderQualityPanel canvas; 111.    private JPanel buttonBox; 112.    private RenderingHints hints; 113.    private int r; 114.    private static final int DEFAULT_WIDTH = 750; 115.    private static final int DEFAULT_HEIGHT = 500; 116. } 117. 118. /** 119.    This panel produces a drawing that hopefully shows some 120.    of the difference caused by rendering hints. 121. */ 122. class RenderQualityPanel extends JPanel 123. { 124.    public RenderQualityPanel() 125.    { 126.       try 127.       { 128.          image = ImageIO.read(new File("clouds.jpg")); 129.       } 130.       catch (IOException e) 131.       { 132.          e.printStackTrace(); 133.       } 134.    } 135. 136.    public void paintComponent(Graphics g) 137.    { 138.       super.paintComponent(g); 139.       Graphics2D g2 = (Graphics2D) g; 140.       g2.setRenderingHints(hints); 141. 142.       g2.scale(1.05, 1.05); 143.       g2.rotate(Math.PI / 12); 144.       g2.translate(120, -30); 145.       g2.drawImage(image, 0, 0, null); 146. 147.       g2.draw(new Ellipse2D.Double(0, 0, image.getWidth(null), image.getHeight(null))); 148.       g2.setFont(new Font("Serif", Font.ITALIC, 40)); 149.       g2.drawString("Hello", 75, 75); 150.       g2.setPaint(Color.YELLOW); 151.       g2.translate(0,-80); 152.       g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); 153.       g2.fill(new Rectangle2D.Double(100, 100, 200, 100)); 154.    } 155. 156.    /** 157.       Sets the hints and repaints. 158.       @param h the rendering hints 159.    */ 160.    public void setRenderingHints(RenderingHints h) 161.    { 162.       hints = h; 163.       repaint(); 164.    } 165. 166.    private RenderingHints hints = new RenderingHints(null); 167.    private Image image; 168. } 

Figure 7-28. Testing the effect of rendering hints



 java.awt.Graphics2D 1.2 

  • void setRenderingHint(RenderingHints.Key key, Object value)

    sets a rendering hint for this graphics context.

  • void setRenderingHints(Map m)

    sets all rendering hints whose key/value pairs are stored in the map.


 java.awt.RenderingHints 1.2 

  • RenderingHints(Map<RenderingHints.Key, ?> m)

    constructs a rendering hints map for storing rendering hints. If m is null, then a default map implementation is provided.



    Core JavaT 2 Volume II - Advanced Features
    Building an On Demand Computing Environment with IBM: How to Optimize Your Current Infrastructure for Today and Tomorrow (MaxFacts Guidebook series)
    ISBN: 193164411X
    EAN: 2147483647
    Year: 2003
    Pages: 156
    Authors: Jim Hoskins

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net