【发布时间】:2018-12-09 07:52:41
【问题描述】:
我正在尝试使用洪水填充算法为 QML 画布实现“桶填充”工具。我的initial implementation in pure QML/Javascript 运行良好,但(预计)速度很慢,并且在移动设备上基本上无法使用。
我想用 C++ 来实现它。不幸的是,使用 C++ 共享 QML 画布内容并不简单/不受支持/未记录。
我目前的方法很复杂,而且肯定效率不高:我首先使用 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 重新编码来访问 C++ QImage,然后在 QML 中使用 base64 字符串作为图像源。
总结: canvas -> base64 encoding via toUrlData -> C++ -> decode into QImage -> flood fill -> re-encode into base64 string -> decode as QML image -> 在画布上绘制 QML 图像。
这显然是非常低效的。
理想情况下,我想从 C++ 访问画布'CanvasImageData 的内存地址以直接编辑像素,无需任何副本。
下一个最佳选择是双向复制 CanvasImageData(但不幸的是,CanvasImageData 的 C++ 类型是私有的)。
还有其他建议吗?
(我想补充一点,我也查看了QImageProvider 界面,但我不知道如何在这种情况下使其工作,因为图像提供程序必须在我的 QML 插件中实例化,并且我看不到如何将图像提供程序注册到 QML 引擎)。
【问题讨论】:
-
您应该实现从 QQuickItem 或 QQuickPaintedItem 派生的自定义类
-
谢谢@folibis,这确实是最好的选择。