CGContextSetFill 带渐变
CGContextSetFill with gradient
我现在有一个可以画二维码的功能
+ (void)drawQRCode:(QRcode *)code context:(CGContextRef)ctx size:(CGFloat)size {}
目前,我可以使用以下方法设置包括色彩空间在内的颜色:
CGContextSetFillColorWithColor(ctx, [theColor colorUsingColorSpaceName:NSCalibratedWhiteColorSpace].CGColor);
我正在尝试实现创建渐变的功能我已将两个 NSColors
转换为 NSGradient
- 似乎没有任何方法可以将渐变作为 NSColor
所以我想知道用渐变设置上下文填充的最佳方法是什么?
提前感谢您的任何建议!
CGContext 有 drawLinearGradient
https://developer.apple.com/documentation/coregraphics/cgcontext/1454782-drawlineargradient
和drawRadialGradient
https://developer.apple.com/documentation/coregraphics/cgcontext/1455923-drawradialgradient
要使用它们来填充形状,请将形状的路径放入上下文中,然后在绘制渐变之前将形状用作剪切路径。
下面是演示该技术的视图中的 drawRect:
- (void) drawRect: (CGRect) rect {
CGColorRef myColors[3] = {
[[UIColor redColor] CGColor],
[[UIColor yellowColor] CGColor],
[[UIColor blueColor] CGColor] };
CGFloat locations[3] = { 0.0, 0.25, 1.0 };
CGRect circleRect = CGRectInset([self bounds], 20, 20);
CGFloat circleRadius = circleRect.size.width / 2.0;
CGContextRef cgContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(cgContext);
CGContextSetFillColorWithColor(cgContext, [[UIColor blackColor] CGColor]);
CGContextFillRect(cgContext, [self bounds]);
CGContextRestoreGState(cgContext);
CGContextSaveGState(cgContext);
CGContextAddEllipseInRect(cgContext, circleRect);
CGContextClip(cgContext);
CGContextTranslateCTM(cgContext, CGRectGetMidX(circleRect), CGRectGetMidY(circleRect));
CGContextRotateCTM(cgContext, M_PI / 3.0);
CFArrayRef colors = CFArrayCreate(nil, (const void**) myColors, 3, &kCFTypeArrayCallBacks);
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, colors, locations);
CFRelease(colors);
CFRelease(colorSpace);
CGContextDrawLinearGradient(cgContext, gradient, CGPointMake(-circleRadius, 0),
CGPointMake(circleRadius, 0), kCGGradientDrawsAfterEndLocation + kCGGradientDrawsBeforeStartLocation);
CFRelease(gradient);
CGContextRestoreGState(cgContext);
}
这是 Swift 中的等效游乐场。
import UIKit
import PlaygroundSupport
class CircleGradientView : UIView {
override func draw(_ rect: CGRect) {
let colors = [
UIColor.red.cgColor,
UIColor.yellow.cgColor, // Yellow
UIColor.blue.cgColor // Blue
]
let colorSpace = CGColorSpace(name: CGColorSpace.sRGB)!
let locations : [CGFloat] = [0.0, 0.25, 1.0]
let gradient = CGGradient(colorsSpace: colorSpace,
colors: colors as CFArray,
locations: locations)
if let context = UIGraphicsGetCurrentContext() {
let circleRect = self.bounds.insetBy(dx: 20, dy: 20)
let circleRadius = circleRect.width / 2.0
context.saveGState()
context.addEllipse(in: circleRect)
context.clip()
context.translateBy(x: circleRect.midX, y: circleRect.midY)
context.rotate(by: .pi / 3.0)
context.drawLinearGradient(gradient!,
start: CGPoint(x: -circleRadius, y: 0),
end: CGPoint(x: circleRadius, y: 0),
options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
context.restoreGState()
}
}
}
let myView = CircleGradientView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
PlaygroundSupport.PlaygroundPage.current.liveView = myView
我现在有一个可以画二维码的功能
+ (void)drawQRCode:(QRcode *)code context:(CGContextRef)ctx size:(CGFloat)size {}
目前,我可以使用以下方法设置包括色彩空间在内的颜色:
CGContextSetFillColorWithColor(ctx, [theColor colorUsingColorSpaceName:NSCalibratedWhiteColorSpace].CGColor);
我正在尝试实现创建渐变的功能我已将两个 NSColors
转换为 NSGradient
- 似乎没有任何方法可以将渐变作为 NSColor
所以我想知道用渐变设置上下文填充的最佳方法是什么?
提前感谢您的任何建议!
CGContext 有 drawLinearGradient
https://developer.apple.com/documentation/coregraphics/cgcontext/1454782-drawlineargradient
和drawRadialGradient
https://developer.apple.com/documentation/coregraphics/cgcontext/1455923-drawradialgradient
要使用它们来填充形状,请将形状的路径放入上下文中,然后在绘制渐变之前将形状用作剪切路径。
下面是演示该技术的视图中的 drawRect:
- (void) drawRect: (CGRect) rect {
CGColorRef myColors[3] = {
[[UIColor redColor] CGColor],
[[UIColor yellowColor] CGColor],
[[UIColor blueColor] CGColor] };
CGFloat locations[3] = { 0.0, 0.25, 1.0 };
CGRect circleRect = CGRectInset([self bounds], 20, 20);
CGFloat circleRadius = circleRect.size.width / 2.0;
CGContextRef cgContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(cgContext);
CGContextSetFillColorWithColor(cgContext, [[UIColor blackColor] CGColor]);
CGContextFillRect(cgContext, [self bounds]);
CGContextRestoreGState(cgContext);
CGContextSaveGState(cgContext);
CGContextAddEllipseInRect(cgContext, circleRect);
CGContextClip(cgContext);
CGContextTranslateCTM(cgContext, CGRectGetMidX(circleRect), CGRectGetMidY(circleRect));
CGContextRotateCTM(cgContext, M_PI / 3.0);
CFArrayRef colors = CFArrayCreate(nil, (const void**) myColors, 3, &kCFTypeArrayCallBacks);
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, colors, locations);
CFRelease(colors);
CFRelease(colorSpace);
CGContextDrawLinearGradient(cgContext, gradient, CGPointMake(-circleRadius, 0),
CGPointMake(circleRadius, 0), kCGGradientDrawsAfterEndLocation + kCGGradientDrawsBeforeStartLocation);
CFRelease(gradient);
CGContextRestoreGState(cgContext);
}
这是 Swift 中的等效游乐场。
import UIKit
import PlaygroundSupport
class CircleGradientView : UIView {
override func draw(_ rect: CGRect) {
let colors = [
UIColor.red.cgColor,
UIColor.yellow.cgColor, // Yellow
UIColor.blue.cgColor // Blue
]
let colorSpace = CGColorSpace(name: CGColorSpace.sRGB)!
let locations : [CGFloat] = [0.0, 0.25, 1.0]
let gradient = CGGradient(colorsSpace: colorSpace,
colors: colors as CFArray,
locations: locations)
if let context = UIGraphicsGetCurrentContext() {
let circleRect = self.bounds.insetBy(dx: 20, dy: 20)
let circleRadius = circleRect.width / 2.0
context.saveGState()
context.addEllipse(in: circleRect)
context.clip()
context.translateBy(x: circleRect.midX, y: circleRect.midY)
context.rotate(by: .pi / 3.0)
context.drawLinearGradient(gradient!,
start: CGPoint(x: -circleRadius, y: 0),
end: CGPoint(x: circleRadius, y: 0),
options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
context.restoreGState()
}
}
}
let myView = CircleGradientView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
PlaygroundSupport.PlaygroundPage.current.liveView = myView