鍍金池/ 教程/ C/ 反走樣
Qt 容器和算法拾遺
自定義 model 之一
反走樣
Hello, world!
Qt 容器類之關(guān)聯(lián)存儲容器
QStringListModel
拖放技術(shù)之一
狀態(tài)欄
QTreeWidget
拖放技術(shù)之二
通用算法
event()
Qt 學(xué)習(xí)之路(18): Qt 標(biāo)準(zhǔn)對話框之 QInputDialog
Qt 容器類之遍歷器和隱式數(shù)據(jù)共享
QListWidget
Meta-Object 系統(tǒng)
事件接收與忽略
Qt 學(xué)習(xí)之路(tip): parent 參數(shù)
Qt 標(biāo)準(zhǔn)對話框之 QColorDialog
QPainter(續(xù))
國際化(下)
漸變填充
自定義委托
創(chuàng)建 shared library
model-view 架構(gòu)
Graphics View Framework
自定義拖放數(shù)據(jù)對象
QSortFilterProxyModel
國際化(上)
組件布局
自定義 Model 之三
事件過濾器
QDirModel
Hello, world!(續(xù))
Qt 標(biāo)準(zhǔn)對話框之 QFileDialog
自定義 model 之二
深入了解信號槽
坐標(biāo)變換
剪貼板操作
QTableWidget
QByteArray 和 QVariant
創(chuàng)建一個(gè)對話框(下)
Qt 學(xué)習(xí)之路(32): 一個(gè)簡易畫板的實(shí)現(xiàn)(Graphics View)
文本文件讀寫
自定義事件
編寫跨平臺的程序
MainWindow
初探信號槽
Qt 學(xué)習(xí)之路(17): Qt 標(biāo)準(zhǔn)對話框之 QMessageBox
繪圖設(shè)備
菜單和工具條(續(xù))
二進(jìn)制文件讀寫
QString
事件(event)
菜單和工具條
QPainter
Qt 容器類之順序存儲容器
進(jìn)程間交互
API 文檔的使用
創(chuàng)建一個(gè)對話框(上)
一個(gè)簡易畫板的實(shí)現(xiàn)(QWidget)

反走樣

今天繼續(xù)前面的內(nèi)容。既然已經(jīng)進(jìn)入 2D 繪圖部分,那么就先繼續(xù)研究一下有關(guān) QPainter 的東西吧!

反走樣是圖形學(xué)中的重要概念,用以防止“鋸齒”現(xiàn)象的出現(xiàn)。很多系統(tǒng)的繪圖 API 里面都會內(nèi)置了反走樣的算法,不過默認(rèn)一般都是關(guān)閉的,Qt 也不例外。下面我們來看看代碼。這段代碼僅僅給出了paintEvent 函數(shù),相信你可以很輕松地替換掉前面章節(jié)中的相關(guān)代碼。

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); 
}

看看運(yùn)行后的效果:

http://wiki.jikexueyuan.com/project/learn-road-qt/images/40.png" alt="" />

左邊的是沒有使用反走樣技術(shù)的,右邊是使用了反走樣技術(shù)的。二者的差別可以很容易的看出來。

下面來看看相關(guān)的代碼。為了嘗試畫筆的樣式,這里故意使用了一個(gè)新的畫筆:

painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap));

我們對照著 API 去看,第一個(gè)參數(shù)是畫筆顏色,這里設(shè)置為黑色;第二個(gè)參數(shù)是畫筆的粗細(xì),這里是5px;第三個(gè)是畫筆樣式,我們使用了 DashDotLine,正如同其名字所示,是一個(gè)短線和一個(gè)點(diǎn)相間的類型;第四個(gè)是 RoundCap,也就是圓形筆帽。然后我們使用一個(gè)黃色的畫刷填充,畫了一個(gè)橢圓。

后面的一個(gè)和前面的十分相似,唯一的區(qū)別是多了一句

painter.setRenderHint(QPainter::Antialiasing, true);

,不過這句也很清楚,就是設(shè)置 Antialiasing 屬性為 true。如果你學(xué)過圖形學(xué)就會知道,這個(gè)長長的單詞就是“反走樣”。經(jīng)過這句設(shè)置,我們就打開了 QPainter 的反走樣功能。還記得我們曾經(jīng)說過,QPainter 是一個(gè)狀態(tài)機(jī),因此,只要這里我們打開了它,之后所有的代碼都會是反走樣繪制的了。

看到這里你會發(fā)現(xiàn),反走樣的效果其實(shí)比不走樣要好得多,那么,為什么不默認(rèn)打開反走樣呢?這是因?yàn)?,反走樣是一種比較復(fù)雜的算法,在一些對圖像質(zhì)量要求不高的應(yīng)用中,是不需要進(jìn)行反走樣的。為了提高效率,一般的圖形繪制系統(tǒng),如 Java2D、OpenGL 之類都是默認(rèn)不進(jìn)行反走樣的。

還有一個(gè)疑問,既然反走樣比不反走樣的圖像質(zhì)量高很多,不進(jìn)行反走樣的繪制還有什么作用呢?前面說的是一個(gè)方面,也就是,在一些對圖像質(zhì)量要求不高的環(huán)境下,或者說性能受限的環(huán)境下,比如嵌入式和手機(jī)環(huán)境,是不必須要進(jìn)行反走樣的。另外還有一點(diǎn),在一些必須精確操作像素的應(yīng)用中,也是不能進(jìn)行反走樣的。請看下面的圖片:

http://wiki.jikexueyuan.com/project/learn-road-qt/images/41.png" alt="" />

上圖是使用 Photoshop 的鉛筆和畫筆工具畫的1像素的點(diǎn)在放大到3200%視圖下截下來的。Photoshop里面的鉛筆工具是不進(jìn)行反走樣,而畫筆是要進(jìn)行反走樣的。在放大的情況下就會知道,有反走樣的情況下是不能進(jìn)行精確到1像素的操作的。因?yàn)榉醋邩雍茈y讓你控制到1個(gè)像素。這不是 Photoshop 畫筆工具的缺陷,而是反走樣算法的問題。如果你想了解為什么這樣,請查閱計(jì)算機(jī)圖形學(xué)里面關(guān)于反走樣的原理部分。

本文出自 “豆子空間” 博客,請務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/194031