MyPaint私家版にさらにPolyfilltoolを実装ッ!(途中)
アイデアとしてはこうです。
「brushlibを弄ってポリゴンフィルを付けるのは面倒だが、pycairoで描いてそのサーフェスをgdk.pixbufに変換しさらにそれをmypaintのレイヤのメソッドload_surface_from_pixbufで流しこめば簡単に出来るのではないか?」
…と思って、思い立ったらガマンできない堪え性のないワタクシ *1は早速着手しました。
と思ったんですが、着想はよかったものの、中々上手く行かず。pycairo、gtk、そしてmypaintのクラス群と、分からない要素の数々がオイラを責め立てる…
しかし数日間の苦闘の後!!
遂に!!
遂にレイヤに描画することに成功しました!!!
まだUIは作ってないけどグラデも出来る!
Cairoにはメッシュグラデも実装されており、UIさえ作ればグフフのフっと…*2
とりあえず描画部分のコードだけ置いときますね(´・ω・`)
MyPaintソースの様々な部分からのコピペ多し…
sx, sy, ex, ey = self._get_maximum_rect(None) sx = int(sx) sy = int(sy) w = int(ex-sx+1) h = int(ey-sy+1) surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) cr = cairo.Context(surf) _draw_node_polygon(cr, None, self.nodes, ox=sx, oy=sy, color=self.foreground_color) surf.flush() pixbuf = Gdk.pixbuf_get_from_surface(surf, 0, 0, w, h) layer = lib.layer.PaintingLayer(name='') layer.load_surface_from_pixbuf(pixbuf, int(sx), int(sy)) del surf, cr tiles = set() tiles.update(layer.get_tile_coords()) rootstack = self.doc.model.layer_stack dstlayer= rootstack.deepget(rootstack.current_path) dstsurf = dstlayer._surface for tx, ty in tiles: with dstsurf.tile_request(tx, ty, readonly=False) as dst: layer.composite_tile(dst, True, tx, ty, mipmap_level=0) bbox = tuple(dstlayer.get_full_redraw_bbox()) dstlayer.root.layer_content_changed(dstlayer, *bbox)
これが出来ると何が良いのか?と申しますと、かつてgimpがメインだった頃一時期凝っていた「パス塗り」が、gimpよりも遥かに簡単に手間なく出来てしまう点。
あと、このpixbuf変換 + レイヤ操作をマスターすれば…OpenCVを使った何らかの操作すら可能だろう…ということ…!!(利根川幸雄風