2013-02-26 6 views
1

아래 그림과 같이 어떻게 이미지를 그릴 수 있습니까? 사진 편집 도구에서이 사진을 만들었습니다. 하지만 iOS를 사용하여 실제로 그걸 풀 수는 없습니다.타원 그라디언트 그리기

좋은 방향으로 날 이끌하지만 정말 아핀 변환의 효과는 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

확인을 나는 새를 가지고 ... 그것은 훨씬 더 내 생각이다. 부드러움 등은 STROKECOUNT, MAXSTROKEWIDTH 등으로 하드 코드됩니다. 실제로 타원은 조금씩 바깥쪽으로 자랍니다. 타원형 rect 내부에 머물러있게하려면 약간의 조정이 필요합니다.

+(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

관련 문제