0

I'm programming in java.

I am essentially doing a paint like tool. The user can select a background image, use a mouse to draw a line, or erase a line. When erasing a line the background image should still the same.

So what I was trying to do was have a separate image for the background image and another image to track the mouse movement and draw lines. I then combine these 2 images to show the final image.

The problem that I'm unable to solve is the erase function. I tried using setXORMode which works great if I have a background image that has 1 color. But if the image has gradient color then the lines I draw over it changes color too.

Here is the snippet of the code I was working on:

private void backgroundImageOverNote()  
{  
    Graphics2D g = image.createGraphics();  
    g.drawImage(backgroundImage.getImage(), 0, 0, 400, 200, null);  
    g.drawImage(sketchImage, 0, 0, 400, 200, null);  
    g.dispose();  
}

public void sketch(SketchData sketchEvent)
{
  if(isValidXYPosition(sketchEvent.getX(), sketchEvent.getY()))
  {
    Graphics2D g = sketchImage.createGraphics();
    g.drawLine(oldX, oldY, sketchEvent.getX(), sketchEvent.getY());
    g.dispose();
  }
  oldX = sketchEvent.getX();
  oldY = sketchEvent.getY();
}


private BufferedImage sketchImage = new BufferedImage(400, 200, BufferedImage.TYPE_INT_ARGB);
private ImageIcon backgroundImage; 

dan
  • 1
  • 1

1 Answers1

1

alt text http://grab.by/grabs/81ccdd4ad6b0d78c130bb2a44d665982.png

You do not need to use XOR at all. Especially if you have the two layers separated, it's much easier than that.

// Opaque
private Composite paintMode = AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f);
// transparent; erases the foreground image allowing the background image through    
private Composite eraseMode = AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f);

Then when it comes time to draw:

if (drawing) {
       graphics.setComposite(paintMode);
   }
   else {
      graphics.setComposite(eraseMode);
   }

Then paint like normal. I have a full source code example I can share if you'd like.

I82Much
  • 26,901
  • 13
  • 88
  • 119
  • Thanks for your reply! But I may not be clear on my earlier post. The 2nd layer that I was using has a white background. If the user wants to erase a line I just basically draw a line in white which matches the background color for the 2nd layer. What I really wanted to happen is when I draw the 2nd layer (sketchImage) I don't want the white to draw on my final image. I set the XOR mode to white before I draw the second layer so that it uses the same color of the backgroundImage. Which lead to the problem I was trying to solve. – dan Aug 05 '10 at 16:49
  • I think this is what I need to do: filter white to transparent http://stackoverflow.com/questions/665406/how-to-make-a-color-transparent-in-a-bufferedimage-and-save-as-png – dan Aug 05 '10 at 16:55
  • 1
    Try what I'm suggesting - trust me, it works. The naive thing to do is to paint over the top layer with the same color as the background layer. But a better solution is to instead *erase* the top layer, letting the bottom layer shine through. It's much simpler, and will be a lot easier to reason about. My method basically does what the linked image does - by setting the alpha composite to clear, anything you draw on the image instead erases (sets to transparent) that section of the image. – I82Much Aug 05 '10 at 19:38