1

For some reason, a string drawn to a BufferedImage appears differently to one drawn straight to a JComponent.

Here's an example. The top string is drawn directly, while the bottom is drawn using a buffer.

Huh?

What is going on here?

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;

public class Main {

    static class Canvas extends JComponent
    {
        @Override
        public void paintComponent(Graphics g)
        {

            g.setColor(Color.WHITE);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            g.setColor(Color.BLACK);
            g.drawString("OMFG look at this 'S'", 10, 20);

            BufferedImage bi = new BufferedImage(150,50,BufferedImage.TYPE_INT_RGB);
            Graphics2D imageG =  bi.createGraphics();
            imageG.setColor(Color.WHITE);
            imageG.fillRect(0, 0, 150, 50);
            imageG.setColor(Color.BLACK);
            imageG.setFont(g.getFont());
            imageG.drawString("OMFG look at this 'S'", 10, 10);

            g.drawImage(bi, 0, 30, this);

        }
    }
    public static void main(String[] args) {
        JFrame jf = new JFrame();
        jf.setMinimumSize(new Dimension(150, 80));
        jf.add(new Canvas());
        jf.setVisible(true);

    }
}
Boann
  • 48,794
  • 16
  • 117
  • 146
eye_mew
  • 8,855
  • 7
  • 30
  • 50
  • 2
    What happens if you add `imageG.setRenderingHints(((Graphics2D)g).getRenderingHints());` ? – Boann Jul 29 '14 at 02:47
  • 1
    On some system, try `apple.awt.graphics.UseQuartz`, for [example](http://stackoverflow.com/a/4572195/230513). – trashgod Jul 29 '14 at 02:51
  • I've tried both! The problem persists :( – eye_mew Jul 29 '14 at 02:55
  • What if you use a different font? – Boann Jul 29 '14 at 03:03
  • @Boann still weird... – eye_mew Jul 29 '14 at 03:12
  • 1
    What if you manually set some rendering hints? Such as `imageG.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);` `imageG.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);` – Boann Jul 29 '14 at 03:15
  • The directly drawn font actually looks nicer! But the buffered one is still warped. I wonder if there's any workaround I can use for buffering... – eye_mew Jul 29 '14 at 03:23
  • [Here's what the manual rendering hints for both drawings produce](http://i.imgur.com/EuQDkfr.png) – eye_mew Jul 29 '14 at 03:28
  • 1
    @s1ice Hmm. I notice that the "150 pixel" image is actually 300 pixels wide. Is this something to do with a "Retina" display I wonder? I've never had a Mac but I've heard about issues with Retina font rendering in some applications. – Boann Jul 29 '14 at 03:32
  • Yes! It is a Retina Display. I feel like you're onto something... – eye_mew Jul 29 '14 at 03:33
  • 3
    @s1ice: Can you try this [example](http://stackoverflow.com/a/8282330/230513) USING `TextLayout`? – trashgod Jul 29 '14 at 03:35
  • 2
    Since Retina seems to mean that the "150 pixel" component is actually twice that size, you might get best rendering by using a 300 pixel buffer and drawing it scaled to 150 pixels on the component. Although even if that works, I don't know if it's really the right solution. – Boann Jul 29 '14 at 03:36
  • 1
    [it works!](http://i.imgur.com/mU1eM7O.png) My application is pretty rendering intensive though, so this is going to hurt performance. – eye_mew Jul 29 '14 at 03:45

0 Answers0