2013-02-26 193 views
1

如何绘制下面的图像?我在一个照片编辑工具中创建了这个。但是不能真正把它与iOS相提并论。绘制椭圆渐变

  • 椭圆
  • “软角”,在某种程度上,它就像只知道它是不是圆的辐射梯度。

enter image description here

https://stackoverflow.com/a/12665177/129202导致我在往好的方向发展,但真正的仿射变换的效果是不是100%。使用

代码:

+(UIImage*)createGradientOval2:(const CGSize)SIZECONTEXT { 
    const CGFloat SCALE = 2.0f; 
    UIGraphicsBeginImageContextWithOptions(SIZECONTEXT, NO, SCALE); 
    CGContextRef ctx = UIGraphicsGetCurrentContext(); 

    // Create gradient 
    CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB(); 

    const CGFloat colors [] = { 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 1.00, // green 
     0.0, 1.0, 0.0, 0.00, // transparent 
    }; 
    //CGGradientRef gradient = CGGradientCreateWithColors(baseSpace, (CFArrayRef)colors, locations); 
    CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 10); 
    CGColorSpaceRelease(baseSpace), baseSpace = NULL; 

    // Scaling transformation and keeping track of the inverse 
    CGAffineTransform scaleT = CGAffineTransformMakeScale(1, 2.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); 

    const CGRect RECT = CGRectMake(0, 0, SIZECONTEXT.width/2, SIZECONTEXT.height/2); 

    // Transform center and radius of gradient with the inverse 
    CGPoint center = CGPointMake((RECT.size.width/2) * invS.x, (RECT.size.height/2) * invS.y); 
    CGFloat radius = (RECT.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); 

    return UIGraphicsGetImageFromCurrentImageContext(); 
} 

回答

1

OK我有一个新的...这是好多了,我认为。光滑度等在STROKECOUNT,MAXSTROKEWIDTH等硬编码。这实际上使椭圆长大了一点点。这将需要一些调整,以强制停留在椭圆矩形内。

+(UIImage*)ellipseWithSmoothEdges:(const CGSize)SIZECONTEXT oval:(const CGRect)RECTFOROVAL { 
    const CGFloat SCALE = 2.0f; 

    UIColor* colorPaint = [UIColor greenColor]; 

    UIGraphicsBeginImageContextWithOptions(SIZECONTEXT, NO, SCALE); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    UIBezierPath* pathEllipseForClippingto = [UIBezierPath bezierPathWithOvalInRect:RECTFOROVAL]; 
    const int STROKECOUNT = 70; 
    const CGFloat BASEALPHA = 1.0f/(CGFloat)STROKECOUNT; 
    const CGFloat MAXSTROKEWIDTH = 50; 
    UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect:RECTFOROVAL]; 

    CGContextSaveGState(context); { 
     [pathEllipseForClippingto addClip]; 
     [colorPaint setFill]; 
     [path fill]; 
     CGContextRestoreGState(context); 
    } 
    for (int i = 0; i < STROKECOUNT; i++) { 
     [[UIColor colorWithRed:0 green:1 blue:0 alpha:BASEALPHA * i] setStroke]; 
     path.lineWidth = MAXSTROKEWIDTH - i; 
     [path stroke]; 
    } 

    UIImage* imageGenerated = UIGraphicsGetImageFromCurrentImageContext(); 

    return imageGenerated; 
} 
+0

我不确定这是做到这一点的最有效的方法,但是如果你没有绘制这些东西的话,它肯定是足够快的。对我来说非常方便。感谢指针! – DanM 2014-01-08 20:48:45