在此示例中,我们演示如何使用 Graphics2D 在 BufferedImage 上叠加文本。我们的目标是提供一种将文本直接渲染到图像上并返回修改后的 BufferedImage 的解决方案。
初始代码和差异:
提供的代码片段试图实现文本覆盖但未能对
问题:
问题在于drawString()方法如何解释x和y坐标。这些坐标表示第一个字符的基线位置,而不是文本的左上角。因此,根据字体和下行字母(“g”或“p”等字符)的存在,文本可能最终会超出图像边界。
解决方案:
为了解决这个问题,我们需要调整文本的位置。我们首先获取当前 Font 对象的 FontMetrics,而不是直接使用 x 和 y。 FontMetrics 允许我们计算正确定位文本所需的偏移量。
具体来说,我们计算水平偏移量以确保文本在可用宽度内居中,并调整垂直偏移量以避免剪切文本text.
用示例重写代码:
import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; public class TextOverlay extends JPanel { private BufferedImage image; public TextOverlay() { try { image = ImageIO.read(new URL( "http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png")); } catch (IOException e) { e.printStackTrace(); } image = process(image); } @Override public Dimension getPreferredSize() { return new Dimension(image.getWidth(), image.getHeight()); } private BufferedImage process(BufferedImage old) { int w = old.getWidth() / 3; int h = old.getHeight() / 3; BufferedImage img = new BufferedImage( w, h,BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = img.createGraphics(); g2d.drawImage(old, 0, 0, w, h, this); g2d.setPaint(Color.red); g2d.setFont(new Font("Serif", Font.BOLD, 20)); String s = "Hello, world!"; FontMetrics fm = g2d.getFontMetrics(); int x = img.getWidth() - fm.stringWidth(s) - 5; int y = fm.getHeight(); g2d.drawString(s, x, y); g2d.dispose(); return img; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(image, 0, 0, null); } private static void create() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new TextOverlay()); f.pack(); f.setVisible(true); } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override public void run() { create(); } }); } }
在此修改代码后,我们根据字体规格正确计算偏移量并相应地渲染文本。因此,覆盖文本将正确定位在图像内。
以上是如何使用 Java 的 Graphics2D 正确地将文本覆盖到 BufferedImage 上?的详细内容。更多信息请关注PHP中文网其他相关文章!