【问题标题】:Back and forth between QML Canvas and C++在 QML Canvas 和 C++ 之间来回切换
【发布时间】: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,这确实是最好的选择。

标签: c++ qt canvas qml


【解决方案1】:

@folibis 建议使用QQuickPaintedItem 是我最终采取的方法,并有效地解决了我的问题——然而不幸的是,不得不在此过程中基本上放弃 QML 画布对象。

【讨论】:

  • 任何提示或指向有关如何做到这一点的来源或材料?
猜你喜欢
  • 2022-08-08
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 2020-01-03
  • 1970-01-01
  • 2019-10-17
  • 2020-02-15
  • 2012-06-29
相关资源
最近更新 更多