Java 如何删除在图像上绘制的形状

Java 如何删除在图像上绘制的形状,java,swing,graphics2d,eraser,Java,Swing,Graphics2d,Eraser,我正在开发一个小的绘画工具。我能够在图像上加载和绘制线、圆和其他形状。我还有一个橡皮擦工具,可以擦除我画的形状。 这是代码: g.setColor(getColor().WHITE); g.fillRect(getXAxis() - getThickness(), getYAxis() - getThickness(), getThickness() * 2, getThickness() * 2); 我的问题是,如果我加载了一个图像并在上面画了一些形状。然后,当我试图擦除形状时,图像也会被替

我正在开发一个小的绘画工具。我能够在图像上加载和绘制线、圆和其他形状。我还有一个橡皮擦工具,可以擦除我画的形状。
这是代码:

g.setColor(getColor().WHITE);
g.fillRect(getXAxis() - getThickness(), getYAxis() - getThickness(), getThickness() * 2, getThickness() * 2);
我的问题是,如果我加载了一个图像并在上面画了一些形状。然后,当我试图擦除形状时,图像也会被替换为白色。

使用
fillRect()
擦除形状时,是否有任何方法将图像设置为背景,以便我的图像不会被触动。

以下是示例。要测试它,您需要将我的图像替换为您的背景图像

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

/**
 * <code>PaintTryout</code>.
 *
 * @author smedvynskyy
 */
public class PaintPanel extends JPanel {

    private Image backgroundImage;

    private BufferedImage paintImage;

    public PaintPanel() {
        try {
            // replace this image with your image
            backgroundImage = ImageIO.read(new File("E:\\icons\\blackboard.png"));
            paintImage = new BufferedImage(backgroundImage.getWidth(this), 
                    backgroundImage.getHeight(this), BufferedImage.TYPE_INT_ARGB);
        } catch (final Exception e) {
            e.printStackTrace();
        }

    }

    public void fillRect() {
        final Graphics g = paintImage.createGraphics();
        g.setColor(Color.RED);
        g.fillRect(0, 0, 50, 50);
        g.dispose();
        repaint();
    }

    public void clearRect() {
        final Graphics2D g = paintImage.createGraphics();
        g.setColor(new Color(0, 0, 0, 0));
        g.setComposite(AlphaComposite.Clear); // overpaint
        g.fillRect(0, 0, 50, 50);
        g.dispose();
        repaint();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(backgroundImage, 0, 0, this);
        g.drawImage(paintImage, 0, 0, this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(backgroundImage.getWidth(this), 
                backgroundImage.getHeight(this));
    }

    public static void main(String[] args) {
        final JFrame frm = new JFrame("Tesp paint");
        final PaintPanel p = new PaintPanel();
        frm.add(p);
        final JPanel buttons = new JPanel();
        final JButton fill = new JButton("Fill Rect");
        fill.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                p.fillRect();
            }
        });
        final JButton clear = new JButton("Clear Rect");
        clear.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                p.clearRect();
            }
        });
        buttons.add(fill);
        buttons.add(clear);
        frm.add(buttons, BorderLayout.SOUTH);
        frm.pack();
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.setLocationRelativeTo(null);
        frm.setVisible(true);
    }
}

实现这一点的简单方法是在XOR模式下绘制线。然后,要删除它们,只需再次绘制它们。

我想在对图形执行任何其他操作之前,您需要先调用g.drawImage(XXX)。是的,我已经在做了。但是问题仍然存在,你需要两张图片一张画在另一张上面。首先是你的源图像。第二个是带有线条/形状的图像。如果要擦除某些内容,需要在第二张图像上用渐变色填充rect。使用drawImage,然后绘制一个圆,然后尝试删除该圆?都在同一个graphics2d实例上?如果是这样的话,删除背景是正常的。@SergiyMedvynskyy,你能给我看一些它的代码吗?在这种情况下,我们将得到的不是一条单色实线,而是一条XOR像素线。在这种情况下,整条线将被删除或添加。但使用橡皮擦,我们应该有能力擦除线的特定部分也。在这种情况下,这可能不是work@SaikiranGosikonda不,在这种情况下,您重新绘制的线条的任何部分都将被删除。@EJP对所有其他形状的效果也是一样的。像长方形,Circle@SergiyMedvynskyy的确如此,但这通常是一个优势。考虑一个在背景从黑色变为白色的表面绘制的线,作为一个极端的例子。Medvyncskyy使用上面的解决方案,当我试图擦除某些东西时,我得到了黑色矩形,你只需要修改<代码> PrimTimeA//C> >上面的例子是很好的。但是,当我在我的代码中使用它来修改缓冲图像时,我得到了黑色的矩形。它工作得非常好。以前,我使用了clearRect()而不是fillRect()。现在,一切都好了。谢谢