【问题标题】:How to make part of area transparent and the rest show semitransparent?如何使部分区域透明而其余部分显示半透明?
【发布时间】:2018-12-28 15:33:29
【问题描述】:

我正在尝试在图像内创建一个可选择的矩形。

Image {
    id: image
    Rectangle { //full-transparent like a viewport
        id: rect
    }
}

看起来像使用屏幕截图,您选择的区域是全透明的,但其余部分是半透明(或模糊)。

我发现opacitymask 有点相似,但我希望该区域的其余部分显示为半透明,而不仅仅是白色。

本项目完整代码:https://github.com/arkceajin/QtDemos/tree/master/CropBox

【问题讨论】:

    标签: qt qml opacity opacitymask


    【解决方案1】:

    对于这些情况,您必须使用 ShaderEffect:

    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("ShaderEffect Example")
    
        Image {
            id: image
            source: "qrc:/dog.png"
            anchors.centerIn: parent
    
            layer.enabled: true
            layer.effect: ShaderEffect {
                property real alpha: 0.4
                property rect sourceRect: Qt.rect(width/4, height/4, width/2, height/2)
    
                property real xStep: 1/width
                property real yStep: 1/height
    
                fragmentShader: "
                    uniform lowp sampler2D source;
                    varying mediump vec2 qt_TexCoord0;
                    uniform lowp float qt_Opacity;
    
                    uniform highp float alpha;
                    uniform highp vec4 sourceRect;
    
                    uniform highp float xStep;
                    uniform highp float yStep;
    
                    bool insideBox(vec2 topLeft, vec2 bottomRight, vec2 point){
                        vec2 s = step(topLeft, point) - step(bottomRight, point);
                        return (s.x * s.y) > 0.0;
                    }
    
                    void main() {
                        vec2 topLeft = vec2(sourceRect.x*xStep, sourceRect.y*yStep);
                        vec2 bottomRight = topLeft + vec2(sourceRect.z*xStep, sourceRect.w*yStep);
                        gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
                        if(!insideBox(topLeft, bottomRight, qt_TexCoord0))
                            gl_FragColor *= alpha;
    
                    }
                "
            }
        }
    }
    

    输出:

    【讨论】:

    • 谢谢!它完美地工作(即使使用视频而不是图像)!
    • 也可以用OpacityMask制作,下面使用ShaderEffect。或 4 个半透明矩形。
    • @GrecKo 我当前的源使用 4 个矩形,但它必须编写太多代码......ShaderEffect 比这更优雅。如果您发布OpacityMask 的答案,那就太好了:D
    猜你喜欢
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多