如何画一个NSImage像图像在NSButtons(有深度)? [英] How to draw a NSImage like images in NSButtons (with a deepness)?

查看:266
本文介绍了如何画一个NSImage像图像在NSButtons(有深度)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以在NSButtons或其他可爱界面元素中绘制像NSImage的图像?

Is there any way to draw an NSImage like images in NSButtons or other cocoa interface elements?

以下是示例:

Here are examples:

Apple使用带有黑色图标的pdf:

Apple uses pdf's with black icons:

推荐答案

如果您只是想要应用此效果在按钮中使用您自己的图像,使用 [myImage setTemplate:YES] 。没有内置的方法可以在具有截图中所示样式的按钮之外使用此效果绘制图像。

If you simply want this effect to be applied when you use your own images in a button, use [myImage setTemplate:YES]. There is no built-in way to draw images with this effect outside of a button that has the style shown in your screenshots.

然而,您可以使用Core Graphics复制效果。如果你仔细看,效果包括一个水平渐变,一个白色阴影和一个黑暗的内部阴影(后者是最困难的)。

You can however replicate the effect using Core Graphics. If you look closely, the effect consists of a horizontal gradient, a white drop shadow and a dark inner shadow (the latter is the most difficult).

你可以实现这个作为 NSImage 上的类别:

You could implement this as a category on NSImage:

//NSImage+EtchedDrawing.h:
@interface NSImage (EtchedImageDrawing)    
- (void)drawEtchedInRect:(NSRect)rect;
@end

//NSImage+EtchedDrawing.m:
@implementation NSImage (EtchedImageDrawing)

- (void)drawEtchedInRect:(NSRect)rect
{
    NSSize size = rect.size;
    CGFloat dropShadowOffsetY = size.width <= 64.0 ? -1.0 : -2.0;
    CGFloat innerShadowBlurRadius = size.width <= 32.0 ? 1.0 : 4.0;

    CGContextRef c = [[NSGraphicsContext currentContext] graphicsPort];

    //save the current graphics state
    CGContextSaveGState(c);

    //Create mask image:
    NSRect maskRect = rect;
    CGImageRef maskImage = [self CGImageForProposedRect:&maskRect context:[NSGraphicsContext currentContext] hints:nil];

    //Draw image and white drop shadow:
    CGContextSetShadowWithColor(c, CGSizeMake(0, dropShadowOffsetY), 0, CGColorGetConstantColor(kCGColorWhite));
    [self drawInRect:maskRect fromRect:NSMakeRect(0, 0, self.size.width, self.size.height) operation:NSCompositeSourceOver fraction:1.0];

    //Clip drawing to mask:
    CGContextClipToMask(c, NSRectToCGRect(maskRect), maskImage);

    //Draw gradient:
    NSGradient *gradient = [[[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceWhite:0.5 alpha:1.0]
                                                          endingColor:[NSColor colorWithDeviceWhite:0.25 alpha:1.0]] autorelease];
    [gradient drawInRect:maskRect angle:90.0];
    CGContextSetShadowWithColor(c, CGSizeMake(0, -1), innerShadowBlurRadius, CGColorGetConstantColor(kCGColorBlack));

    //Draw inner shadow with inverted mask:
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef maskContext = CGBitmapContextCreate(NULL, CGImageGetWidth(maskImage), CGImageGetHeight(maskImage), 8, CGImageGetWidth(maskImage) * 4, colorSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colorSpace);
    CGContextSetBlendMode(maskContext, kCGBlendModeXOR);
    CGContextDrawImage(maskContext, maskRect, maskImage);
    CGContextSetRGBFillColor(maskContext, 1.0, 1.0, 1.0, 1.0);
    CGContextFillRect(maskContext, maskRect);
    CGImageRef invertedMaskImage = CGBitmapContextCreateImage(maskContext);
    CGContextDrawImage(c, maskRect, invertedMaskImage);
    CGImageRelease(invertedMaskImage);
    CGContextRelease(maskContext);

    //restore the graphics state
    CGContextRestoreGState(c);
}

@end

视图中的用法示例:

- (void)drawRect:(NSRect)dirtyRect
{
    [[NSColor colorWithDeviceWhite:0.8 alpha:1.0] set];
    NSRectFill(self.bounds);

    NSImage *image = [NSImage imageNamed:@"MyIcon.pdf"];
    [image drawEtchedInRect:self.bounds];
}

这将给你以下结果$ b

This would give you the following result (shown in different sizes):

您可能需要位与两个阴影的渐变颜色和偏移/模糊半径以更接近原始效果。

You may need to experiment a bit with the gradient colors and offset/blur radius of the two shadows to get closer to the original effect.

这篇关于如何画一个NSImage像图像在NSButtons(有深度)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