将图像裁剪成 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,w,360,Arc2D.PIE));
      Shape shapeClipSave = g2.getClip();

      g2.setClip(areaoval);
      g2.drawImage(bufferedImage,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();

enter image description here

解决方法

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

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,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,size);

        g2.setComposite(AlphaComposite.SrcIn);
        g2.drawImage(image,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);
}

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

Circular selection of image

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

image = createCircular(image,h));

具有以下内容:

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

请注意,形状坐标与图像的大小有关,而不是以像素为单位。