views:

60

answers:

1

I'm trying to implement a smudge tool like one you would find in Gimp or Photoshop. I've tried lots of variations but they all have problems. The basic method I've tried for smudging from position P1 to P2 on an image is:

  1. Copy a rectangle the size of the current brush from P1.
  2. Draw this rectangle at P2 with a low opacity.

It looks fine and smudges as expected but the main problems I'm having is that the smudge seems to make things darker. Especially when using a small brush spacing, repeated smudging will turn the area to black. Any suggestions on what I'm doing wrong or some standard algorithms I can look at? I've had a look at the Gimp source but it's very hard to follow.

If it matters, I'm working on a mobile device (Android, Java) so something fast would be preferable.

A: 

I suspect that you algorithm constantly renders your rectangles on top of each other, likely averaging their values to get the new color value below. Depending on how the particulars of you program is set up, I would wager that the RGB values are going to 0x000000 due to this repeated averaging. This also explains why smaller step distances blacken faster, as more steps equates to more averaging. I had a similar problem with a color changer that was repeatedly blurred going black on the edges.

A good tutorial on creating your own smudge tool can be found here: http://losingfight.com/blog/2007/09/04/how-to-implement-smudge-and-stamp-tools/

Unfortunately, the examples are all in Objective-C but the text explains fairly well what is going on.

Hope this helps.

phobos51594
Thanks for the hint. Can you suggest what I can do when blending the smudge image back onto the destination image so that it doesn't blacken? I've actually read that tutorial (it's about the only one I can find!) a few times and I cannot see what he's doing differently to me. He doesn't mention blending modes. Any ideas?
RichardNewton
It has been quite some time since I worked in computer graphics, but here goes. From what I can tell, the problem is introduced due to your opacity. How are you actually performing that part of the transform? If we take the values to extremes there are several distinct possibilities. Averaging, say, blue with itself should always give you blue as in the case where a solid block of color is smudged into itself. Now, what happens if you drag blue into red? Theoretically, you should get purple. Repeated smudges should give you more uniform purple until you hit 0xFF00FF.
phobos51594
Thanks for the reply. All I'm doing is saying "draw the bitmap from the previous position onto the new position with alpha set to X percent" using the standard draw bitmap procedure (so the bitmap will appear above the first slight transparent). Smudging blue into red does indeed give purple. Strangely, I can keep rubbing purple, red and blue separately and they don't get darker. However, rubbing where the purple and the blue are overlapping quickly produces black (which is not the case for purple+red) and rubbing anything with some black in it quickly produces more black.
RichardNewton
Hm. I find the behavior of getting black from blue and purple rather puzzling as, at no point, are you manually introducing anything on the green channel. I assume you started using a white canvas and only moved to blue + red at my urging? In that case, the green channel should be 255, not zero. Can you post your code? Apologies, but I am rather stumped otherwise.
phobos51594
Oops, I found a bug in my color picker so the blue and red both had a bit of green in them... Mixing blue and red has the expected behaviour. However, if I use a blue-green color and red, I can make black by smudging. :-\
RichardNewton