4

iPhone 용 CALayer 드로잉에 이상한 문제가 있습니다. 나는 "거품"을 나타내는 많은 하위 레이어를 추가하는 루트 레이어를 가지고 있습니다. 최종 결과는 다음과 같을 것으로 예상되는 :CALayer 및 CGGradientRef 앤티 앨리어싱?

http://www.expensivedna.com/IMG_0018.PNG http://www.expensivedna.com/IMG_0018.PNG

문제는 내가 앤티 앨리어싱에 레이어를 (거품의 계단 현상을주의) 얻이 수없는 것이다. 다음과 같이 버블의 CALayer에 대한 drawInContext을 덮어 내 코드는 다음과 같습니다 이제

- (void)drawInContext:(CGContextRef)theContext{ 
CGContextSetAllowsAntialiasing(theContext, true); 
CGContextSetShouldAntialias(theContext, true); 

size_t num_locations = 2; 
CGFloat locations[2] = { 0.0, 1.0 }; 
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5, // Start color 
          1.0, 1.0, 1.0, 0.0 }; // End color 
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB(); 
CGGradientRef glossGradient = 
CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations); 

CGPoint topCenter = CGPointMake(25, 20); 
CGPoint midCenter = CGPointMake(25, 25); 
CGContextDrawRadialGradient(theContext, glossGradient, midCenter, 20, topCenter, 10, kCGGradientDrawsAfterEndLocation); 

}

정말 이상한 것은 내가 약간에 그리기 코드를 변경하면 다음과 같은 경우에만 정상적인 빨간색 원을 그리는 것입니다 :

http://www.expensivedna.com/IMG_0017.PNG http://www.expensivedna.com/IMG_0017.PNG

:
- (void)drawInContext:(CGContextRef)theContext{ 
CGContextSetAllowsAntialiasing(theContext, true); 
CGContextSetShouldAntialias(theContext, true); 

CGContextSetFillColorWithColor(theContext, [UIColor redColor].CGColor); 
CGContextFillEllipseInRect(theContext, CGRectMake(0, 0, 40,40)); 
} 

모든 앤티 앨리어싱 OK 보인다

나는이 겉으로보기에는 이상한 행동을 알아낼 수 없습니다. 안티 앨리어싱 그라데이션과 일반 서클 사이의 차이점이 누락 되었습니까?

감사합니다.

답변

4

감사합니다. 그래서 대답은 당신의 두 답변 (멍청이와 알렉스)의 조합이라고 밝혀졌습니다. 기본적으로 CGDrawRadialGradient 함수는 끝 서클이 아닌 시작 서클에서 앨리어싱 만있는 것처럼 보입니다. 내가 앨리어스 "가장자리"모두를 원하기 때문에, 내가 먼저 다음과 같은 최초의 "끝"을 담당 밖으로 내부에서 그릴 수있는 기능을 설정할 수 있지만 생산 :

그런 Step 1

, 나는 클립 coob 제안하고이 버블의 최종 가장자리 주위에 좋은 앨리어싱을 제공합니다 이미지로 :

Step 2

나를 위해 충분 보이는!

- (void)drawInContext:(CGContextRef)theContext{ 
CGContextSetAllowsAntialiasing(theContext, true); 
CGContextSetShouldAntialias(theContext, true); 

size_t num_locations = 2; 
CGFloat locations[2] = { 0.0, 1.0 }; 
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.0, // Start color 
       1.0, 1.0, 1.0, 0.5 }; // End color 
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB(); 
CGGradientRef glossGradient = 
CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations); 

CGContextAddEllipseInRect(theContext, CGRectMake(5, 5, 40, 40)); 
CGContextClip(theContext); 

CGPoint topCenter = CGPointMake(25, 20); 
CGPoint midCenter = CGPointMake(25, 25); 
CGContextDrawRadialGradient(theContext, glossGradient, topCenter, 10, midCenter, 20, kCGGradientDrawsAfterEndLocation); 

}

0

어쩌면 kCGGradientDrawsAfterEndLocation을 삭제하려고합니까? 알파로 이상한 일을하고있을 수도 있습니다

2

Jeff - topCenter를 조금 더 멀리 만들고 원형 마스크가있는 CGContextClipToMask를 사용하십시오.

편집 : 사실 훨씬 더 좋은 방법은 CGContextClip을 사용하여 벡터 클리핑 패스를 사용하는 것입니다.

편집 2 : 샘플 코드 :

CGContextAddEllipseInRect(theContext, CGRectMake(20, 20, 10, 10)); 
CGContextClip(theContext); 

당신이 당신의 그라데이션을 그리기 전에이 추가 밖으로 조금 더를 그립니다.

+0

팁 : 완전히 여기에 계단 현상을 제거하기 위해 1 포인트 내 RECT를 인세했다. – mattorb

관련 문제