imagecomposition工程存放在Qt安装目录下的
Examples\Qt-x.xx.xx\widgets\painting\imagecomposition
目录下。其中
x.xx.xx为Qt的版本号。该工程展示了QPainter::CompositionMode的含义。要弄懂本工程请先参考《QPainter类的CompositionMode各值含义》
,否则本工程对初学者很难弄懂。

预备知识:

把将要画上去的颜色称为“源颜色”,把原来的颜色称为“目标颜色”。初次画的时候,窗体上什么都没有,则窗体或窗体的一个区域(当运用裁剪时)为目标,即将要画上去的图形为源。

弄懂本工程的关键是要搞懂QPainter类的CompositionMode各值含义、源图像和目标图像的概念。

loadImage函数分析

该工程的loadImage函数代码如下:

void ImageComposer::loadImage(const QString &fileName, QImage *image,QToolButton *button)
{image->load(fileName);// Scale the image to given size*image = image->scaled(resultSize, Qt::KeepAspectRatio);QImage fixedImage(resultSize, QImage::Format_ARGB32_Premultiplied);QPainter painter(&fixedImage);painter.setCompositionMode(QPainter::CompositionMode_Source);painter.fillRect(fixedImage.rect(), Qt::transparent);painter.setCompositionMode(QPainter::CompositionMode_SourceOver);painter.drawImage(imagePos(*image), *image);painter.end();button->setIcon(QPixmap::fromImage(fixedImage));*image = fixedImage;recalculateResult();
}

当代码执行到第11行但11行后的代码没执行时,即将第12、13、19行代码注释掉,根据前面源和目标的定义可以知道:此时窗体为目标,fixedImage为源,根据《QPainter类的CompositionMode各值含义》文章对QPainter::CompositionMode_Source的描述,可以知道,此时只显示源,但因为fixedImage设置为透明的,所以即使显示的是源,但看到的是源后面的窗体,如下:

如果将第11行改为:

painter.fillRect(fixedImage.rect(), Qt::red);

则输出如下:

因为源是红色的,不再透明,所以看不到后面的窗体,显示的是源的红色。将第11行依然设置为红色,取消12、13行注释,则此时11行绘制上去的红色QImage对象fixedImage为目标,第13行绘制的image对象为源,因为绘图组合模式是QPainter::CompositionMode_SourceOver,根据《QPainter类的CompositionMode各值含义》文章对QPainter::CompositionMode_SourceOver的描述,可以知道此时目标和源重叠的部分进行混合,且源盖住(遮挡住)目标,没有重叠部分各自保留即都绘制出来,结果如下:
将第11行依然设置为Qt::transparent,则如下:

在ImageComposer类的构造函数中,通过本函数分别加载了两张图形,一张用于最左侧QToolButton按钮贴图,一张用于中间QToolButton按钮贴图。

recalculateResult函数分析

函数代码如下:

void ImageComposer::recalculateResult()
{QPainter::CompositionMode mode = currentMode();QPainter painter(&resultImage);painter.setCompositionMode(QPainter::CompositionMode_Source);painter.fillRect(resultImage.rect(), Qt::transparent);painter.setCompositionMode(QPainter::CompositionMode_SourceOver);painter.drawImage(0, 0, destinationImage);painter.setCompositionMode(mode);painter.drawImage(0, 0, sourceImage);painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);painter.fillRect(resultImage.rect(), Qt::white);painter.end();resultLabel->setPixmap(QPixmap::fromImage(resultImage));
}

代码执行到第7行时,即代码如下:

void ImageComposer::recalculateResult()
{QPainter::CompositionMode mode = currentMode();QPainter painter(&resultImage);painter.setCompositionMode(QPainter::CompositionMode_Source);painter.fillRect(resultImage.rect(), Qt::transparent);/* painter.setCompositionMode(QPainter::CompositionMode_SourceOver);painter.drawImage(0, 0, destinationImage);painter.setCompositionMode(mode);painter.drawImage(0, 0, sourceImage);painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);painter.fillRect(resultImage.rect(), Qt::white);*/painter.end();resultLabel->setPixmap(QPixmap::fromImage(resultImage));
}

