2009-03-10 6 views
17

J'ai une petite application qui permet à l'utilisateur de dessiner sur l'écran avec le doigt. J'ai un UIImageView où l'utilisateur dessine, en créant un CGContextRef et les diverses fonctions CG draw. Je dessine principalement des traits/lignes avec la fonction CGContextAddLineToPointComment dessiner un trait transparent (ou de toute façon partie claire d'une image) sur l'iPhone

Maintenant, mon problème est le suivant: L'utilisateur peut dessiner des lignes de différentes couleurs. Je veux lui donner la possibilité d'utiliser un outil "rubber" pour supprimer une partie de l'image dessinée jusqu'ici, avec le doigt. J'ai d'abord fait cela en utilisant une couleur blanche pour le coup (réglé avec la fonction CGContextSetRGBStrokeColor) mais cela n'a pas fonctionné ... parce que j'ai découvert plus tard que le UIImage sur le UIImageView avait effectivement un fond transparent, pas blanc ... donc je finirais avec une image transparente avec des lignes blanches dessus!

Est-il possible de définir une couleur de trait "transparent" ou existe-t-il un autre moyen de supprimer le contenu du CGContextRef sous le doigt de l'utilisateur, lorsqu'il le déplace? Merci

Répondre

57

Cela fera l'affaire:

CGContextSetBlendMode(context, kCGBlendModeClear) 
+1

ne serait-ce effacer l'image ainsi que les lignes tracées? Que faire si je veux empêcher l'effacement de l'image? et seulement effacer la peinture? – Shailesh

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

J'ai essayé d'utiliser:

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

mais cela ne fonctionne pas, car il semble être « dessin » au-dessus du contexte avec une couleur invisible (et la couleur invisible + quelle que soit la couleur sur laquelle elle dessine = la couleur sur laquelle elle dessine).

La seule solution que j'ai trouvé (ce qui est optimal) est:

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

Malheureusement, cela signifie que vous devez tracer une série de rects et de générer la ligne vous-même ...

6

Je fini par utiliser l'algorithme de ligne de Bresenham (harkening retour aux jours d'autrefois quand je devais écrire mes propres routines graphiques) ...

- (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); 
     } 
    } 
} 

Ouf! C'est un long chemin à parcourir pour créer une ligne de gomme (un peu) maladroite.

Pour l'utiliser, faire quelque chose comme:

- (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]; 
} 

Cela suppose que vous avez déjà créé un drawingView (UIImageView) et DrawingBoard (UIImage).

Ensuite, pour effacer une ligne, il suffit de faire quelque chose comme:

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

(remplacer x1, y1, x2 et y2 avec des valeurs appropriées) ...

-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

Cela ne fonctionne pas - Dessine à son tour une ligne marron sur une image – Shailesh

Questions connexes