咱们在光栅图形显示器上绘制非水平、非垂直的直线或多边形边界时,或多或少会呈现锯齿状外观。这是由于直线和多边形的边界是连续的,而光栅则是由离散的点组成。在光栅显示设备上表现直线、多边形等,必须在离散位置采样。因为采样不充分重建后形成的信息失真,就叫走样;用于减小或消除这种效果的技术,就称为反走样。算法
反走样是图形学中的重要概念,用以防止一般所说的“锯齿”现象的出现。不少系统的绘图 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