如何创建循环缓冲图像,而不是使用Graphics在Java中创建矩形缓冲图像

时间:2014-05-15 04:35:37

标签: graphics bufferedimage java-2d

我需要创建一个bufferedimage (圆形)但我只能创建矩形类型。然后我想在bufferedimage中创建一个带有一些配置的椭圆形,最后我想在圆形内部绘制一个矩形图标,应该插入圆形而不是矩形bufferedimage。 现在我能够做到以下

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

(这会在bfImage对象中创建一个圆形椭圆) 现在我需要绘制" img"它的形状为矩形,例如100 * 100。 我可以使用这个画 当我这样做时,我的最终图像是在矩形BfImage中绘制的,我不想要它。我想要图像" img"以圆形椭圆形绘制,不应超出圆形椭圆形的边界。 总之,不是在矩形bfImage上绘制我的最终图像,我可以有一个圆形bfImage,我可以直接绘制我的图像。 使用图形在Java2D中执行此操作的任何逻辑。

2 个答案:

答案 0 :(得分:2)

我从来没有遇到过一个二维数组意义上的“圆形图像”,它是不是的矩形形式。如果您只关心圆圈外的像素是不可见的,只需将这些像素的alpha设置为0即可。一个简单的方法是首先用ARGB(0,0,0,0)填充整个矩形图像,然后绘制你想要的任何其他图像。

此外,如果您打算将此缓冲区保留为图像文件,则必须确保导出/保存为支持透明度的PNG或TIFF等格式。

答案 1 :(得分:1)

正如@justinzane所说,你不能拥有真正的圆形图像。所有BufferedImage都是矩形的。

但是:您可以使用AlphaComposite类和规则AlphaComposite.SrcIn来实现您所追求的效果。我已经添加了一个完整运行的示例,加上下面的屏幕截图,compose方法是重要的部分。

Screen shot, showing how a template + image = image inside template

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

有关详细信息和示例,请参阅示例the Compositing tutorial