2012-06-22 1 views
6

내 그림에 "엠 보스/그림자 효과"를 구현하는 데 문제가 있습니다. 모든 방법과코어 그래픽 (손가락 페인트 용)을 사용하여 엠보싱 또는 그림자 효과를 만드는 방법

편집 코드 : 핑거 페인트 기능은 현재 아래에있는 내 사용자 정의 UIView와 함께 잘 작동하고 나의 drawRect 방법 코드 나는 점 페인트 효과를 얻고이를 구현 한

- (void)drawRect:(CGRect)rect 
{ 
    CGPoint mid1 = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2 = midPoint(currentPoint, previousPoint1); 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    [self.layer renderInContext:context]; 

    CGContextMoveToPoint(context, mid1.x, mid1.y); 
    CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 
    CGContextSetLineCap(context, kCGLineCapRound); 
    CGContextSetLineWidth(context, self.lineWidth); 
    CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor); 
    CGContextSaveGState(context); 

    // for shadow effects 
    CGContextSetShadowWithColor(context, CGSizeMake(0, 2),3, self.lineColor.CGColor); 
    CGContextStrokePath(context); 
    [super drawRect:rect]; 
} 

CGPoint midPoint(CGPoint p1, CGPoint p2) 
{ 
    return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5); 
} 


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 

    UITouch *touch = [touches anyObject]; 

    previousPoint1 = [touch previousLocationInView:self]; 
    previousPoint2 = [touch previousLocationInView:self]; 
    currentPoint = [touch locationInView:self]; 

    [self touchesMoved:touches withEvent:event]; 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 

    UITouch *touch = [touches anyObject]; 

    previousPoint2 = previousPoint1; 
    previousPoint1 = [touch previousLocationInView:self]; 
    currentPoint = [touch locationInView:self]; 


    // calculate mid point 
    CGPoint mid1 = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2 = midPoint(currentPoint, previousPoint1); 

    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathMoveToPoint(path, NULL, mid1.x, mid1.y); 
    CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 
    CGRect bounds = CGPathGetBoundingBox(path); 
    CGPathRelease(path); 

    CGRect drawBox = bounds; 

    //Pad our values so the bounding box respects our line width 
    drawBox.origin.x  -= self.lineWidth * 2; 
    drawBox.origin.y  -= self.lineWidth * 2; 
    drawBox.size.width  += self.lineWidth * 4; 
    drawBox.size.height  += self.lineWidth * 4; 

    UIGraphicsBeginImageContext(drawBox.size); 
    [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    curImage = UIGraphicsGetImageFromCurrentImageContext(); 
    [curImage retain]; 
    UIGraphicsEndImageContext(); 



    [self setNeedsDisplayInRect:drawBox]; 

} 

도트 점 ...

아래 이미지 (그림자 또는 엠보싱 효과가 없음)를 참조하십시오. 이러한 효과를 추가하는 방법에 대한 아이디어가 있다면 제게 제안 해주십시오. 어떻게 해결할 수 있습니까?

enter image description here

답변

4

당신이 수백, 별도의 경로 어쩌면 수천, 각각의 drawRect에 하나를 만들 것으로 보인다. 당신은 [self.layer renderInContext]을 사용하여 이것들을 평평하게 만들었지 만, 나는 그것이 좋은 방법이라고 생각하지 않습니다. 대신, 당신이하고 싶은 일은 UIBezierPath를 만들어서 손가락을 추적하고 경로를 추가하고 UIBezierPath를 화면에 그려 보는 것입니다. 두 개의 레이어 (또는 뷰)를 만들면 상단 (투명)을 "그리기"로 설정할 수 있습니다. 사용자가 손가락을 떼면 UIBezierPath 전체를 두 번째 레이어에 렌더링하고 (이전에 그려진 데이터와 함께) 새로운 UIBezierPath를 만들어 다음 손가락 추적을 그립니다. 이 방법을 사용하면 다른 사람의 손가락을 추적 할 때 하나의 레이어 (맨 위 레이어) 만 업데이트합니다. 이렇게하면 장치가 너무 많은 경로를 그리는 속도를 늦추는 것을 방지 할 수 있습니다.

