天天看點

2D繪圖

2D繪圖

Qt4中的2D繪圖部分稱為Arthur繪圖系統.它由3個類支撐整個架構,QPainter,QPainterDevice和QPainterEngine.QPainter用來執行具體的繪圖相關操作

如畫點,畫線,填充,變換,alpha通道等。QPainterDevice是QPainter用來繪圖的繪圖裝置,Qt中有幾種預定義的繪圖裝置,如QWidget,QPixamp,QPrinter

等.他們都從QPaintDevice繼承。QPaintEngine類提供了不同類型裝置的接口,QPaintEngine對程式員不透明,由QPainter,QPaintDevice類與其進行互動。

從Qt4.2開始,Graphics View架構取代了QCanvas,QGraphics View架構使用了MVC模式,适合對大量2D圖元的管理,Grphics View架構中,場景(scene)

存儲了圖形資料,它通過視圖(view)以多種表現形式,每個圖元(item)可以單獨進行控制.

Arthur繪圖基礎

在Arthur繪圖架構中的基本繪圖元素是畫筆,畫刷。

QPainter類具有GUI程式需要的絕大多數函數,能夠繪制基本圖形(點,線,矩形,多邊形等)以及複雜的圖形(如繪圖路徑).使用繪圖路徑(QPaintPath)的優點是複雜形狀

的圖形之用生成一次,以後再使用的時候是需要調用QPainter::drawPath()就可以了。QPainterPath對象可以用來填充,繪制輪廓。

線和輪廓都可以用畫筆(QPen)進行繪制,畫刷(QBrush)進行填充。畫筆定義了風格(線形),寬度,筆尖畫刷以及端點是如何繪制的(cap-style),端點的連接配接方式(join-style)

.畫刷用來填充畫筆繪制的圖形,可以定制不同的填充模式和顔色的畫刷。

當繪制文字時,字型使用QFont類定義,Qt使用指定字型的屬性,如果沒有比對的字型,Qt将使用最接近的字型。字型屬性可以通過QFontInfo來擷取。字型的度量(measurement)

使用QFontMetrics類來擷取。QFontDatabase類可以獲得底層視窗系統所有可用的字型.

通常情況下QPainter以預設的坐标系統進行繪制,也可以用QMatrix類對坐标進行變換。

當繪制時,可以使用QPainter::RenderHint來告訴繪圖引擎是否啟用飯鋸齒功能使圖變得平滑。

QPainter::RenderHint的可取如表6-1中的值

------------------------------------------------------------------------------------------------

QPainter::Antialiasing           告訴繪圖引擎應該在可能的情況下進行邊的反鋸齒繪制

QPainter::TextAntialiasing       盡可能的情況下文字的反鋸齒繪制

QPainter::SmoothPixmapTransform  使用平滑的pixmap變換算法(雙線性插值算法),而不是近鄰插值算法

-------------------------------------------------------------------------------------------------

QPainter的繪圖函數

-------------------------------------------------------------------------------------------------

drawArc()                                 弧

drawChord()                               弦

drawConvexPolygon()                       凸多邊形

drawEllipse()                             橢圓

drawImage()                               QImage表示的圖像

drawLine()                                線

drawLines()                               多條線

drawPath()                                路徑

drawPicture()                             按QPainter指令繪制

drawPie()                                 扇形

drawPixmap()                              QPixmap表示的圖像

drawPoint()                               點

drawPoints()                              多個點

drawPolygon()                             多邊形

drawPolyline()                            多折線

drawRect()                                矩形

drawRects()                               多個矩形

drawRoundRect()                           圓角矩形

drawText()                                文字

drawTiledPixmap()                         平鋪圖像

drawLineSegments()                        繪制折線

------------------------------------------------------------------------------------------------

drawPicture()函數負責繪制QPicture中存儲的QPainter指令,QPicture是可以記錄QPainter繪圖指令的類.它将QPainter的繪圖指令串行化為平台無關的存儲格式。

下面的代碼将記錄的繪圖指令重繪。

QPicture picture;

picture.load("mypicture.pic");

QPainter painter(this);

painter.drawPicture(0,0,picture);//在(0,0)處重放繪圖指令,也可以使用QPicture::play()完成相同的功能

