问题描述
我想将矩形图像裁剪成特定直径的圆。我可以通过 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();
解决方法
这是我的看法。我重写了一些部分以获得性能和更好的保真度(我无法使用剪辑消除圆形区域的边缘)。虽然您的代码也应该可以正常工作,但一般来说。
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);
}
使用你的长颈鹿作为输入,我得到以下输出,橙色背景只是为了让透明部分清晰可见:
或者,如果您使用 TwelveMonkeys 库和 Adobe 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));
请注意,形状坐标与图像的大小有关,而不是以像素为单位。