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

Qt 如何在qml中沿特定路径剪裁图像,qt,qml,qtquick2,qtquickcontrols,qquickitem,Qt,Qml,Qtquick2,Qtquickcontrols,Qquickitem,我有一个背景图像 为此,我必须使用进度填充图像生成进度条效果 如何沿进度条的凹槽路径剪裁进度填充图像(背景凹槽图像)。 目前我正在尝试做横向剪切,但这不是我想要的。剪切应该垂直于路径进行,如我的代码的路径插值器中所述。 在代码“RPM_BG.png”中,是与“RPM_Fill.png”(进度填充图像)形状相似的背景槽图像 导入QtQuick 2.5 导入QtQuick.Window 2.2 导入QtGraphicalEffects 1.0 导入QtQuick.Controls 1.4 导入多

我有一个背景图像

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

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

导入QtQuick 2.5
导入QtQuick.Window 2.2
导入QtGraphicalEffects 1.0
导入QtQuick.Controls 1.4
导入多媒体5.0
导入QtQuick.Controls.Styles 1.4
窗口{
可见:正确
颜色:“黑色”
宽度:357
高度:221+200
形象
{
id:groove1
来源:“qrc:/RPM\u BG.png”
锚。顶部:父级。顶部
锚。左:父。左
项目{
id:displayWindow1
高度:parent.height
宽度:(225*(滑块值)/8000)+32
剪辑:对
.bottom:parent.bottom
anchors.left:parent.left
锚。右:针。右
archors.rightMargin:/*8*/{开关(true)
{
大小写slider.value>=0&&slider.value<111:返回10;
大小写slider.value>=111&&slider.value<124:返回9.7;
大小写slider.value>=124&&slider.value<132:返回8.4;
大小写slider.value>=132&&slider.value<135:返回8;

case slider.value>=135&&slider.value=165&&slider.value您可以为此使用基本片段着色器。类似于:

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;
        }"
    }
ShaderEffect{
id:displayWindow2
高度:groove1.height
宽度:槽1.5米宽
anchors.top:parent.top
anchors.right:父项.right
属性变量base:groove1
属性变量覆盖:speedarcfill
属性real pointX:motionPath.x/width
属性实数pointY:motionPath.y/height
属性实点角度:(motionPath.angle+90)%360
碎片着色器:“
均匀的二维基底;
均匀二维叠加;
可变高vec2qt_TexCoord0;
均匀低浮动qt_不透明度;
均匀高浮点数角;
均匀高p浮点x;
均匀高p浮点;
void main(){
lowp vec4 baseTex=纹理2d(基本,qt_TexCoord0.st);
lowp vec4 overlayTex=纹理2d(叠加,qt_TexCoord0.st);
//直线方程=>(y-y1)/(x-x1)=斜率;斜率!=无穷大
highp浮动角度=弧度(点角);
高P浮动斜率=tan(角度);
highp float deltay=qt_TexCoord0.y-pointY;
highp float deltax=qt_TexCoord0.x-pointX;
//如果覆盖是透明的,则从底部获取纹理
如果(overlytex.a>0.0)
{
//检查当前点所在的位置,并与正常点进行比较。
如果((斜率>=0.0&&deltay-deltax*斜率>0.0)| |(斜率<0.0&&deltax<0.0))
gl_FragColor=叠加*qt_不透明度;
else gl_FragColor=baseTex*qt_不透明度;
}
else gl_FragColor=baseTex*qt_不透明度;
}"
}
这是完整的文件,我已经在这里讨论过写这个:

您可以查看。
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;
        }"
    }