在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]; }
现在你有点L
, T1
, T2
。 从这里有很多方法来检测线路是否被击中。 我最喜欢的是首先使用点积来看看印刷机是否接近这样的行:
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; }
希望这是有帮助的。