How to create a circular bufferedimage rather than creating a rectangular one in Java using Graphics

我只是一个虾纸丫 提交于 2019-12-24 12:37:02

问题


I need to create a bufferedimage (circular type) but I am able to create only rectangular type. Then I want to create a oval inside the bufferedimage with some configurations and finally i want to draw a rectangular icon inside the circular shape which should be inserted on the circular shape and not on the rectangular bufferedimage. Now i am able to do the following

BufferedImage img = "SomeImage.png";
BufferedImage bfImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics       = bfImage.createGraphics();
graphics.fillOval(0, 0, 200, 200); 
graphics.drawImage(img, 0, 0, null);

(This creates a circular oval inside the bfImage object) Now i need to draw "img" which is rectangular in shape of say 100*100 size. This i can draw using When i am doing this my final image is getting drawn in the Rectangular BfImage, which i dont want.I want the image "img" to be drawn in the circular oval and it should not come outside the boundaries of the circular oval shape. In short instead of drawing my final image on the rectangular bfImage can i have a circular bfImage on which i can directly draw my image. Any logic to do this in Java2D using graphics.


回答1:


I've never encountered a "circular image" in the sense of a two dimensional array that is not in rectangular form. If all you are concerned about is that the pixels outside the circle are not visible, just set the alpha to 0 for those pixels. An easy way to do this is to fill the entire rectangular image with ARGB(0,0,0,0) first and then draw whatever else you want.

Also, not that if you intent to persist this buffer as an image file, you must make sure that you export/save to a format like PNG or TIFF that supports transparency.




回答2:


As @justinzane says, you can't have a truly circular image. All BufferedImages will be rectangular.

But: You can achieve the effect you are after, by using the AlphaComposite class, and the rule AlphaComposite.SrcIn. I've added a fully running example, plus a screen shot below, the compose method is the important part.

public class AlphaCompositeTest {
    private static BufferedImage compose(final BufferedImage source, int w, int h) {
        BufferedImage destination = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = destination.createGraphics();
        try {
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.setColor(Color.BLACK); // The color here doesn't really matter
            graphics.fillOval(0, 0, destination.getWidth(), destination.getHeight());

            if (source != null) {
                graphics.setComposite(AlphaComposite.SrcIn); // Only paint inside the oval from now on
                graphics.drawImage(source, 0, 0, null);
            }
        }
        finally {
            graphics.dispose();
        }

        return destination;
    }

    public static void main(String[] args) throws IOException {
        final BufferedImage original = ImageIO.read(new File("lena.png"));
        final BufferedImage template = compose(null, original.getWidth(), original.getHeight());
        final BufferedImage composed = compose(original, original.getWidth(), original.getHeight());

        SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

                JPanel panel = new JPanel(new BorderLayout(10, 10));
                panel.add(new JLabel("+", new ImageIcon(template), SwingConstants.LEFT), BorderLayout.WEST);
                panel.add(new JLabel("=", new ImageIcon(original), SwingConstants.LEFT), BorderLayout.CENTER);
                panel.add(new JLabel(new ImageIcon(composed)), BorderLayout.EAST);

                frame.add(new JScrollPane(panel));

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

See for example the Compositing tutorial for more info and examples.



来源:https://stackoverflow.com/questions/23669333/how-to-create-a-circular-bufferedimage-rather-than-creating-a-rectangular-one-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!