8

光栅化矢量图像的一般算法是什么?我发现了很多光栅化基元的算法,如直线、圆、贝塞尔曲线等。但一般来说,我该怎么办?简单地说,在矢量图中寻找每个矢量图,获取它的像素并将它们放入光栅图像中?或者是其他东西?

还有一个问题,如何提高并发处理的时间?例如,我可以分离矢量图并同时获取它们的像素。但也许还有其他方法可以做到这一点?

4

1 回答 1

4

对于图像中的每个多边形,一般的光栅化算法是这样的。

(多边形被定义为一条或多条由直线段和参数样条曲线组成的闭合曲线 - 在通常的实践中,这些曲线是二阶(圆锥别名二次)和三阶(三次)贝塞尔样条曲线。这些闭合曲线被定义为当曲线穿过时,内部总是在左边;所以普通形状逆时针运行,孔顺时针运行。)

(i)(投影)将多边形转换为与目标位图相同的坐标系。分辨率不必相同,抗锯齿图像的分辨率通常更高:例如,FreeType 使用 64 像素。

(ii) (使 Y 单调)如有必要,将多边形的每个部分分割成更小的部分,这些部分连续向上或向下延伸。此阶段仅适用于曲线段,并且在使用 Bézier 样条时相对容易。通常的方法是重复平分直到达到单调性。丢弃所有水平线段。

(iii)(标记运行限制)将每个段绘制成一个临时位图。对直线使用 Bresenham 算法;对于曲线,平分直到直线距离真实曲线不超过(例如)1/8像素,然后从开始到结束使用直线。绘制时,以某种方式标记像素以指示(a)它们是运行的开始还是结束 - 向下的线是开始,向上的线是结束;(b) 覆盖 - 形状内部的像素部分。这是算法在细节上有所不同的地方,也是区分缠绕规则(非零奇偶数)的地方。

(iv) (scan) 逐行遍历临时位图。对于每一行,从左到右扫描。通过(例如)将存储在位图中的数字与存储的数字相加,保持指示当前位置是否在形状内的状态。在简单的单色光栅化中,在前一阶段写入的这个数字在穿过边缘进入形状时将为 +1,而在离开形状时为 -1。累积相同状态的像素运行。将运行发送到您的绘图模块:例如,FreeType 发出由 Y 坐标、开始和结束 X 坐标以及从 0 到 255 的覆盖范围组成的运行。绘图模块可以将覆盖范围用作应用于当前绘图颜色的 alpha 值,或作为应用于纹理的蒙版。

以上是一个很大的过度简化,但给出了一般的想法。

大多数开源程序使用从以下项目之一派生的光栅化代码:

FreeType - 一种字体光栅化器,它包含单声道和抗锯齿光栅化模块,相对容易独立使用 - 也就是说,适用于任何形状,而不仅仅是字体。我已经在几个商业便携式 C++ 项目中成功地使用了这个系统。

FreeType 的系统受到 Raph Levien 的Libart的启发。

Anti-Grain是另一个流行且有影响力的 C++ 库。

还有 Kiia Kallio 实现的扫描线边缘标志系统,看起来很有希望,而且似乎比 Anti-Grain 更快。

大多数但不是所有这些库都接受由二次和三次贝塞尔样条以及直线段制成的形状。那些不采用的(例如,K. Kallio 的图书馆)只采用直边多边形;但是很容易将曲线“展平”为一系列线段,这些线段比与实际曲线的所需最大距离更近。FreeType 在内部执行此操作,并且可以在必要时借用其代码。

于 2012-12-24T19:49:36.240 回答