2016-04-13 13 views
2

Ich möchte eine Funktion wie ein Pinsel erfüllen. Der Bereich, in dem sich der Finger wischt, ändert sich mit der allmählich geänderten Grenze. Folgend CodesWie kann ich mit CoreGraphics eine Linie zeichnen, die sich allmählich ändert?

enter image description here
Ich kann nur die Farbe Kristall mit klarer jetzt ändern:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
if(self.eraser) return; 

CGFloat scale = self.transform.a; 
if (scale < 1) scale = 1; 

CGPoint p = [[touches anyObject] locationInView: self]; 
CGPoint q = [[touches anyObject] previousLocationInView: self]; 

UIImage* image; 
image = self.image; 
CGSize size = self.frame.size; 
UIGraphicsBeginImageContext(size); 
CGRect rect; 
rect.origin = CGPointZero; 
rect.size = size; 
[image drawInRect:rect]; 
CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextSetLineCap(context, kCGLineCapRound); 

CGContextBeginPath(context); 
CGContextSaveGState(context); 
CGContextSetLineWidth(context, (10.0/scale) + 1); 
CGContextSetBlendMode(context, kCGBlendModeClear); 

CGContextMoveToPoint(context, q.x, q.y); 
CGContextAddLineToPoint(context, p.x, p.y); 
CGContextStrokePath(context); 
CGContextRestoreGState(context); 

UIImage* editedImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
[self setBounds:rect]; 
[self setImage:editedImage]; 

}

Wie kann ich die Kante mit allmählich ändern bekommen? Danke im Voraus.

Antwort

4

Sie können diesen Effekt erzielen, indem Sie an jeder Stelle, an der der Benutzer vorbeigeht, im Modus kCGBlendModeDestinationIn einen radialen Farbverlauf mit einer variablen Alpha zeichnen.

Dieser Mischmodus bewirkt, dass nur das Alpha der Ebene auf die darunter liegenden Ebenen angewendet wird. Mit der variablen Alpha unseres Gradienten können wir diesen Effekt erzielen.

const CGFloat kBrushSize = 10.f; 

CGContextSaveGState(context); 

// Make a radial gradient that goes from transparent black on the inside 
// to opaque back on the outside. 
size_t num_locations = 2; 
CGFloat locations[2] = { 0.0, 1.0 }; 
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.0, 
          1.0, 1.0, 1.0, 1.0 }; 

CGColorSpaceRef myColorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 
CGGradientRef myGradient = CGGradientCreateWithColorComponents (myColorspace, components, 
                   locations, num_locations); 
CGColorSpaceRelease(myColorspace); 

// Draw the gradient at the point using kCGBlendModeDestinationIn 
// This mode only applies the new layer's alpha to the lower layer. 
CGContextSetBlendMode(context, kCGBlendModeDestinationIn); 
CGContextDrawRadialGradient(context, myGradient, p, 0.f, p, (kBrushSize/scale) + 1, kCGGradientDrawsAfterEndLocation); 

CGGradientRelease(myGradient); 

CGContextRestoreGState(context); 

Hier ist ein Screenshot von diesem Code in Aktion:

CGBrush Scribble

Hinweis: Mit dieser Technik, wenn der Benutzer seine/ihre Finger sehr schnell bewegt, können Sie einen Abstand Effekt sehen können wo einzelne Pinselpunkte sichtbar sind. Dies ist eine Eigenschaft einiger Grafikprogramme, aber wenn dies für Sie nicht wünschenswert ist, können Sie Code hinzufügen, um die Punkte zwischen dem aktuellen und dem letzten zu interpolieren, um mehr Pinselpunkte zu zeichnen, wodurch ein kontinuierlicherer Strich entsteht.

Auch sollten Sie in der Lage sein, die Farbverlaufsstopps einzustellen, um jede Art von Pinselweichheit zu erzielen, die Sie mögen.

Quelle: https://developer.apple.com/library/mac/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html