2017-09-04 2 views
-1

QT Quick 응용 프로그램에서 QR 코드를 그래픽으로 표현하는 가장 좋은 방법은 무엇입니까 (성능 및 메모리 소비 측면에서)?QR 코드를 렌더링하는 쉐이더

QR 코드 비트 맵은 일부 셰이더를 사용하여 흑백 셀의 정사각형 행렬로 그래픽으로 표현할 수 있다고 생각합니다. 성능에 최적화 된 솔루션이 될 것입니다.

현재 GridView의 묶음으로 만 초를 생성 할 수 있습니다. 그것은 저장할 메모리와 CPU/GPU 렌더링 시간 낭비로 간주됩니다.

셰이더는 어떻게 생겼을까요?

라고 말하면 QBitArrayn*n입니다.

답변

1

쉐이더 자체는 간단합니다. 기본적으로 조각 위치 x와 y를 qr 코드 크기와 행과 열로 나누고 두 개를 추가하여 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는 제작에 시간을 투자 할 가치가 없다는 것은 더 복잡한 저수준 솔루션입니다.

을 구현하고 qr 코드 데이터를 이미지로 변환 한 다음 smooth: false으로 원하는 크기로 이미지를 확대하면 희미 해지지 않고 선명한 결과가 유지됩니다. 바로 이것이 가장 직접적이고 효율적이며 간단한 솔루션입니다.

+0

비 래스터 이미지를 생성 할 수 있습니까? 말해봐, SVG xml? – Orient

+0

@Orient - SVG가 여전히 특정 크기로 렌더링되도록 래스터 화되기 때문에 아무런 의미가 없습니다. SVG QR 코드는 비트 맵보다 많은 공간을 차지합니다. 부드럽게 해제하면 비트 맵이 완벽하고 무한대로 확장됩니다. – dtech

1

응용 프로그램에 QR 코드가 하나만 있으면 시간을 절약하고 GridView를 수행하십시오.

다른 옵션은 다음과 같습니다

  • C++ 사용자 정의 QQuickItem : 생성하고 텍스처를로드 (Qt는 장면 그래프 API)
  • C++ 사용자 정의 QQuickFramebufferObject : 텍스처를 생성하고로드 (대부분 순수의 OpenGL API)
  • C++ 사용자 정의 QQuickPaintedItem (QPainter를 2 차원 API)
  • QML-JS 캔버스/Context2D (HTML 차원 API)
  • QML-JS Canvas3D/Context3D : 생성하고 테로드 xture (WebGL API) - 다른 모든 C++ 옵션과 비슷하지만 JS 버전의 OpenGL에서
  • C++ 사용자 정의 QQuickImageProvider : 전체 QR 데이터를 이미지 이름으로 사용자 정의 QQuickImageProvider으로 전달하면서 텍스처 (ImageProvider 및 OpenGL API)를 생성하고로드합니다.

텍스처 대신 정점 버퍼/균일 버퍼를 사용하면 효과가 있지만 특이한 셰이더 코드가 필요합니다. QR은 질감으로 더 적합하다고 생각합니다.

+0

반대로 셰이더는 실제로 매우 평범하고 사소한 것입니다. – dtech

관련 문제