2017-09-04 76 views
-1

什么是最好的(在性能和内存消耗意识)的方式来代表QR代码图形Qt快速应用程序?着色器渲染QR代码

我认为QR码位图可以使用一些着色器以图形方式表示为黑白单元的方形矩阵。这将是性能最佳的解决方案。

目前我只能创建一个GridView与一堆矩形 s。存储和CPU/GPU渲染时间被认为是浪费内存。

着色器的外观如何?

说的是QBitArrayn*n大小。

回答

1

着色器本身是微不足道的,基本上你可以将片段位置x和y除以qr代码的大小和层数来获得行和列,然后通过添加两个找到1d索引,然后查找qt数据在该索引处的数组,如果它包含0,则片段颜色为白色,如果它包含1,则颜色为黑色。

但是,QML着色器目前不提供传递常规1d阵列的工具。

您必须将数组转换为位图图像并将其传递给数组,这意味着您还必须实现图像提供者才能使QImage与QML一起使用,因为令人惊讶的是,它仍然不会默认情况下,

我不会为性能打扰太多,这是不成熟的优化,这在99%的情况下是不好的。即使是微不足道的,100%QML的解决方案是足够快:

ApplicationWindow { 
    id: main 
    visible: true 
    width: 640 
    height: 480 
    color: "darkgray" 

    property var qrdata: [] 

    MouseArea { 
    anchors.fill: parent 
    onClicked: { 
     qrdata = [] 
     for (var i = 0; i < (100 * 100); ++i) qrdata.push(Math.round(Math.random())) 
     code.requestPaint() 
    } 
    } 

    Canvas { 
    id: code 
    width: 300 
    height: 300 
    onPaint: { 
     console.time("p") 
     var c = getContext("2d") 
     c.fillStyle = Qt.rgba(1, 1, 1, 1); 
     c.fillRect(0, 0, width, height) 
     c.fillStyle = Qt.rgba(0, 0, 0, 1); 
     var l = qrdata.length 
     var step = Math.sqrt(l) 
     var size = width/step 
     for (var i = 0; i < l; ++i) { 
     if (qrdata[i]) { 
      var rw = Math.floor(i/step), cl = i % step 
      c.fillRect(cl * size, rw * size, size, size) 
     } 
     } 
     console.timeEnd("p") 
    } 
    } 
} 

在我的系统,绘制一个100×100 QR码大约需要2毫秒。海事组织是非常好的,投入时间制作更复杂的低层解决方案并不值得。

不过,我会亲自做的就是实现一个image provider,QR码数据转换成图像,然后缩放该图像一样大,我想smooth: false这将避免模糊并保持一个清晰的结果。这是迄今为止最直接,最有效和最直接的解决方案。

+0

是否可以生成非光栅图像?说,SVG XML? – Orient

+0

@Orient - 没有意义,因为SVG仍然被光栅化以呈现特定的大小。 SVG二维码将比位图占用更多空间。如果禁用平滑,则位图将完美无限地放大。 – dtech

1

如果你在应用程序中只有一个QR码,那么节省你的时间并做一个GridView。

其他选项是:

  • C++定制QQuickItem:生成并加载纹理(Qt的场景图API)
  • C++定制QQuickFramebufferObject:生成并加载纹理(主要是纯的OpenGL API)
  • C++定制QQuickPaintedItem(QPainter的2D API)
  • QML-JS帆布/ Context2D(HTML 2D API)
  • QML-JS Canvas3D /的Context3D:生成并加载一个TE xture(WebGL API) - 与所有其他C++选项一样,但是在OpenGL的JS版本中
  • C++定制QQuickImageProvider:生成并加载纹理(ImageProvider和OpenGL API),同时将整个QR数据作为图像名称传递给您的定制QQuickImageProvider (可能有点太巧了)

使用vertex-buffers/uniform-b​​uffers而不是纹理可能会起作用,但它需要一个不寻常的着色器代码。我认为,QR更适合作为纹理。

+0

相反,着色器实际上是一个非常平常而且微不足道的着色器。 – dtech