在ios中从UIImage中删除行

我在UIImageView中有一个图像。 我已经成功地在图像上画线。现在我想要移除那个用户将执行长按手势的特定线。 我怎样才能做到这一点 ? 我的代码是:

{

// gets the location in the form of (x,y) coordinates CGPoint location=[sender locationInView:imageView]; // convetrs the location relative to the image CGPoint contextLocation = CGPointMake(location.x*imageView.image.size.width/imageView.frame.size.width, location.y*imageView.image.size.height/imageView.frame.size.height); // converts the location point into NSValue NSValue *imagePoint=[NSValue valueWithCGPoint:contextLocation]; // Adds the image into NSMutable Array [imageLocations addObject:imagePoint]; // color of line UIColor * linearcolor=[UIColor blueColor]; UIGraphicsBeginImageContext(imageView.image.size); [imageView.image drawAtPoint:CGPointMake(0, 0)]; CGContextRef context=UIGraphicsGetCurrentContext(); // Brush widt CGContextSetLineWidth(context, 3.0); // Line Color CGContextSetStrokeColorWithColor(context, [linearcolor CGColor]); // Hard coded point for location 2 CGPoint location2=CGPointMake(300, 400); CGContextMoveToPoint(context, contextLocation.x, contextLocation.y); CGContextAddLineToPoint(context, location2.x, location2.y); CGContextStrokePath(context); newImage=UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); imageView.image=newImage; } 

你需要做的是find行按下,并从你拥有的点数组中删除,然后用线条重画整个图像。

我想问题是如何find正确的路线:

比方说,你有一个位置从手势获得。 那么你需要的是遍历所有的点对,如

 for(NSInteger i=0; i< imageLocations.count.count-1; i+=2) { CGPoint T1 = [imageLocations[i] CGPointValue]; CGPoint T2 = [imageLocations[i+1] CGPointValue]; } 

现在你有点LT1T2 。 从这里有很多方法来检测线路是否被击中。 我最喜欢的是首先使用点积来看看印刷机是否接近这样的行:

 CGFloat dotValue = dot(normalized(T1-L), normalized(T2-L)) 

在线查找点积和点的标准化程序。 现在dotValue应该接近-1被击中的行。 你应该使用像if(dotValue > -.7f) continue; 沿着线路去除所有距离印刷机太远的线路。

接下来是实际find点的距离。 这实际上是一个交叉产品的Z分量:

 CGFloat crossValue = fabsf(cross((L-T1), normalized(T2-T1)).z); 

我知道你没有Z组件如此使用:

 crossValue = Ax*By - Ay*Bx 

所以现在你已经拥有了所有的这些伪代码应该是这样的:

 CGPoint L; NSInteger bestLineIndex = -1; CGFloat bestLineDistance = 10000.0f; // something large for (CGPoint T1, T2; NSInteger index) { dotValue = ... if(dotValue < -.7) { crossValue = ... if(crossValue < bestLineDistance) { bestLineDistance = crossValue; bestLineIndex = index; } } } 

所以最后你有你的第一个线点的索引,如果不是-1(如果在触摸点附近没有find-1的话)应该被删除。

对于使用叉积的点的线距:

 - (CGFloat)distanceBetweenPoint:(CGPoint)L andLineWithStart:(CGPoint)T1 end:(CGPoint)T2 { CGPoint T1toL = CGPointMake(Lx-T1.x, Ly-T1.y); CGPoint T2toL = CGPointMake(Lx-T2.x, Ly-T2.y); CGFloat T2toLDistance = sqrt(T2toL.x*T2toL.x + T2toL.y*T2toL.y); CGPoint T2toLNormalized = CGPointMake(T2toL.x/T2toLDistance, T2toL.y/T2toLDistance); CGFloat zComponentOfCross = T1toL.x*T2toLNormalized.y - T1toL.y*T2toLNormalized.x; return fabs(zComponentOfCross); } 

这很简单。 我将下面的代码添加为您的问题。

 // gets the location in the form of (x,y) coordinates CGPoint location=[sender locationInView:imageView]; // convetrs the location relative to the image CGPoint contextLocation = CGPointMake(location.x*imageView.image.size.width/imageView.frame.size.width, location.y*imageView.image.size.height/imageView.frame.size.height); // converts the location point into NSValue NSValue *imagePoint=[NSValue valueWithCGPoint:contextLocation]; // Adds the image into NSMutable Array [imageLocations addObject:imagePoint]; // color of line UIColor * linearcolor=[UIColor blueColor]; UIGraphicsBeginImageContext(imageView.image.size); [imageView.image drawAtPoint:CGPointMake(0, 0)]; CGContextRef context=UIGraphicsGetCurrentContext(); // Brush widt CGContextSetLineWidth(context, 3.0); **CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);** // Hard coded point for location 2 CGPoint location2=CGPointMake(300, 400); CGContextMoveToPoint(context, contextLocation.x, contextLocation.y); CGContextAddLineToPoint(context, location2.x, location2.y); CGContextStrokePath(context); newImage=UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); imageView.image=newImage; } 

希望这是有帮助的。