目录

  1. 项目概述
  2. 技术栈选择
  3. 架构设计
  4. 核心功能实现
  5. 开发要点与技巧
  6. 常见问题与解决方案
  7. 总结与展望

项目概述

在这里插入图片描述

项目地址:https://gitcode.com/szkygc/HarmonyOs_PC-PGC/tree/main/GraphicsEffect

项目背景

在HarmonyOS应用开发中,图形效果是提升用户体验的重要手段。本项目基于Qt/QML框架和QtGraphicalEffects模块,实现了一个图形效果演示应用,展示了模糊、透明、颜色叠加和阴影四种常见的图形效果,为HarmonyOS应用开发提供实用的图形效果实现方案。

项目目标

本项目的主要目标包括:

  1. 效果实现:实现模糊、透明、颜色叠加和阴影四种图形效果
  2. 实时控制:通过滑块实时调整效果参数,直观展示效果变化
  3. 平台适配:适配HarmonyOS平台的特殊要求,确保效果正常显示
  4. 性能优化:确保图形效果在移动设备上的流畅运行

功能特性

  • 模糊效果(Blur):使用FastBlur实现图片模糊,支持0-30范围调整
  • 透明效果(Opacity):通过opacity属性实现图片透明度控制
  • 颜色叠加效果(Colorize):使用ColorOverlay实现黑色叠加效果
  • 阴影效果(Shadow):使用DropShadow实现图片阴影效果
  • 实时预览:通过滑块实时调整效果参数,即时查看效果变化
  • 响应式布局:支持不同屏幕尺寸的自适应显示

技术栈选择

前端框架:Qt/QML

选择理由:

  1. QtGraphicalEffects模块:提供了丰富的图形效果组件,包括FastBlur、ColorOverlay、DropShadow等
  2. OpenGL硬件加速:图形效果基于OpenGL ES实现,性能优异
  3. 声明式UI:QML的声明式语法使得效果应用更加直观
  4. 跨平台能力:Qt/QML提供了强大的跨平台支持

核心技术点

  • QtQuick 2.15:UI框架
  • QtGraphicalEffects 1.15:图形效果模块
  • FastBlur:快速模糊效果
  • ColorOverlay:颜色叠加效果
  • DropShadow:阴影效果
  • ShaderEffectSource:着色器效果源

架构设计

整体架构

应用采用简单的单页面架构,包含效果展示区域和控制区域:

ApplicationWindow
├── Rectangle (背景)
│   └── ColumnLayout
│       ├── Rectangle (效果展示区域)
│       │   └── GridLayout (2x2网格)
│       │       ├── Column (模糊效果)
│       │       ├── Column (透明效果)
│       │       ├── Column (颜色效果)
│       │       └── Column (阴影效果)
│       └── Rectangle (控制区域)
│           └── ColumnLayout
│               ├── RowLayout (模糊+透明滑块)
│               └── RowLayout (颜色+阴影滑块)

核心属性

// 效果控制参数
property real blurRadius: 0        // 模糊半径 0-30
property real opacityValue: 1.0     // 透明度 1.0-0.0 (值越大越透明)
property real colorizeStrength: 0.0 // 颜色强度 0.0-1.0
property real dropShadowRadius: 0   // 阴影模糊半径 0-100

// UI尺寸配置
readonly property real scaleFactor: width > 1000 ? 2.0 : 1.0
readonly property real imageSize: 192 * scaleFactor
readonly property real fontSize: 14 * scaleFactor
readonly property real titleFontSize: 18 * scaleFactor

核心功能实现

1. 模糊效果(Blur)

功能特点:

  • 使用FastBlur组件实现快速模糊
  • 支持0-30范围的模糊半径调整
  • 通过transparentBorder属性控制边缘处理

实现原理:

Item {
    width: imageSize
    height: imageSize

    Image {
        id: blurImage
        anchors.fill: parent
        source: "qrc:/images/1.png"
        fillMode: Image.PreserveAspectFit
        visible: false  // 源图片不可见
    }

    ShaderEffectSource {
        id: blurSource
        anchors.fill: blurImage
        sourceItem: blurImage
        hideSource: true
    }

    FastBlur {
        anchors.fill: parent
        source: blurSource
        radius: blurRadius * 2.5  // 增强模糊效果
        transparentBorder: true   // 消除边缘边框
    }
}

