前言
接着序列三,图像的合成模式。
图像的合成模式(CompositionMode
)是在讲述当多个图像重叠时重叠部分该如何显示的问题。
正文
先看合成模式的定义,下面是分析。
1. enum CompositionMode
- 这个枚举类型
CompositionMode
定义了多种图像合成模式。图像合成模式用于控制QPainter
在绘制时如何将源图像与目标图像进行组合。不同的合成模式会影响图像的叠加方式、颜色混合效果等。
主要合成模式:
CompositionMode_SourceOver
: 默认模式,源图像覆盖在目标图像上,考虑透明度。CompositionMode_DestinationOver
: 目标图像覆盖在源图像上,考虑透明度。CompositionMode_Clear
: 清除目标图像区域,设置为完全透明。CompositionMode_Source
: 仅绘制源图像,忽略目标图像。CompositionMode_Destination
: 保留目标图像,忽略源图像。CompositionMode_SourceIn
: 显示源图像在目标图像透明部分的交集。CompositionMode_DestinationIn
: 显示目标图像在源图像透明部分的交集。CompositionMode_SourceOut
: 显示源图像在目标图像不透明部分的区域。CompositionMode_DestinationOut
: 显示目标图像在源图像不透明部分的区域。CompositionMode_SourceAtop
: 源图像叠加在目标图像不透明部分上,其他部分保持目标图像。CompositionMode_DestinationAtop
: 目标图像叠加在源图像不透明部分上,其他部分保持源图像。CompositionMode_Xor
: 显示源图像和目标图像的不透明区域的独占或。
SVG 1.2 blend modes(混合模式):
这些模式通常用于高级图形效果,例如通过特定的数学运算混合两幅图像。
CompositionMode_Plus
: 源图像和目标图像的颜色值相加。CompositionMode_Multiply
: 源图像和目标图像的颜色值相乘,结果颜色更暗。CompositionMode_Screen
: 源图像和目标图像的颜色值反转相乘,再反转,结果颜色更亮。CompositionMode_Overlay
: 源图像和目标图像的颜色值结合,通过不同的算法增强对比度。CompositionMode_Darken
: 选择源图像和目标图像中较暗的颜色值。CompositionMode_Lighten
: 选择源图像和目标图像中较亮的颜色值。CompositionMode_ColorDodge
: 通过增加亮度来使源图像变亮。CompositionMode_ColorBurn
: 通过增加亮度来使源图像变暗。CompositionMode_HardLight
: 结合Multiply
和Screen
模式,根据源图像的亮度应用。CompositionMode_SoftLight
: 类似于HardLight
,但效果更柔和。CompositionMode_Difference
: 计算源图像和目标图像的颜色差异。CompositionMode_Exclusion
: 类似于Difference
,但对比度更低。
ROPs(光栅操作模式):
这些模式源自早期图形硬件中的光栅操作(Raster Operations),用于像素级的图像处理。
RasterOp_SourceOrDestination
: 源图像和目标图像的像素进行按位或(OR)操作。RasterOp_SourceAndDestination
: 源图像和目标图像的像素进行按位与(AND)操作。RasterOp_SourceXorDestination
: 源图像和目标图像的像素进行按位异或(XOR)操作。RasterOp_NotSourceAndNotDestination
: 源图像和目标图像的像素进行按位非(NOT)和按位与(AND)操作。RasterOp_NotSourceOrNotDestination
: 源图像和目标图像的像素进行按位非(NOT)和按位或(OR)操作。RasterOp_NotSourceXorDestination
: 源图像和目标图像的像素进行按位非(NOT)和按位异或(XOR)操作。RasterOp_NotSource
: 对源图像的像素进行按位非(NOT)操作。RasterOp_NotSourceAndDestination
: 对源图像的像素进行按位非(NOT)和目标图像进行按位与(AND)操作。RasterOp_SourceAndNotDestination
: 源图像和目标图像的像素进行按位与(AND)和按位非(NOT)操作。RasterOp_NotSourceOrDestination
: 对源图像进行按位非(NOT)和目标图像进行按位或(OR)操作。RasterOp_SourceOrNotDestination
: 源图像和目标图像的像素进行按位或(OR)和按位非(NOT)操作。RasterOp_ClearDestination
: 清除目标图像。RasterOp_SetDestination
: 将目标图像设置为全白或全黑。RasterOp_NotDestination
: 对目标图像进行按位非(NOT)操作。
2. void setCompositionMode(CompositionMode mode)
- 这个方法设置
QPainter
的合成模式。通过传递不同的CompositionMode
值,你可以改变QPainter
如何将源图像与目标图像进行组合。
3. CompositionMode compositionMode() const
- 这个方法返回当前
QPainter
正在使用的合成模式。
例子
void PaintWidget::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QImage SourceImg(200, 200, QImage::Format_ARGB32);
QImage SrcImg(500, 500, QImage::Format_ARGB32);
//SourceImg.fill(Qt::transparent);
//SrcImg.fill(Qt::transparent);
SourceImg.fill(0);
SrcImg.fill(0);
QPainter painter;
painter.begin(&SourceImg);
QRect sourceRect(0, 0, 200, 200);
QColor sourceColor(0, 0, 255, m_sourceOpacity);
painter.fillRect(sourceRect, sourceColor);
painter.end();
painter.begin(&SrcImg);
painter.save();
// 设置目标图像为红色矩形
QRect destinationRect(50, 50, 200, 200);
QColor srcColor(255, 0, 0, m_srcOpacity);
painter.fillRect(destinationRect, srcColor);
// 设置合成模式
painter.setCompositionMode(currentMode);
painter.drawImage(0, 0, SourceImg);
painter.end();
painter.begin(this);
painter.drawImage(0, 0, SrcImg);
painter.end();
}
效果
合成模式
小结
在上面仅仅是把主要合成模式和混和模式添加进来,光栅那个没加,想来也差不多。在做这个例子的时候前期我有一个很大的误区,老是想把QPainter
画出的图形直接使用合成模式,结果很悲催,要么没有啥效果,要么效果不符合预期。下面就是错误的代码
QPainter painter(this);
// 设置目标图像为红色矩形
QRect destinationRect(50, 50, 200, 200);
QColor srcColor(255, 0, 0, m_srcOpacity);
painter.fillRect(destinationRect, srcColor);
// 设置合成模式
painter.setCompositionMode(currentMode);
QRect sourceRect(0, 0, 200, 200);
QColor sourceColor(0, 0, 255, m_sourceOpacity);
painter.fillRect(sourceRect, sourceColor);
给大家看张我设置clear模式的截图
源图像直接黑掉了,我又查询了许多资料,有的说是我背景颜色没设置好,但是我早就已经在样式表中设置过了,最后才发现是要使用图片,悲催。
还有在设置透明度时我发现有两个不一样的点。
-
通过
QPainter::setOpacity()
设置透明度时:- 参数的取值范围是 0 到 1,表示透明度的比例。
0
表示完全透明,1
表示完全不透明。- 例如:
painter.setOpacity(0.5);
会将接下来的绘制操作的透明度设置为 50%。
-
通过颜色(
QColor
)来设置透明度时:- 透明度的参数取值范围是 0 到 255,表示颜色的 Alpha 通道值。
0
表示完全透明,255
表示完全不透明。- 例如:
QColor color(255, 0, 0, 128);
表示一个 50% 不透明的红色(128 是 Alpha 值)或者color.setAlpha(128)
。
还有就是img.fill(0)
和 img.fill(Qt::transparent)
1. img.fill(0)
- 参数:
0
是一个整数值,它代表的是一种颜色。 - 效果: 当使用
img.fill(0)
时,图像的所有像素将被填充为 纯黑色,并且如果图像的格式支持透明度(例如QImage::Format_ARGB32
),Alpha 通道会被设置为 完全透明。 - 适用场景: 这个方法会将图像填充为黑色,并且如果有透明度,透明度会被设置为完全透明。
2. img.fill(Qt::transparent)
- 参数:
Qt::transparent
是一个颜色常量,表示完全透明。 - 效果: 使用
img.fill(Qt::transparent)
时,图像的所有像素将被填充为 完全透明。在具有 Alpha 通道的图像格式中(例如QImage::Format_ARGB32
),这意味着所有像素的颜色将是透明的,无论原本的颜色是什么。 - 适用场景: 这个方法通常用于需要清除图像内容,使图像变得完全透明的时候。
总结
img.fill(0)
: 填充图像为黑色,同时在支持 Alpha 通道的图像格式下,该黑色会被设置为完全透明的黑色。img.fill(Qt::transparent)
: 填充图像为完全透明,通常用于清除图像内容。