2009-03-10 13 views
17

Ich habe eine kleine App, die es dem Benutzer erlaubt, auf dem Bildschirm mit dem Finger zu zeichnen. Ich habe eine UIImageView, wo der Benutzer zeichnet, indem Sie eine CGContextRef und die verschiedenen CG draw Funktionen erstellen. Ich zeichne hauptsächlich Striche/Linien mit der Funktion CGContextAddLineToPointWie zeichne ich einen transparenten Strich (oder sowieso klarer Teil eines Bildes) auf dem iPhone

Jetzt ist mein Problem das: Der Benutzer kann Linien verschiedener Farben zeichnen. Ich möchte ihm die Möglichkeit geben, ein "rubber" Werkzeug zu verwenden, um einen Teil des Bildes, das bis jetzt gezeichnet wurde, mit dem Finger zu löschen. Ich tat dies zunächst mit einer weißen Farbe für den Strich (mit der CGContextSetRGBStrokeColor Funktion eingestellt), aber es hat nicht funktioniert ... weil ich später entdeckte, dass die UIImage auf der UIImageView tatsächlich hatte einen transparenten Hintergrund, nicht weiß ... so würde ich mit einem transparenten Bild mit weißen Linien auf dem Bildschirm enden!

Gibt es trotzdem eine "transparent" Strichfarbe oder gibt es eine andere Möglichkeit, den Inhalt des CGContextRef unter dem Finger des Benutzers zu löschen, wenn er es bewegt? Dank

Antwort

57

Dies wird den Trick tun:

CGContextSetBlendMode(context, kCGBlendModeClear) 
+1

Würde dies das Bild nicht löschen zusammen mit den gezogenen Linien? Was, wenn ich verhindern möchte, dass das Bild gelöscht wird? und lösche nur die Farbe? – Shailesh

-13
UIColor *clearColor = [UIColor clearColor]; 
1

Ich habe versucht mit:

CGContextSetStrokeColorWithColor (myContext, [[UIColor clearColor] CGColor]); 

aber das funktioniert nicht, weil es „Zeichnung“ auf dem Zusammenhang mit einer unsichtbaren Farbe (und unsichtbarer Farbe zu sein scheint + Welche Farbe auch immer es zeichnet = die Farbe, auf der es gezeichnet wird.

Die einzige Lösung, die ich gefunden habe (was nicht optimal ist) ist:

CGContextClearRect (myContext, CGRectMake(x, y, width, height)); 

Leider bedeutet das Sie eine Reihe von Rects zu verfolgen haben und erzeugen die Linie selbst ...

6

beenden I Bresenham-Algorithmus (harkening zurück zu dem alten Zeiten, als ich hatte meine eigenen Grafik-Routinen zu schreiben) mit bis ...

- (void) contextEraseLine:(CGContextRef) ctx from:(CGPoint)startPoint to:(CGPoint) endPoint withThickness:(int)thickness { 
    int x, cx, deltax, xstep, 
    y, cy, deltay, ystep, 
    error, st, dupe; 

    int x0, y0, x1, y1; 

    x0 = startPoint.x; 
    y0 = startPoint.y; 
    x1 = endPoint.x; 
    y1 = endPoint.y; 

    // find largest delta for pixel steps 
    st = (abs(y1 - y0) > abs(x1 - x0)); 

    // if deltay > deltax then swap x,y 
    if (st) { 
     (x0 ^= y0); (y0 ^= x0); (x0 ^= y0); // swap(x0, y0); 
     (x1 ^= y1); (y1 ^= x1); (x1 ^= y1); // swap(x1, y1); 
    } 

    deltax = abs(x1 - x0); 
    deltay = abs(y1 - y0); 
    error = (deltax/2); 
    y = y0; 

    if (x0 > x1) { xstep = -1; } 
    else   { xstep = 1; } 

    if (y0 > y1) { ystep = -1; } 
    else   { ystep = 1; } 

    for ((x = x0); (x != (x1 + xstep)); (x += xstep)) 
    { 
     (cx = x); (cy = y); // copy of x, copy of y 

     // if x,y swapped above, swap them back now 
     if (st) { (cx ^= cy); (cy ^= cx); (cx ^= cy); } 

     (dupe = 0); // initialize no dupe 

     if(!dupe) { // if not a dupe, write it out 
      //NSLog(@"(%2d, %2d)", cx, cy); 

      CGContextClearRect(ctx, CGRectMake(cx, cy, thickness, thickness)); 

    } 

     (error -= deltay); // converge toward end of line 

     if (error < 0) { // not done yet 
      (y += ystep); 
      (error += deltax); 
     } 
    } 
} 

Puh! Das ist ein langer Weg, um eine (etwas) klobige Radiergummi-Linie zu erstellen.

es zu benutzen, so etwas wie:

- (void)eraseStart { 
    // erase lines 
    UIGraphicsBeginImageContext(drawingBoard.size); 
    ctx = UIGraphicsGetCurrentContext(); 
    CGContextDrawImage(ctx,CGRectMake(0,0,drawingBoard.size.width, drawingBoard.size.height),[drawingBoard CGImage]); 
} 

- (void)eraseEnd { 
    drawingBoard = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    [drawingView removeFromSuperview]; 
    [drawingView release]; 

    drawingView = [[UIImageView alloc] initWithImage:drawingBoard]; 
    drawingView.frame = CGRectMake(intEtchX, intEtchY, intEtchWidth, intEtchHeight); 

    [self.view addSubview:drawingView]; 
} 

Dies setzt voraus, Sie haben bereits eine drawingView (UIImageView) und DrawingBoard (UIImage) erstellt.

Dann eine Linie zu löschen, einfach so etwas wie:

CGContextRef ctx = UIGraphicsGetCurrentContext(); 
[self eraseStart]; 
[self contextEraseLine:ctx from:CGPointMake (x1, y1) to:CGPointMake (x2, y2) withThickness:10]; 
[self eraseEnd]; 

(ersetzen x1, y1, x2 und y2 mit den entsprechenden Werten) ...

-2
//erase part 
if(mouseSwiped) 
{ 

//**************Working Code*************// 


UIGraphicsBeginImageContext(frontImage.frame.size); 
[frontImage.image drawInRect:CGRectMake(0, 0, frontImage.frame.size.width, frontImage.frame.size.height)]; 
CGContextSetLineCap(UIGraphicsGetCurrentContext(),kCGImageAlphaNone); //kCGImageAlphaPremultipliedLast); 
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 10); 
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1, 0, 0, 10); 
CGContextBeginPath(UIGraphicsGetCurrentContext()); 
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); 
CGContextClearRect (UIGraphicsGetCurrentContext(), CGRectMake(lastPoint.x, lastPoint.y, 10, 10)); 
CGContextStrokePath(UIGraphicsGetCurrentContext()); 
frontImage.image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 


lastPoint = currentPoint; 

mouseMoved++; 

if (mouseMoved == 10) 
{ 
    mouseMoved = 0; 
} 
} 
+0

Dies funktioniert nicht - Zeichnet wiederum eine braune Linie über eine Bildansicht – Shailesh

Verwandte Themen