回答
下面的一组例行程序创建一个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];
}
谢谢!所有地区都是已知的。 – Andrey05 2012-04-10 17:58:21
为什么不画uiiview? UIImage * image = [self maskImage:beginImage toAreaInsidePath:Figure]; [image drawAtPoint:CGPointZero]; – Andrey05 2012-04-11 12:32:37
请详细解释。你是否试图在UIView中显示图像?如果是这样,将这两行放在'drawRect'方法内应该可以工作。 – Dondragmer 2012-04-11 12:51:45
这可以做,但它需要一些三角。让我们考虑一下上面的图像。首先,确定UIBezierPath
的最底端点,并使用UIGraphicsBeginImageContext
获取图像上方的顶部。这将如下所示:
现在,假设你的线是直的,沿着画线的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_x
。 next_y_point_on_your_line
的计算方法如下:
next_y_point_on_your_line = m*currentPixel_x + c
每个垂直stroke
为1个像素宽和高度将取决于你通过他们如何穿越。一些迭代后,你的图像看起来大致(请原谅我那可怜的照片编辑技能!),如:
有你如何画明确招多种方式,这只是一种方式去关于它。如果给出更好的结果,您也可以使用与给定路径平行的清晰笔划。
另一种方法是该线下方的像素的阿尔法设置为0。
非常感谢! – Andrey05 2012-04-10 13:25:13
我测试的剪裁,并在几个不同的测试中,它比屏蔽来实现相同的结果,我在其他的答案[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;
}
你的意思是你有一个UIBezierPath存储行?它是(1)一条线,还是(2)围绕图像右上部分的闭合曲线?如果(2),您可以在裁剪路径时将图像绘制到新的图像上下文中。 – Dondragmer 2012-04-10 12:21:08
已知整个上图。这可能更详细吗? – Andrey05 2012-04-10 12:38:28