2013-02-26 243 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