2017-09-04 16 views
-1

QT QuickアプリケーションでQRコードをグラフィカルに表現するにはどうすればよいですか?QRコードをレンダリングするシェーダ

QRコードのビットマップは、いくつかのシェーダーを使って白黒セルの正方行列としてグラフィカルに表現できると思います。パフォーマンスに最適なソリューションです。

現在、私はGridViewの束を使って作成することができます。長方形 s。それは記憶するメモリの浪費とCPU/GPUのレンダリング時間とみなされます。

シェイダーの外観はどうですか?

と言って、QBitArrayn*nサイズを指定します。

答えて

1

基本的にシェーダ自体は簡単ですが、基本的にフラグメント位置xとyをqrコードサイズとフロアで分割して行と列を得てから、その2つを足して1dインデックスを探してからqtデータを検索しますそのインデックスに配列、0が含まれている場合はフラグメントの色は白、1の場合は黒です。

しかし、QMLシェーダは現在、通常の1d配列を渡す機能を提供していません。

配列をビットマップイメージに変換して配列に渡す必要があります。これは、QImageをQMLと連携させるためにイメージプロバイダを実装する必要があることを意味します。なぜなら、デフォルトではありません。

私はパフォーマンスについてあまり気にしませんが、それは時期尚早の最適化です。これは99%のケースでは悪いです。でも些細な、100%のQMLのソリューションは、十分に高速である:100×100 QRコードを描画

私のシステムで
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") 
    } 
    } 
} 

は、約2ミリ秒かかります。 IMOは十分に優れており、作成に時間を費やすのに本当に価値がないので、より複雑な低レベルの解決策です。

image providerを実装し、qrコードデータを画像に変換して、ぼかしを避けて鮮明な結果を保存するsmooth: falseで画像を拡大縮小します。これははるかに直接的で効率的で簡単な解決策です。

+0

非ラスタ画像を生成することは可能ですか?言って、SVG xml? – Orient

+0

@Orient - SVGはまだ特定のサイズでレンダリングするためにラスタライズされるため、意味はありません。 SVGのQRコードは、ビットマップよりも多くの領域を占有します。スムーズを無効にすると、ビットマップは完全に無期限にスケールアップされます。 – dtech

1

アプリケーションにQRコードが1つしかない場合は、時間を節約して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:QRデータ全体を画像名としてカスタムQQuickImageProviderに渡しながらテクスチャ(ImageProviderおよびOpenGL API)を生成して読み込みます

テクスチャの代わりに頂点バッファ/均一バッファを使用することはできますが、異常なシェーダコードが必要です。 QRはテクスチャとしてもっとフィットすると思います。

+0

それどころか、シェーダは実際には非常に普通で些細なものになります。 – dtech

関連する問題