2011-03-23 85 views
0

這是我現在使用的代碼:開羅(w/Python):是否可以使用透明線填充多邊形?

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, *image.size) 
context = cairo.Context(surface) 
context.set_source_rgba(1, 1, 1, 1) 
context.new_path() 
for i in xrange(len(points)): 
    context.line_to(*points[i]) 

context.close_path() 
context.fill() 

的問題是,它填補了相同的顏色我繪製多邊形。我試圖在這個畫一個新的多邊形,只做context.stroke(),而不是fill(),但只有當我使用不同的顏色,因爲否則白色是在下面。我試着用(0,0,0,0),所以它會是透明的,但是然後白色在它下面。

我可以得出一個顏色的線(比如(0.5,0.5,0.5,1)),它與write_to_png保存爲圖像,與PIL加載,轉換爲numpy.array和更換正確的顏色與背景顏色(0, 0, 0, 0)每個像素,但是這不是高效。

我也嘗試將線寬設置爲0,這也不起作用。

此外,我很好,其他方法,讓我這樣做,而不是開羅。我嘗試過ImageDraw的polygon,但它沒有繪製出確切的形狀(我不確定如何解釋,但它在多邊形之外繪製一些額外的像素,它不應該),所以ImageDraw不會幫助我。

+0

我不能正是你想要的瞭解。一個人不會用「線」「填充」一個形狀 - 你想做什麼?如果yu只想要多邊形的輪廓,請嘗試使用「.stroke()」而不是「.fill()」。如果您希望繪圖顏色透明,請爲Alpha使用中間值(顏色中的第四個元素 - 您將其始終設置爲1) – jsbueno 2011-03-23 02:27:09

+0

當我使用填充時,它會在多邊形上繪製輪廓。我不想要那個輪廓/線條。 – pppphhhhuuuu 2011-03-23 02:31:04

回答

0

我明白了。所以沒有辦法做到這一點 - 所有關於開羅風格的2D繪圖API都假設「填充」包含邊界。它在Cairo提供的大多數後端上都是這樣工作的,比如Postscript和SVG,所以很難想象它可能會有什麼不同。

「乾淨」的方法是迭代你的多邊形,這樣你就可以生成只限定你不填充區域的點 - 也就是說,你必須自己計算線區域。

另一方面,你的破解似乎很聰明,因爲它處理光柵是不可能在開羅完全完成的。但是,除了保存到磁盤並重新加載之外,還可以採用其他方法 - 例如,您可以在Pygame中將開羅表面數據用作SDL表面來僞造「複製和粘貼」操作。

http://doswa.com/blog/2010/03/29/using-cairo-in-pygame/ http://www.pygame.org/wiki/CairoPygame

(其實,.我試着想用Pyagame工作流程和不能 - 選項 操縱阿爾法像素和複製/粘貼在它上面是相當有限的)。

我的最終建議是:不要使用pycairo - 檢查使用GIMP Python API是否適合您。 GIMP是一個功能齊全的2D繪圖程序,具有可從Python使用的完整API。例如,您可以使用GIMP「矢量」對象繪製yur多邊形,並且儘管「填充」 也將包含多邊形線,但在填充之前您可以調用jsut,例如「gimp_selection_shrink」。或者,您可以使用圖層來獲得所需的確切效果。

從GIMP內部,您可以在幫助 - >程序數據庫菜單中檢查整個API。

腳本準備就緒後,可以通過coomand行運行GIMP來運行程序,而不需要圖形顯示。

以下是你需要使用pygimp工作流程:

  • 創建GIMP向量與poligon分對象: pdb.gimp_image_add_vectors,pdb.gimp_vectors_stroke_new_from_points
  • 創建一個新層(與圖像層以上你想保留沿着這條線) pdb.gimp_layer_new(還有一些其他函數必須調用以將圖層綁定到圖像上)
  • 將您的多邊形轉換爲選區 - pdb.gimp_vectors_to_selection
  • 填入新層,將具有所需顏色pdb.gimp_edit_bucket_fill
  • 從層轉換的選擇,以「厚」的選擇與 pdb.gimp_selection_border
  • 剪切像素 - pdb.gimp_Edit_cut
  • 合併新層到以前的形象 - pdb.gimp_image_merge_down
1
fill_preserve() 
context.set_source_rgba(0, .6, 1, .7) #line color 
context.set_line_width(2.35) 
context.stroke()