如何使用Java2D使旋转文本看起来很好

时间:2012-04-30 17:45:33

标签: text rotation render java-2d

我的问题不是如何用Java2D旋转文本;我知道该怎么做。我不知道的是如何使旋转的文本“看起来很好”。例如,如果在PowerPoint中创建文本框并旋转它,则无论旋转角度如何,文本都会显得清晰明了。但是,使用g2D.drawString()绘制的文本在0度或90度时看起来不错,但在其他角度则不太好。有没有办法操纵文本来清理或锐化它?如果是这样,那么如果有人能指出我要去学习如何做到这一点我会非常感激。

下面是一个小程序,说明了我在说什么。旋转时较大的字体不是太糟糕但仍然看起来不太专业。旋转时较小的字体很糟糕。

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class RotateTest extends JPanel {
    String message = "How does this text look?";

    public RotateTest() {
        this.setPreferredSize(new Dimension(640, 280));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2D = (Graphics2D) g;

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

        g2D.setFont(new Font("MyriadPro", Font.BOLD, 20));
        g2D.drawString(message, 80, 20);

        AffineTransform orig = g2D.getTransform();

        double angle = Math.toRadians(7.0);
        g2D.rotate(-angle, -10, 80);
        g2D.drawString(message, 80, 80);
        g2D.setTransform(orig);

        angle = Math.toRadians(30.0);
        g2D.rotate(-angle, -40, 80);
        g2D.drawString(message, 60, 260);
        g2D.setTransform(orig);

        g2D.setFont(new Font("MyriadPro", Font.BOLD, 12));
        g2D.drawString(message, 380, 20);

        angle = Math.toRadians(7.0);
        g2D.rotate(-angle, -10, 80);
        g2D.drawString(message, 380, 120);
        g2D.setTransform(orig);

        angle = Math.toRadians(30.0);
        g2D.rotate(-angle, -40, 80);
        g2D.drawString(message, 320, 400);
        g2D.setTransform(orig);
    }

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

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new RotateTest().display();
            }
        });
    }
}

2 个答案:

答案 0 :(得分:6)

我曾遇到过类似的问题,并通过高精度地将图像绘制到图像上,然后绘制旋转的图像来解决它。

以下是代码:

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class RotatedText extends JPanel {
    String message = "How does this text look?";

    public RotatedText() {
        this.setPreferredSize(new Dimension(640, 280));
    }

    public BufferedImage createStringImage(Graphics g, String s) {
        int w = g.getFontMetrics().stringWidth(s) + 5;
        int h = g.getFontMetrics().getHeight();

        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D imageGraphics = image.createGraphics();
        imageGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        imageGraphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        imageGraphics.setColor(Color.BLACK);
        imageGraphics.setFont(g.getFont());
        imageGraphics.drawString(s, 0, h - g.getFontMetrics().getDescent());
        imageGraphics.dispose();

        return image;
    }

    private void drawString(Graphics g, String s, int tx, int ty, double theta, double rotx, double roty) {
        AffineTransform aff = AffineTransform.getRotateInstance(theta, rotx, roty);
        aff.translate(tx, ty);

        Graphics2D g2D = ((Graphics2D) g);
        g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2D.drawImage(createStringImage(g, s), aff, this);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setFont(new Font("MyriadPro", Font.BOLD, 20));

        drawString(g, message, 80, 20, 0, 0, 0);
        drawString(g, message, 80, 80, -Math.toRadians(7.0), -10, 80);
        drawString(g, message, 60, 260, -Math.toRadians(30.0), -40, 80);

        g.setFont(new Font("MyriadPro", Font.BOLD, 12));

        drawString(g, message, 380, 20, 0, 0, 0);
        drawString(g, message, 380, 120, -Math.toRadians(7.0), -10, 80);
        drawString(g, message, 320, 400, -Math.toRadians(30.0), -40, 80);
    }

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

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new RotatedText().display();
            }
        });
    }
}

答案 1 :(得分:1)

我没有时间测试这个,但以下代码会有帮助吗?:

Graphics2D g2d; 
g2d.setRenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

这只适用于Graphics2D。如果您使用的是普通图形,则可以将Graphics对象转换为2D版本,如下所示:

Graphics2D g2d = (Graphics2D) g; //if Graphics object name is g.

让我知道! 祝你好运