コミックブックアーカイブビューアを作っている筆者でありますが。
スクリーントーンの描写が変になる場合があることに困っていた。
Clutter(OpenGL ES) でリサイズしているのが悪いのかな?
と思い GdkPixbuf をリサイズしてからレンダリングで解決した。
よかったよかった、じゃない!もう少し調べよう。
Jトーン 網点(ドットパターン) J-00|スクリーントーン 通販【ジェイトーン・ネットショッピング】
トーンは上記のサンプル画像をお借りしてと。
#!/usr/bin/env python3 import gi gi.require_version("Gtk", "3.0") gi.require_version("Clutter", "1.0") gi.require_version("GtkClutter", "1.0") from gi.repository import Gtk, Gdk, GdkPixbuf, Clutter, GtkClutter, Cogl class DrawWindow(Gtk.Window): """ 2D and 3D View Check """ def __init__(self): Gtk.Window.__init__(self) # tone self.pixbuf = GdkPixbuf.Pixbuf.new_from_file("tone.jpg") # cairo (2D) self.da = Gtk.DrawingArea() self.da.connect("draw", self.on_draw) # OpenGL ES (3D) embed = GtkClutter.Embed() stage = embed.get_stage() stage.set_background_color(Clutter.Color.new(0, 0, 0, 255)) stage.connect("allocation-changed", self.on_stage_allocation_changed) self.actor = Clutter.Actor() image = Clutter.Image() image.set_data( self.pixbuf.get_pixels(), Cogl.PixelFormat.RGBA_8888 if self.pixbuf.get_has_alpha() else Cogl.PixelFormat.RGB_888, self.pixbuf.get_width(), self.pixbuf.get_height(), self.pixbuf.get_rowstride() ) self.actor.set_content(image) stage.add_child(self.actor) # set vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) vbox.pack_start(self.da, True, True, 0) vbox.pack_start(embed, True, True, 0) self.add(vbox) self.connect("delete-event", Gtk.main_quit) self.show_all() def on_stage_allocation_changed(self, actor, box, flags): aw = box.x2 ah = box.y2 w = self.pixbuf.get_width() h = self.pixbuf.get_height() if aw * h > ah * w: width = w * ah / h height = ah x = (aw - width) / 2 y = 0 else: width = aw height = h * aw / w x = 0 y = (ah - height) / 2 self.actor.set_size(width , height) self.actor.set_position(x, y) def on_draw(self, widget, cr): d_width = widget.get_allocated_width() d_height = widget.get_allocated_height() cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, d_width, d_height) cr.fill() p_width = self.pixbuf.get_width() p_height = self.pixbuf.get_height() if (d_width * p_height) > (d_height * p_width): width = p_width * d_height / p_height height = d_height else: width = d_width height = p_height * d_width / p_width pixbuf = GdkPixbuf.Pixbuf.scale_simple(self.pixbuf, width, height, GdkPixbuf.InterpType.BILINEAR) Gdk.cairo_set_source_pixbuf(cr, pixbuf, (d_width-width)/2, (d_height-height)/2) cr.paint() GtkClutter.init() DrawWindow() Gtk.main()
動かす。
上半分が cairo で下が Clutter です。
拡大はまったく同じ描写になるけど縮小は全然違うものになることが解る。
なんだよこの 3D 描写。。。。。
画像処理や 3D に詳しいわけではないので細かい解説はできないけど。
単なるラスターデータとして扱う 2D と RGB として扱う 3D の違いだろう。
網点を RGB 色として認識した結果こんな悲惨なことに。
とにかく 3D では小さめな画像かアニメ調のベタ塗りでないとこんなことになる。
スクリーントーンを多用するコミック表示には徹底的に向いていないようです。
Clutter で cairo が使える手段があるのはそういうことか。
cairo で作り替えしよ。