反走樣-26
阿新 • • 發佈:2019-01-09
今天繼續前面的內容。既然已經進入2D繪圖部分,那麼就先繼續研究一下有關QPainter的東西吧!
反走樣是圖形學中的重要概念,用以防止“鋸齒”現象的出現。很多系統的繪圖API裡面都會內建了反走樣的演算法,不過預設一般都是關閉的,Qt也
不例外。下面我們來看看程式碼。這段程式碼僅僅給出了paintEvent函式,相信你可以很輕鬆地替換掉前面章節中的相關程式碼。
void
PaintedWidget::paintEvent(QPaintEvent *event
)
{
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);
} 看看執行後的效果: 左邊的是沒有使用反走樣技術的,右邊是使用了反走樣技術的。二者的差別可以很容易的看出來。 下面來看看相關的程式碼。為了嘗試畫筆的樣式,這裡故意使用了一個新的畫筆: painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap)); 我們對照著API去看,第一個引數是畫筆顏色,這裡設定為黑色;第二個引數是畫筆的粗細,這裡是5px;第三個是畫筆樣式,我們使用了 DashDotLine,正如同其名字所示,是一個短線和一個點相間的型別;第四個是RoundCap,也就是圓形筆帽。然後我們使用一個黃色的畫刷填 充,畫了一個橢圓。 後面的一個和前面的十分相似,唯一的區別是多了一句
painter.setRenderHint(QPainter::Antialiasing, true
);
,不過這句也很清楚,就是設定Antialiasing屬性為true。如果你學過圖形學就會知道,這個長長的單詞就是“反走樣”。經過這句設
置,我們就打開了QPainter的反走樣功能。還記得我們曾經說過,QPainter是一個狀態機,因此,只要這裡我們打開了它,之後所有的程式碼都會是
反走樣繪製的了。
看到這裡你會發現,反走樣的效果其實比不走樣要好得多,那麼,為什麼不預設開啟反走樣呢?這是因為,反走樣是一種比較複雜的演算法,在一些對影象
質量要求不高的應用中,是不需要進行反走樣的。為了提高效率,一般的圖形繪製系統,如Java2D、OpenGL之類都是預設不進行反走樣的。
還有一個疑問,既然反走樣比不反走樣的影象質量高很多,不進行反走樣的繪製還有什麼作用呢?前面說的是一個方面,也就是,在一些對影象質量要求
不高的環境下,或者說效能受限的環境下,比如嵌入式和手機環境,是不必須要進行反走樣的。另外還有一點,在一些必須精確操作畫素的應用中,也是不能進行反
走樣的。請看下面的圖片:
上圖是使用Photoshop的鉛筆和畫筆工具畫的1畫素的點在放大到3200%檢視下截下來的。Photoshop裡面的鉛筆工具是不進行反
走樣,而畫筆是要進行反走樣的。在放大的情況下就會知道,有反走樣的情況下是不能進行精確到1畫素的操作的。因為反走樣很難讓你控制到1個畫素。這不是
Photoshop畫筆工具的缺陷,而是反走樣演算法的問題。如果你想了解為什麼這樣,請查閱計算機圖形學裡面關於反走樣的原理部分。
{
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);
} 看看執行後的效果: 左邊的是沒有使用反走樣技術的,右邊是使用了反走樣技術的。二者的差別可以很容易的看出來。 下面來看看相關的程式碼。為了嘗試畫筆的樣式,這裡故意使用了一個新的畫筆: painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap)); 我們對照著API去看,第一個引數是畫筆顏色,這裡設定為黑色;第二個引數是畫筆的粗細,這裡是5px;第三個是畫筆樣式,我們使用了 DashDotLine,正如同其名字所示,是一個短線和一個點相間的型別;第四個是RoundCap,也就是圓形筆帽。然後我們使用一個黃色的畫刷填 充,畫了一個橢圓。 後面的一個和前面的十分相似,唯一的區別是多了一句