【问题标题】:Opposite for OpacityMaskOpacityMask 的对面
【发布时间】:2016-09-28 17:18:00
【问题描述】:

它用另一个项目掩蔽源项目,因此源仅在掩码不透明的情况下可见。如何使源仅在蒙版透明的地方可见?

目前它是用着色器完成的,但我想替换它。

不能反转蒙版,因为它由多张图像组成:单个反转图像的总和与总和的反转不同。

【问题讨论】:

  • GraphicalEffects 中的所有组件都在使用着色器。可以肯定的是,没有任何组件可以为您完成 - 您需要自己制作一个。我不知道这里有什么问题。我想到的一个想法是在 C++ 中手动反转你的蒙版,然后在 QML 中应用它,但它比着色器更好吗?我不这么认为。在最好的情况下,差异会很小。你的着色器出了什么问题?
  • @FilipHazubski,至少得到确认没有组件是件好事。在代码审查期间,着色器提出了进一步调查的建议(这就是我的着色器的问题)。

标签: qt qml qt5 opacitymask


【解决方案1】:

Qt 没有任何组件可以满足您的需求。 OpacityMask 最接近您的需要。您可以在官方存储库或您的机器上的以下路径查看其代码hereQt_folder/Qt_version/Qt_kit/qml/QtGraphicalEffects/OpacityMask.qml。这样您就可以轻松浏览所有 QtGraphicalEffects 组件的来源。

使用ShaderEffect 是完成任务的不错选择。

正如GrecKo 指出的那样,OpacityMask 对象中已经有一个invert 属性。它将在 Qt 5.7 中可用,但代码已经在上面的链接中可用。您可以等待更新或下载组件并在您的项目中使用它。

【讨论】:

  • 在链接的代码(OpacityMask 的 Qt 5.7 版本)中有一个 invert 属性。所以你可以复制代码或等待 Qt 5.7 发布并设置invert: true
  • @GrecKo 非常好的建议!我已将其添加到我的答案中(希望您没问题)。
【解决方案2】:

如果您喜欢使用 QML 项目(矩形),您可以使用以下代码:

import QtQuick 2.6

Item {
    anchors.fill: parent
    Image {
        anchors.fill: parent
        source: "http://i.imgur.com/R3yMj0y.jpg"
        fillMode: Image.PreserveAspectCrop
        focus: true
        Keys.onRightPressed: _mask.maskX += 100
        Keys.onLeftPressed: _mask.maskX -= 100
        Keys.onUpPressed: _mask.maskY -= 100
        Keys.onDownPressed: _mask.maskY += 100
        MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            onPositionChanged: {
                _mask.maskX = mouseX;
                _mask.maskY = mouseY;
            }
        }
    }

    Rectangle {
        id: _bk
        anchors.fill: parent
        color: "#33000000"
        visible: false
        layer.enabled: true
        layer.smooth: true
    }

    Rectangle {
        id: _mask
        anchors.fill: parent
        color: "transparent"
        visible: true
        property int maskX: 0
        property int maskY: 0
        Rectangle {
            id: circle
            width: 100; height: 100
            x: _mask.maskX-50; y: _mask.maskY-50
            radius: 50
            color: "#000"
            Behavior on x { NumberAnimation { duration: 400; easing.type: Easing.OutBack; easing.overshoot: 1.4 } }
            Behavior on y { NumberAnimation { duration: 400; easing.type: Easing.OutBack; easing.overshoot: 1.4 } }
        }
        layer.enabled: true
        layer.samplerName: "maskSource"
        layer.effect: ShaderEffect {
            property variant source: _bk
            fragmentShader: "
                varying highp vec2 qt_TexCoord0;
                uniform highp float qt_Opacity;
                uniform lowp sampler2D source;
                uniform lowp sampler2D maskSource;
                void main(void) {
                    gl_FragColor = texture2D(source, qt_TexCoord0.st) * (1.0-texture2D(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
                }
            "
        }
    }
    Rectangle {
        id: _mask2
        anchors.fill: parent
        color: "transparent"
        visible: true
        Rectangle {
            id: circle2
            width: 150; height: 150
            x: _mask.maskX-75; y: _mask.maskY-75
            radius: 75
            color: "#000"
            Behavior on x { NumberAnimation { duration: 550; easing.type: Easing.OutBack; easing.overshoot: 2.4 } }
            Behavior on y { NumberAnimation { duration: 550; easing.type: Easing.OutBack; easing.overshoot: 2.4 } }
        }
        layer.enabled: true
        layer.samplerName: "maskSource"
        layer.effect: ShaderEffect {
            property variant source: _bk
            fragmentShader: "
                varying highp vec2 qt_TexCoord0;
                uniform highp float qt_Opacity;
                uniform lowp sampler2D source;
                uniform lowp sampler2D maskSource;
                void main(void) {
                    gl_FragColor = texture2D(source, qt_TexCoord0.st) * (1.0-texture2D(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
                }
            "
        }
    }
    Rectangle {
        id: _mask3
        anchors.fill: parent
        color: "transparent"
        visible: true
        Rectangle {
            id: circle3
            width: 220; height: 220
            x: _mask.maskX-110; y: _mask.maskY-110
            radius: 110
            color: "#000"
            Behavior on x { NumberAnimation { duration: 650; easing.type: Easing.OutBack; easing.overshoot: 3.0 } }
            Behavior on y { NumberAnimation { duration: 650; easing.type: Easing.OutBack; easing.overshoot: 3.0 } }
        }
        layer.enabled: true
        layer.samplerName: "maskSource"
        layer.effect: ShaderEffect {
            property variant source: _bk
            fragmentShader: "
                varying highp vec2 qt_TexCoord0;
                uniform highp float qt_Opacity;
                uniform lowp sampler2D source;
                uniform lowp sampler2D maskSource;
                void main(void) {
                    gl_FragColor = texture2D(source, qt_TexCoord0.st) * (1.0-texture2D(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
                }
            "
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-07
    • 2015-04-22
    • 2022-06-13
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 2018-01-30
    相关资源
    最近更新 更多