2013-04-28 44 views
0

假設我有一張圖像,該圖像是通過用貝塞爾路徑將其他圖像繪製到圖像中進行繪製的。我想要的是能夠以這樣一種方式渲染結果圖像,使得新圖像的邊緣看起來像是傾斜的。我在想,用一些線條厚度來繪製貝塞爾路徑的東西,這種線條的厚度會隨着路徑的角度而改變顏色,這正是我想要的。有沒有一個可以自動化這個過程的功能?我一直在想,否則就不會有這樣的按鈕陣列等等。貝塞爾路徑修剪的圖像邊框

例如,應用程序圖標就是我正在尋找的插圖。他們在右下角有一種投影,左上角有一個高光。

回答

0

這取決於你在找什麼。您可以使用2D卷積核,類似於in this article中描述的內容。

我不確定它是否可以在iOS上使用,但Core Image附帶CIHeightFieldFromMask過濾器,它可以生成您想要的東西。

+0

我不確定這些文章如何適用於我的問題。我正在尋找的是在CGPath或UIBezierCurve上運行的東西,而不是圖像內容。 – 2013-04-29 02:23:31

+0

他們產生的結果聽起來像你要找的東西,如果你做得對。但考慮到你的態度,也許你想要的是[中軸轉換](http://en.wikipedia.org/wiki/Medial_axis)。計算起來非常困難,但是可以爲任何形狀創建一個真正的斜角。祝你好運! – user1118321 2013-04-29 02:31:03

+0

態度?我根本不明白你的回答如何適用於我的問題並尋求澄清。順便說一下,誰是「他們」? – 2013-04-29 02:34:49

3

我已經寫出了合理簡單形狀的斜切算法。算法將採用閉合路徑,將其斜切(45°插入),然後應用提供的特定光源角度下的高光/陰影顏色。這並不完美,在複雜的形狀上你可能無法得到你想要的效果,但我發現它適用於大多數「正常」形狀(正方形,圓形,三角形,圓角,甚至星形,齒輪和稍微更多複雜的形狀)。該算法將嘗試通過計算路徑的另一側與光源的光線相交的位置來應用高亮/陰影。我在這裏寫了一篇關於它的博客文章:http://aaronhayman.com/2012/beveling-shapes-in-core-graphics/,但博客文章與實際代碼有點過時,自從我第一次寫這篇文章以來,我已經改進了這些代碼。你可以在這裏找到代碼:https://gist.github.com/ahayman/2830483。代碼以直線「c」書寫,旨在儘可能快速和緊湊。

有幾件事情需要注意:

  • 如果你的一種斜切一個CGPath影像(如前所述),考慮通過在高亮區/陰影顏色與半tranparent阿爾法。例如,下面的顏色會產生一種微妙的斜角效果:

UIColor *highlight = [UIColor colorWithWhite:1 alpha:.25f];

UIColor *shadow = [UIColor colorWithWhite:0 alpha:.25f];

  • 注意,該算法不會錐圖像本身(或彎曲的圖像看起來斜面) 。它只是在形狀上畫一個斜角。實際上,彎曲圖像需要Core Image。但是,如果使用透明度,則可能看起來好像圖像頂部有一個透明斜角。這可能夠了。

替代

你也可以騙一點,在描邊路徑繪製一個漸變。我想很多人都沒有注意到這個小核心圖形功能,但CGPathCreateCopyByStrokingPath是一個奇妙的小功能。實際上,它允許您通過撫摸另一條路徑來創建新路徑。然後,您可以採用返回的路徑並對其應用漸變以創建「斜面外觀」。作爲一個例子,假設我有一個UIBezierPath *path變量,它代表了你想斜切的bezier路徑。

 UIBezierPath *path = [self imageClippingPath]; 
     CGPathRef stroke = CGPathCreateCopyByStrokingPath(path.CGPath, NULL, 2.0f, path.lineCapStyle, path.lineJoinStyle, path.miterLimit); 
     UIBezierPath *strokedPath = [UIBezierPath bezierPathWithCGPath:stroke]; 
     [self drawGradientInPath:strokedPath inContext:context]; 
     CGPathRelease(stroke); 

請注意,如果你夾的路徑,你會得到一個行程,這只是1.0F寬,因爲中風是由路徑周圍和剪輯將削減行程中的一半。

通過創建兩個不同寬度的單獨描邊路徑,可以創建更好的「斜角」:稱寬度爲4.0f的「內」斜角和寬度爲2.0f的「外」斜角。首先繪製「內」斜面,然後將外斜面(內部寬度的一半)鋪在它上面。如果您還將自己的上下文剪輯到您正在撫摸的路徑上,則最終會形成兩個單獨的斜角,每個斜角大小爲1.0f。請記住,筆畫是左右的路徑。所以只有一半的行程會在剪輯區域內。如果你用不同的漸變填充內斜角,你可以創建一個模仿許多蘋果自己的插入按鈕外觀。仔細觀察Apple的按鈕之後,我很確定這正是他們所做的(或者非常相似的東西)以獲得斜面外觀。

+0

非常感謝您的建議。我會嘗試你的第二個建議。我已經試過類似的東西,但沒有梯度 – 2013-04-29 13:45:47

+0

嗯。如果這是行得通的,我想我將不得不使用單獨的貝塞爾曲線,而不是由連接曲線組成的整條曲線。這是因爲連接的曲線形成了一個閉環。結果似乎是,在設置剪輯時,它不是剪輯區域內的原始路徑,而是路徑包圍的空間。我希望這是有道理的。好消息是,無論如何,我將要使用單獨的Bezier曲線,以便能夠應用有意義的漸變。我認爲我現在將此表列出來,專注於應用程序中更緊迫的問題。 – 2013-04-29 18:16:04

+0

我發現這個舊帖子(因爲這是一個受歡迎的問題,顯然),並意識到我沒有接受答案。我打算接受這個答案,但其中的鏈接被打破。如果你更新它,我可以接受它。或者我會在後來添加我自己的答案與我實際做的事情。 – 2017-10-08 17:09:32