arn*_*bpl 5 java swing 2d image awt
有一个叫方法scale(double sx, double sy)在Graphics2DJava中.但是这种方法似乎将图像缩放为单独的表面而不是单个表面.结果,如果原始图像没有额外的宽度和高度,则缩放图像具有尖角.以下屏幕截图演示了此问题:

这是代码:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class TestJava {
static int scale = 10;
public static class Test extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.scale(scale, scale);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
BufferedImage img = null;
try {
img = ImageIO.read(new File("Sprite.png"));
} catch (IOException e) {
e.printStackTrace();
}
g2.drawImage(img, null, 5, 5);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Test test = new Test();
test.setBackground(Color.WHITE);
frame.add(test);
frame.setSize(300, 350);
frame.setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
该问题的一种可能的解决方案是具有额外宽度和高度的原始图像(在这种情况下"Sprite.png").但这似乎不是解决问题的好方法.所以我在Java中寻求一种编程方式来解决这个问题,而不是使用图像编辑器.这样做的方法是什么?
一个有趣的问题(+1)。我认为为此找到一个好的解决方案并不简单:放大图像时的插值总是发生在图像内部,并且我无法想象一种方法可以使其模糊图像外部的缩放像素。
这导致了相当简单的解决方案:可以在整个图像周围添加 1 像素边距。事实上,这就是您自己提出的解决方案的编程方式。结果如下:

(左边是原始的,右边是额外的1像素边框)
这里作为 MCVE,基于您的示例
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class ScaledPaint
{
static int scale = 10;
public static class Test extends JPanel
{
BufferedImage image = createTestImage();
BufferedImage imageWithMargin = addMargin(image);
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.scale(scale, scale);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2.drawImage(image, 5, 5, null);
g2.drawImage(imageWithMargin, 30, 5, null);
}
}
private static BufferedImage createTestImage()
{
BufferedImage image =
new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setColor(Color.RED);
g.drawOval(0, 0, 19, 19);
g.dispose();
return image;
}
private static BufferedImage addMargin(BufferedImage image)
{
return addMargin(image, 1, 1, 1, 1);
}
private static BufferedImage addMargin(BufferedImage image,
int left, int right, int top, int bottom)
{
BufferedImage newImage =
new BufferedImage(
image.getWidth() + left + right,
image.getHeight() + top + bottom,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, left, top, null);
g.dispose();
return newImage;
}
private static BufferedImage convertToARGB(BufferedImage image)
{
BufferedImage newImage =
new BufferedImage(image.getWidth(), image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return newImage;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Test test = new Test();
test.setBackground(Color.WHITE);
frame.add(test);
frame.setSize(600, 350);
frame.setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
...这种方法的一个问题已经可以在屏幕截图中看到:图像变大。绘制图像时必须考虑到这一点。因此,如果您的原始精灵都有一个漂亮的、预定义的、易于处理的尺寸(例如 16x32),那么它们之后的尺寸将为 18x34,这对于图块来说相当奇怪。这可能不是问题,具体取决于您处理图块尺寸的方式。但如果这是一个问题,人们可以考虑可能的解决方案。一种解决方案可能是...
但考虑到在这种大小的精灵中,每个像素都可能很重要,这也可能会产生不良影响......
旁白:虽然我认为您发布的代码只是作为 MCVE,但我想指出(对于可能阅读此问题和代码的其他人):
paintComponent在方法中加载图像convertToARGB。