如何在qml中沿特定路径剪辑图像

Posted

技术标签:

【中文标题】如何在qml中沿特定路径剪辑图像【英文标题】:how to clip an image along specific path in qml 【发布时间】:2017-05-24 19:10:36 【问题描述】:

我有一个背景凹槽图像

为此我必须使用进度填充图像来产生进度条效果

如何沿进度条的凹槽路径(背景凹槽图像)剪辑进度填充图像。 目前我正在尝试横向裁剪,但这不是我想要的。如我的代码的路径插值器中所述,剪切应该垂直于路径。 代码中“RPM_BG.png”是背景凹槽图像,其形状与“RPM_Fill.png”(进度填充图像)相似。

import QtQuick 2.5
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.4
import QtMultimedia 5.0
import QtQuick.Controls.Styles 1.4
Window 
    visible: true
    color:"black"
        width: 357
        height: 221+200


        Image
        
            id:groove1
            source:"qrc:/RPM_BG.png"
            anchors.top:parent.top
            anchors.left:parent.left

            Item
                        id: displayWindow1
                        height: parent.height 
                         width: (225*(slider.value)/8000)+32


                        clip: true

                            anchors.bottom: parent.bottom
                            anchors.left: parent.left
                            anchors.right:needle.right
                            anchors.rightMargin:/*8*/switch(true)
                            
                                case slider.value>=0 && slider.value < 111:return 10;
                                case slider.value>=111 && slider.value < 124:return 9.7;
                                case slider.value>=124 && slider.value < 132:return 8.4;
                                case slider.value>=132 && slider.value < 135:return 8;
                                case slider.value>=135 && slider.value <= 165:return 7.15;
                                case slider.value>=165 && slider.value <= 240:return 6;

                                
                            

                        Image
                        
                            id:speedarcfill
                            anchors.top:parent.top
                            anchors.left:parent.left
                            source:"qrc:/RPM_Fill.png"
                            z: 1
                        
                    

        PathInterpolator 
            id: motionPath
            property int value

            path: Path 
                startX: 27; startY: 189
                PathLine  x: 98; y: 54 
                PathArc  x: 176; y: 12; radiusX: 90; radiusY: 90 
                PathLine  x: 245; y: 11 
            
            progress:slider.value/8000
        
        

        Slider 
                    id: slider
                    anchors.top:groove1.bottom
                    anchors.topMargin:100
                    anchors.left:parent.left
                    anchors.leftMargin: 5
                    width: parent.width-10
                    height: 100

                    style: SliderStyle 
                        handle:
                            Rectangle 
                                        anchors.centerIn: parent
                                        color: control.pressed ? "white" : "lightgray"
                                        border.color: "gray"
                                        implicitWidth: 10
                                        implicitHeight: 40
                                    

                        groove: Rectangle 
                            width: slider.width
                            height: 10
                            color:"black"

                            LinearGradient 
                                anchors.verticalCenter: parent.verticalCenter
                                start: Qt.point(0, 0)
                                end: Qt.point(parent.width, 0)
                                width: styleData.handlePosition
                                height: 10

                                gradient: Gradient 
                                    GradientStop position: 0.0; color: "#008BFF" 
                                    GradientStop position: 0.5; color: "#3FFFD0" 
                                    GradientStop  position: 1.0; color: "#3FFF41" 
                                
                            
                        

                    

                    maximumValue: 8000

                

    

请为我建议一种方法,以便我可以垂直于进度路径剪辑进度填充图像。

【问题讨论】:

您可以查看OpacityMask 【参考方案1】:

您可以为此使用基本的片段着色器。比如:

ShaderEffect 
        id: displayWindow2
        height: groove1.height
        width: groove1.width
        anchors.top: parent.top
        anchors.right: parent.right

        property var base: groove1
        property var overlay: speedarcfill
        property real pointX: motionPath.x/width
        property real pointY: motionPath.y/height
        property real pointAngle: (motionPath.angle  + 90)%360

        fragmentShader: "
        uniform sampler2D base;
        uniform sampler2D overlay;
        varying highp vec2 qt_TexCoord0;
        uniform lowp float qt_Opacity;
        uniform highp float pointAngle;
        uniform highp float pointX;
        uniform highp float pointY;
        void main() 
            lowp vec4 baseTex = texture2D(base, qt_TexCoord0.st);
            lowp vec4 overlayTex = texture2D(overlay, qt_TexCoord0.st);
            //line equation => (y - y1)/(x - x1) = slope ; slope != infinity
            highp float angle = radians(pointAngle);
            highp float slope = tan(angle);
            highp float deltay = qt_TexCoord0.y - pointY;
            highp float deltax = qt_TexCoord0.x - pointX;

            //If overlay is transparent, get the texture from base
            if(overlayTex.a > 0.0)
            
                //check where the current point lies, wrt the normal.
                if( ( slope >= 0.0 && deltay - deltax*slope > 0.0 ) || (slope < 0.0 && deltax < 0.0))
                    gl_FragColor = overlayTex * qt_Opacity;
                else gl_FragColor = baseTex*qt_Opacity;
            
            else gl_FragColor = baseTex*qt_Opacity;
        "
    

这是完整的文件,我已经尝试过写这个:https://bpaste.net/show/2b0c0fd1cc69

【讨论】:

以上是关于如何在qml中沿特定路径剪辑图像的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SVG 剪辑路径中居中对齐图像?

在 iOS 中沿路径均匀地绘制图像

如何使用 CSS 在两个图像之间创建剪辑路径 [关闭]

使用 Python / PIL 进行多边形裁剪/剪辑

如何使用 SVG 形状进行图像剪辑?

javascript - 如何使用 drawImage/putImageData 进行剪辑