咱們在光柵圖形顯示器上繪製非水平、非垂直的直線或多邊形邊界時,或多或少會呈現鋸齒狀外觀。這是由於直線和多邊形的邊界是連續的,而光柵則是由離散的點組成。在光柵顯示設備上表現直線、多邊形等,必須在離散位置採樣。因爲採樣不充分重建後形成的信息失真,就叫走樣;用於減小或消除這種效果的技術,就稱爲反走樣。算法
反走樣是圖形學中的重要概念,用以防止一般所說的「鋸齒」現象的出現。不少系統的繪圖 API 裏面都內置了有關反走樣的算法,不過因爲性能問題,默認通常是關閉的,Qt 也不例外。下面咱們來看看代碼:工具
void paintEvent(QPaintEvent *) { QPainter painter(this); painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap)); painter.setBrush(Qt::yellow); painter.drawEllipse(50, 150, 200, 150); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap)); painter.setBrush(Qt::yellow); painter.drawEllipse(300, 150, 200, 150); }
看看運行後的結果:性能
注意看左側橢圓與右側橢圓在邊界處的區別。左側沒有使用反鋸齒,明細顯示出鋸齒的樣子;右側則增長了反鋸齒代碼。this
在這段代碼中,咱們建立了一個黑色 5 像素寬的畫筆,使用了點線的樣式,圓形筆帽:code
painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap));
而後咱們使用一個黃色的畫刷填充,繪製一個橢圓。圖片
第二個橢圓的繪製與第一個十分類似,惟一的區別是多了一句ip
painter.setRenderHint(QPainter::Antialiasing, true);
顯然,咱們經過這條語句,將Antialiasing
屬性(也就是反走樣)設置爲 true。通過這句設置,咱們就打開了QPainter
的反走樣功能。還記得咱們曾經說過,QPainter
是一個狀態機,所以,只要這裏咱們打開了它,以後全部的代碼都會是反走樣繪製的了。因爲反走樣須要比較複雜的算法,在一些對圖像質量要求不是很高的應用中,是不須要進行反走樣的。爲了提升效率,通常的圖形繪製系統,如 Java2D、OpenGL 之類都是默認不進行反走樣的。class
雖然反走樣比不反走樣的圖像質量高不少,可是,沒有反走樣的圖形繪製仍是有很大用處的。首先,就像前面說的同樣,在一些對圖像質量要求不高的環境下,或者說性能受限的環境下,好比嵌入式和手機環境,通常是不進行反走樣的。另外,在一些必須精確操做像素的應用中,也是不能進行反走樣的。這是因爲反走樣技術自己的限制的。請看下面的圖片:效率
這是使用 Photoshop 的鉛筆和畫筆工具繪製的 1 像素的點,放大 3200% 的視圖。在必定程度上,咱們能夠認爲,Photoshop 的鉛筆工具是不進行反走樣,而畫筆是要進行反走樣的。在放大的狀況下就會知道,有反走樣的狀況下是不能進行精確到 1 像素的操做的。由於反走樣很難讓你控制到 1 個像素。這不是 Photoshop 畫筆工具的缺陷,而是反走樣算法的問題。反走樣之因此看起來比較模糊,就是由於它須要以一種近似色來替換原始的像素色,這樣一來就會顯得模糊而圓滑。im