imagecomposition工程分析
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工程分析相关推荐
- MATLAB数学计算与工程分析范例教程,MATLAB数学计算与工程分析范例教程
基本信息 书名:MATLAB数学计算与工程分析范例教程 定价:28.00元 作者:石博强,赵金 编著 出版社:中国铁道出版社 出版日期:2005-05-01 ISBN:9787#113057596 字 ...
- ML之FE:利用FE特征工程(分析两两数值型特征之间的相关性)对AllstateClaimsSeverity(Kaggle2016竞赛)数据集实现索赔成本值的回归预测
ML之FE:利用FE特征工程(分析两两数值型特征之间的相关性)对AllstateClaimsSeverity(Kaggle2016竞赛)数据集实现索赔成本值的回归预测 目录 输出结果 设计思路 核心代 ...
- 机器学习cae_CAE工程分析技术年会记
读书使人充实,讨论使人机智,笔记使人准确,读史使人明智,读诗使人灵秀,数学使人周密,科学使人深刻,伦理使人庄重,逻辑修辞使人善辩.凡有所学,皆成性格.---- (英国)培根 可能是会议热度不够,非常遗 ...
- 03-instancing 工程分析详解
opengl编程指南第8版源码怎么下载.编译,请参考<opengl编程指南第8版源码编译详细说明> 1. 程序启动 请参考<03-drawcommands工程分析详解> 2. ...
- python与金融工程的区别_科研进阶 | 纽约大学 | 金融工程、量化金融、商业分析:Python金融工程分析...
科研进阶 | 纽约大学 | 金融工程.量化金融.商业分析:Python金融工程分析(2021.2.6开课)mp.weixin.qq.com 课题名称 = Python金融工程分析 = 项目配景 大数 ...
- MATLAB数学计算与工程分析范例教程,MATLAB 2016数学计算与工程分析从入门到精通...
全书通过近400个实例讲解了利用MATLAB 2016进行数学计算和工程分析的方法和技巧,涵盖了MATLAB的五大功能:1)数值计算功能:2)符号计算功能:3)图形与数据可视化功能:4)可视化建模与仿 ...
- 计算机辅助工程分析课程论文,教学大纲—计算机辅助工程分析.doc
<计算机辅助工程分析>课程教学大纲 英文课程名Computer Aided Engineering总 学 时32学 分2课程编码202725理论教学学时8适用专业机械工程.过程装备与控制工 ...
- FPGA设计心得(5)Aurora 例子工程分析与仿真实例分析(streaming版)
文章目录 背景 例子工程预览 例子程序用户模块逻辑分析 收(CHECK) 发(GEN) 例子程序仿真文件分析 写在最后 工程分享 参考资料 交个朋友 背景 熬夜写完了上两篇博客: Aurora IP ...
- 【Android 逆向】Android 逆向通用工具开发 ( PC 端工程分析 | 网络初始化操作 | PC 端工程核心业务逻辑 )
文章目录 前言 一.网络初始化操作 二.PC 端工程核心业务逻辑 三.博客资源 前言 本篇博客重点分析 PC 端 hacktool 模块 ; 一.网络初始化操作 HackCommand::Prepar ...
最新文章
- C# 多网卡 Server Listen
- 2019全新学习路线图发布
- CMap在用CString做key类型时,ARG_KEY要选LPCTSTR
- 如何让 python 处理速度翻倍?内含代码
- iphone-common-codes-ccteam源代码 CCNSArray.m
- mysql事务最大个数_事务、mysql数据库的默认最大连接数、分页
- 加入karia2开源项目
- 如何减少电脑对眼睛视力的影响
- 刘汉国老师的3路单火智能开关
- IAR for STM8下载、安装、注册
- 此网站的安全证书有问题
- 手机如何将PDF文件拆分?分享两种手机拆分文件方法
- Android Activity 透明主题 使用
- CF1526C2 Potions (Hard Version) (贪心 + 线段树)
- Springboot的快速入门
- 网络安全知识之Cross-Site Request Forgery (CSRF) 简介
- 如何基于已有的 REST API 实现 GraphQL API
- C++反射机制的实现
- 记录mybatis添加表数据时报出的错误:Could not set property ‘id‘ of ‘class com.xxx.Manager with value ‘xx...xx‘
- Mac cocoapods安装步骤
热门文章
- 一位头发发白的神人教你怎么写程序,运维,买电脑,写文章,平面设计!
- HDLBits答案(4)_如何避免生成锁存器?
- oracle logminer java_Oracle logminer
- java时间api_什么是java时间API?
- linux杀死oracle进程,杀死进程后,oracle数据库无法启动
- SDUTOJ2828_字典树
- 洛谷 P1494 [国家集训队]小Z的袜子
- flask框架(十): 闪现
- Andrew Ng's Deep Learning学习记录
- 元素或为1或为-1的行列式的值的估计