我已经编写了一个小类来从base64编码的JPEG字节数组创建一个圆形图像,但它似乎经常导致segfault。这是我能找到的在GJS中创建cairo曲面的最简单方法,尽管我并不反对Clutter,如果它能解决我的问题的话。
var CircularImage = new Lang.Class({
Name: "CircularImage",
Extends: Gtk.DrawingArea,
_init: function (bytearray, win, size) {
this.parent({
height_request: size,
width_request: size
});
this.size = size;
let image_stream = Gio.MemoryInputStream.new_from_data(
GLib.base64_decode(bytearray),
GLib.free
);
let pixbuf = GdkPixbuf.Pixbuf.new_from_stream(
image_stream,
null
)
pixbuf.scale_simple(this.size, this.size, GdkPixbuf.InterpType.HYPER);
this._surface = Gdk.cairo_surface_create_from_pixbuf(
pixbuf,
0,
win.get_window()
);
this.connect("draw", (widget, cr) => {
this._draw(widget, cr);
return false;
});
},
_draw: function (widget, cr) {
cr.setSourceSurface(this._surface, 0, 0);
cr.arc(this.size/2, this.size/2, this.size/2, 0, 2*Math.PI);
cr.clip();
cr.paint();
}
});
CairoImageSurface似乎没有破坏功能或信号,我试着打开pixbuf看看是否有帮助,但这导致了一个错误:
GLib GObject警告**:g_object_remove_toggle_ref:找不到切换引用0x7f445456b19e0((零))
我在一个简单的Gtk窗口中使用过它,它很有效,但它似乎有一半的时间会导致segfault。我对内存管理知之甚少,因为我通常使用垃圾收集语言,所以我只认为这与我没有释放的内存有关。
有没有什么明显的我做错了,用Clutter更简单的方法来做这件事,或者用简单的方法追踪任意的segfault?
即使底层库需要,也不应该在GJS中处理内存管理。如果这样做,那就是一个错误。无论如何,尝试这样做肯定会导致崩溃。(因此,如果你在GJS文档中看到任何调用GLib.free()
或GObject.unref()
的指令,它们是从C文档中自动生成的,不应该存在。)
不幸的是,这种需要您关心内存管理的错误仍然存在,其中两个错误与您的代码片段有关。
您现在遇到的错误是:https://bugzilla.gnome.org/show_bug.cgi?id=747431相反,做一些类似的事情:
let image_stream = Gio.MemoryInputStream.new_from_bytes(
GLib.base64_decode(bytearray).toGBytes());
另一个稍后可能变得相关的GJS错误是,当您连接到draw
信号时,您当前必须在Cairo上下文上调用cr.$dispose()
,否则内存将泄漏。