根据你的问题,我假设你想将两张图片合并在一起,并从一张图片到另一张图片进行某种淡入淡出?
我使用了 OpacityMask 和 LinearGradient,它们都是 Qt 5 Compatibility API 的一部分。根据您使用的 Qt 版本,您可以使用:
示例工作如下:
LinearGradient
,用作遮罩。visible: false
隐藏它们)。OpacityMask
实例,它们都应用了相同的蒙版(底部使用invert: true
)和不同的源图像。我还建议使用自定义 shaders 以实现该效果,因为它会更快并且不像绘制
OpacityMask
两次那样多余。
编辑: 我已经添加了提到的
ShaderEffect
和随附的片段着色器。结果与 OpacityMask
解决方案有点不同,但这也可能是由于该示例使用的 GLSL mix()
函数。
我的示例使用的是 Qt 6.4.0,您可以从这里获得完整的源代码。
import QtQuick
import Qt5Compat.GraphicalEffects
Window {
id: root
width: 640
height: 940
visible: true
title: qsTr("Hello World")
readonly property int _width: 200
readonly property int _height: 300
LinearGradient {
id: mask
width: root._width
height: root._height
start: Qt.point(0, 0)
end: Qt.point(0, root._height)
visible: false
gradient: Gradient {
GradientStop { position: 0.0; color: "black" }
GradientStop { position: 1.0; color: "transparent" }
}
}
Grid {
columns: 3
spacing: 20
Image {
id: imgSourceTop
source: "https://picsum.photos/id/54/%1/%2".arg(root._width).arg(root._height)
smooth: true
}
Image {
id: imgSourceBottom
source: "https://picsum.photos/id/93/%1/%2".arg(root._width).arg(root._height)
smooth: true
}
Item {
width: root._width
height: root._height
OpacityMask {
anchors.fill: parent
source: imgSourceTop
maskSource: mask
}
OpacityMask {
anchors.fill: parent
source: imgSourceBottom
maskSource: mask
invert: true
}
}
LinearGradient {
id: gradientSourceTop
width: root._width
height: root._height
start: Qt.point(0, 0)
end: Qt.point(root._width, 0)
gradient: Gradient {
GradientStop { position: 0.0; color: "#1E9600" }
GradientStop { position: 0.5; color: "#FFF200" }
GradientStop { position: 1.0; color: "#FF0000" }
}
}
LinearGradient {
id: gradientSourceBottom
width: root._width
height: root._height
start: Qt.point(0, 0)
end: Qt.point(root._width, 0)
gradient: Gradient {
GradientStop { position: 0.0; color: "#833ab4" }
GradientStop { position: 0.5; color: "#fd1d1d" }
GradientStop { position: 1.0; color: "#fcb045" }
}
}
Item {
width: root._width
height: root._height
OpacityMask {
anchors.fill: parent
source: gradientSourceTop
maskSource: mask
}
OpacityMask {
anchors.fill: parent
source: gradientSourceBottom
maskSource: mask
invert: true
}
}
Image {
id: shaderSourceTop
source: "https://picsum.photos/id/54/%1/%2".arg(root._width).arg(root._height)
smooth: true
}
Image {
id: shaderSourceBottom
source: "https://picsum.photos/id/93/%1/%2".arg(root._width).arg(root._height)
smooth: true
}
ShaderEffect {
width: root._width
height: root._height
property variant sourceTop: shaderSourceTop
property variant sourceBottom: shaderSourceBottom
fragmentShader: "shaders/blend.frag.qsb"
}
}
}
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D sourceTop;
layout(binding = 2) uniform sampler2D sourceBottom;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
};
void main()
{
vec4 top = texture(sourceTop, qt_TexCoord0);
vec4 bottom = texture(sourceBottom, qt_TexCoord0);
fragColor = mix(top, bottom, qt_TexCoord0.y);
}
我不确定这是你要问的,但是,我尝试使用 QML 重新创建你的图像。第二张图片我使用平铺的 SVG 图像作为基础,然后在顶部我使用 LinearGradient 但我设置了不透明度所以我可以看到部分基础:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
Page {
id: page
ColumnLayout {
Frame {
Layout.preferredWidth: 500
Layout.preferredHeight: 300
LinearGradient {
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(width, 0)
gradient: Gradient {
GradientStop { position: 0.0; color: "yellow" }
GradientStop { position: 1.0; color: "purple" }
}
}
}
Frame {
Layout.preferredWidth: 300
Layout.preferredHeight: 300
padding: 0
Image {
anchors.fill: parent
source: "squares.svg"
fillMode: Image.Tile
}
LinearGradient {
anchors.fill: parent
start: Qt.point(0, height)
end: Qt.point(0, 0)
gradient: Gradient {
GradientStop { position: 0.0; color: "white" }
GradientStop { position: 1.0; color: "blue" }
}
opacity: 0.5
}
}
}
}
// squares.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect x="0" y="0" width="16" height="16" fill="#ccc"/>
<rect x="16" y="0" width="16" height="16" fill="#eee"/>
<rect x="0" y="16" width="16" height="16" fill="#eee"/>
<rect x="16" y="16" width="16" height="16" fill="#ccc"/>
</svg>
您可以在线试用!