Qt:如何将2个QQuickItems合并为一个,然后将其保存到png中

Gam*_*ads 2 qt qimage qml qquickitem

通过对StackOverflow的讨论,我可以将QML项目中的图像保存到文件中png/jpeg.

如何叠加或合并两个不同的qml图层并将它们合并为一个,以将其保存为png/jpeg?

注意:我可以保存一个QQuickItem.只需要知道如何覆盖2 QQuickItem

dte*_*ech 5

只需将两个qml对象作为根的子对象Item,然后抓取该根项,它将捕获其所有内容.

只需确保根项目足够大以包围子项,并且子项不在负空间中,因为它只捕获根项目的足迹内部.

您也可以使用C++甚至QML进行手动合成.

你评论中描述的问题是你不能移动东西,所以你能做什么?您可以拥有两个Image元素,而不是将原始QML对象作为同一根的父元素,然后捕获项目A并将捕获结果设置为图像A的源,然后对项目B执行相同操作,最后,捕获根项目,将两个图像一起捕获.

好的,这是一个简单的例子,它看起来有点复杂,因为抓取是异步的,你必须等待单个抓取结果完成才能获得"最终"根项,从而使用计时器.在此示例中,不同的项目连续排列,但您可以按照自己喜欢的方式组合它们:

ApplicationWindow {
  id: window
  visible: true
  width: 640
  height: 480

  Rectangle {
    id: s1
    visible: false
    width: 200
    height: 200
    color: "red"
  }
  Rectangle {
    id: s2
    visible: false
    width: 200
    height: 200
    color: "blue"
  }

  Row {
    id: joiner
    visible: false
    Image { id: t1 }
    Image { id: t2 }
  }

  Image {
    id: result
    y: 200
  }

  Timer {
    id: finish
    interval: 10
    onTriggered: joiner.grabToImage(function(res) {result.source = res.url})
  }

  Component.onCompleted: {
    s1.grabToImage(function(res) {t1.source = res.url})
    s2.grabToImage(function(res) {t2.source = res.url; finish.start() })
  }
}
Run Code Online (Sandbox Code Playgroud)

首先捕获两个矩形并将其用作木匠中图像的源,然后捕获木匠并在结果图像中显示,除最终结果图像之外的所有对象都被隐藏.

更简单的是,您可以使用这个漂亮的小帮手快速加入单个图像中的任意数量的项目:

  Item {
    id: joinHelper
    visible: false
    property Component ic: Image { }
    property var cb: null

    Row { id: joiner }

    Timer {
      id: finish
      interval: 100
      onTriggered: joiner.grabToImage(joinHelper.cb)
    }

    function join(callback) {
      if (arguments.length < 2) return // no items were passed
      var i
      if (joiner.children.length) { // clean previous captures
        for (i = 0; i < joiner.children.length; ++i) {
          joiner.children[i].destroy()
        }
      }
      cb = callback // set callback for later
      for (i = 1; i < arguments.length; ++i) { // for every item passed
        var img = ic.createObject(joiner) // create empty image
        // need to capture img by "value" because of JS scoping rules
        // otherwise you end up with only one image - the final one
        arguments[i].grabToImage(function(temp){ return function(res){temp.source = res.url}}(img))
      }
      finish.start() // trigger the finishing step
    }
  }
Run Code Online (Sandbox Code Playgroud)

你这样使用它:

joinHelper.join(function(res) { result.source = res.url }, s1, s2)
Run Code Online (Sandbox Code Playgroud)

它仍然使用一行,但您可以轻松调整它以进行自己的布局.它通过传递最终回调和你想要捕获的所有项目来工作,在内部它为每个项目创建一个图像,将它们放入容器中,然后触发完成计时器.

请注意,根据系统的速度和项目的复杂程度以及计数的大小,您可能需要延长计时器间隔,因为最终的回调需要在所有捕获完成后才执行,图像源已分配并调整图像大小以使行具有适当的尺寸.

我还注释了大多数事情,以便更容易理解.