关键技术点:

  • ShaderEffectSource:将Image转换为着色器效果源
  • FastBlur:快速模糊算法,性能优于GaussianBlur
  • transparentBorder: true:消除模糊边缘的边框效果
  • radius * 2.5:增强模糊效果,使效果更明显

效果增强技巧:

  • 将模糊半径放大2.5倍,使效果更加明显
  • 设置 transparentBorder: true避免边缘出现边框

2. 透明效果(Opacity)

功能特点:

  • 使用Image的opacity属性实现透明度控制
  • 支持0.0-1.0范围的透明度调整
  • 滑块值越大,透明度越高(图片越透明)

实现原理:

Image {
    id: opacityImage
    width: imageSize
    height: imageSize
    source: "qrc:/images/2.png"
    fillMode: Image.PreserveAspectFit
    opacity: opacityValue  // 直接使用opacity属性
}

滑块控制逻辑:

Slider {
    id: opacitySlider
    from: 0
    to: 10
    value: 10 - (opacityValue * 10)  // 反转:滑块值越大,透明度越低
    onValueChanged: {
        opacityValue = 1.0 - (value / 10.0)  // 转换为0.0-1.0
    }
}

关键技术点:

  • 直接使用 opacity属性,无需额外的图形效果组件
  • 滑块值反转:用户操作更直观(向右滑动增加透明度)
  • 值转换:将滑块值(0-10)转换为透明度值(1.0-0.0)

3. 颜色叠加效果(Colorize)

功能特点:

  • 使用ColorOverlay组件实现颜色叠加
  • 模拟QGraphicsColorizeEffect的黑色着色效果
  • 支持0.0-1.0范围的强度调整

实现原理:

Item {
    width: imageSize
    height: imageSize

    Image {
        id: colorizeImage
        anchors.fill: parent
        source: "qrc:/images/3.png"
        fillMode: Image.PreserveAspectFit
        visible: false
    }

    ShaderEffectSource {
        id: colorizeSource
        anchors.fill: colorizeImage
        sourceItem: colorizeImage
        hideSource: true
    }

    ColorOverlay {
        anchors.fill: parent
        source: colorizeSource
        // QGraphicsColorizeEffect 使用 QColor(0, 0, 0, 100)
        // alpha = 100/255 ≈ 0.39
        color: Qt.rgba(0, 0, 0, colorizeStrength * 0.39)
    }
}

关键技术点:

  • ColorOverlay:在原图上叠加颜色,不改变原图颜色
  • QColor(0, 0, 0, 100):对应RGBA的alpha值为100/255≈0.39
  • colorizeStrength * 0.39:根据强度调整叠加的alpha值
  • 使用 ColorOverlay而非 Colorize:保持原图颜色,只叠加黑色

注意事项:

  • Colorize组件会完全改变图像颜色(如变成红色),不适合模拟QGraphicsColorizeEffect
  • ColorOverlay只是在原图上叠加颜色,保持原图不变,更符合需求

4. 阴影效果(Shadow)

功能特点:

  • 使用DropShadow组件实现阴影效果
  • 支持0-100范围的阴影半径调整
  • 动态调整阴影偏移和采样数以提升效果

实现原理:

Item {
    width: imageSize
    height: imageSize

    Image {
        id: dropShadowImage
        anchors.fill: parent
        source: "qrc:/images/4.png"
        fillMode: Image.PreserveAspectFit
        visible: false
    }

    ShaderEffectSource {
        id: shadowSource
        anchors.fill: dropShadowImage
        sourceItem: dropShadowImage
        hideSource: true
    }

    DropShadow {
        anchors.fill: parent
        source: shadowSource
        radius: dropShadowRadius * 1.8  // 增强阴影模糊半径
        samples: Math.max(16, Math.floor(dropShadowRadius / 3) + 16)
        color: "#D0000000"  // 半透明黑色(约81%不透明度)
        horizontalOffset: dropShadowRadius > 0 ? 12 : 0
        verticalOffset: dropShadowRadius > 0 ? 12 : 0
    }
}

