Cocoa 绘制带有圆角和阴影的图像

发布于 2024-10-10 16:53:01 字数 372 浏览 7 评论 0原文

我正在尝试使用核心图形绘制图像,使其具有圆角和阴影。这是我的代码片段:

CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 2, shadowColor);    
CGContextAddPath(context, path);
CGContextClip(context);
CGContextDrawImage(context, rect, image);

我遇到的问题是创建圆角的剪切也会剪切阴影。由于图像的某些区域可能是透明的,因此我不能简单地在图像下方绘制带有阴影的圆角矩形。我想我需要先将圆形形状应用于图像,然后将生成的图像绘制到屏幕上并添加阴影。有谁知道该怎么做?

谢谢!

I am trying to draw an image using core graphics such that it has rounded corners and a drop shadow. Here is a snippet of my code:

CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 2, shadowColor);    
CGContextAddPath(context, path);
CGContextClip(context);
CGContextDrawImage(context, rect, image);

The problem I am having is that the clipping to create the rounded corners is also clipping the shadow. Since the image may be transparent in areas, I cannot simply draw the rounded rectangle with a shadow under the image. I guess I need to apply the rounded shape to the image first, and then draw the resulting image to the screen and add the shadow. Does anyone know how to do this?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

唯憾梦倾城 2024-10-17 16:53:01

好吧,假设你有一个 UIView 子类,它有一个实例变量 image,它是一个 UIImage,那么你可以像这样执行你的 drawRect: 函数...

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGRect _bounds = [self bounds];
    CGColorRef aColor;
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Create a path
    CGRect insetRect = CGRectInset(_bounds, kBSImageButtonBorder, kBSImageButtonBorder);
    CGRect offsetRect = insetRect; offsetRect.origin = CGPointZero;

    UIGraphicsBeginImageContext(insetRect.size);
    CGContextRef imgContext = UIGraphicsGetCurrentContext();
    CGPathRef clippingPath = [UIBezierPath bezierPathWithRoundedRect:offsetRect cornerRadius:CORNER_RADIUS].CGPath; 
    CGContextAddPath(imgContext, clippingPath);
    CGContextClip(imgContext);  
    // Draw the image
    [image drawInRect:offsetRect];
    // Get the image
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Setup the shadow
    aColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.5f].CGColor;
    CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 2.0f), 2.0f, aColor);     

    // Draw the clipped image in the context
    [img drawInRect:insetRect];

}

我自己对 Quartz 编程有点陌生,但是那应该给你你的图像,以矩形为中心,减去边框,带有角半径,并且在其下方有一个 2.f 点阴影 2.f 点。希望有帮助。

Okay, so assuming that you have a UIView subclass, which has an instance variable, image, which is a UIImage, then you can do your drawRect: function like so...

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGRect _bounds = [self bounds];
    CGColorRef aColor;
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Create a path
    CGRect insetRect = CGRectInset(_bounds, kBSImageButtonBorder, kBSImageButtonBorder);
    CGRect offsetRect = insetRect; offsetRect.origin = CGPointZero;

    UIGraphicsBeginImageContext(insetRect.size);
    CGContextRef imgContext = UIGraphicsGetCurrentContext();
    CGPathRef clippingPath = [UIBezierPath bezierPathWithRoundedRect:offsetRect cornerRadius:CORNER_RADIUS].CGPath; 
    CGContextAddPath(imgContext, clippingPath);
    CGContextClip(imgContext);  
    // Draw the image
    [image drawInRect:offsetRect];
    // Get the image
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Setup the shadow
    aColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.5f].CGColor;
    CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 2.0f), 2.0f, aColor);     

    // Draw the clipped image in the context
    [img drawInRect:insetRect];

}

I'm a little new to Quartz programming myself, but that should give you your image, centered in the rectangle, minus a border, with a corner radius, and a 2.f point shadow 2.f points below it. Hope that helps.

追我者格杀勿论 2024-10-17 16:53:01

这是一个使用 Daniel Thorpe 的答案来圆化图像角的函数,以防你像我一样来到这里,只是在寻找一种方法来做到这一点。

+ (UIImage *) roundCornersOfImage:(UIImage *)image toRadius:(float)radius {

    // create image sized context
    UIGraphicsBeginImageContext(image.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    // add rounded rect clipping path to context using radius
    CGRect imageBounds = CGRectMake(0, 0, image.size.width, image.size.height);
    CGPathRef clippingPath = [UIBezierPath bezierPathWithRoundedRect:imageBounds cornerRadius:radius].CGPath;
    CGContextAddPath(context, clippingPath);
    CGContextClip(context);

    // draw the image
    [image drawInRect:imageBounds];

    // get the image
    UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return outImage;
}

Here is a function to round the corners of an image using Daniel Thorpe's answer, in case you came here, like me, just looking for a way to do this.

+ (UIImage *) roundCornersOfImage:(UIImage *)image toRadius:(float)radius {

    // create image sized context
    UIGraphicsBeginImageContext(image.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    // add rounded rect clipping path to context using radius
    CGRect imageBounds = CGRectMake(0, 0, image.size.width, image.size.height);
    CGPathRef clippingPath = [UIBezierPath bezierPathWithRoundedRect:imageBounds cornerRadius:radius].CGPath;
    CGContextAddPath(context, clippingPath);
    CGContextClip(context);

    // draw the image
    [image drawInRect:imageBounds];

    // get the image
    UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return outImage;
}
拿命拼未来 2024-10-17 16:53:01

您可以将 imageView 与图层一起使用,该图层具有用于设置阴影和边框的属性,方法如下:

    self.imageView = [[NSImageView alloc] initWithFrame:NSMakeRect(0,0,60,60)];
    self.imageView.image = [NSImage imageNamed:@"yourImageName"];
    self.imageView.wantsLayer = YES;
    self.imageView.layer.cornerRadius = 10;
    //make the shadow and set it
    NSShadow* shadow = [[NSShadow alloc] init];
    shadow.shadowBlurRadius = 2;
    shadow.shadowOffset = NSMakeSize(2, -2);
    shadow.shadowColor = [NSColor blackColor];
    self.imageView.shadow = shadow;

希望这会有所帮助,这比使用 drawRect 覆盖绘制起来要快得多

You can use an imageView with a layer, the layer has properties for setting shadows and borders, this is how:

    self.imageView = [[NSImageView alloc] initWithFrame:NSMakeRect(0,0,60,60)];
    self.imageView.image = [NSImage imageNamed:@"yourImageName"];
    self.imageView.wantsLayer = YES;
    self.imageView.layer.cornerRadius = 10;
    //make the shadow and set it
    NSShadow* shadow = [[NSShadow alloc] init];
    shadow.shadowBlurRadius = 2;
    shadow.shadowOffset = NSMakeSize(2, -2);
    shadow.shadowColor = [NSColor blackColor];
    self.imageView.shadow = shadow;

Hope this helps, this is also much faster to draw then using drawRect overrides

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文