GTK3 中嘈杂的 cairo 创建的自定义光标
Noisy cairo-created custom cursor in GTK3
我正在研究图像注释工具。它涉及在图像顶部绘制不同大小的圆圈。为了方便起见,我想将光标修改为某个半径的圆。下面的代码片段(特别是 custom_cursor() 函数)允许我使用自定义光标(使用 cairo 绘制)并使用括号键(“[”和“]”)更改其半径。我遇到的问题在这个视频中很明显:https://imgur.com/a/swEmbzL。基本上,在某些半径值下,有很多伪像覆盖了整个光标图像。这是什么原因,是否可以消除这种噪音?
import gi
import numpy as np
import cairo
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkPixbuf
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title = "Test")
self.maximize()
self.radius = 137
viewport = Gtk.Viewport()
self.darea = Gtk.DrawingArea()
self.darea.connect("draw", self.draw)
self.pixbuf = GdkPixbuf.Pixbuf.new_from_file("any_image.jpg")
self.darea.set_size_request(self.pixbuf.get_width(), self.pixbuf.get_height());
grid = Gtk.Grid()
self.add(grid)
scrolled = Gtk.ScrolledWindow()
scrolled.set_hexpand(True)
scrolled.set_vexpand(True)
scrolled.connect("key-press-event",self.press)
viewport.add(self.darea)
scrolled.add(viewport)
grid.add(scrolled)
self.custom_cursor(self.radius)
def draw(self, widget, cr):
Gdk.cairo_set_source_pixbuf(cr, self.pixbuf, 0, 0)
cr.paint()
self.darea.queue_draw()
def custom_cursor(self, radius):
display = self.get_screen().get_display()
pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 2 * radius, 2 * radius)
surface = Gdk.cairo_surface_create_from_pixbuf(pb, 0, None)
context = cairo.Context(surface)
context.arc(radius, radius, radius, 0, 2 * np.pi)
context.set_source_rgba(0, 0, 0, 1)
context.stroke()
pbdrawn = Gdk.pixbuf_get_from_surface(surface, 0, 0, surface.get_width(), surface.get_height())
cursor = Gdk.Cursor.new_from_pixbuf(display, pbdrawn, radius, radius)
self.darea.get_screen().get_root_window().set_cursor(cursor)
def press(self, widget, event):
if (event.keyval == 93):
self.radius = self.radius + 2
self.custom_cursor(self.radius)
elif (event.keyval == 91):
self.radius = self.radius - 2
self.custom_cursor(self.radius)
win = MainWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
编辑:这可能是图形问题。如果有人能确认有(没有)噪音,我将不胜感激。
来自 gdk_pixbuf_new
的文档:
Note that the buffer is not cleared; you will have to fill it completely yourself.
https://developer.gnome.org/gdk-pixbuf/2.36/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new
基本上,您在这里看到的是未初始化的内存。
我建议直接创建一个 cairo 图像表面,而不是创建一个 pixbuf 只是为了将它转换为 cairo 表面。开罗为你初始化新的图像表面
我正在研究图像注释工具。它涉及在图像顶部绘制不同大小的圆圈。为了方便起见,我想将光标修改为某个半径的圆。下面的代码片段(特别是 custom_cursor() 函数)允许我使用自定义光标(使用 cairo 绘制)并使用括号键(“[”和“]”)更改其半径。我遇到的问题在这个视频中很明显:https://imgur.com/a/swEmbzL。基本上,在某些半径值下,有很多伪像覆盖了整个光标图像。这是什么原因,是否可以消除这种噪音?
import gi
import numpy as np
import cairo
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkPixbuf
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title = "Test")
self.maximize()
self.radius = 137
viewport = Gtk.Viewport()
self.darea = Gtk.DrawingArea()
self.darea.connect("draw", self.draw)
self.pixbuf = GdkPixbuf.Pixbuf.new_from_file("any_image.jpg")
self.darea.set_size_request(self.pixbuf.get_width(), self.pixbuf.get_height());
grid = Gtk.Grid()
self.add(grid)
scrolled = Gtk.ScrolledWindow()
scrolled.set_hexpand(True)
scrolled.set_vexpand(True)
scrolled.connect("key-press-event",self.press)
viewport.add(self.darea)
scrolled.add(viewport)
grid.add(scrolled)
self.custom_cursor(self.radius)
def draw(self, widget, cr):
Gdk.cairo_set_source_pixbuf(cr, self.pixbuf, 0, 0)
cr.paint()
self.darea.queue_draw()
def custom_cursor(self, radius):
display = self.get_screen().get_display()
pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 2 * radius, 2 * radius)
surface = Gdk.cairo_surface_create_from_pixbuf(pb, 0, None)
context = cairo.Context(surface)
context.arc(radius, radius, radius, 0, 2 * np.pi)
context.set_source_rgba(0, 0, 0, 1)
context.stroke()
pbdrawn = Gdk.pixbuf_get_from_surface(surface, 0, 0, surface.get_width(), surface.get_height())
cursor = Gdk.Cursor.new_from_pixbuf(display, pbdrawn, radius, radius)
self.darea.get_screen().get_root_window().set_cursor(cursor)
def press(self, widget, event):
if (event.keyval == 93):
self.radius = self.radius + 2
self.custom_cursor(self.radius)
elif (event.keyval == 91):
self.radius = self.radius - 2
self.custom_cursor(self.radius)
win = MainWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
编辑:这可能是图形问题。如果有人能确认有(没有)噪音,我将不胜感激。
来自 gdk_pixbuf_new
的文档:
Note that the buffer is not cleared; you will have to fill it completely yourself.
https://developer.gnome.org/gdk-pixbuf/2.36/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new
基本上,您在这里看到的是未初始化的内存。
我建议直接创建一个 cairo 图像表面,而不是创建一个 pixbuf 只是为了将它转换为 cairo 表面。开罗为你初始化新的图像表面