2011-07-28 3 views
3

사용자가 이미지의 일부를 잘라낼 수있는 앱을 만들고 있습니다. 이렇게하기 위해, 그들은 UIBezierPaths를 만들어 클리핑 패스를 만듭니다. 현재 설정은 다음과 같습니다.iOS : UIBezierPath에서 이미지 클리핑 패스 만들기

  • UIImageView는 절단중인 이미지를 표시합니다.
  • 위 UIImageView는 이 사용자가 추가중인 UIBezierPaths를 표시/업데이트하기위한 사용자 지정 drawRect : 메서드를 수행하는 UIImageView의 사용자 지정 하위 클래스입니다.
  • 사용자가 "완료"버튼을 클릭하면 저장되어있는 배열을 반복하고 appendPath :를 호출하여 사용자가 만든 모든 개별 경로를 통합 한 새로운 UIBezierPath 객체가 만들어집니다. 이 새로운 UIBezierPath는 경로를 닫습니다.

그 정도까지입니다. UIBezierPath에는 addClip 메서드가 있지만 설명서에서 사용 방법을 알 수는 없습니다.

일반적으로 클리핑을 위해 본 모든 예제는 UIBezierPath 래퍼가 아닌 Core Graphics를 직접 사용합니다. UIBezierPath에는 CGPath 속성이 있다는 것을 알았습니다. 그래서 전체 UIBezierPath 객체보다는 클리핑 할 때 이것을 사용해야합니까?

+1

어떻게 자르고 싶은 부분을 감지하고 있습니까? 몸짓으로? – Shrawan

답변

0

애플은 UIImageView class reference에 따라 UIImageView를 서브 클래 싱하지 않는다고 말합니다. 이 점을 지적하기 위해 @rob mayoff에 감사드립니다.

그러나 자신 만의 drawRect를 구현하려면 고유 한 UIView 하위 클래스로 시작하십시오. 그리고, 당신은 addClip을 사용하는 drawRect 내에 있습니다. UIBezierPath를 CGPath로 변환하지 않고이 작업을 수행 할 수 있습니다.

- (void)drawRect:(CGRect)rect 
{ 
    // This assumes the clippingPath and image may be drawn in the current coordinate space. 
    [[self clippingPath] addClip]; 
    [[self image] drawAtPoint:CGPointZero]; 
} 

범위를 채우기 위해 위 또는 아래로 축척을 변경하려면 그래픽 컨텍스트의 크기를 조정해야합니다. (먼저하는 clippingpath을 복사해야합니다 것입니다, 그래서 당신은 또한하는 clippingpath에 CGAffineTransform을 적용 할 수 있지만,이 영구적입니다.)

- (void)drawRect:(CGRect)rect 
{ 
    // This assumes the clippingPath and image are in the same coordinate space, and scales both to fill the view bounds. 
    if ([self image]) 
    { 
     CGSize imageSize = [[self image] size]; 
     CGRect bounds = [self bounds]; 

     CGContextRef context = UIGraphicsGetCurrentContext(); 
     CGContextScaleCTM(context, bounds.size.width/imageSize.width, bounds.size.height/imageSize.height); 

     [[self clippingPath] addClip]; 
     [[self image] drawAtPoint:CGPointZero]; 
    } 
} 

이 각 축에 개별적으로 이미지 크기를 조정합니다. 종횡비를 유지하려면 전체 배율을 조정해야하며 중앙 정렬 또는 정렬되도록 변환해야합니다.

마지막으로 경로가 많이 확보되면이 모든 작업이 상대적으로 느립니다. CALayer에 이미지를 저장하는 것이 더 빠르며 경로가 포함 된 CAShapeLayermask을 찾는 것이 좋습니다. 테스트를 제외하고는 다음 방법을 사용하지 마십시오. 이미지 레이어와 마스크를 따로 줄 이도록 정렬해야합니다. 이점은 렌더링되는 기본 이미지없이 마스크를 변경할 수 있다는 것입니다.

- (void) setImage:(UIImage *)image; 
{ 
    // This method should also store the image for later retrieval. 
    // Putting an image directly into a CALayer will stretch the image to fill the layer. 
    [[self layer] setContents:(id) [image CGImage]]; 
} 

- (void) setClippingPath:(UIBezierPath *)clippingPath; 
{ 
    // This method should also store the clippingPath for later retrieval. 
    if (![[self layer] mask]) 
     [[self layer] setMask:[CAShapeLayer layer]]; 

    [(CAShapeLayer*) [[self layer] mask] setPath:[clippingPath CGPath]]; 
} 

레이어 마스크로 이미지를 클리핑하면 더 이상 drawRect 메서드가 필요하지 않습니다. 효율성을 위해 그것을 제거하십시오.