日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

QPainter类的CompositionMode各值含义

發布時間:2023/12/15 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QPainter类的CompositionMode各值含义 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

QPainter類的QPainter::CompositionMode枚舉用于說明源圖像和目標圖像怎樣合成顯示,一般用于圖像的混合,其實在OPenGL中也有混合的技術,和QPainter類的QPainter::CompositionMode大同小異,思想類似。
Qt官方手冊Assistant對QPainter::CompositionMode枚舉的解釋,沒有真正在項目中實戰用過QPainter::CompositionMode的童鞋來說,理解起來很費勁,網上的資料也是你抄我,我抄你的,真正弄懂、有價值的很少。今天我以示例和OPenGL中有關的闡述來講解這幾個枚舉。
目標圖像
目標圖像是劃定的繪制設備像素所在區域(如:窗體、圖片或窗體圖片的一部分區域)或上次繪制的圖像。前者是初次繪制時,如:初次想在窗體區域上繪制,此時窗體區域什么都沒有,則目標圖像是指窗體、圖片中程序劃定的要繪制區域所在像素。后者指在窗體或圖像上已經繪制過圖像。
源圖像
源圖像是指最新、最近繪制的圖像。如:起始繪制了a圖像到窗體上(此時窗體所在像素形成的區域是目標圖像,a圖像是源圖像),當a繪制完后,又在a的上面繪制了b圖像,則b成為源圖像,a成為目標圖像。
總結:把將要畫上去的圖像稱為“源圖像”,把原來的圖像稱為“目標圖像”。

  • QPainter::CompositionMode_SourceOver
    該模式是默認模式,使用該模式時,源圖像如果和目標圖像有重疊,繪制時,則重疊部分是源圖像在目標圖像上面(源遮擋住目標),重疊部分源的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]閉區間。如下代碼:
  • #include <QtWidgets/QWidget> #include "ui_compositionModeDemo.h" #include<QPainter> #include <QImage> class compositionModeDemo : public QWidget {Q_OBJECTpublic:compositionModeDemo(QWidget *parent = Q_NULLPTR);private :void paintEvent(QPaintEvent *event)override; private slots:void srcAlphaValueChanged(int newAlphaValue);void destAlphaValueChanged(int newAlphaValue); private:Ui::compositionModeDemoClass ui;QImage* firstImage = nullptr;QImage* secondImage = nullptr;int m_srcAlpha{255};int m_destAlpha{ 255 }; }; #include "compositionModeDemo.h"compositionModeDemo::compositionModeDemo(QWidget *parent): QWidget(parent) {ui.setupUi(this);connect(ui.srcAlphaSlider, SIGNAL(valueChanged(int)), this, SLOT(srcAlphaValueChanged(int)));connect(ui.destAlphaSlider, SIGNAL(valueChanged(int)), this, SLOT(destAlphaValueChanged(int)));firstImage = new QImage(500, 500, QImage::Format_ARGB32_Premultiplied);secondImage = new QImage(500, 500, QImage::Format_ARGB32_Premultiplied);}void compositionModeDemo::destAlphaValueChanged(int newAlphaValue) {m_destAlpha = newAlphaValue;update(); }void compositionModeDemo::srcAlphaValueChanged(int newAlphaValue) {m_srcAlpha = newAlphaValue;update(); }void compositionModeDemo::paintEvent(QPaintEvent *event) {//繪制第一張圖片QPainter painterFirst(firstImage);firstImage->fill(Qt::transparent);//設置透明painterFirst.setBrush(QColor(255, 0, 0, m_destAlpha));painterFirst.drawRect(50, 50, 100, 100);//繪制第二張圖片QPainter painterSecond(secondImage);secondImage->fill(Qt::transparent);painterSecond.setBrush(QColor(0, 0, 255, m_srcAlpha));painterSecond.drawRect(100, 100, 100, 100);//設置圖片的重疊模式painterFirst.setCompositionMode(QPainter::CompositionMode_SourceOver);//重疊圖片painterFirst.drawImage(0, 0, *secondImage);//展示圖片QPainter painter2(this);painter2.drawImage(0, 0, *firstImage);}

    第一次繪制的紅色矩形為目標,第二次繪制的藍色矩形為源,采用的模式為QPainter::CompositionMode_SourceOver,則效果如下:

    通過調節源alpha的滑塊,改變其值,如下為源alpha為111時的效果:

    如下為源apha為0即源完全透明的效果,即能透過源看到后面的目標:

    當源的alpha為0時,公式1源和目標合成后的圖像的alpha只有目標 Ad*Da 值了。然后保持源的alpha滑塊在最大值255處不變,調節目標的alpha到中間,如下為目標的alpha為92的情況:

    如下為目標的alpha為0的情況:

    將上述cpp中第39行代碼改為如下:

    painterSecond.drawRect(200, 200, 100, 100);

    以便目標和源不重疊,則輸出如下,即源和目標都顯示:

    調節源和目標各自的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行代碼改為如下:

    painterSecond.drawRect(200, 200, 100, 100);

    以便目標和源不重疊,則輸出如下,即源和目標都顯示:

    調節源和目標各自的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行代碼改為如下:

    painterSecond.drawRect(200, 200, 100, 100);

    以便目標和源不重疊,則輸出如下,即什么都不顯示:

    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行代碼改為如下:
    painterSecond.drawRect(200, 200, 100, 100);

    以便目標和源不重疊,則輸出如下,即什么都不顯示:

    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行代碼改為如下:

    painterSecond.drawRect(200, 200, 100, 100);

    即讓源和目標不重疊,結果如下:

    此時調節目標的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各值含义的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。