===================================================================================

使用畫筆

畫筆的屬性包括線型,線寬,顔色等。畫筆的屬性可以在構造函數中指定,也可以使用setStyle(),setWidth(),setBrush(),setCapStyle(),setJoinStyle()等函數

逐項設定畫筆的各項屬性.Qt中使用Qt::PenStyle定義了6種畫筆風格,分别是Qt::SolidLine,Qt::DashLine,Qt::DotLine,Qt::DashDotLine,Qt::DashDotDotLine,

Qt::CustomDashLine.自定義線風格(Qt::CustomDashLine),需要使用QPen的setDashPattern()函數來設定自定義風格.

下面代碼設定了一個自定義QPen

QPen pen;

QVector customDashes;

qreal blank=4;

dashes<<2< pen.setDashPattern(customDashes);

端點風格(cap style)

端點風格決定了線的端點樣式,它隻對線寬大于1的線有效。Qt種定義了三種端點風格用枚舉類型Qt::PenCapStyle表示,分别為Qt::SqureCap,QT::FlatCap,Qt::RoundCap,

連接配接風格(Join style)

連接配接風格是兩條線如何連接配接,連接配接風格對線寬大于等于1的線有效。Qt定義了四種連接配接方式用枚舉類型Qt::PenStyle表示.分别是Qt::MiterJoin,Qt::BevelJoin,Qt::RoundJoin.

Qt::SvgMiterJoin.

2.畫刷

在Qt中圖形使用QBrush進行填充,畫刷包括填充顔色和風格(填充模式).在Qt中,顔色使用QColor類表示,QColor支援RGB,HSV,CMYK顔色模型。QColor還支援alpha混合的輪廓和

填充。基本模式填充包括有各種點,線組合的模式。Qt支援RGB,HSV,和CMYK顔色模型。RGB是面向硬體的模型。顔色由紅綠藍三種基色混合而成。HSV模型比較符合人對顔色的感覺,由

色調(0-359),飽和度(0-255),亮度(0-255)組成.CMYK由青,洋紅,黃,黑四種基色組成。主要用于列印機等硬體拷貝裝置上。每個顔色分量的取值是0-255.另外QColor還可以用

SVG1.0中定義的任何顔色名為參數初始化.

Qt4提供了漸變填充的畫刷,漸變填充包括兩個要素,顔色的變化和路徑的變化。顔色變化可以指定從一種顔色漸變到另外一種顔色。也可以在變化的路徑上指定一些點的顔色進行分段漸變。

Qt4中,提供了三種漸變填充:線性(QLinearGradient),圓形(QRadialGradient)和圓錐漸變(QConicalGradient).所有的類都從QGradient類繼承.

------------------

線性漸變填充

線性漸變填充指定兩個控制點,畫刷在兩個控制點之間進行顔色插值。通過建立QLinearGradient對象來設定畫刷.

QLinearGradient linearGradient(0,0,200,100);

linearGradient.setColorAt(0,Qt::red);

linearGradient.setColorAt(0.5,Qt::green);

linearGradient.setColorAt(1,Qt::blue);

painter.setBrush(linearGradient);

painter.drawRect(0,0,200,100);

在QGradient構造函數中指定線行填充的兩點分别為(0,0),(100,100).setColorAt()函數在0-1之間設定指定位置的顔

------------------

圓形漸變填充

圓形漸變填充需要指定圓心,半徑和焦點。畫刷在焦點和圓上的所有點之間進行顔色插值。建立QRadialGradient對象設定畫刷

QRadialGradient radialGradient(50,50,50,30,30);

radialGradient.setColorAt(0.2,Qt::cyan);

radialGradient.setColorAt(0.8,Qt::yellow);

radialGradient.setColorAt(1,Qt::magenta);

painter.setBrush(radialGradient);

painter.drawEllipse(0,0,100,100);

-------------------------------

圓錐漸變填充

圓錐漸變填充指定圓心和開始角,畫刷沿圓心逆時針對顔色進行插值,建立QConicalGradient對象并設定畫刷.

QConicalGradient conicalGradient(60,40,30);

