【问题标题】:General algorithm for rastering vector image光栅化矢量图像的通用算法
【发布时间】:2011-11-29 15:26:17
【问题描述】:

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

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

【问题讨论】:

  • 你目前使用什么矢量图形环境?我知道的任何框架都有现成的解决方案,可以在屏幕上绘制矢量图形或光栅位图,为您解决光栅化问题。
  • 我同意@DocBrown。除非您尝试了所有可能的现有选项,否则不要重新发明轮子,即使那样,也要尽可能多地使用无数其他人已经完成的工作,这样您就可以尽可能少地重蹈覆辙。
  • 这是问题的特点,我不需要光栅化任何具体的向量,也没有使用具体的框架。这是一个理论问题,我很感兴趣,这些框架使用什么算法以及如何通过并发改进这些算法:)
  • 关于第二个问题:这取决于您解决问题的抽象级别。您的环境/框架的基本操作是什么(即使是假设的)?只绘制单个像素,还是绘制基本图形?如果有,有哪些数字?您的框架是否允许对一个栅格进行多个并行绘图操作?
  • 使用这些作为入门的基础。它们是可移植的 C 语言光栅化器。 github.com/MalcolmMcLean/babyx/blob/master/src/common/…github.com/MalcolmMcLean/babyx/blob/master/src/common/…

标签: vector-graphics rasterizing raster-graphics


【解决方案1】:

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

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

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

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

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

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

以上内容过于简单化,但给出了总体思路。

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

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

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

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

还有 Kiia Kallio 实现的scan-line edge flag system,看起来很有希望,而且似乎比 Anti-Grain 更快。

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

【讨论】:

  • 问题不是关于“什么库是这样做的”,而是关于“它们是如何做到的”。不过,谢谢你的回答
  • 你是对的。我试图以一种简单的方式解决这个问题。不过,光栅化算法确实变得非常复杂,主要是因为需要速度,最好通过 Google 查找更完整的解释。
猜你喜欢
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
相关资源
最近更新 更多