目标是QLabel类型的resultLabel子窗体部件,源是透明的QImage类对象resultImage,采用CompositionMode_Source模式绘制,结果就是将resultImage贴在resultLabel子窗体部件上面,因为resultImage是透明的,所以至第7行时,resultImage绘制和没绘制都一样,你看到的都是resultLabel子窗体部件。代码执行到第8、9行时,即代码如下:

void ImageComposer::recalculateResult()
{QPainter::CompositionMode mode = currentMode();QPainter painter(&resultImage);painter.setCompositionMode(QPainter::CompositionMode_Source);painter.fillRect(resultImage.rect(), Qt::transparent);painter.setCompositionMode(QPainter::CompositionMode_SourceOver);painter.drawImage(0, 0, destinationImage);/*  painter.setCompositionMode(mode);painter.drawImage(0, 0, sourceImage);painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);painter.fillRect(resultImage.rect(), Qt::white);*/painter.end();resultLabel->setPixmap(QPixmap::fromImage(resultImage));
}

设置QPainter::CompositionMode_SourceOver模式后再以resultImage为画布(绘图设备)绘制了destinationImage,此时destinationImage为源,resultImage为目标。根据《QPainter类的CompositionMode各值含义》文章对QPainter::CompositionMode_SourceOver的描述,可以知道此时目标和源重叠的部分进行混合,且源盖住(遮挡住)目标,没有重叠部分各自保留即都绘制出来,结果如下红色方框所示:

代码执行到第10、11行时,即代码如下:

void ImageComposer::recalculateResult()
{QPainter::CompositionMode mode = currentMode();QPainter painter(&resultImage);painter.setCompositionMode(QPainter::CompositionMode_Source);painter.fillRect(resultImage.rect(), Qt::transparent);painter.setCompositionMode(QPainter::CompositionMode_SourceOver);painter.drawImage(0, 0, destinationImage);painter.setCompositionMode(mode);painter.drawImage(0, 0, sourceImage);/* painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);painter.fillRect(resultImage.rect(), Qt::white);*/painter.end();resultLabel->setPixmap(QPixmap::fromImage(resultImage));
}

根据界面的选择来设置相应的组合模式,并绘制sourceImage,此时第10行之前绘制的结果即destinationImage为目标,即将要绘制的sourceImage为源,如下红色方框为在界面下拉框选择组合模式为SourceOver的输出:

代码执行到13行,即代码如下时:

void ImageComposer::recalculateResult()
{QPainter::CompositionMode mode = currentMode();QPainter painter(&resultImage);painter.setCompositionMode(QPainter::CompositionMode_Source);painter.fillRect(resultImage.rect(), Qt::transparent);painter.setCompositionMode(QPainter::CompositionMode_SourceOver);painter.drawImage(0, 0, destinationImage);painter.setCompositionMode(mode);painter.drawImage(0, 0, sourceImage);painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);painter.fillRect(resultImage.rect(), Qt::white);painter.end();resultLabel->setPixmap(QPixmap::fromImage(resultImage));
}

此时resultImage为源,之前绘制的为目标,又因为第12行设置模式为QPainter::CompositionMode_DestinationOver,即源图像如果和目标图像有重叠,绘制时,则重叠部分是目标图像在源图像上面(目标遮挡住源),当目标的alpha为255时,源被目标完全遮挡。重叠部分的源和重叠部分的目标进行混合,混合之后得出的RGBA值为重叠部分的RGBA值,没有重叠部分各自保留即都绘制出来。所以最终的输出结果如下:

可以结合《QPainter类的CompositionMode各值含义》文章对各个组合模式的描述,读者自行选择界面下拉框上的不同的模式进行体会、理解。