conicalGradient.setColorAt(0,Qt::gray);

conicalGradient.setColorAt(0.4,Qt::darkGreen);

conicalGradient.setColorAt(0.6,Qt::darkMagenta);

conicalGradient.setColorAt(1,Qt::drakBlue);

painter.setBrush(conicalGradient);

painter.drawEllipse(0,0,100,100);

---------------------------------

為了實作自定義填充,還可以使用QPixmap或者QImage對象進行紋理填充。兩種圖像分别使用setTexture()和setTextureImage()函數加載紋理.

======================================================================================================================

雙緩沖繪圖

在Qt4中,所有的視窗部件預設都使用雙緩沖進行繪圖。使用雙緩沖,可以減輕繪制的閃爍感。在有些情況下,使用者要關閉雙緩沖,自己管理繪圖。下面的語句設定了視窗部件

的Qt::WA_PaintOnScreen屬性 ,就關閉了視窗部件的雙緩沖.

mywidget->setAttribute(Qt::WA_PaintOnScreen);

由于Qt4不再提供異或筆,組合模式QPainter::CompostionMode_Xor()并不是異或筆,Qt4隻提供了QRubberBand實作矩形和直線的繪圖回報。是以要實作在繪圖中動态

回報必須使用其他方法。程式中使用雙環沖來解決這個問題。在繪圖過程中,一個緩沖區繪制臨時記憶體,一個緩沖區儲存繪制好的内容,最後進行合并。

在互動繪圖過程中,程式将圖像緩沖區複制到臨時緩沖區,并在臨時緩沖區上繪制,繪制完畢在将結果複制到圖像緩沖區,如果沒有互動複制,則直接将圖像緩沖區繪制顯示到螢幕上。

------------------------

使用alpha通道

在windows,Mac OSX和有XRender擴充的X11系統上,Qt4能夠支援Alpha通道,通過使用Alpha通道,可以實作半透明效果,QColor類中定義了Alpha通道的透明度,0表示完全透明

255表示完全不透明。注意QWidget類有一個屬性windowOpacity,通過setWindowOpacity(qreal level)可以設定視窗的透明度。但該屬性和Alpha通道的原理并不相同,Qt4在

Windows和Mac OS X平台上才支援該屬性,但在X11平台上卻需要Composite擴充才能工作。(alpha通道使用的是X11的xRender擴充).

---------------------------------------

繪圖裝置

QPaintDevice類是實際的繪制裝置的基類.QPainter能夠在QPaintDevice子類上進行繪制,如QWidget,QImage,QPixmap,QGLWidget,QGLPixelBuffer,QPicture,QPrinter

QSvgGenerator.要實作自己的繪圖裝置,必須從QPaintDevice類繼承并實作其虛函數QPaintDevice::paintEngine()以告之QPainter能夠在這個特定的裝置上繪制圖形,同時還需要從

QPaintEngine類繼承自定義的圖形繪制引擎。

1 QWidget

QWidget是所有使用者界面元素的基類,視窗部件時使用者界面的原子元素,他接受滑鼠,鍵盤,視窗系統的其他事件并在螢幕上繪制自己。

2 QImage

QImage類提供了與硬體無關的圖像表示,它為直接操作像素提供優化,QImage支援單色,8-bit,32-bit和alpha混合圖像,使用QImage的優點在于可以獲得平台無關的繪制操作,另外還有一個好處

時圖像可以不必在GUI線程中處理。

3 QPixmap

QPixmap時背景顯示的圖像,它為在螢幕上顯示圖像提供優化,不同于QImage,pixmap的圖像資料使用者不可見,而且由底層視窗系統管理,為了優化QPixmap圖像,Qt提供了QPixmapCache類來存儲

臨時的pixmap.Qt還提供了QPixmap的繼承類QBitmap類,QBitmap表示單色的pixmap,主要用來建立自定義的QCursor和QBrush對象,構造QRegion對象,設定pixmap和視窗部件的掩碼。

4 OPenGLWidget

Qt提供了QtOpenGL子產品來實作OpenGL操作,QGLWidget允許使用OpenGL API進行繪制。同時QGLWidget時QWidget的子類,是以QPainter也可以在上面繪制。這樣可以使Qt能夠利用OpenGl

