【问题标题】:Java2D Graphics anti-aliasedJava2D 图形抗锯齿
【发布时间】:2011-05-16 04:31:14
【问题描述】:

我是 Java 新手,正在尝试使用 Java2D 图形来创建图像。但是输出是抗锯齿的。我尝试了很多方法来纠正它,但没有奏效。字符变得扭曲或锯齿状。

public BufferedImage createNameOnButton(String label) {
    int messageWidth = 0;
    Font font = new Font("Arial", Font.PLAIN, 11);

    BufferedImage bi = new BufferedImage(
        10, 10, BufferedImage.TYPE_INT_RGB);

    Graphics2D g2d = (Graphics2D) bi.getGraphics();
    g2d.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(
        RenderingHints.KEY_TEXT_ANTIALIASING,
        RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g2d.setRenderingHint(
        RenderingHints.KEY_FRACTIONALMETRICS,
        RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    g2d.setFont(font);

    bi = g2d.getDeviceConfiguration()
        .createCompatibleImage(500, 30, Transparency.BITMASK);
    FontMetrics fm = bi.getGraphics().getFontMetrics(font);
    int messageHeight = fm.getHeight() - fm.getDescent();
    for (char ch : label.toCharArray()) {
        messageWidth += fm.charWidth(ch);
    }

    bi = bi.getSubimage(50, 0, messageWidth + 10, fm.getHeight());
    Graphics g = bi.getGraphics();
    g.setColor(Color.black);
    AttributedString as = new AttributedString(label);
    as.addAttribute(TextAttribute.FONT, font);
    g.drawString(as.getIterator(), 5, messageHeight);
    g2d.dispose();
    g.dispose();
    return bi;
}

谁能帮我纠正错误?

【问题讨论】:

  • 你先创建一个 10x10 的图像是什么?您的代码对于它应该做的事情真的很复杂。
  • 我不确定我是否理解。从你的问题,我知道你不希望角色被抗锯齿。但是阅读代码也就不足为奇了,因为它到处都写着 ANTIALIAS_ON。你能解释一下吗?
  • 感谢您的说明 - 我使用 ANTIALIAS_OFF 测试了代码,但仍有一些字符作为抗锯齿(不是所有字符)出现,例如 N 的垂直 '\'、'a'、 'v', 'e', y' , 'o' - 基本上字符的边缘不光滑。我还有什么事情要做吗?
  • 也如下所述 - 我的要求是编写一个函数,该函数返回一个 BufferedImage,其中包含模式文本“Deliver Me to ”。短语“Deliver Me to”应为黑色,而流中收集的“”应为蓝色。你能提供一些相同的意见吗?

标签: java graphics java-2d antialiasing


【解决方案1】:

正如 Traroth 所说,这很可能是由于

g2d.setRenderingHint(
    RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(
    RenderingHints.KEY_TEXT_ANTIALIASING,
    RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

这应该是

g2d.setRenderingHint(
    RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(
    RenderingHints.KEY_TEXT_ANTIALIASING,
    RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);

【讨论】:

  • 感谢您的说明 - 我使用 ANTIALIAS_OFF 测试了代码,但仍有一些字符作为抗锯齿(不是所有字符)出现,例如 N 的垂直 '\'、'a'、 'v', 'e'' y' , 'o' - 基本上字符的边缘不平滑。我还有什么事情要做吗?
  • 你似乎不明白抗锯齿是什么意思。抗锯齿=平滑。
【解决方案2】:

假设您确实想要平滑(无锯齿)文本,TextLayout 可能会使这更容易。 FontRenderContext 构造函数可以管理抗锯齿和分数指标设置。

附录:使用g2d.setColor(Color.blue) 似乎产生了预期的效果。

附录:在 Mac OS X 上,/Developer/Applications/Graphics Tools/ 中的Pixie 应用程序便于检查抗锯齿像素。在其他平台上,可以使用Zoom

/** @see https://stackoverflow.com/questions/4285464 */
public class BITest extends JPanel {

    private BufferedImage image = createNameOnButton("Sample");

    public BITest() {
        this.setPreferredSize(new Dimension(
            image.getWidth(), image.getHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, null);
    }

    public BufferedImage createNameOnButton(String label) {
        Font font = new Font("Arial", Font.PLAIN, 64);
        FontRenderContext frc = new FontRenderContext(null, true, true);
        TextLayout layout = new TextLayout(label, font, frc);
        Rectangle r = layout.getPixelBounds(null, 0, 0);
        System.out.println(r);
        BufferedImage bi = new BufferedImage(
            r.width + 1, r.height + 1,
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) bi.getGraphics();
        g2d.setColor(Color.blue);
        layout.draw(g2d, 0, -r.y);
        g2d.dispose();
        return bi;
    }

    private void display() {
        JFrame f = new JFrame("BITest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setUndecorated(true);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new BITest().display();
            }
        });
    }
}

【讨论】:

  • 感谢示例程序。我的要求是编写一个函数,该函数返回一个 BufferedImage,其中包含模式文本“Deliver Me to ”。短语“Deliver Me to”应为黑色,而流中收集的“”应为蓝色。你能提供一些相同的意见吗?
  • 另外忘记补充了,因为它必须放在按钮上,所以图像大小必须具有特定的宽度和高度。我尝试了示例程序,但渲染的图像完全是黑色的,并且无法看到所写的文本。请注意,我是 Java 新手。
  • 只是添加 - 我得到了图像,但实际上我需要在文件中存储和查看相同的图像。那么如何将通过 display() 方法显示的内容写入文件。
  • @Prakash:我会使用ImageIO.write() 来保存BufferedImage。每一行都可以根据需要拨打setColor()
  • 谢谢,但是 setColor() 方法将整个图像设置为绿色而不是文本颜色。我需要将文本以黑色和背景打印为白色/灰色。
【解决方案3】:

我发现只有this line 可以解决问题:

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

之后,只需使用drawString()

【讨论】:

    猜你喜欢
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    • 1970-01-01
    • 2016-06-28
    • 2011-07-05
    • 2014-03-19
    相关资源
    最近更新 更多