【问题标题】:Is there a way to draw a CGContextDrawRadialGradient as an oval instead of a perfect circle?有没有办法将 CGContextDrawRadialGradient 绘制为椭圆而不是完美的圆形?
【发布时间】:2011-10-18 07:09:29
【问题描述】:

我需要椭圆形或椭圆形的径向渐变,看起来 CGContextDrawRadialGradient 只能绘制一个完美的圆形。我一直在绘制方形上下文,然后复制/绘制到矩形上下文中。

有更好的方法吗?

谢谢!

【问题讨论】:

    标签: quartz-graphics gradient ellipse radial-gradients


    【解决方案1】:

    我发现这样做的唯一方法是按照 Mark F 的建议,但我认为答案需要一个更容易理解的示例。

    在 iOS 中的视图中绘制椭圆渐变(并使用 ARC):

    - (void)drawRect:(CGRect)rect {
    
        CGContextRef ctx = UIGraphicsGetCurrentContext();
    
        // Create gradient
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGFloat locations[] = {0.0, 1.0};
    
        UIColor *centerColor = [UIColor orangeColor];
        UIColor *edgeColor = [UIColor purpleColor];
    
        NSArray *colors = [NSArray arrayWithObjects:(__bridge id)centerColor.CGColor, (__bridge id)edgeColor.CGColor, nil];
        CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
    
        // Scaling transformation and keeping track of the inverse
        CGAffineTransform scaleT = CGAffineTransformMakeScale(2, 1.0);
        CGAffineTransform invScaleT = CGAffineTransformInvert(scaleT);
    
        // Extract the Sx and Sy elements from the inverse matrix
        // (See the Quartz documentation for the math behind the matrices)
        CGPoint invS = CGPointMake(invScaleT.a, invScaleT.d);
    
        // Transform center and radius of gradient with the inverse
        CGPoint center = CGPointMake((self.bounds.size.width / 2) * invS.x, (self.bounds.size.height / 2) * invS.y);
        CGFloat radius = (self.bounds.size.width / 2) * invS.x;
    
        // Draw the gradient with the scale transform on the context
        CGContextScaleCTM(ctx, scaleT.a, scaleT.d);
        CGContextDrawRadialGradient(ctx, gradient, center, 0, center, radius, kCGGradientDrawsBeforeStartLocation);
    
        // Reset the context
        CGContextScaleCTM(ctx, invS.x, invS.y);
    
        // Continue to draw whatever else ...
    
        // Clean up the memory used by Quartz
        CGGradientRelease(gradient);
        CGColorSpaceRelease(colorSpace);
    }
    

    放入一个黑色背景的视图中:

    【讨论】:

      【解决方案2】:

      您可以更改上下文的变换以绘制椭圆(例如,在调用 CGContextDrawRadialGradient () 之前应用 CGContextScaleCTM(context, 2.0, 1.0) 以绘制宽度为高度两倍的椭圆渐变)。不过,请记住将逆变换应用于您的起点和终点。

      【讨论】:

      • 这帮助我走上了正轨。谢谢!我用下面的代码示例对此进行了扩展。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      相关资源
      最近更新 更多