完成繪制操作,如變換和繪制pixmap

5 pixel Buffer

QGLPixelBuffer從QPaintDevice繼承,封裝了OpenGL pbuffer.使用pbuffer繪制通常時全硬體加速,這比使用QPixmap繪制更為迅速。

6 FrameBuffer

QGLFrameBufferObject從QPaintDevice繼承,QGLFrameBufferObject封裝了OpenGL frameBuffer對象,FrameBuffer對戲那個用來實作背景螢幕繪制,比pixel buffer更好一些。

7 picture

QPicture類時能夠記錄和重演QPainter指令的繪圖裝置,picture串行化painter的指令為平台無關的格式,QPicture同時也于分辨率無關,如QPicuture能夠在不同的裝置上(svg,pdf,ps

列印機和螢幕)有一隻的顯示。QPicture::load()和QPicture::save()函數分别完成載入和存儲圖像。

8 Printer

QPrinter類時在列印機上繪制的繪圖裝置,在Windows和MAC OS X上,QPrinter使用内建的列印機驅動程式,在X11上,QPrinter山城postscript代碼并發送給lpr,lp或者其他列印程式,QPrinter可以在任意其他QPrintEngine對象上列印,也可以直接生成PDF檔案。

QPrintEngine類定義了QPrinter如何和其他列印機系統互動的接口,主要建立自己的列印引擎時,可以從QPaintEngine和QPaintEngine上繼承。

======================================================================================================

  坐标系統與坐标變換

1. Qt坐标系統由QPainter控制,同時也由 QPaintDevice和QPaintEngine類控制.QPaintDevice類是繪圖裝置的基類,QWidget,QPixmap,QImage,和QPrinter都是QPaintDevice類的子類。Qt繪圖裝置預設坐标原點是左上角,X軸向右增長,Y軸向下增長,預設的機關在基于像素的裝置上是像素,在列印機裝置上是1/72英寸(0.35毫米).QPainter的邏輯坐标與QPainterDevice的實體坐标之間的映射由QPainter的變換矩陣,視口和視窗處理。邏輯坐标和實體坐标也是一直的。QPainter也支援坐标變換(如旋轉和伸縮);

2. 坐标變換。

  通常QPainer在裝置的坐标系統上繪制圖形,但QPainter也支援坐标變換。可以通過QPainter::scale()函數進行比例變換。使用QPainter::rotate()函數進行旋轉變換。平移變換則使用QPainter::translate()函數,QPainter::shear()函數對圖形進行扭曲操作,所有變換操作的變換矩陣都可以通過QPainter::wordMatrix()函數取出。不同的變換矩陣可以使用堆棧儲存。

用QPainter::save()儲存變換矩陣到堆棧,用QPainter::restore()函數将其彈出堆棧。

  QMatrix定義了系統的二維變換。QMatrix對象實際上定義了一個3x3矩陣。

  --------------

  m11  m12  0

  m21  m22  0

  dx   dy   1

  ---------------

   x//'=m11*x+m21*y+dx;

   y//'=m22*y+m12*x+dy;

其中dx,dy表示水準和垂直偏移量,m11,m22表示水準和垂直方向上的比例。m12和m21表示水準和垂直方向上的扭曲程度。

   矩陣可以通過setMatrix函數進行設定,然後可以使用translate(),rotate(),scale(),shear()等函數進行變換.Qt4.3中引入QTransform類表示變換矩陣。與QMatrix不同的是,QTransform()支援透視變換。使用toAffine()函數可以将QTransform對象轉換為QMatrix對象。這将丢失QTransform的透視變換資料。邏輯坐标和實體坐标的變換由QPainter的worldMatrix()函數。以及QPainter的viewport()和window()函數處理。視口表示實體坐标下的任意矩形。而在視窗表示在邏輯坐标下的相同矩形。預設情況下邏輯坐标與實體坐标時相同的。與繪圖裝置上的矩形也是一緻的。使用視窗-視口變換可以使邏輯坐标符合自定義要求,這個機制通常用來完成裝置無關的繪圖代碼。例如,可以設定邏輯坐标(-100,-100)到(100,100)且在原點(0,0),通過調用QPainter::setWindow()函數可以完成下列操作。

 QPainter painter(this);

 painter.setWindow(QRect(-100,-100,200,200));