현재의 방법은 멋지게 보이는 "3D"효과를냅니다.

+0

귀하의 제안에 감사드립니다. 나는 UIBezierPath를 사용하여 구현했지만 기능을 지우는 것과 같은 몇 가지 문제에 직면하고 다른 색상의 페인트를 선택합니다. 결국 마침내 모든 기능을 변경하고 CGContext를 사용합니다. 이제는 지우개와 같은 모든 기능, 브러쉬의 색상 변경이 제대로 작동합니다. 엠 보스 또는 그림자 효과를 만드는 것만 가능합니다. 그 효과가 제대로 작동하지 않습니다 .. 그림자 효과와 잘 작동하는 스트레이트 라인. 그러나 곡선 효과 (부드러운) 잘 작동하지 않습니다. CGZext를 사용하여 몇 가지 suggeetion 말해줘. – Hitarth

+0

빠른 질문 : 지우개를 어떻게 사용 하시겠습니까? 대부분의 '그리기'프로그램은 각각의 별도 '경로'를 지 웁니다 (하나의 손가락 터치/끌기/끝 이벤트로 정의 됨). 이것은 내 제안/대답과 함께 작동합니다. 그러나 각 경로 지점이나 심지어 각 픽셀을 지우려고하는 경우 ... 달성하기가 훨씬 어려울 것입니다. –

+0

현재 컨텍스트를 사용하여 지우기. 그리고 그것은 잘 작동합니다. – Hitarth

0

엠보싱에 대해서는 잘 모르겠지만 점차적으로 업데이트되는 드로잉에 그림자를 적용하는 것이 좋은 방법이라면 CALayers (link to a tutorial)을 사용하는 것이 좋습니다. 기본적으로 프로그레시브 그리기는 투명한 이미지를 업데이트하며 (이 이미지에 그림자를 그리지 않고)이 이미지는 CALayer를 통해 그림자로 표시되도록 구성됩니다.

0

그림자가 테두리에 만들어지고 선의 작은 세그먼트를 그리면이 효과가 생성됩니다. 경로를 만든 다음 한 번 획을 긋을 필요가 있습니다. 이 코드는 도움이 될 :)

for (int i=0; i<[currentPath count]; i++) 
{ 
    CGPoint mid1 = [[self midPoint:[currentPath objectAtIndex:i+1] :[currentPath objectAtIndex:i]] CGPointValue]; 
    CGPoint mid2 = [[self midPoint:[currentPath objectAtIndex:i+2] :[currentPath objectAtIndex:i+1]] CGPointValue]; 
    CGContextMoveToPoint(context, mid1.x, mid1.y); 
    CGContextAddQuadCurveToPoint(context, [[currentPath objectAtIndex:i+1] CGPointValue].x, [[currentPath objectAtIndex:i+1] CGPointValue].y, mid2.x, mid2.y); 
    CGContextSetShadow(context, CGSizeMake(-2, -2), 3); 

    CGContextSetLineCap(context, kCGLineCapRound); 
    CGContextSetStrokeColorWithColor(context,[color CGColor]);    
    CGContextSetLineWidth(context, linewidth);    

    i+=2; 
} 
CGContextStrokePath(context); 

이 그것을 뇌졸중 ..이 .. 먼저 UR 경로를 만들어 문제를 해결할 수있는 해결이 방법을 시도하고 완전히 만든 후. 이것은 모든 작은 라인에서 스트로크가 발생하고 그로 인해 그림자가 만들어지기 때문에이 효과가 발생합니다.

+0

코드에서 CurrntPath는 무엇이며 루프를 사용하는 이유는 무엇입니까? Plz 내 전체 소스 코드 (편집)를 참조하십시오. – Hitarth

+0

나는 포인트 배열을 만들고 있는데, 현재 경로는 그 배열이다. 이 배열은 터치로 시작하여 끝으로 터치하여 시작하여 포인트로 생성됩니다. :) – DivineDesert