将图像裁剪成圆形

cropping in image into an cricle

我想将矩形的图像裁剪成特定直径的圆。我可以通过 graphics2D 做到这一点,并保存图像,但是,当我通过 ImagIO 读取它时,尽管它被裁剪成一个圆圈,但我再次获得了完整的图像。图像是一个蒙版圆圈,外面的一切都像蒙版一样被丢弃。我在这里附上图片。尽管它被剪裁了,但当我通过 imageIO 读取它时,我得到了完整的图像渲染。这是代码。

 int w = bufferedImage.getWidth();
  int h = bufferedImage.getHeight();
  BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

  Graphics2D g2 = output.createGraphics();
  Area areaOval = new Area(new Arc2D.Double(0, 0, w, w, 0, 360,
      Arc2D.PIE));
      Shape shapeClipSave = g2.getClip();

      g2.setClip(areaOval);
      g2.drawImage(bufferedImage, 0, 0, null);
      g2.setClip(shapeClipSave);
  bufferedImage=output;
  try {
    ImageIO.write(bufferedImage,"png", new File("D:/new.png"));
    bufferedImage= ImageIO.read(new File("D:/new.png"));
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  g2.dispose();

这是我的看法。我重写了一些部分以获得性能和更好的保真度(我无法使用剪辑使圆形区域的边缘抗锯齿)。虽然您的代码也应该可以工作,但一般来说。

public static void main(String[] args) throws IOException {
    BufferedImage image = ImageIO.read(new File(args[0]));

    // Remove odd borders (imgur issue?)... Remove this if your input doesn't have borders
    image = image.getSubimage(10, 0, image.getWidth() - 20, image.getHeight() - 10);

    int w = image.getWidth();
    int h = image.getHeight();

    image = createCircular(image, Math.min(w, h));

    if (!ImageIO.write(image, "png", new File("new.png"))) {
        System.err.println("Could not write PNG format");
        System.exit(1);
    }

    image = ImageIO.read(new File("new.png"));

    showItAll(image);

}

private static BufferedImage createCircular(BufferedImage image, int size) {
    BufferedImage output = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2 = output.createGraphics();
    try {
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.fillOval(0, 0, size, size);

        g2.setComposite(AlphaComposite.SrcIn);
        g2.drawImage(image, 0, 0, null);
    } 
    finally {
        g2.dispose();
    }
    
    return output;
}

private static void showItAll(BufferedImage image) {
    JFrame frame = new JFrame("test");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setContentPane(new JPanel() {
        {
            setBackground(Color.ORANGE);
        }
    });
    frame.getContentPane().add(new JLabel(new ImageIcon(image)));
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

使用你的长颈鹿作为输入,我得到了以下输出,橙色背景只是为了让透明部分清晰可见:

或者,如果您使用 TwelveMonkeys 库和 Adob​​e Path 支持模块,您可以替换:

image = createCircular(image, Math.min(w, h));

具有以下内容:

int size = Math.min(w, h);
image = Paths.applyClippingPath(new Ellipse2D.Float(0, 0, 1, 1), 
                                image.getSubimage(0, 0, size, size));

请注意形状坐标是相对于图像大小的,而不是像素。