現在,邏輯坐标的(-100,-100)對應着繪圖裝置的(0,0),這樣可以繪制獨立于裝置,始終在指定邏輯坐标上工作。設定視窗或視口矩形實際上是執行線性變換。本質上是視窗四個角映射到對應的視口四個角,反之亦然,是以保持視口和視窗x軸和y軸之間的比例變換一緻,保證變換沒有變形。視窗-視口變換隻是線性變換,不執行裁剪操作,例如當繪制超出視窗後,這些繪制仍然 通過線性變換映射到

視口進行繪制。Qt的繪制過程是進行坐标變換,在進行視窗-視口變換。

==================================================================================================================

  使用不同的字型

  Qt提供了Font類來表示字型,當建立QFont對象時,Qt會使用指定的字型,如果沒有對應的字型,Qt将尋找一種最接近的已安裝字型。字型資訊可以通過

QFontInfo取出,并可用QFontMetrics取得字型的相關資料。函數exactMatch()判斷底層視窗系統中是否有完全對應的字型。使用QApplication::setFont()可以設定應用程式預設的字型,如果選擇的字型不包括所有要顯示的字元,QFont将會嘗試尋找最基接近的字型。當QPainter繪制指定的字型中不存在的字元時

将繪制一個空心的正方行。

 繪圖路徑  --QPainterPath

繪圖路徑(painter path)由基本圖元(矩形,橢圓,直線,曲線)組成,繪圖路徑可以是閉合的路徑,如矩形和圓,或者是非閉合的路徑,如直線和曲線。繪圖路徑在Qt中使用QPainterPth類表示,

它提供了繪圖操作的容器,可以使圖形能夠複用。繪圖路徑可以進行填充,顯示輪廓和裁剪。要生成可填充的輪廓的繪圖路徑,可以使用QPainterPathStroker類.使用QPainterPath的優點是複雜的

圖形隻需建立一次,就可以多次使用。QPainterPath對象可以時隻有起點的空路徑,或者從其他QPainterPath對象複制,建立了QPainterPath對象後,可以使用lineTo(),cubicTo(),

quadTo()函數将直線和曲線添加到路徑中來,直線和曲線從currentPosition()開始繪制。currentPosition()總是傳回最後的子路經繪制的終點。使用moveTo()函數可以在不增加路徑的情況下移動currentPositon(),它關閉了一個子路經,開始一個新的子路經。closeSubPath()也可以關閉目前路徑,并從currentPosition()連接配接一條直線到繪圖路徑的起點。QPainter可以使用addEllipse(),addPath(),addRect(),addRegion(),addText()将Qt的一些基本圖元加入繪圖路徑。一個已有的繪圖路徑可以通過connectPath()函數加入到另一個繪圖路徑中。

如下代碼繪制了一個箭頭:

QPainterPath path;

path.moveTo(10,100);

path.cubicTo(10,100,100,10,200,70);

path.lineTo(200,50);

path.lineTo(220,80);

path.lineTo(200,110);

path.lineTo(200,90);

path.cuticTo(200,100,100,50,50,100);

QPainter painter(this);

QPen pen(QColor(255,0,0),2);

painter.setPen(pen);

painter.drawPath(path);

Qt提供了兩種填充方式,Qt::OddEventFill和Qt::WindingFill.Qt::OddEvent時預設的填充規則,它指定QPainterPath使用奇偶填充規則,該規則判斷一個點是否在論經圖形内的方法是從該店畫一條水準線到路徑外,計算水準線和路徑的交點數,如果交點時奇數個則說明該點在路徑圖形内。QPainterPath還有一些函數可以擷取路徑資訊,如elementAt()函數可以取出指定的子路經元素,

