与 OpacityMask 相反

Opposite for OpacityMask

它用另一个项目遮盖源项目,因此只有在遮罩不透明的情况下,源才可见。如何使源仅在蒙版透明的地方可见?

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

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

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

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

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

如果你喜欢使用 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;
                }
            "
        }
    }
}