2011-07-28 62 views
3

我正在創建一個應用程序,允許用戶剪出圖像的一部分。爲了做到這一點,他們將創建一堆UIBezierPaths來形成剪切路徑。我目前的設置如下:iOS:從UIBezierPath創建圖像剪切路徑

  • UIImageView顯示他們正在剪切的圖像。
  • 在此之上,UIImageView是UIImageView的一個自定義子類, 執行自定義drawRect:方法來顯示/更新用戶添加的UIBezierPaths的 。
  • 當用戶單擊「完成」按鈕時,將創建一個新的UIBezierPath對象,該對象通過循環存儲在其中的數組並循環調用appendPath:自身來合併用戶創建的所有單個路徑。這個新的UIBezierPath然後關閉它的路徑。

這就像我已經得到。我知道UIBezierPath有一個addClip方法,但我無法從文檔中找出如何使用它。

一般來說,我見過的所有用於裁剪的示例都直接使用Core Graphics而不是UIBezierPath包裝器。我意識到UIBezierPath有一個CGPath屬性。那麼我應該在裁剪時使用它而不是完整的UIBezierPath對象嗎?

+1

你如何檢測你想要剪輯的部分?通過手勢? – Shrawan

回答

0

根據UIImageView class reference,蘋果表示不要繼承UIImageView。感謝@rob mayoff指出了這一點。

但是,如果您正在實現自己的drawRect,請從您自己的UIView子類開始。並且,它在drawRect中使用addClip。您可以使用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]; 
} 

如果要向上或向下縮放以填充邊界,則需要縮放圖形上下文。 (你也可以申請一個CGAffineTransform到clippingPath,但那是永久性的,所以你需要先複製clippingPath。)

- (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中的速度更快,並且包含路徑的CAShapeLayer除測試外,請勿使用以下方法。您需要分別縮放圖像圖層和蒙版以使其排列整齊。優點是您可以更改蒙版而不渲染底層圖像。

- (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方法。刪除它的效率。