isEmpty()函數判斷目前路徑是否為空。controlPointRect()函數傳回路徑中所有的點和控制點的矩形,該函數運作速度比傳回精确包容框boundingRect()函數快得多。contains()函數判斷一個點或一個矩形是否在路徑内。intersects()判斷指定的矩形與路徑是否相交.QPainterPath可以将矩形圖形轉換為其他圖形,如使用toFillPolygon(),toFillPolygon(),toSubpathPOlygons()函數将路徑轉化為多邊形。

QPainterPath還可以使用文字作為路徑,下面的代碼示範了文字路徑,并使用線性漸變填充。

QLinearGradient linearGrad(QPointF(200,0),QPointF(1000,0));

linearGrad.setColorAt(0,Qt::black);

linearGrad.setColorAt(1,Qt::white);

QFont font("隸書",80);

font.setBold(true);

QPainterPath textPath();

textPath.addText(200,300,font,tr("電子工業出版社"));

painter.setBrush(linearGrad);

painter.drawPath(textPath);

===========================================================================

  QImage和QPixmap繪圖裝置

Qt提供了4個處理圖像的類。QImage,QPixmap,QBitmap,QPicure.他們有着各自的特點。QImage優化了I/O操作,可以直接存取操作像素資料。QPixmap主要用來在螢幕上顯示圖像。QBitmap從QPixmap繼承,隻能表示兩種顔色,QPicture是可以記錄和重放QPrinter指令的類。QImage提供了與硬體無關的圖像表示方法。通過QImage可以直接存取像素資料,QImage也可以用作繪圖裝置。

QImage支援的圖像顔色可以是單色,8位,32位和alpha混合的格式。因為QImage從QPainterDevice繼承,是以QPainter可以直接在QImage上繪圖。除了繪制文字格式外(QFont依賴于底層的GUI).其他的繪制操作可以在任意線程中完成,如果要在其他線程中繪制文字,可以使用QPainterPath。QImage對象具有隐式共享,作為傳值參數,可以使用資料流及進行比較等特性。

讀入圖像可以通過QImage構造函數,load(),loadFromData()幾種方法完成。還可以通過QImage的靜态函數fromData()由指定資料構造一個QImage對象。既可以從檔案系統裝入,也可以從Qt應用程式的嵌入式資源中讀取,使用save()可以儲存QImage對象。可以通過QImageReader::supportedImageFormats()和QImageWriter::supportedImageFormats()擷取QImage支援的所有檔案格式清單。

------------------------------------------

QImage函數

--------------------------------------------------------------------------------------------------------------------------------------------------

幾何函數   size(),widt(),dotsPermeterX(),dotsPerMeterY()函數擷取圖像大小和比例資訊。

         rect()函數傳回圖像的包容矩形,valid()測試給定的坐标是否在此矩形内。offset()擷取圖像和其他圖像之間的相對偏移量。setOffset()函數設定偏移量。

顔色函數   某個像素的顔色可以通過pixel函數擷取,傳回值是QRgb類型,對于單色和256色圖像,colorTable()傳回調色闆,numColors傳回調色闆中的條目數.用pixelIndex()

            函數擷取像素的顔色索引,然後使用color()函數取出實際的顔色值.hasAlphaChannel()函數傳回圖像是否使用了alpha通道。allGray(),isGrayscale()測試圖像是否為灰階圖像。

文字        text()函數傳回圖像附屬的文字,textKeys()傳回文字的鍵值表。setText()函數改變圖像附屬文字.

低級資訊   depth()函數擷取圖像顔色位數.支援1,8,32位.format().bytesPerLine()和numBytes()函數傳回圖像的資料存儲資訊.serieralNumber()函數取得唯一辨別QImage對象的數字.

--------------------------------------------------------------------------------------------------------------------------------------------------

QImage的8位和單色圖像采用顔色索引表的方式存取,32為的圖像則直接存儲ARGB值.是以他們的像素操作函數也不相同,對32位的圖像,setPixel()函數可以改變指定像素的QRgb顔色值,對8位和

