Search code examples
javaarraysgraphicsbufferedimageantialiasing

Fix jagged edges of a BufferedImage made from 2D array


I am trying to make BufferedImages with color data stored in a 2D array. It works, but I was wondering if there was a simple way to fix the jagged, saw-tooth-like, edges.

Anti-alias

I am guessing there may be an API or a simple trick this, but I been looking at numerous Java Docs to no avail. Vector Magic does do what I am looking for, but I want to learn how to code this on my own.


Solution

  • If you're interested in a quick way to just "turn on" anti-aliasing capabilities, then you may be able to take advantage of the Java2D APIs for Controlling Rendering Quality. You can pass options in the form of RenderingHints by calling Graphics2D#setRenderingHints. One of the available hints is to request anti-aliasing.

    The following code sample displays 2 windows that both draw the same circle, one with the anti-aliasing option off, and the other with the anti-aliasing option on. If you look closely, you'll see that the one generated with the anti-aliasing rendering hint is less jaggy.

    TestAntiAliasing.java

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class TestAntiAliasingPanel extends JPanel {
    
        private final RenderingHints rh;
    
        private TestAntiAliasingPanel(RenderingHints rh) {
            this.rh = rh;
        }
    
        @Override
        public void paint(Graphics g) {
            BufferedImage bufferedImage = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = (Graphics2D)bufferedImage.getGraphics();
            g2.setRenderingHints(rh);
            g2.setColor(Color.BLUE);
            g2.fillOval(50, 50, 300, 300);
            g.drawImage(bufferedImage, 50, 50, this);
        }
    
        public static void main(String[] args) {
            createFrameWithAntiAliasingOption(false);
            createFrameWithAntiAliasingOption(true);
        }
    
        private static void createFrameWithAntiAliasingOption(boolean antiAliasingOption) {
            RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                    antiAliasingOption ? RenderingHints.VALUE_ANTIALIAS_ON :
                    RenderingHints.VALUE_ANTIALIAS_OFF);
            JFrame frame = new JFrame();
            frame.getContentPane().add(new TestAntiAliasingPanel(rh));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(500, 500);
            frame.setVisible(true);
        }
    }
    

    Compile with javac TestAntiAliasingPanel.java and then run with java TestAntiAliasingPanel.

    ...but I want to learn how to code this on my own.

    If you're really interested in learning how to code the buffer manipulations to do the anti-aliasing yourself directly, then this is a big topic that would require external research. As a starting point, Wikipedia has articles on several anti-aliasing algorithms.