一、基础定位、头文件、继承关系
1. 引入头文件
cpp
#include <qgssinglebandpseudocolorrenderer.h>
2. 继承链
QgsRasterRenderer
↳ QgsSingleBandRenderer
↳ QgsSingleBandPseudoColorRenderer
- QgsRasterRenderer :栅格渲染器顶层抽象基类,所有栅格渲染器统一父类,定义
block()、clone()、XML读写、透明度等通用接口; - QgsSingleBandRenderer:单波段渲染器公共父类,封装「渲染波段号」基础逻辑;
- QgsSingleBandPseudoColorRenderer :单波段伪彩色渲染器,专门实现单波段数值→渐变色/分级上色(DEM、NDVI、温度热力图底层渲染器)。
3. 完整渲染链路总览
QgsRasterLayer
↓
QgsSingleBandPseudoColorRenderer (当前讲解对象:控制渲染波段、透明度、持有QgsRasterShader)
↓
QgsRasterShader (scale/offset、拉伸min/max、Nodata透明、亮度对比度)
↓
QgsColorRampShader (分段色标、插值渐变/离散/精确匹配逻辑)
4. 核心职责
- 指定要渲染的目标波段(1起始);
- 持有唯一
QgsRasterShader着色器实例,所有数值转颜色逻辑由shader提供; - 实现栅格像素块渲染入口
block(),从provider读取像素、调用shader上色、输出RGBA画布; - 统一管理图层透明度、灰度转换、图层混合模式;
- 提供克隆、序列化XML(保存到qgs工程)。
二、构造函数
cpp
// 空构造,无数据源、无shader,仅用于反序列化加载工程
QgsSingleBandPseudoColorRenderer();
// 标准业务构造(最常用)
// provider:栅格数据源;bandNo:渲染波段;shader:着色器(传入后renderer接管内存)
QgsSingleBandPseudoColorRenderer( QgsRasterDataProvider *provider,
int bandNo,
QgsRasterShader *shader = nullptr );
三、核心属性读写API
1. 渲染波段(继承自 QgsSingleBandRenderer)
cpp
// 获取当前渲染波段
int band() const;
// 修改渲染波段,切换后需要重新统计极值、刷新shader拉伸区间
void setBand( int bandNo );
注意:波段号从1开始,传0会渲染失效。
2. 着色器 QgsRasterShader 管理(核心)
cpp
// 获取内部着色器,可修改min/max、scale/offset、shaderFunction
QgsRasterShader *rasterShader() const;
// 设置新着色器,renderer 获得 shader 所有权,自动释放旧shader
void setRasterShader( QgsRasterShader *shader );
内存规则:
setRasterShader()传入的shader由渲染器托管,外部禁止手动delete;- 替换shader时,旧着色器会自动销毁,无内存泄漏。
3. 图层全局透明度(继承 QgsRasterRenderer)
cpp
// 透明度 0~100,0完全不透明,100完全透明
int opacity() const;
void setOpacity( int opacity );
4. 图层混合模式(叠加、正片叠底等)
cpp
QPainter::CompositionMode compositionMode() const;
void setCompositionMode( QPainter::CompositionMode mode );
5. Nodata全局透明开关(兼容层,实际优先走shader透明配置)
cpp
bool usesTransparentNodata() const;
void setUsesTransparentNodata( bool transparent );
四、核心渲染入口函数 block()
函数签名(重写父类虚函数)
cpp
QgsRasterBlock *block(
const QgsRectangle &extent,
int width,
int height,
QgsRasterBlockFeedback *feedback = nullptr
) override;
功能:生成RGBA彩色像素块,供画布绘制
内部完整执行步骤
- 调用
provider->readBlock(band(), extent, width, height)读取原始单波段浮点像素块; - 创建RGBA 4通道输出像素块(Byte类型,0~255);
- 遍历每一行每一列像素:
- 判断是否Nodata:若shader开启透明Nodata,直接填充Alpha=0;
- 取出原始rawVal,交给
rasterShader()->shade()计算RGBA; - 应用图层全局透明度opacity衰减Alpha通道;
- 返回彩色RGBA像素块,上层绘图组件渲染;
- 进度反馈
feedback用于大影像渲染时进度条、取消渲染。
五、克隆、序列化(工程保存/加载必备)
1. 深度克隆 clone()
cpp
QgsRasterRenderer *clone() const override;
- 完整复制:波段号、透明度、混合模式、内部完整QgsRasterShader(连带内部QgsColorRampShader色标列表深度拷贝);
- 返回全新渲染器对象,使用完成必须手动delete。
2. XML读写 writeXml / readXml
cpp
void writeXml( QDomDocument &doc, QDomElement &parentElem ) const override;
void readXml( const QDomElement &rendererElem ) override;
存储内容:
- 渲染波段、透明度、混合模式;
- 完整序列化
QgsRasterShader(min/max、scale/offset、亮度对比度、transparentNodata); - 嵌套序列化
QgsColorRampShader(全部色标、插值模式clip开关等)。
QGIS工程保存、样式文件(.qml)读写底层依赖这两个接口。
六、自动生成拉伸区间工具函数(高频业务接口)
cpp
// 根据栅格波段统计,自动填充shader的min/max(原始像素值,scale=offset=0场景)
void setShaderMinMaxToNone();
void setShaderMinMaxToFullExtent();
void setShaderMinMaxToCurrentExtent( const QgsRectangle ¤tExtent );
常用场景
cpp
// 自动用整幅栅格的波段极值填充shader拉伸窗口
renderer->setShaderMinMaxToFullExtent();
内部逻辑:调用provider->bandStatistics()获取min/max,赋值给shader的minimumValue/maximumValue。
七、完整分层协作示例代码(DEM伪彩色渲染)
cpp
#include <qgsrasterdataprovider.h>
#include <qgsrasterbandstats.h>
#include <qgsrastershader.h>
#include <qgsrastercolorrampshader.h>
#include <qgssinglebandpseudocolorrenderer.h>
#include <qgsrasterlayer.h>
// DEM单波段伪彩色渲染封装函数
void setupDemPseudoColorRender(QgsRasterLayer* demLayer)
{
QgsRasterDataProvider* prov = demLayer->dataProvider();
if (!prov || !prov->isValid()) return;
int renderBand = 1;
// 1. 统计波段原始极值
QgsRasterBandStats stats = prov->bandStatistics(
renderBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max
);
if (!stats.isValid()) return;
// 2. 构建色标(无scale/offset,displayVal=rawVal)
QList<QgsColorRampItem> items;
items.append(QgsColorRampItem(stats.minVal, QColor(10, 40, 200), "低海拔"));
items.append(QgsColorRampItem((stats.minVal+stats.maxVal)/2, QColor(30, 190, 50), "中海拔"));
items.append(QgsColorRampItem(stats.maxVal, QColor(210, 20, 20), "高海拔"));
// 3. 色带着色函数
QgsColorRampShader* rampFunc = new QgsColorRampShader(items, QgsColorRampShader::Interpolated);
rampFunc->setClipBelow(true);
rampFunc->setClipAbove(true);
// 4. 外层Shader
QgsRasterShader* shader = new QgsRasterShader();
shader->setMinimumValue(stats.minVal);
shader->setMaximumValue(stats.maxVal);
shader->setTransparentNodata(true);
shader->setRasterShaderFunction(rampFunc);
// 5. 创建伪彩色渲染器(核心类)
QgsSingleBandPseudoColorRenderer* render = new QgsSingleBandPseudoColorRenderer(prov, renderBand, shader);
render->setOpacity(90); // 图层透明度90%
render->setCompositionMode(QPainter::CompositionMode_SourceOver);
// 6. 绑定到栅格图层
demLayer->setRenderer(render);
demLayer->triggerRepaint(); // 刷新画布
}
八、与其他栅格渲染器对比区分
| 渲染器类 | 用途 | 是否依赖 QgsRasterShader |
|---|---|---|
| QgsSingleBandPseudoColorRenderer | 单波段渐变/分级伪彩色(DEM、NDVI、热力图) | ✅ 必须依赖 |
| QgsSingleBandGrayRenderer | 单波段黑白灰度拉伸 | ✅ 依赖灰度shader |
| QgsMultiBandColorRenderer | RGB三波段真彩色遥感影像 | ❌ 无shader,直接合成三色 |
| QgsPalettedRasterRenderer | 索引色栅格(自带色表) | ❌ |
关键区分
QgsSingleBandGrayRenderer 和 QgsSingleBandPseudoColorRenderer 同属单波段渲染器,都持有QgsRasterShader:
- 灰度渲染器内部shaderFunction是灰度映射;
- 伪彩色渲染器搭配
QgsColorRampShader实现多色渐变分级。
九、开发高频踩坑点
1. 内存所有权问题
cpp
// 正确:renderer接管shader,无需手动delete shader
QgsRasterShader* shader = new QgsRasterShader();
QgsSingleBandPseudoColorRenderer* render = new QgsSingleBandPseudoColorRenderer(prov, 1, shader);
// 错误:外部手动delete shader,渲染器析构时二次释放崩溃
delete shader;
2. scale/offset 存在时,shader min/max 不能填原始波段极值
QgsSingleBandPseudoColorRenderer 只负责持有shader,不会自动换算scale/offset后的区间;
需要手动计算 displayMin = (rawMin-offset)*scale 赋值给shader。
3. 切换波段后极值不刷新
调用 setBand(2) 切换渲染波段后,旧shader的min/max仍是波段1的区间,必须重新统计并更新shader拉伸窗口。
4. 浮点栅格使用 Exact 模式匹配失败
Exact精确匹配仅适合整型分类栅格,浮点存在精度误差,渲染器会大面积透明。
5. 渲染器替换后图层不刷新
修改完renderer必须调用 layer->triggerRepaint() 触发画布重绘。
6. 多线程渲染限制
block() 内部会读取provider,GDAL驱动非线程安全,多线程并行渲染同一图层需要加互斥锁。
十、典型业务使用场景
- DEM数字高程模型渐变伪彩色渲染;
- NDVI、NDWI植被指数热力分级;
- 气温、降雨量、污染物浓度热力图;
- 坡度、地形起伏度离散分级设色;
- 单波段灰度数据自定义渐变色展示。
十一、类层级结构精简总结
QgsRasterRenderer (顶层栅格渲染器)
└── QgsSingleBandRenderer (单波段公共父类:管理波段号)
└── QgsSingleBandPseudoColorRenderer
├─ 成员:QgsRasterShader* mShader
├─ 核心方法:block() 输出RGBA彩色像素块
├─ 辅助:setShaderMinMaxToFullExtent() 自动拉伸
├─ 生命周期:clone()、writeXml/readXml 序列化
└─ 配置:透明度、图层混合模式