單色圖像,setPixel()改變在預定義顔色表中的索引值,如果要改變顔色表,可以使用setColor()函數。QImage提供scanLine()函數傳回指定行的資料。bits()函數傳回第一個像素的指針。每個像素在QImage中都使用整數形式表示。單色圖像使用一位的索引指向隻有兩種顔色的調色闆,有兩種類型的單色圖像,big endia(MSB),little endian(LSB).256色圖像使用8位顔色調色闆,調色闆的資料類型是QVector,QRgb實際上時無符号整數型,存儲ARGB的格式是0xAARRGGBB.32位的圖像直接存儲,有三種類型的存儲格式:RGB,ARGB和已預乘的ARGB。在已預乘ARGB中,紅綠藍三色已經和alpha相乘并模除255.allGray()和isGrayscale()函數可以判斷一個彩色圖像能否安全轉化為灰階圖像。圖像的格式用format()函數讀取出,convertToFormat()可以進行圖像格式轉化,QImage支援的存儲格式如下:

QImage::Format_Mono            單色圖像(MSB)

QImage::Format_MonoLSB         單色圖像(LSB)

QImage::Format_Indexed8        使用顔色表的256色圖像

QImage::Format_RGB32           不支援Alpha通道的32位圖像

QImage::FOrmat_ARGB32          含Alpha通道的32位圖像

QImage::Format_ARGB32_Premultiplied   已預乘的含Alpha通道的32位圖像.

-----------------------------------

QPixmap

QPixmap主要完成螢幕背景(off-screen)緩沖區繪圖。QPixmap對象可以使用QLabel或QAbstractButton子類(QPushButton,QToolButton)顯示,QLabel通過設定pixmap屬性,QAbstractButton通過設定icon屬性來完成,除了使用構造函數初始化,QPixmap對象還可以使用靜态函數grabWidget()和grabWindow()函數建立,并繪制指定的視窗和視窗部件.QPixmap中的像素資料時内部的,并且由底層的視窗系統進行管理,如果要存取像素,隻有通過QPrinter函數将QPixmap對戲那個轉換為QImage對象,根據底層系統的不同,QPixmap可以RGB32或者混合alpha格式存儲,如果圖像有Alpha通道且底層系統允許,則優先使用混合alpha格式,是以QPixmap時依賴于底層系統的,在X11上和Mac上,QPixmap存儲在伺服器端,QImage存儲在客戶點,在windows上,這兩個類表達方式時相同的。QImage和QPixmap可以互相轉換,通常QImage載入圖像并進行直接操作,然後轉換為QPixmap在螢幕上顯示。如果不需要操作像素,就直接使用QPixmap.在windows上,QPixmap還可以與HBITMAP之間互相轉換,QPixmap和QImage一樣使用隐式共享,也能夠使用資料流。

=======================================================================================================

組合模式繪圖

組合模式(Composition Mode)用來指定如何合并源圖像和一個圖像,最常見的是SourceOver(通常也叫alpha混合),當原像素和目标像素以這種方式混合時,源圖像的alpha通道定義了像素的透明度。組合模式繪圖隻支援Format_ARGB32_Premultiplied和Format_ARGB32格格式,而且應該優先使用Format_ARGB32_Premultiplied格式,設定了組合模式後,它對所有的繪圖操作都有效,如畫筆,畫刷,漸變效果和pixmap/image繪制。QPainter::CompositeMode枚舉類型中前12中組合類型是T.Porter和T.Duff于1984年在淪為(Compositing Digital Image)中闡明的12種混合規則(Porter-Duff規則)混合的計算方法在此給出。以便了解混合的過程。

首先定義混合的因子 :

As:       原像素的alpha分量

Cs:       原像素種計算好(premultiplied)色彩分量

Ad:       目标像素的alpha分量

Cd;       目标像素計算好的色彩分量

Fs:       原像素在輸出結果種占有的比例

Fd:       目标像素在輸出結果種占有的比例

Ar:       輸出結果種的Alpha分量

Cr:       輸出結果種計算好的色彩分量

Porter和Duff定義了選擇混合因子Fs和Fd産生不同的視覺效果的12種規則,最終結果種的Alpha值和色彩值由下面的公式決定

    Fs=f(Ad);

    Fd=f(As);

    Ar=AsxFs+AdxFd

    Cr=CsxFs+CdxFd

每種類型的Fs和Fd取值如表所示

------------------------------------------------------------------------------------------

             常 量                                             Fs        Fd              說明

