Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

gbenna

macrumors member
Original poster
Jul 27, 2011
62
0
I have created a drawing app for iPhone, iPad, iPod in which the user can color on top of an outline image (coloring book). I have an erasure that removes all that is on the page, but I would like to create an erasure that would lift some but not all the color that is on the page off, much like a kneaded erasure does in real life. I have searched the net for such a thing but haven't found anything. Does anyone have any suggestions?
I was wondering if one could use a texture filter to let only part of the erasure effect the underlying drawing but don't know how to do that.
I have tried setting the alpha on a clearColor but there isn't one.
HELP!
 

DannyBres

macrumors 65816
Oct 30, 2007
1,412
6
UK
This is an insanely complex issue.

How do you save the currently drawn lines in your model?
 

gbenna

macrumors member
Original poster
Jul 27, 2011
62
0
I have three imageViews
1. the image that I draw on top of from my photos
2. the saved drawing
3. a temporary image view that I draw on

So I draw on the temp image but constantly save to the drawing image view.

All this works fine but when I try to erase I can't set the alpha so it doesn't erase just a little but all or none.

this is my code

Code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    

            self.RealImage.frame = CGRectMake(12,137,740,850);
            
            self.imageView.frame = CGRectMake(12,137,740,850);
            self.tempImage.frame = CGRectMake(12,137,740,850);
      

    ctr = 0;
    UITouch *touch = [touches anyObject];
    pts[0] = [touch locationInView:self.tempImage];
    
    lastPoint = [touch locationInView:tempImage];
    
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   
    
   self.RealImage.frame = CGRectMake(12,137,740,850);
            
            self.imageView.frame = CGRectMake(12,137,740,850);
            self.tempImage.frame = CGRectMake(12,137,740,850);
    
    
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self.tempImage];
    currentPoint = [touch locationInView:tempImage];
    ctr++;
    pts[ctr] = p;
   
    if (ctr == 4)
    {
        pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0); 
        [path moveToPoint:pts[0]];
        [path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]];
        
        [self draw2];
        
        
        // replace points and get ready to handle the next segment
        pts[0] = pts[3];
        pts[1] = pts[4];
        ctr = 1;
    }
     NSLog(@"ctr:%d",ctr);
    lastPoint = currentPoint;
    
}



- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
   
    
    [path removeAllPoints];
    ctr = 0;
   
    
    
    UIGraphicsBeginImageContext(self.tempImage.frame.size);
    
  
    self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
    self.tempImage.image = nil;
    
    
    
    UIGraphicsEndImageContext();
    
  
   
}

- (void)draw2
{
    
    
    UIGraphicsBeginImageContext(self.tempImage.frame.size);
    [self.tempImage.image drawInRect:CGRectMake(0, 0, self.tempImage.frame.size.width, self.tempImage.frame.size.height)];
    
    pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0); 
    [path moveToPoint:pts[0]];
    [path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]];
    
    

   if ([pencilString isEqualToString:@"black"]) {
        [[UIColor blackColor] setStroke];
        [path setLineWidth:w];
    }
        
    else if ([pencilString isEqualToString:@"clear"]) {
        [[UIColor clearColor] setStroke];
        [path setLineWidth:w];
         CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeCopy);
    }
   
    [path stroke];
    
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
    
   
    self.tempImage.image = UIGraphicsGetImageFromCurrentImageContext();
    [self.tempImage setAlpha:a];
   
    
    UIGraphicsEndImageContext();
    }
    
    
}

can you use a filter like a watercolor filter that lets a little of background show through but use a grainy filter that lets you erase just a little so the more grainy the less you erase but the less grainy the more you erase. How do you apply filters for different textures.
 
Last edited by a moderator:

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Few comments:

One way to erase is simply drawing in clearColor. Imagine you have a bitmap that is filled with clearColor. The brush draws lines into this bitmap with another color, say redColor. After that you can draw with clearColor to 'erase' the redColor. The brush you erase with could be different than the brush you draw with. It could be wider or have some different algorithm for which pixels are erased to clear based on the touch.

Something like that could work for you if you maintain layers. The original image plus a second clear layer that is drawn into. You'd only flatten the image into a single layer as your last step.

Another way to erase would be to fill with pixels from the original image. You keep the original image and a copy that is drawn on. To erase the drawn image you copy pixels to it from the original image based on the touch.
 

gbenna

macrumors member
Original poster
Jul 27, 2011
62
0
So I have this pretty well done.

I created another imageView (Copy) that copies the base imageView (Base) in touchesBegan

Then in touchesMoved I create two paths and have path1 erase the base imageView along the stoke using
Code:
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeCopy);
and then path2 draws the copied imageView back in along the stroke using
Code:
 [[UIColor colorWithPatternImage:theImage]setStroke];
where "theImage" is the copied imageView.image. into another imageView (tempView)
This tempView's alpha is set to the selected alpha on a slider selected for the kneaded erasure.

In TouchesEnded the tempView is transferred to the base imageView and the tempView is set to nil.

My only problem is that where the stroked path2 is draw into the tempView a small clear line is in between the path2 segments even though I use
Code:
 [path2 setLineCapStyle:kCGLineCapButt];

I am not sure why this is happening since when I use colorWithPatternImage and setLineCapStyle:kCGLineCapButt when I don't erase the imageView first everything works fine and there is no clear line between segments.

I have included an attachment. Can someone figure this out?
 

Attachments

  • kneaded erasure lines.jpg
    kneaded erasure lines.jpg
    30.1 KB · Views: 73
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.