我有一个功能,用户可以绘制/着色图像的特定区域,然后将绘制区域作为裁剪结果。
目前我将绘制坐标存储在一个数组中,在该过程的最后,我使用 UIBezierPath 和 CGContextClipToMask 来裁剪图像。问题是我只需要存储在数组中的绘制坐标的外部坐标。有没有办法过滤CGPoints只能得到外部坐标?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// add the first coordinate
[points addObject:[NSValue valueWithCGPoint:lastPoint]];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// add more coordinates as finger moves
[points addObject:[NSValue valueWithCGPoint:currentPoint]];
}
- (void) crop {
CGRect rect = CGRectZero;
rect.size = self.mainImage.image.size;
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0);
{
[[UIColor blackColor] setFill];
UIRectFill(rect);
[[UIColor whiteColor] setFill];
UIBezierPath * beziPath = [UIBezierPath bezierPath];
NSValue * firstValue = [points objectAtIndex:0];
CGPoint firstPoint = firstValue.CGPointValue;
[beziPath moveToPoint:[ARCroppingViewController
convertCGPoint:firstPoint fromRect1:self.mainImage.frame.size
toRect2:self.mainImage.image.size]];
for (uint i = 1; i < points.count; i++) {
NSValue * value = [points objectAtIndex:i];
CGPoint point = value.CGPointValue;
NSLog(@"point: %@", NSStringFromCGPoint(point));
[beziPath addLineToPoint:[ARCroppingViewController
convertCGPoint:point fromRect1:self.mainImage.frame.size
toRect2:self.mainImage.image.size]];
}
[beziPath closePath];
[beziPath fill];
}
UIImage *mask = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);
{
CGContextClipToMask(UIGraphicsGetCurrentContext(), rect, mask.CGImage);
[self.mainImage.image drawAtPoint:CGPointZero];
}
UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(@"mask image: %@", NSStringFromCGSize(maskedImage.size));
self.mainImage.image = maskedImage;
}
答案 0 :(得分:0)
为了获得优势,我会在保存阶段保存极值(向数组添加点)。因此保持最高和最低的x和y值。认为它比过滤数组更容易:)
修改的
int xMin, xMax, yMin, yMax;
-(void)resetValues
{
xMax = yMax = 0;
xMin = yMin = self.mainImage.image.size.width;
}
- (void)checkForExtremes:(CGPoint)point
{
// Have my IDE not here for checking the MIN() and MAX(), so using this way :P
lastPoint.x > xMax ? xMax = lastPoint.x : nil;
lastPoint.x < xMin ? xMin = lastPoint.x : nil;
lastPoint.y > yMax ? yMax = lastPoint.y : nil;
lastPoint.y < yMin ? yMin = lastPoint.y : nil;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// add the first coordinate
[points addObject:[NSValue valueWithCGPoint:lastPoint]];
[self checkForExtremes:lastPoint];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// add more coordinates as finger moves
[points addObject:[NSValue valueWithCGPoint:currentPoint]];
[self checkForExtremes:currentPoint];
}
然后,结果是
答案 1 :(得分:0)
只需循环遍历点(就像现在一样)但检查每个点并存储x和y值的最大值和最小值。然后在循环结束时,您可以在(现在正方形)选定区域的角落处获得4个点。
CGFloat minX, maxX, minY, maxY;
for (... {
minX = MIN(minX, point.x);
maxX = ...
}
CGPoint topLeft = CGPointMake(minX, minY);
CGPoint topRight = ...
您还可以在用户跟踪形状时执行这些计算(您也可以修改贝塞尔曲线路径)。