关键技术点:

  • DropShadow:实现投影阴影效果
  • radius * 1.8:增强阴影模糊半径,使阴影更明显
  • samples:动态调整采样数,根据半径提升质量
  • color: "#D0000000":使用半透明黑色,增强阴影可见性
  • horizontalOffsetverticalOffset:添加偏移使阴影可见

效果增强技巧:

  • 阴影半径放大1.8倍
  • 使用更高的不透明度(81%)
  • 增加偏移量(12像素)使阴影更明显
  • 动态调整采样数以平衡质量和性能

开发要点与技巧

1. OpenGL硬件加速配置

关键配置:

main.cpp中,必须确保使用OpenGL硬件加速,而不是软件渲染:

// ❌ 错误:软件渲染不支持图形效果
// qputenv("QT_QUICK_BACKEND", "software");

// ✅ 正确:使用硬件加速
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);

QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGLES);
format.setVersion(2, 0);
QSurfaceFormat::setDefaultFormat(format);

重要提示:

  • QtGraphicalEffects模块需要OpenGL硬件加速才能工作
  • 软件渲染会导致图形效果无法显示
  • 如果设备不支持OpenGL,可能需要使用其他实现方式

2. ShaderEffectSource的使用

标准模式:

Image {
    id: sourceImage
    visible: false  // 源图片始终不可见
}

ShaderEffectSource {
    id: effectSource
    anchors.fill: sourceImage
    sourceItem: sourceImage
    hideSource: true  // 隐藏源,只显示效果
}

EffectComponent {
    source: effectSource  // 使用ShaderEffectSource作为源
}

注意事项:

  • 源Image必须设置为 visible: false
  • ShaderEffectSourcehideSource: true确保源不显示
  • 效果组件使用 ShaderEffectSource而非直接使用 Image

3. 效果参数映射

模糊效果:

  • QtWidgets版本:QGraphicsBlurEffect::setBlurRadius(value),范围0-30
  • QML版本:FastBlur::radius = blurRadius * 2.5(增强效果)

透明效果:

  • QtWidgets版本:QGraphicsOpacityEffect::setOpacity(1.0 - value/10.0),范围0-10
  • QML版本:Image::opacity = opacityValue,范围1.0-0.0

颜色效果:

  • QtWidgets版本:QGraphicsColorizeEffect::setStrength(value/10.0),使用 QColor(0, 0, 0, 100)
  • QML版本:ColorOverlay::color = Qt.rgba(0, 0, 0, colorizeStrength * 0.39)

阴影效果:

  • QtWidgets版本:QGraphicsDropShadowEffect::setBlurRadius(value),范围0-100
  • QML版本:DropShadow::radius = dropShadowRadius * 1.8(增强效果)

4. 响应式设计

缩放因子:

readonly property real scaleFactor: width > 1000 ? 2.0 : 1.0
readonly property real imageSize: 192 * scaleFactor
readonly property real fontSize: 14 * scaleFactor

使用方式:

Text {
    font.pixelSize: fontSize
    spacing: 20 * scaleFactor
}

优势:

  • 自动适配不同屏幕尺寸
  • 大屏设备(>1000px)使用2倍缩放
  • 小屏设备使用1倍缩放

常见问题与解决方案

问题1:图形效果不显示

症状:

  • 模糊、颜色、阴影效果都不工作
  • 只显示原始图片

原因:

  • 使用了软件渲染后端
  • OpenGL不可用

解决方案:

// 移除软件渲染设置
// qputenv("QT_QUICK_BACKEND", "software");  // ❌ 删除这行

// 确保使用硬件加速
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);

问题2:模糊效果有边框

症状:

  • 模糊图片边缘出现明显的边框

原因:

  • FastBlurtransparentBorder属性设置为 false

解决方案:

FastBlur {
    transparentBorder: true  // 设置为true消除边框
}

问题3:颜色效果改变了原图颜色

