Java中的图像高级文本?

时间:2018-03-31 22:25:21

标签: java image-processing graphics2d

在另一个答案中,我发现了这段代码:

public void displayText(BufferedImage image, String text, Font font, int x, int y){
   Graphics2d g = image.createGraphics();
   g.setFont(font);
   g.drawString(text, x, y);
   g.dispose();
}

但是我想在这里创建一些更精细的东西:

https://www.geckoandfly.com/wp-content/uploads/2014/03/motivation-motivational-quotes-poster-wallpaper8.jpg

有更好的选择吗?

1 个答案:

答案 0 :(得分:2)

在任何图形环境中渲染文本都是一个复杂的主题。我强烈建议您首先查看Working with Text APIs,因为它将解释您需要了解的许多概念以及可用的API

如果你花时间看,还有很多其他的例子。

这是一个非常快速和基本的例子。就个人而言,我希望减少重复并更好地利用可重用的概念

Winners

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private String[] lines = new String[]{
            "You can never quit",
            "WINNERS",
            "never quit and quitters never win"
        };

        private Font baseFont;
        private Font largeFont;

        public TestPane() {
            baseFont = new Font("Arial", Font.BOLD, 24);
            largeFont = baseFont.deriveFont(80f);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            TextLayout line1 = new TextLayout(lines[0], baseFont, g2d.getFontRenderContext());
            TextLayout line2 = new TextLayout(lines[1], largeFont, g2d.getFontRenderContext());
            TextLayout line3 = new TextLayout(lines[2], baseFont, g2d.getFontRenderContext());

            Rectangle2D bounds = line2.getBounds();
            double xPos = (getWidth() - bounds.getWidth()) / 2;
            double yPos = (getHeight() / 2) + (bounds.getHeight() / 2);

            Shape textLine2Shape = line2.getOutline(AffineTransform.getTranslateInstance(xPos, yPos));
            g2d.fill(textLine2Shape);

            double yOffset = yPos - bounds.getHeight();
            xPos = (getWidth() - line1.getBounds().getWidth()) / 2;
            Shape textLine1Shape = line1.getOutline(AffineTransform.getTranslateInstance(xPos, yOffset));
            g2d.fill(textLine1Shape);

            yOffset = yPos + line3.getBounds().getHeight();
            xPos = (getWidth() - line3.getBounds().getWidth()) / 2;
            g2d.fill(line3.getOutline(AffineTransform.getTranslateInstance(xPos, yOffset)));

            Rectangle2D textLine1Bounds = textLine1Shape.getBounds2D();
            Rectangle2D textLine2Bounds = textLine2Shape.getBounds2D();
            Area whole = new Area(new Rectangle2D.Double(textLine2Bounds.getX(), textLine1Bounds.getY(), textLine2Bounds.getWidth(), textLine1Bounds.getHeight()));
            whole.subtract(new Area(textLine1Bounds));

            g2d.setClip(whole);

            xPos = textLine2Bounds.getX();
            yPos = textLine1Bounds.getCenterY();

            g2d.draw(new Line2D.Double(xPos, yPos, xPos + textLine2Bounds.getWidth(), yPos));

            g2d.dispose();
        }

    }

}