ios - poner - Cómo dibujar un trazo transparente(o, de todos modos, borrar parte de una imagen) en el iPhone
organizar apps iphone (5)
Esto hará el truco:
CGContextSetBlendMode(context, kCGBlendModeClear)
Tengo una pequeña aplicación que permite al usuario dibujar en la pantalla con el dedo. Tengo un UIImageView
donde el usuario dibuja, creando un CGContextRef
y las diversas funciones de CG draw
. Principalmente dibujo trazos / líneas con la función CGContextAddLineToPoint
Ahora mi problema es este: el usuario puede dibujar líneas de varios colores. Quiero darle la posibilidad de usar una herramienta de "rubber"
para eliminar alguna parte de la imagen dibujada hasta ahora, con el dedo. Inicialmente hice esto usando un color blanco para el trazo (configurado con la función CGContextSetRGBStrokeColor
) pero no funcionó ... porque más tarde descubrí que el UIImage
en el UIImageView
realidad tenía un fondo transparente, no blanco ... ¡Así que terminaría con una imagen transparente con líneas blancas!
¿Hay alguna forma de establecer un color de trazo "transparent"
o hay alguna otra forma de borrar el contenido de CGContextRef
bajo el dedo del usuario, cuando lo mueve? Gracias
He intentado usar:
CGContextSetStrokeColorWithColor (myContext, [[UIColor clearColor] CGColor]);
pero eso no funciona, porque parece estar "dibujando" en la parte superior del contexto con un color invisible (y un color invisible + cualquier color en el que esté dibujando = el color en el que está dibujando).
La única solución que he encontrado (que no es óptima) es:
CGContextClearRect (myContext, CGRectMake(x, y, width, height));
Desafortunadamente, eso significa que tienes que rastrear una serie de rectas y generar la línea tú mismo ...
Terminé usando el algoritmo de línea de Bresenham (recordando los tiempos de antaño cuando tuve que escribir mis propias rutinas gráficas) ...
- (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);
}
}
}
¡Uf! Eso es un largo camino por recorrer para crear una línea de borradores torpes (algo).
Para usarlo, haz algo como:
- (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];
}
Esto supone que ya ha creado un drawingView (UIImageView) y drawingBoard (UIImage).
Luego, para borrar una línea, simplemente haga algo como:
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self eraseStart];
[self contextEraseLine:ctx from:CGPointMake (x1, y1) to:CGPointMake (x2, y2) withThickness:10];
[self eraseEnd];
(Reemplace x1, y1, x2 e y2 con los valores apropiados) ...
//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;
}
}
UIColor *clearColor = [UIColor clearColor];