如何在圆形贝塞尔曲线路径内绘制图像

时间:2014-12-25 14:03:31

标签: ios objective-c core-graphics

我正在尝试创建自定义视图,以便在CD上绘制带有专辑插图的音乐CD。

目前我使用核心图形在drawRect方法中绘制两个圆形磁盘。内部磁盘的颜色设置为视图的背景颜色,使其看起来像一个空心圆圈。

我的问题是我无法在圆形贝塞尔曲线路径中绘制UIImage以获得我需要的结果。

这是我的drawRect代码:

// Draw a CD like view using three drawing operations:
// 1st draw the main disk
// 2nd draw the image if it is set
// 3rd draw the inner disk over the image so that it looks like it is a hollow disk with the image painted on the disk.
// Note:) This view expects its aspect ratio to be set as 1:1
- (void)drawRect:(CGRect)rect
{
    // Draw the main Circular CD disk
    UIBezierPath* outerRing = [UIBezierPath bezierPathWithOvalInRect:self.bounds];

    [self.mainColor setFill];
    [outerRing fill];

    [self.outerRingColor setStroke];
    [outerRing stroke];

    // Draw the album image if it is set
    if(self.artwork){
        [self.artwork drawInRect:self.bounds blendMode:kCGBlendModeNormal alpha:1.0];
    }

    // now draw another smaller disk inside
    // this will be a percentage smaller than the whole disk's bounds and will be centered inside it
    CGFloat sidePaddingCoord = ((1.0f - INNER_DISK_SIZE_PERCENTAGE) / 2) * self.bounds.size.height;
    CGFloat side = INNER_DISK_SIZE_PERCENTAGE * self.bounds.size.width;

    UIBezierPath* innerRing = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(sidePaddingCoord, sidePaddingCoord, side, side)];

    [self.innerRingColor setFill];
    [innerRing fill];

    [innerRing stroke];
}

将图像填充为正方形。我希望将图像剪切到 outerRing bezier路径中,使其看起来像音乐CD。

我确信除了使用图片的drawInRect方法之外,还有一种方法可以使用核心图形来实现其他目的。有什么方法可以剪辑'圆形贝塞尔曲线路径内的图像或仅在贝塞尔曲线路径内绘制?

2 个答案:

答案 0 :(得分:2)

我已经阅读了rob mayoff,UIBezierPath Subtract PathiOS UIImage clip to paths的精彩帖子,非常感谢。

这是他的代码的采用。保留outerRinginnerRing的创建代码,将其添加到名为paths的数组中。

[self.paths addObject:outerRing];
[self.paths addObject:innerRing];

然后使用此帮助方法。

- (UIImage *)maskedImage
{
    CGRect rect = CGRectZero;
    rect.size = self.originalImage.size;
    UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0);

    UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:CGRectInfinite];
    [clipPath appendPath:self.paths[1]];
    clipPath.usesEvenOddFillRule = YES;

    CGContextSaveGState(UIGraphicsGetCurrentContext()); {
        [clipPath addClip];
        [[UIColor orangeColor] setFill];
        [self.paths[0] fill];
    } CGContextRestoreGState(UIGraphicsGetCurrentContext());

    UIImage *mask = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0); {
        CGContextClipToMask(UIGraphicsGetCurrentContext(), rect, mask.CGImage);
        [self.originalImage drawAtPoint:CGPointZero];
    }
    UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return maskedImage;
}

drawRect

UIImage *maskedImage = [self maskedImage];
[maskedImage drawInRect:self.bounds blendMode:kCGBlendModeNormal alpha:1.0];

答案 1 :(得分:-1)

尝试以下代码:

    UIImageView *userImageView= [[UIImageView alloc] initWithFrame:CGRectMake(85, 55.0, 90, 90)];
    userImageView.layer.cornerRadius = 90/2;
    userImageView.clipsToBounds = YES;
    userImageView.layer.borderWidth = 1.0f;
    userImageView.layer.borderColor = [UIColor blueColor];
    [self.view addSubview:userImageView]; //or add it to the view you want
    UIImage *userImage = [UIImage imageNamed:@"<image you want to set>"];
    userImageView= [[UIImageView alloc] initWithFrame:CGRectMake(90, 60.0, 80, 80)];
    userImageView.image = userImage;
    userImageView.layer.cornerRadius = 80/2;
    userImageView.clipsToBounds = YES;
    userImageView.layer.borderWidth = 1.0f;
    userImageView.layer.borderColor = [UIColor blueColor;
    [self.view addSubview:userImageView]; //or add it to the view you want