imagecomposition工程分析相关推荐

  1. MATLAB数学计算与工程分析范例教程,MATLAB数学计算与工程分析范例教程

    基本信息 书名:MATLAB数学计算与工程分析范例教程 定价:28.00元 作者:石博强,赵金 编著 出版社:中国铁道出版社 出版日期:2005-05-01 ISBN:9787#113057596 字 ...

  2. ML之FE:利用FE特征工程(分析两两数值型特征之间的相关性)对AllstateClaimsSeverity(Kaggle2016竞赛)数据集实现索赔成本值的回归预测

    ML之FE:利用FE特征工程(分析两两数值型特征之间的相关性)对AllstateClaimsSeverity(Kaggle2016竞赛)数据集实现索赔成本值的回归预测 目录 输出结果 设计思路 核心代 ...

  3. 机器学习cae_CAE工程分析技术年会记

    读书使人充实,讨论使人机智,笔记使人准确,读史使人明智,读诗使人灵秀,数学使人周密,科学使人深刻,伦理使人庄重,逻辑修辞使人善辩.凡有所学,皆成性格.---- (英国)培根 可能是会议热度不够,非常遗 ...

  4. 03-instancing 工程分析详解

    opengl编程指南第8版源码怎么下载.编译,请参考<opengl编程指南第8版源码编译详细说明> 1. 程序启动 请参考<03-drawcommands工程分析详解> 2. ...

  5. python与金融工程的区别_科研进阶 | 纽约大学 | 金融工程、量化金融、商业分析:Python金融工程分析...

    科研进阶 | 纽约大学 | 金融工程.量化金融.商业分析:Python金融工程分析(2021.2.6开课)​mp.weixin.qq.com 课题名称 = Python金融工程分析 = 项目配景 大数 ...

  6. MATLAB数学计算与工程分析范例教程,MATLAB 2016数学计算与工程分析从入门到精通...

    全书通过近400个实例讲解了利用MATLAB 2016进行数学计算和工程分析的方法和技巧,涵盖了MATLAB的五大功能:1)数值计算功能:2)符号计算功能:3)图形与数据可视化功能:4)可视化建模与仿 ...

  7. 计算机辅助工程分析课程论文,教学大纲—计算机辅助工程分析.doc

    <计算机辅助工程分析>课程教学大纲 英文课程名Computer Aided Engineering总 学 时32学 分2课程编码202725理论教学学时8适用专业机械工程.过程装备与控制工 ...

  8. FPGA设计心得(5)Aurora 例子工程分析与仿真实例分析(streaming版)

    文章目录 背景 例子工程预览 例子程序用户模块逻辑分析 收(CHECK) 发(GEN) 例子程序仿真文件分析 写在最后 工程分享 参考资料 交个朋友 背景 熬夜写完了上两篇博客: Aurora IP ...

  9. 【Android 逆向】Android 逆向通用工具开发 ( PC 端工程分析 | 网络初始化操作 | PC 端工程核心业务逻辑 )

    文章目录 前言 一.网络初始化操作 二.PC 端工程核心业务逻辑 三.博客资源 前言 本篇博客重点分析 PC 端 hacktool 模块 ; 一.网络初始化操作 HackCommand::Prepar ...

最新文章

  1. C# 多网卡 Server Listen
  2. 2019全新学习路线图发布
  3. CMap在用CString做key类型时,ARG_KEY要选LPCTSTR
  4. 如何让 python 处理速度翻倍?内含代码
  5. iphone-common-codes-ccteam源代码 CCNSArray.m
  6. mysql事务最大个数_事务、mysql数据库的默认最大连接数、分页
  7. 加入karia2开源项目
  8. 如何减少电脑对眼睛视力的影响
  9. 刘汉国老师的3路单火智能开关
  10. IAR for STM8下载、安装、注册
  11. 此网站的安全证书有问题
  12. 手机如何将PDF文件拆分?分享两种手机拆分文件方法
  13. Android Activity 透明主题 使用
  14. CF1526C2 Potions (Hard Version) (贪心 + 线段树)
  15. Springboot的快速入门
  16. 网络安全知识之Cross-Site Request Forgery (CSRF) 简介
  17. 如何基于已有的 REST API 实现 GraphQL API
  18. C++反射机制的实现
  19. 记录mybatis添加表数据时报出的错误:Could not set property ‘id‘ of ‘class com.xxx.Manager with value ‘xx...xx‘
  20. Mac cocoapods安装步骤

热门文章

  1. 一位头发发白的神人教你怎么写程序,运维,买电脑,写文章,平面设计!
  2. HDLBits答案(4)_如何避免生成锁存器?
  3. oracle logminer java_Oracle logminer
  4. java时间api_什么是java时间API?
  5. linux杀死oracle进程,杀死进程后,oracle数据库无法启动
  6. SDUTOJ2828_字典树
  7. 洛谷 P1494 [国家集训队]小Z的袜子
  8. flask框架(十): 闪现
  9. Andrew Ng's Deep Learning学习记录
  10. 元素或为1或为-1的行列式的值的估计