在QML Canvas和C ++之间来回

时间:2018-12-07 22:23:35

标签: c++ qt canvas qml

我正在尝试使用泛洪填充算法为QML画布实现“存储桶填充”工具。我的initial implementation in pure QML/Javascript运行良好,但(预期)运行缓慢,并且在移动设备上基本上无法使用。

我想改为用C ++实现。不幸的是,与C ++共享QML canvas内容并不简单/不支持/未记录。

我当前的方法很复杂,而且肯定效率不高:我首先使用canvas.dataToUrl("image/bmp")序列化画布内容,将base64编码的图像传递给执行填充的C ++ QML插件:

void FloodFill::setImageData(const QString &data)
{
    QByteArray base64Data = data.mid(22).toUtf8();

    QImage image;
    image.loadFromData(QByteArray::fromBase64(base64Data), "BMP");

    fill(image);

    emit onCanvasFilled();
}

然后,在下一次QML画布重绘时,我通过在C ++一侧的base64中对其重新编码,然后使用base64字符串作为QML中的图像源来访问C ++ QImage

总结:画布->通过toUrlData进行base64编码-> C ++->解码为QImage->泛洪填充->重新编码为base64字符串->解码为QML图像->在画布上绘制QML图像。

这显然效率很低。

理想情况下,我想从C ++访问画布'CanvasImageData的内存地址,以直接编辑像素,而无需任何副本。

下一个最佳选择是同时复制CanvasImageData的两种方式(但是不幸的是,CanvasImageData的C ++类型是私有的)。

还有其他建议吗?

(我想补充一下,我在QImageProvider界面上的外观也不错,但是我看不到如何在这种情况下使用它,因为必须在我的内部实例化图像提供者QML插件,我看不到如何向QML引擎注册图像提供程序。

1 个答案:

答案 0 :(得分:0)

@folibis建议使用QQuickPaintedItem是我最终采取的途径,可以有效地解决我的问题-但是,不幸的是,在此过程中必须放弃QML画布对象。