对于图像,将图像绘制成另一张大 2 像素的图像就足够了,然后使用双线性插值绘制得到的图像。所以你可以通过这样的方法传递你的图像:
private static BufferedImage addBorder(BufferedImage image)
{
BufferedImage result = new BufferedImage(
image.getWidth() + 2, image.getHeight() + 2,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(image, 1, 1, null);
g.dispose();
return result;
}
结果会是这样的:
这是 MCVE,包括设置..._INTERPOLATION_BILINEAR 渲染提示的行:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ImageBorderAntialiasing
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui()
{
//BufferedImage img = loadUnchecked("7bI1Y.jpg");
BufferedImage img = addBorder(loadUnchecked("7bI1Y.jpg"));
JFrame frame = new JFrame();
frame.add(new JPanel()
{
@Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30),
getWidth() / 2.0, getHeight() / 2.0);
g2d.drawImage(img, 0, 0, this);
g2d.fill(new Rectangle(-100, 100, 100, 100));
}
});
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static BufferedImage addBorder(BufferedImage image)
{
BufferedImage result = new BufferedImage(
image.getWidth() + 2, image.getHeight() + 2,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(image, 1, 1, null);
g.dispose();
return result;
}
private static BufferedImage loadUnchecked(String fileName)
{
try
{
return ImageIO.read(new File(fileName));
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
}
回答完这个问题后,问题更新为还询问clip方法
对clip 操作的结果进行抗锯齿处理可能会更加困难。 clip 操作“本质上”是非常困难的(我假设它最终将由硬件中的 Stencil Buffer 之类的东西处理)。
解决此问题的一种方法可以手动进行剪辑。所以不要这样做
g2d.clip(new Rectangle(-110, 110, 80, 110));
g2d.fill(new Rectangle(-100, 100, 100, 100));
你可以做类似的事情
Shape clip = new Rectangle(-110, 110, 80, 110);
Shape rectangleA = new Rectangle(-100, 100, 100, 100);
g2d.fill(clip(clip, rectangleA));
clip 方法用于手动计算形状的交集。
注意:计算两个形状的交集可能相当昂贵。如果这成为一个问题,人们可能不得不修改方法。但另一方面:我已经大量从事 Swing 编程大约 20 年了,并且不记得曾经使用过 Graphics2D#clip 方法根本... .
使用Graphics2D#clip和手动裁剪的区别如下:
还有一个特写:
还有代码:
(它不再包含图像部分,因为问题完全不相关......)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ClippedDrawingAntialiasing
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui()
{
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new GridLayout(1,2));
frame.getContentPane().add(new JPanel()
{
@Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30),
getWidth() / 2.0, getHeight() / 2.0);
g2d.clip(new Rectangle(-110, 110, 80, 110));
g2d.fill(new Rectangle(-100, 100, 100, 100));
g2d.setColor(Color.BLUE);
g2d.fill(new Rectangle(-60, 120, 60, 170));
}
});
frame.getContentPane().add(new JPanel()
{
@Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30),
getWidth() / 2.0, getHeight() / 2.0);
Clipper clipper =
new Clipper(new Rectangle(-110, 110, 80, 110));
g2d.fill(clipper.clip(new Rectangle(-100, 100, 100, 100)));
g2d.setColor(Color.BLUE);
g2d.fill(clipper.clip(new Rectangle(-60, 120, 60, 170)));
}
});
frame.setSize(1200, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static class Clipper
{
private final Shape shape;
Clipper(Shape shape)
{
this.shape = shape;
}
Shape clip(Shape other)
{
Area a = new Area(shape);
a.intersect(new Area(other));
return a;
}
}
}