2

我编写了一个小类来从 base64 编码的 JPEG 字节数组创建一个圆形图像,但它似乎经常导致段错误。这是我能找到的在 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-WARNING **:g_object_remove_toggle_ref:找不到切换参考 0x7f45456b19e0((nil))

我在一个简单的 Gtk 窗口中使用了它并且它可以工作,但它似乎会导致大约一半的时间段错误。我对内存管理知之甚少,因为我通常使用垃圾收集语言,所以我只假设这与我没有释放的内存有关。

有没有什么明显的我做错了,更简单的方法来做这个杂乱或简单的方法我可以追踪任意段错误?

4

1 回答 1

2

即使底层库需要它,您也不应该在 GJS 中处理内存管理。如果你这样做,这是一个错误。无论如何尝试这样做肯定会导致崩溃。(因此,如果您看到任何调用说明,GLib.free()甚至GObject.unref()在 GJS 文档中 - 它们是从 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信号时,您当前必须调用cr.$dispose()Cairo 上下文,否则内存将被泄漏。

于 2017-11-01T02:38:26.180 回答