我想制作一个带圆角的图片。输入一张图片后,我会将其变成带圆角的图片并保存。我使用纯Java。我应该如何做?我需要像这样的函数:
public void makeRoundedCorner(Image image, File outputFile){
.....
}
编辑:添加了一张图片以提供信息。
我想制作一个带圆角的图片。输入一张图片后,我会将其变成带圆角的图片并保存。我使用纯Java。我应该如何做?我需要像这样的函数:
public void makeRoundedCorner(Image image, File outputFile){
.....
}
编辑:添加了一张图片以提供信息。
RenderingHint
。public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius) {
int w = image.getWidth();
int h = image.getHeight();
BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = output.createGraphics();
// This is what we want, but it only does hard-clipping, i.e. aliasing
// g2.setClip(new RoundRectangle2D ...)
// so instead fake soft-clipping by first drawing the desired clip shape
// in fully opaque white with antialiasing enabled...
g2.setComposite(AlphaComposite.Src);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius));
// ... then compositing the image on top,
// using the white shape from above as alpha source
g2.setComposite(AlphaComposite.SrcAtop);
g2.drawImage(image, 0, 0, null);
g2.dispose();
return output;
}
这是一个测试驱动程序:
public static void main(String[] args) throws IOException {
BufferedImage icon = ImageIO.read(new File("icon.png"));
BufferedImage rounded = makeRoundedCorner(icon, 20);
ImageIO.write(rounded, "png", new File("icon.rounded.png"));
}
以下是上述方法的输入/输出:
输入:
使用 setClip()
产生的丑陋、不平滑输出:
使用复合技巧产生的漂亮、平滑输出:
在灰色背景下角落的近距离照片(左侧为 setClip()
,右侧为复合):
RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_PURE
,以确保输出对称。您会注意到在您的示例中,右下角与左上角有些不同。 - Gary我找到了另一种使用TexturePaint
的方法:
ImageObserver obs = ...;
int w = img.getWidth(obs);
int h = img.getHeight(obs);
// any shape can be used
Shape clipShape = new RoundRectangle2D.Double(0, 0, w, h, 20, 20);
// create a BufferedImage with transparency
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D bg = bi.createGraphics();
// make BufferedImage fully transparent
bg.setComposite(AlphaComposite.Clear);
bg.fillRect(0, 0, w, h);
bg.setComposite(AlphaComposite.SrcOver);
// copy/paint the actual image into the BufferedImage
bg.drawImage(img, 0, 0, w, h, obs);
// set the image to be used as TexturePaint on the target Graphics
g.setPaint(new TexturePaint(bi, new Rectangle2D.Float(0, 0, w, h)));
// activate AntiAliasing
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// translate the origin to where you want to paint the image
g.translate(x, y);
// draw the Image
g.fill(clipShape);
// reset paint
g.setPaint(null);
new BufferedImage
,getGraphics()
,setClip(new RoundedRectangle.Float(...))
和调用drawImage()
。 - Philipp ReichartsetClip()
,让我写了一个实际的答案,见下文 :) - Philipp Reichart