QPainter::CompositionMode_SourceOver            1        1-As         預設模式,源alpha和目标像素混合

QPainter::CompositionMode_DestinationOver       1-Ad       1          和SourceOver相反,目标Alpha和源像素混合

QPainter::CompositionMode_Clear                 N/A       N/A         清除目标像素

QPainter::CompositionMode_Source                N/A       N/A         輸出源像素

QPainter::CompositionMode_SourceIn              Ad        0           在目标部分的源替代目标

QPainter::CompositionMode_DestinationI          0         As          于SourceIn相反

QPainter::CompositionMode_SourceOut             1-Ad      0           在目标之外的源替代目标

QPainter::CompositionMode_DestinationOut        0         1-As        于SourceOut相反

Qpainter::CompositionMode_SourceAtop            Ad        1-As        在目标部分的源和目标組合

QPainter::CompositionMode_DestinationAtop       1-Ad      As          與sourceatop相反

QPainter::CompositionMode_Xor                   1-Ad      1-As        在目标之外的源和源之外的目标混合

--------------------------------------------------------------------------------------------------------

注意,上面的說明并沒有完全概括各種混合的含義,要準确了解他們可以看公式并進行實踐,畜類上面12種Porter_Duff規則外,Qt還支援12種擴充混合模式。下面給出計算公式需要注意如果結果中alpha值和色彩值超過0-255的範圍,數值将會被截斷

1  QPainter::CompositionMode_Plus           源和目标相加,該操作實作動畫中兩幅圖像的溶解和過度過程。Cr=Cs+Cd   Ar=As+Ad

2  QPainter::CompositionMode_Multiply       源和目标進行正片疊底(multiply)操作。結果的顔色至少是源和目标種較暗的顔色。任何顔色和黑色作該操作産生黑色。任何顔色和白色作

                                                           該操作将不會改變。Cr=CsxCd+Csx(1-Ad)+Cdx(1-As)  Ar=AsxAd+Asx(1-Ad)+Adx(1-As)=As+Ad-AsxAd

3  QPainter::CompositionMode_Screen         源和目标互補然後相乘結果的顔色至少是源和目标種較亮的顔色。任何顔色和黑色進行濾色操作不會改變,任何顔色和白色進行濾色操

                                                           作還是白色

4  QPainter::CompositionMode_Overlay        根據目标顔色值不同,進行相乘操作或濾色操作,源色彩保持亮度和陰影覆寫在目标上。目标顔色和源顔色混合以反應目标的亮度。

5  QPainter::CompositionMode_Darken         選擇源和目标種較暗的顔色

6  QPainter::CompositionMode_Lighten        選擇源和目标種較亮的顔色

7  QPainter::CompositoinMode_ColorDodge     加亮目标顔色以反應源顔色,繪制黑色将沒有效果

8  QPainter::CompositionMode_ColorBurn      使目标顔色變暗以反應源顔色,繪制白色沒有效果。

9  QPainter::CompositionMode_HardLight      根據源的顔色,決定是正片疊底還是濾色操作。如果源顔色高于0.5,目标顔色将變亮。即進行濾色操作。如果源顔色亮度值低于0.5,目标将

                                                           會變暗,相當于進行了正片疊底操作。如果源亮度值等于0.5,目标不會改變,變亮或者變暗成都取決于源顔色和0.5的差,繪制純黑色和純白

                                                           色結果還是純黑或純白。

10 QPainter::CompositionMode_SoftLight      根據源的顔色,決定進行變暗(darken)操作還是變亮(lighten)操作。如果源顔色比0.5亮,目标将變亮,即進行了濾色操作。如果源顔色

                                                           比0.5暗,目标将變暗,相當于進行了顔色加深(burn)操作,如果等于0.5.目标不會發生改變。變亮或者變暗的程度取決于源顔色和0.5的差

                                                           值。

11 QPainter::CompositionMode_Difference     源和目标種較暗的顔色減去較亮的顔色,繪制導緻白色反轉成目标顔色黑色沒化                                                           

12 Qpainter::CompositionMode_Exclusion      和上一條規則的效果類似,但對比對較低一些,繪制白色将導緻反轉成目标顔色,繪制黑色沒有