如何用QML/JavaScript/Fragment实现垂直渐变+横向分色的图像合成
实现垂直淡入线性渐变的多方案(QML/JS/Fragment Shader)
以下是针对两张图像合成、从上到下垂直淡入线性渐变的不同技术实现方案,包含具体代码示例:
一、QML 实现方案
利用 Qt Quick 的图形特效组件,通过遮罩实现上层图像的垂直渐变显示:
import QtQuick 2.15 import QtGraphicalEffects 1.15 Item { width: 400 height: 600 // 底层背景图 Image { id: bgImage anchors.fill: parent source: "background.png" // 替换为你的背景图路径 } // 上层需渐变淡入的图 Image { id: topImage anchors.fill: parent source: "top-layer.png" // 替换为你的上层图路径 visible: false } // 垂直渐变遮罩:从上到下从全透明过渡到不透明 OpacityMask { anchors.fill: parent source: topImage maskSource: LinearGradient { anchors.fill: parent start: Qt.point(0, 0) end: Qt.point(0, parent.height) gradient: Gradient { GradientStop { position: 0.0; color: "#00000000" } // 顶部完全透明 GradientStop { position: 1.0; color: "#FFFFFFFF" } // 底部完全不透明 // 可添加中间过渡色:GradientStop { position: 0.5; color: "#80FFFFFF" } } } } }
二、Web端 JavaScript 实现
方案1:CSS 遮罩快速实现
通过 CSS mask-image 属性给上层图像添加垂直渐变遮罩:
<div class="image-container"> <img src="background.png" alt="背景图" class="bg-img"> <img src="top-layer.png" alt="上层图" class="top-img"> </div> <style> .image-container { position: relative; width: 400px; height: 600px; overflow: hidden; } .bg-img, .top-img { position: absolute; width: 100%; height: 100%; object-fit: cover; } .top-img { -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,1)); mask-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,1)); // 若需带颜色的渐变叠加,可替换为: // background: linear-gradient(to bottom, #ff000000, #ff0000ff); // mix-blend-mode: multiply; } </style>
方案2:Canvas 手动绘制合成
通过 JavaScript 操控 Canvas 完成图像采样与渐变混合:
const canvas = document.getElementById('gradientCanvas'); const ctx = canvas.getContext('2d'); canvas.width = 400; canvas.height = 600; const bgImg = new Image(); const topImg = new Image(); let loadedCount = 0; function draw() { if (loadedCount < 2) return; // 绘制背景图 ctx.drawImage(bgImg, 0, 0, canvas.width, canvas.height); // 创建垂直线性渐变 const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height); gradient.addColorStop(0, 'rgba(255,255,255,0)'); // 顶部透明 gradient.addColorStop(1, 'rgba(255,255,255,1)'); // 底部不透明 // 应用渐变遮罩并绘制上层图 ctx.save(); ctx.fillStyle = gradient; ctx.rect(0, 0, canvas.width, canvas.height); ctx.clip(); ctx.drawImage(topImg, 0, 0, canvas.width, canvas.height); ctx.restore(); } bgImg.onload = () => { loadedCount++; draw(); }; topImg.onload = () => { loadedCount++; draw(); }; bgImg.src = 'background.png'; topImg.src = 'top-layer.png';
三、Fragment Shader 实现(以 Qt Quick ShaderEffect 为例)
通过着色器直接控制像素级颜色混合,实现更灵活的渐变效果:
import QtQuick 2.15 Item { width: 400 height: 600 Image { id: bgImage anchors.fill: parent source: "background.png" } Image { id: topImage anchors.fill: parent source: "top-layer.png" visible: false } ShaderEffect { anchors.fill: parent property variant source: bgImage property variant topSource: topImage fragmentShader: " varying highp vec2 qt_TexCoord0; uniform sampler2D source; uniform sampler2D topSource; uniform highp float qt_Opacity; void main() { highp vec4 bgColor = texture2D(source, qt_TexCoord0); highp vec4 topColor = texture2D(topSource, qt_TexCoord0); // 基于Y轴坐标计算渐变因子(0=顶部,1=底部) highp float gradientFactor = qt_TexCoord0.y; // 可调整渐变曲线:gradientFactor = pow(gradientFactor, 2.0); // 混合两张图颜色 highp vec4 finalColor = mix(bgColor, topColor, gradientFactor); gl_FragColor = finalColor * qt_Opacity; } " } }
相关学习方向
- QML:参考 Qt 官方文档中
LinearGradient、OpacityMask、ShaderEffect模块的示例,覆盖基础图形合成逻辑。 - Web端:MDN 文档中关于 CSS 遮罩、Canvas 图像绘制的章节,有详细的渐变合成教程。
- Fragment Shader:学习 OpenGL ES 着色器基础,重点掌握纹理采样与颜色混合的核心逻辑,多数图形编程入门教程都会包含线性渐变实现内容。
内容的提问来源于stack exchange,提问作者S At
相关产品推荐
相关产品推荐

