如何在 Java 中使用 Graphics2D 绘制图像的一部分

How to Draw Portion of an Image Using Graphics2D in Java

所以我正在和一个朋友一起开发一个 Discord 机器人,它可以跟踪玩家等级,并且在使用 !rank 命令时,使用显示各种信息的 Graphics2D 一起编辑自定义“等级卡”。基本卡如下所示:

用户可以使用各种命令对其进行自定义,例如更改颜色、强调色、不透明度和背景。所有这些都很好用,除了后台命令似乎过度压缩图像。本质上,当用户执行“!rank background”时,机器人使用 URL link 将 PNG 文件(在 IMGUR 或其他类似网站上)设置为背景。我现在设置它的方式是,将此背景裁剪为默认背景的大小,但这似乎会缩放整个图像以适应这些范围。

原图URL:https://cdn.discordapp.com/attachments/558371806655021108/733489277031153764/image0.jpg

如您所见,它似乎在挤压整个图像以将整个图像放入默认背景形状,而我想要的只是新图像的一些随机部分的一小部分(即使部分图片被截断了)。

我正在寻找一种方法,只需截取较大图像的一小部分,然后将其绘制为背景。我不需要将整个图像挤到背景中,只需要默认背景大小的一小部分。

BufferedImage base = ImageIO.read(new File("data/images/rankCardBase.png"));
BufferedImage outline = ImageIO.read(new File("data/images/rankCardOutline.png"));
Graphics2D g = (Graphics2D) base.getGraphics();
 
//Add Custom Background
if (!player.getString("background").isEmpty()) {
    BufferedImage background = ImageIO.read(new URL(player.getString("background")));
    BufferedImage rectBuffer = new BufferedImage(base.getWidth(), base.getHeight(), BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2 = rectBuffer.createGraphics();
    g2.setClip(new Rectangle2D.Float(0, 0, base.getWidth(), base.getHeight()));
    g2.drawImage(background, 0, 0, base.getWidth(), base.getHeight(), 0, 0, background.getWidth(), background.getHeight(), null);
    g.drawImage(rectBuffer, 0, 0, base.getWidth(), base.getHeight(), null);
}

本质上,g2.drawImage(background, 0, 0, base.getWidth(), base.getHeight(), 0, 0, background.getWidth(), background.getHeight(), null); 将尝试缩放图像以适应指定区域。

相反,您可以只在某个(可能是随机的)点绘制图像,例如,以下将使背景在基本图像中居中...

BufferedImage baseImage = new BufferedImage(400, 121, BufferedImage.TYPE_INT_RGB);
BufferedImage background = ImageIO.read(new URL("https://cdn.discordapp.com/attachments/558371806655021108/733489277031153764/image0.jpg"));

Graphics2D g2d = baseImage.createGraphics();
g2d.setColor(Color.GRAY);
g2d.fillRect(0, 0, 400, 121);

g2d.setClip(new RoundRectangle2D.Float(20, 20, baseImage.getWidth() - 40, baseImage.getHeight() - 40, 20, 20));

Random rnd = new Random();

int x = baseImage.getWidth() - background.getWidth() / 2;
int y = baseImage.getHeight() - background.getHeight() / 2;

g2d.drawImage(background, x, y, null);

g2d.dispose();

JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(baseImage)));

另一个想法可能是查看 BufferedImage#getSubImage