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