QPainter类的CompositionMode各值含义
QPainter類的QPainter::CompositionMode枚舉用于說明源圖像和目標圖像怎樣合成顯示,一般用于圖像的混合,其實在OPenGL中也有混合的技術,和QPainter類的QPainter::CompositionMode大同小異,思想類似。
Qt官方手冊Assistant對QPainter::CompositionMode枚舉的解釋,沒有真正在項目中實戰用過QPainter::CompositionMode的童鞋來說,理解起來很費勁,網上的資料也是你抄我,我抄你的,真正弄懂、有價值的很少。今天我以示例和OPenGL中有關的闡述來講解這幾個枚舉。
目標圖像
目標圖像是劃定的繪制設備像素所在區域(如:窗體、圖片或窗體圖片的一部分區域)或上次繪制的圖像。前者是初次繪制時,如:初次想在窗體區域上繪制,此時窗體區域什么都沒有,則目標圖像是指窗體、圖片中程序劃定的要繪制區域所在像素。后者指在窗體或圖像上已經繪制過圖像。
源圖像
源圖像是指最新、最近繪制的圖像。如:起始繪制了a圖像到窗體上(此時窗體所在像素形成的區域是目標圖像,a圖像是源圖像),當a繪制完后,又在a的上面繪制了b圖像,則b成為源圖像,a成為目標圖像。
總結:把將要畫上去的圖像稱為“源圖像”,把原來的圖像稱為“目標圖像”。
該模式是默認模式,使用該模式時,源圖像如果和目標圖像有重疊,繪制時,則重疊部分是源圖像在目標圖像上面(源遮擋住目標),重疊部分源的RGBA值和重疊部分目標的RGBA值進行混合,沒有重疊部分各自保留即都繪制出來。假定源和目標的混合因子為:
Sr、Sg、Sb、Sa
Dr、Dg、Db、Da
其中Sr表示源的R分量的混合因子,Dr表示目標的R分量的混合因子,Sa表示源的alpha混合因子,Da表示目標的alpha混合因子,其它依次類似,相應地表示四元組RGBA的縮放因子。
一般地,源圖像和目標圖像重疊部分按照下述公式進行顏色的混合:
( Rs* Sr + Rd*Dr , Gs*Sg + Gd*Dg, Bs*Sb + Bd*Db, As*Sa + Ad*Da ) ----公式1
其中RGBA的下標s和d分別表示源的RGBA值和目標的RGBA值。將上述結果相乘相加后進行截取,以保證值在[0, 255]閉區間。如下代碼:
第一次繪制的紅色矩形為目標,第二次繪制的藍色矩形為源,采用的模式為QPainter::CompositionMode_SourceOver,則效果如下:
通過調節源alpha的滑塊,改變其值,如下為源alpha為111時的效果:
如下為源apha為0即源完全透明的效果,即能透過源看到后面的目標:
當源的alpha為0時,公式1源和目標合成后的圖像的alpha只有目標 Ad*Da 值了。然后保持源的alpha滑塊在最大值255處不變,調節目標的alpha到中間,如下為目標的alpha為92的情況:
如下為目標的alpha為0的情況:
將上述cpp中第39行代碼改為如下:
以便目標和源不重疊,則輸出如下,即源和目標都顯示:
調節源和目標各自的alpha,都只對自己的透明度有影響。
可以看到:
-
源圖像如果和目標圖像有重疊,繪制時,則重疊部分是源圖像在目標圖像上面(源遮擋住目標),當源的alpha為255時,目標被源完全遮擋。
-
重疊部分RGBA值按公式1進行進行混合,混合之后得出的RGBA值為重疊部分的RGBA值。
-
沒有重疊部分各自保留即都繪制出來。
2. QPainter::CompositionMode_DestinationOver
將上述cpp代碼中的第42行改為QPainter::CompositionMode_DestinationOver,則: -
源圖像如果和目標圖像有重疊,繪制時,則重疊部分是目標圖像在源圖像上面(目標遮擋住源),當目標的alpha為255時,源被目標完全遮擋。。
-
重疊部分的源和重疊部分的目標按公式1進行進行混合,混合之后得出的RGBA值為重疊部分的RGBA值。
-
沒有重疊部分各自保留即都繪制出來。
注意:和QPainter::CompositionMode_SourceOver的區別,唯一的區別是當源和目標有重疊時,目標蓋住源,該模式是QPainter::CompositionMode_SourceOver的的逆操作。如下為源和目標的alpha都為255時的效果:
如下為源alpha為255,目標alpha為168效果:
如下為源alpha為255,目標alpha為0效果,即目標完全透明,能透過目標看到后面的源:
將上述cpp中第39行代碼改為如下:
以便目標和源不重疊,則輸出如下,即源和目標都顯示:
調節源和目標各自的alpha,都只對自己的透明度有影響。
3.
QPainter::CompositionMode_Source
將上面cpp代碼的第42行改為QPainter::CompositionMode_Source,則:
- 無論什么情況,都只顯示源,不顯示目標,目標就像不存在、沒繪制一樣。如下為源和目標的alpha都為255的效果:
如下為源的alpha為0,目標alpha為255的效果:
可以看到,即使源完全透明,依然看不到目標。
4.QPainter::CompositionMode_Destination
將上面cpp代碼第42行換為:QPainter::CompositionMode_Destination,則:
- 無論什么情況,都只顯示目標,不顯示源,源就像不存在、沒繪制一樣,該模式是QPainter::CompositionMode_Source逆操作。如下為源和目標的alpha都為255的效果:
如下為目標的alpha為0,源alpha為255的效果:
可以看到,即使目標完全透明,依然看不到源。
5.QPainter::CompositionMode_SourceIn
將上面cpp代碼第42行換為:QPainter::CompositionMode_SourceIn,則:
- 如果目標和源有重疊,則只顯示重疊部分中的源區域,不顯示重疊部分的目標區域。目標和源不重疊部分都剔除、都不顯示,
- 如果目標和源不重疊,則什么都不顯示,不繪制,就像源和目標不存在一樣。
- 目標和源重疊部分圖像的alpha受到目標alpha的影響而削減(具體計算公式暫不清楚,知道的可以留言給我)。
如下為源和目標的alpha值都為255的結果:
如下為源的alpha值為255, 目標alpha值為0的結果:
如下為源的alpha值為0, 目標alpha值為255的結果:
如下為源的alpha值為0, 目標alpha值為0的結果:
如下為源的alpha值為128, 目標alpha值為133的結果:
將上述cpp中第39行代碼改為如下:
以便目標和源不重疊,則輸出如下,即什么都不顯示:
6.QPainter::CompositionMode_DestinationIn
將上面cpp代碼第42行換為:QPainter::CompositionMode_DestinationIn,則:
- 只顯示目標和源重疊部分中的目標部分,不顯示重疊部分的源部分。目標和源不重疊部分都剔除、都不顯示,
- 如果目標和源不重疊,則什么都不顯示,不繪制,就像源和目標不存在一樣。
- 目標和源重疊部分圖像的alpha受到源的alpha的影響而削減(具體計算公式暫不清楚,知道的可以留言給我)。
- 該模式是QPainter::CompositionMode_SourceIn的逆操作。
如下為源和目標的alpha值都為255的結果:
如下為源的alpha值為255, 目標alpha值為0的結果:
如下為源的alpha值為0, 目標alpha值為255的結果:
如下為源的alpha值為0, 目標alpha值為0的結果:
如下為源的alpha值為128, 目標alpha值為116的結果:
將上述cpp中第39行代碼改為如下:
以便目標和源不重疊,則輸出如下,即什么都不顯示:
7.QPainter::CompositionMode_SourceOut
將上面cpp代碼第42行換為:QPainter::CompositionMode_SourceOut,則:
- 如果源和目標有重疊,則輸出全部的源,但源和目標重疊部分默認完全透明,屬于目標但不屬于目標和源重疊的部分不輸出。此時目標alpha對重疊部分的alpha有影響即目標透明度影響重疊區域透明度;當目標alpha值為255即完全不透明時,源alpha對重疊區域alpha無影響,即此時源的透明度不影響重疊區域的透明度;當目標alpha值不為255即部分透明時,源alpha對重疊區域的alpha有影響,即此時源的透明度影響重疊區域透明度。
- 如果源和目標沒有重疊,則輸出全部源,不輸出目標。此時目標透明度對源沒有影響,這種情況下和QPainter::CompositionMode_Source相同。
如下為源和目標有重疊,且源alpha值為255, 目標alpha值為255的結果,可以看到重疊區域完全透明,
保持源alpha為255不變,分別調小目標的alpha為154、0,可以看到重疊區域受到目標透明度的影響:
保持目標alpha為255不變,分別調小源的alpha為103、38,可以看到重疊區域不受源透明度影響,此時源透明度只影響屬于源自身但不屬于重疊部分的源區域:
將目標alpha為135,源的alpha調為91、209,結果分別如下:
將上述cpp中第39行代碼改為如下:
即讓源和目標不重疊,結果如下:
此時調節目標的alpha對源的透明度沒任何影響。
8.QPainter::CompositionMode_DestinationOut
將上面cpp代碼第42行換為:QPainter::CompositionMode_DestinationOut,則:
- 如果源和目標有重疊,則輸出全部目標,但源和目標重疊部分默認完全透明,屬于源但不屬于源和目標重疊的部分不輸出。此時源alpha對重疊部分的alpha有影響即源透明度影響重疊區域透明度;當源alpha值為255即完全不透明時,目標alpha對重疊區域alpha無影響,即此時目標的透明度不影響重疊區域的透明度;當源alpha值不為255即部分透明時,目標alpha對重疊區域的alpha有影響,即此時目標透明度影響重疊區域透明度。
- 如果源和目標沒有重疊,則輸出全部目標,不輸出源。此時源透明度對目標沒有影響,這種情況下和QPainter::CompositionMode_Destination相同。該模式是CompositionMode_SourceOut.模式的逆操作。
結果就是把CompositionMode_SourceOut.藍色截圖換成紅色就行。
9.QPainter::CompositionMode_SourceAtop
將上面cpp代碼第42行換為:QPainter::CompositionMode_SourceAtop,則:
- 輸出全部目標。
- 如果源和目標有重疊,則只輸出源重疊部分,且源重疊部分在目標的上面即遮擋住目標。源和目標不重疊的部分不輸出。
- 如果源和目標沒有重疊,則只輸出全部的目標,不輸出源。
如下為目標的alpha為255,源alpha為255時的效果::
重疊部分中,源在目標上面(遮擋住目標),重疊部分像素值由源和目標混合得出,源的alpha受到目標像素的alpha而削減。
如下為目標的alpha為0,源alpha為255時的效果:
如下為目標的alpha為255,源alpha為0時的效果:
如下為目標的alpha為128,源alpha為128時的效果:
將上述cpp代碼中的39行改為如下,即源和目標不重疊
painterSecond.drawRect(200,200, 100, 100);
則效果如下:
可以看到只輸出目標,沒有輸出源。
10.QPainter::CompositionMode_DestinationAtop
將上面cpp代碼第42行換為:QPainter::CompositionMode_DestinationAtop,則:
- 輸出全部源。
- 如果目標和源有重疊,則只輸出目標重疊部分,且目標重疊部分在源上面即遮擋住源。目標和源不重疊的部分不輸出。
- 如果目標和源沒有重疊,則只輸出全部的源,不輸出目標。
- 該模式是QPainter::CompositionMode_SourceAtop的逆操作。
截圖略。
11 QPainter::CompositionMode_Xor
源(其alpha值與目標alpha值的倒數成反比)與目標合并,該目標的alpha值與源alpha的倒數成反比。
截圖略
12.QPainter::CompositionMode_Clear
源和目標無論在什么情況下都不顯示,就像源、目標不存在一樣。
總結:
- Qt總共有35種組合模式,但是很多不常用,所以本文就沒再描述說明,當用戶需要研究時,可以將上面cpp代碼42行換成你要的模式,進行研究。
- 上面很多有關alpha減小、混合的內容,應該都有相應的公式的,但qt官方沒有給出,這屬于圖形圖像學的內容,OPengl中有一些,但和Qt的還是有些不同,如果讀者知道這些混合方面的,alpha方面的公式,可以和我留言。
參考資料:
【1】:《 OpenGL編程指南(原書第7版)》 6.1節 混合。
【2】:QT多張圖片的重疊顯示
總結
以上是生活随笔為你收集整理的QPainter类的CompositionMode各值含义的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 脑洞大开!科学家想用气球“撬动”太阳 阻
- 下一篇: foreach、qAsConst用法总结