2012-04-10 101 views
2

如何将黑线分成UIImage两部分。上轮廓集合UIBezierPath沿着UIBezierPath将UIImage分成两部分

我需要得到两个结果UIImage秒。那有可能吗?

+0

你的意思是你有一个UIBezierPath存储行?它是(1)一条线,还是(2)围绕图像右上部分的闭合曲线?如果(2),您可以在裁剪路径时将图像绘制到新的图像上下文中。 – Dondragmer 2012-04-10 12:21:08

+0

已知整个上图。这可能更详细吗? – Andrey05 2012-04-10 12:38:28

回答

7

下面的一组例行程序创建一个UIImage的版本与或者仅内部内容的路径,或仅含量那条路径。

两者均使用使用CGBlendMode的compositeImage方法。 CGBlendMode非常强大,可以屏蔽任何可以绘制的任何东西。调用compositeImage:与其他混合模式可以有趣的(如果不总是有用的)效果。所有模式请参阅CGContext Reference

我在你对OP的评论中描述的裁剪方法确实有效,并且速度可能更快,但前提是你的UIBezierPaths定义了你想要裁剪的所有区域。

- (UIImage*) compositeImage:(UIImage*) sourceImage onPath:(UIBezierPath*) path usingBlendMode:(CGBlendMode) blend; 
{ 
    // Create a new image of the same size as the source. 
    UIGraphicsBeginImageContext([sourceImage size]); 

    // First draw an opaque path... 
    [path fill]; 
    // ...then composite with the image. 
    [sourceImage drawAtPoint:CGPointZero blendMode:blend alpha:1.0]; 

    // With drawing complete, store the composited image for later use. 
    UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext(); 

    // Graphics contexts must be ended manually. 
    UIGraphicsEndImageContext(); 

    return maskedImage; 
} 

- (UIImage*) maskImage:(UIImage*) sourceImage toAreaInsidePath:(UIBezierPath*) maskPath; 
{ 
    return [self compositeImage:sourceImage onPath:maskPath usingBlendMode:kCGBlendModeSourceIn]; 
} 

- (UIImage*) maskImage:(UIImage*) sourceImage toAreaOutsidePath:(UIBezierPath*) maskPath; 
{ 
    return [self compositeImage:sourceImage onPath:maskPath usingBlendMode:kCGBlendModeSourceOut]; 
} 
+0

谢谢!所有地区都是已知的。 – Andrey05 2012-04-10 17:58:21

+0

为什么不画uiiview? UIImage * image = [self maskImage:beginImage toAreaInsidePath:Figure]; [image drawAtPoint:CGPointZero]; – Andrey05 2012-04-11 12:32:37

+0

请详细解释。你是否试图在UIView中显示图像?如果是这样,将这两行放在'drawRect'方法内应该可以工作。 – Dondragmer 2012-04-11 12:51:45

2

这可以做,但它需要一些三角。让我们考虑一下上面的图像。首先,确定UIBezierPath的最底端点,并使用UIGraphicsBeginImageContext获取图像上方的顶部。这将如下所示:

Top portion

现在,假设你的线是直的,沿着画线的clearColor(环路顶部垂直stroke s个像素移动像素进到类似的线底部。 ):

for(int currentPixel_x=0;currentPixel_x<your_ui_image_top.size.width) 
    UIGraphicsBeginImageContext(your_ui_image_top.size); 
    [your_ui_image_top drawInRect:CGRectMake(0, 0, your_ui_image_top.size.width, your_ui_image_top.size.height)]; 
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1.0); 
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeClear); 
    CGContextSetStrokeColorWithColor(UIGraphicsGetCurrentContext(),[UIColor clearColor].CGColor); 
    CGContextBeginPath(UIGraphicsGetCurrentContext()); 
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), currentPixel_x, m*currentPixel_x + c); 
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPixel_x, your_ui_image_top.size.height); 
    CGContextStrokePath(UIGraphicsGetCurrentContext()); 
    your_ui_image_top = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
} 

UIBezierPath将转换为表格y = m*x + c的直线。这个公式中的x将在上面的currentPixel_x。遍历整个图像的宽度,每次增加currentPixel_xnext_y_point_on_your_line的计算方法如下:

next_y_point_on_your_line = m*currentPixel_x + c 

每个垂直stroke为1个像素宽和高度将取决于你通过他们如何穿越。一些迭代后,你的图像看起来大致(请原谅我那可怜的照片编辑技能!),如:

enter image description here

有你如何画明确招多种方式,这只是一种方式去关于它。如果给出更好的结果,您也可以使用与给定路径平行的清晰笔划。

另一种方法是该线下方的像素的阿尔法设置为0。

+0

非常感谢! – Andrey05 2012-04-10 13:25:13

2

我测试的剪裁,并在几个不同的测试中,它比屏蔽来实现相同的结果,我在其他的答案[maskImage: toAreaInsidePath:]方法较慢25%。为了保持完整性,我将它包含在这里,但请不要在没有充分理由的情况下使用它。

- (UIImage*) clipImage:(UIImage*) sourceImage toPath:(UIBezierPath*) path; 
{ 
    // Create a new image of the same size as the source. 
    UIGraphicsBeginImageContext([sourceImage size]); 

    // Clipping means drawing only happens within the path. 
    [path addClip]; 

    // Draw the image to the context. 
    [sourceImage drawAtPoint:CGPointZero]; 

    // With drawing complete, store the composited image for later use. 
    UIImage *clippedImage = UIGraphicsGetImageFromCurrentImageContext(); 

    // Graphics contexts must be ended manually. 
    UIGraphicsEndImageContext(); 

    return clippedImage; 
}