症状:

  • 使用 Colorize后,图片变成红色或其他颜色
  • 原图颜色完全改变

原因:

  • Colorize组件会完全改变图像颜色
  • 不适合模拟 QGraphicsColorizeEffect的叠加效果

解决方案:

// ❌ 错误:Colorize会改变原图颜色
Colorize {
    saturation: ...
    lightness: ...
}

// ✅ 正确:ColorOverlay只叠加颜色
ColorOverlay {
    color: Qt.rgba(0, 0, 0, colorizeStrength * 0.39)
}

问题4:阴影效果不明显

症状:

  • 阴影太淡,几乎看不见
  • 阴影没有偏移

解决方案:

DropShadow {
    radius: dropShadowRadius * 1.8  // 增强半径
    color: "#D0000000"  // 增加不透明度
    horizontalOffset: 12  // 添加偏移
    verticalOffset: 12
    samples: Math.max(16, Math.floor(dropShadowRadius / 3) + 16)  // 提升质量
}

问题5:效果强度不够

症状:

  • 模糊效果不够明显
  • 阴影效果太弱

解决方案:

  • 模糊效果:将半径乘以系数(如2.5倍)
  • 阴影效果:增加半径系数、不透明度和偏移量

总结与展望

项目总结

本项目成功实现了四种常见的图形效果,为HarmonyOS应用开发提供了实用的图形效果实现方案。通过QtGraphicalEffects模块,我们可以轻松实现各种视觉效果,提升应用的用户体验。

主要成果:

  • ✅ 实现了模糊、透明、颜色叠加、阴影四种图形效果
  • ✅ 提供了实时参数调整功能
  • ✅ 适配了HarmonyOS平台的OpenGL要求
  • ✅ 实现了响应式布局设计

技术要点:

  • QtGraphicalEffects模块需要OpenGL硬件加速
  • ShaderEffectSource是图形效果的标准源组件
  • ColorOverlay适合叠加效果,Colorize适合完全着色
  • 通过参数增强可以提升效果可见性

未来展望

可能的改进方向:

  1. 更多效果:添加更多图形效果,如发光、浮雕、马赛克等
  2. 性能优化:针对移动设备优化渲染性能
  3. 效果组合:支持多个效果同时应用
  4. 自定义效果:使用ShaderEffect实现自定义图形效果
  5. 动画效果:为效果切换添加动画过渡

应用场景:

  • 图片编辑应用
  • 滤镜效果应用
  • UI美化组件
  • 视觉特效展示

附录

完整代码示例

main.qml核心代码:

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15

ApplicationWindow {
    id: root
    width: Screen.width > 1000 ? 1600 : 800
    height: Screen.height > 1000 ? 2560 : 741
    visible: true
    title: "GraphicsEffect"

    property real blurRadius: 0
    property real opacityValue: 1.0
    property real colorizeStrength: 0.0
    property real dropShadowRadius: 0

    Rectangle {
        anchors.fill: parent
        color: "#f0f0f0"

        ColumnLayout {
            anchors.fill: parent
            spacing: 0

            // 效果展示区域
            Rectangle {
                Layout.fillWidth: true
                Layout.fillHeight: true
                color: "#f0f0f0"

                GridLayout {
                    anchors.centerIn: parent
                    columns: 2
                    rowSpacing: 60
                    columnSpacing: 100

                    // 模糊效果
                    Column {
                        Item {
                            width: 192
                            height: 192
                            Image {
                                id: blurImage
                                anchors.fill: parent
                                source: "qrc:/images/1.png"
                                visible: false
                            }
                            ShaderEffectSource {
                                id: blurSource
                                anchors.fill: blurImage
                                sourceItem: blurImage
                                hideSource: true
                            }
                            FastBlur {
                                anchors.fill: parent
                                source: blurSource
                                radius: blurRadius * 2.5
                                transparentBorder: true
                            }
                        }
                    }

                    // 其他效果...
                }
            }

            // 控制区域
            Rectangle {
                Layout.fillWidth: true
                Layout.preferredHeight: 200
                // 滑块控制...
            }
        }
    }
}

参考资源

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