如何在Java中制作圆角图像

2022-09-02 09:19:20

我想制作一个圆角的图像。图像将来自输入,我将使其圆角,然后保存它。我使用纯java。我该怎么做?我需要一个像这样的函数

public void makeRoundedCorner(Image image, File outputFile){
.....
}

Schema

编辑 :添加了图像以供参考。


答案 1

我建议这种方法获取图像并生成图像并将图像IO保持在外部:

编辑:我最终设法在Chris Campbell的Java 2D Trickery:Soft Clipping的帮助下制作了Java2D软剪辑图形。可悲的是,这不是Java2D开箱即用的一些.RenderhingHint

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"));
}

这就是上述方法的输入/输出的样子:

输入:

input image

丑陋,锯齿状的输出,带有:setClip()

jagged with setclip

漂亮,流畅的输出与复合技巧:

smooth with composite trick

灰色背景上角落的特写(显然是左边,复合右边):setClip()

closeup corners on gray bacjground


答案 2

我正在写一篇关于Philipp Reichart答案的后续文章。答案作为答案。

要删除白色背景(在图片中显示为黑色),请更改为g2.setComposite(AlphaComposite.SrcAtop);g2.setComposite(AlphaComposite.SrcIn);

这对我来说是一个大问题,因为我有不同的透明度图像,我不想丢失。

我的原始图像:
enter image description here

如果我使用 :g2.setComposite(AlphaComposite.SrcAtop);
enter image description here

当我使用背景是透明的。g2.setComposite(AlphaComposite.SrcIn);


推荐