☰
GerberView开源工具:PCB工程师的Gerber文件查看与校验利器
2026/10/28 8:11:28 网站建设 项目流程

简介:GerberView-开源是一份面向Linux桌面用户与PCB设计初学者的Gerber文件查看工具资源,主要解决在Ubuntu系统下缺少轻量级、可自由使用的Gerber预览方案的问题,适合需要快速核对光绘文件、检查图层与图形细节的硬件工程师及电子爱好者。压缩包共7个文件,约1015KB,以3个so动态库为核心,配合可执行主程序、头文件、脚本与辅助数据文件,构成可直接运行的小型查看环境,脚本负责启动与文件获取,动态库承担图形绘制与事件处理,整体结构紧凑、依赖清晰。该资源已有637人学习下载,具备一定参考基础。读者可获得一套可在Ubuntu上部署的Gerber查看工具,理解其模块划分与运行方式,并据此完成光绘文件的打开、浏览与初步校验,为后续PCB生产前的检查工作提供便利。

1. GerberView 开源工具:PCB 工程师的 Gerber 文件查看与校验利器

手上拿到一块外包打样的板子,工厂发回来一包.gbr、.drl、.gko文件,你双击打不开,装个商业 CAM 软件又要授权又要联网激活,这时候一个能离线跑、源码可查的 Gerber 查看器就很有价值。GerberView 这个开源项目解决的就是这件事:把 RS-274X 格式的 Gerber 光绘文件和 Excellon 钻孔文件解析出来,渲染成可视化的板层图像,让你在投板前肉眼核对线宽、间距、阻焊开窗和钻孔对位。它适合 PCB 设计工程师、硬件创客、以及需要做 Gerber 自动化校验的测试开发人员。关键词开源软件在这里的意义很直接——解析逻辑全在源码里,格式兼容出问题时你能自己改,而不是对着黑匣子干瞪眼。

2. Gerber 格式解析原理与渲染管线拆解

2.1 RS-274X 到底存了什么

Gerber 不是图片格式,它是一套命令流。文件里每一行要么是功能码(G04注释、G01线性插值、G36/G37区域填充起止),要么是坐标数据(X…Y…D01/D02/D03),要么是属性指令(%FS格式声明、%MO单位、%AD光圈定义、%AM自定义光圈宏)。渲染器要做的第一件事是建一个状态机:维护当前坐标、当前光圈(aperture)、插值模式、单位缩放,逐行喂进去,把 D01(画线)、D02(移动)、D03(闪绘)翻译成图元。

这里最容易翻车的是%FSLAX46Y46*%这类格式声明。它表示坐标是 4 位整数 + 6 位小数,且省略了小数点。也就是说文件里写X1000000,实际坐标是 100.000000(单位由%MOMM或%MOIN决定)。很多自写解析器忘了除以 10^6,结果整块板子被放大一百万倍,视口里啥也看不见。GerberView 的解析层在读取%FS后会把scale = 10^-decimal存进上下文,后续所有坐标乘这个系数,这是必须做对的第一步。

光圈定义%ADD10C,0.200000*%表示 D 码 10 是一个直径 0.2mm 的圆形光圈。渲染时每个 D 码要映射成一个具体的笔刷形状,D01 沿路径扫这个笔刷,D03 在点上盖一个笔刷。自定义光圈宏%AM更麻烦,里面可以有圆、线、多边形、挖空(clear polarity),解析宏体需要一个小型表达式求值器。常见做法是先把宏展开成一组基本图元,再统一走渲染。

2.2 从命令流到像素:坐标变换与层合成

解析出来的图元是板坐标系(毫米或英寸),要显示到屏幕上得经过三步变换:先按板子包围盒(bounding box)算缩放比,再平移到视口中心,最后处理 Y 轴翻转。Gerber 的 Y 轴向上为正,屏幕坐标 Y 轴向下为正,漏掉翻转会导致板子上下镜像——丝印文字反了就是这个问题。

层合成是另一个技术点。一块双层板至少有顶层铜、底层铜、顶层阻焊、底层阻焊、丝印、钻孔、板框七八个文件。GerberView 一般按文件后缀或用户手动指定层类型,给每层分配颜色和透明度,按固定顺序叠加。钻孔层(Excellon)要单独解析,它的格式和 Gerber 不同:T1C0.300定义刀具,X10.5Y20.3是钻孔坐标,单位可能是英寸也可能是毫米,靠文件头METRIC或INCH判断。

下面是一段最小化的 Gerber 坐标解析逻辑,演示状态机怎么把一行命令翻译成图元:

import re class GerberParser: def __init__(self): self.scale = 1.0 # 由 %FS 决定,默认 1 self.unit = 1.0 # mm 为 1,inch 需乘 25.4 self.cur_x = 0.0 self.cur_y = 0.0 self.apertures = {} # D码 -> 光圈参数 self.primitives = [] # 输出图元列表 def parse_line(self, line): line = line.strip() if not line: return # 格式声明:%FSLAX46Y46*% m = re.match(r'%FSLAX(\d)(\d)Y(\d)(\d)\*%', line) if m: dec = int(m.group(2)) self.scale = 10 ** (-dec) return # 单位声明 if line.startswith('%MOMM'): self.unit = 1.0 return if line.startswith('%MOIN'): self.unit = 25.4 return # 光圈定义:%ADD10C,0.200000*% m = re.match(r'%ADD(\d+)([A-Z]),([\d.]+)\*%', line) if m: self.apertures[int(m.group(1))] = (m.group(2), float(m.group(3))) return # 坐标操作:X..Y..D01/D02/D03 m = re.match(r'X(-?\d+)Y(-?\d+)D0([123])\*', line) if m: x = int(m.group(1)) * self.scale * self.unit y = int(m.group(2)) * self.scale * self.unit op = m.group(3) if op == '1': # 画线 self.primitives.append(('line', self.cur_x, self.cur_y, x, y)) elif op == '3': # 闪绘 self.primitives.append(('flash', x, y)) self.cur_x, self.cur_y = x, y

这段代码的关键参数是scale和unit:scale来自%FS的小数位数,unit把英寸统一换算成毫米,两者相乘才是最终毫米坐标。primitives里只存了线段的起终点和闪绘点,实际渲染还要结合当前光圈宽度把线段扩成矩形或圆头笔刷。真实项目里还要处理G36/G37区域填充、%LPD/%LPC极性切换,以及G75圆弧模式下的I/J偏移量,这些在 GerberView 源码里都有对应分支,读的时候按功能码逐个对照规范即可。

2.3 渲染后端选型:为什么不用现成图像库硬画

有人会想,直接把图元画到 PIL 或 Canvas 上不就完了。小文件可以,但一块 200mm×150mm 的高密度板,Gerber 动辄几十万条线段,逐条调绘图 API 会卡到没法交互。GerberView 这类工具通常走两条路:一是把图元批量转成三角形网格交给 GPU(OpenGL/WebGL),二是用空间索引(四叉树或网格分桶)做视口裁剪,只渲染当前可见区域的图元。缩放和平移时重算可见集,而不是重画全量。

选型上,桌面端用 Qt + OpenGL 或直接用 Skia 做抗锯齿光栅化都行;Web 端用 Canvas 2D 做小文件预览、WebGL 做大数据量。判断标准很简单:文件超过 5MB 或图元超过 10 万条,就必须上 GPU 或裁剪,否则拖动会明显掉帧。这个阈值不是拍脑袋,是实测交互流畅度的经验线。

3. 本地跑起来:环境搭建与首块板子渲染

3.1 依赖安装与源码编译

开源 Gerber 查看器常见的技术栈是 C++/Qt 或 Python/PyQt,也有 Electron 套壳的。不管哪种,第一步都是把依赖装齐。以 Python + PyQt5 + OpenGL 的组合为例,虚拟环境里装这几样:

python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install PyQt5 PyOpenGL numpy # 如果项目带 requirements.txt,直接: pip install -r requirements.txt

PyQt5提供窗口和事件循环,PyOpenGL负责把图元批量提交给显卡,numpy用来存顶点数组——几十万个顶点用 Python list 存会慢得离谱,转成np.float32数组再上传显存,帧率能差一个数量级。装完先跑项目自带的示例或单元测试,确认解析器能正确读出一个最小 Gerber 文件,再上真实板子。

编译型项目则是cmake一套:

mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release cmake --build . -j$(nproc)

Release模式必须开,Debug 下光栅化和解析都会慢好几倍,拿 Debug 版测性能没有意义。-j后面跟核数,编译大项目能省一半时间。

3.2 加载第一组 Gerber 文件并核对层对齐

把工厂发回的压缩包解压,通常是一堆以层名命名的文件。启动查看器后按层类型逐个加载:顶层铜.gtl、底层铜.gbl、顶层阻焊.gts、底层阻焊.gbs、丝印.gto/.gbo、钻孔.drl、板框.gko。加载顺序不影响结果,但层类型标错会导致颜色和叠放顺序乱掉。

对齐是第一个要盯的点。所有层必须共用同一个原点,如果某层偏移了,多半是导出时原点设置不一致。核对方法:打开钻孔层和顶层铜层,看焊盘中心和钻孔中心是否重合。偏个 0.1mm 在屏幕上可能就一两个像素,放大到焊盘级别才看得出来。GerberView 一般提供层偏移手动微调,但正确做法是回设计软件重新导出,而不是在查看器里硬掰。

提示:加载后先看板框层包围盒的尺寸,和设计文件里的板子尺寸对一遍。尺寸对不上,八成是单位搞错了(英寸当毫米,或反之),这时候别急着调偏移,先查%MO声明。

3.3 用钻孔文件验证层间对位

钻孔文件是天然的基准。Excellon 文件里每个孔都有明确坐标,把它叠在铜层上,过孔环宽是否均匀、安装孔是否落在焊盘正中,一眼就能看出来。操作步骤:先加载钻孔层并设为高亮色,再逐层打开铜层,缩放到 200% 以上扫一遍板边和密集过孔区。发现某个孔偏出焊盘,记录坐标,回设计文件里查那个封装的原点定义。

这里有个参数要留意:钻孔文件的坐标格式可能是2.4(2 位整数 4 位小数)也可能是3.3,文件头不一定写清楚。解析错了孔位会整体缩放。判断办法是拿一个已知间距的排针孔(比如 2.54mm)量一下,屏幕上量出来是 25.4mm 就是格式读错了一位。

4. 避坑与排查:Gerber 查看器常见的五类翻车

4.1 打开一片空白或板子巨大/极小

现象:加载后视口里什么都没有,或者只有一条边。原因:%FS格式声明没解析对,坐标缩放系数错了,图元被放大或缩小到视口外。解决:打印解析出的包围盒坐标,和板子实际尺寸对比;检查scale是否按小数位数取了10^-n,单位是否在%MOIN时乘了 25.4。这是最高频的翻车点,十有八九栽在格式声明上。

4.2 丝印文字镜像或上下颠倒

现象:字符反着显示,或者整块板上下翻转。原因:Y 轴方向没翻转,或者翻转了两次。Gerber 坐标 Y 向上,屏幕 Y 向下,变换矩阵里只应翻转一次。解决:检查视图变换里scaleY的符号,确保只在一处取负;如果用了多层各自的变换,确认没有重复翻转。

4.3 阻焊开窗和焊盘对不上

现象:阻焊层比铜层大一圈或小一圈,开窗位置偏移。原因:阻焊层本身有工艺补偿(通常单边大 0.05~0.1mm),这是设计软件加的,不是解析错误;但如果偏移量随位置变化,则是两层原点不一致。解决:先确认偏移是均匀扩张还是整体平移。均匀扩张属正常工艺补偿,整体平移要回设计软件查层原点设置。

4.4 圆弧画成直线或缺口

现象:板框圆角、圆形焊盘边缘出现直线段或断裂。原因:G75多象限圆弧模式没处理,I/J偏移量被当成绝对坐标,或者圆弧方向(G02/G03)判断反了。解决:确认解析器在G75下用I/J作为圆心相对当前点的偏移,且按G02顺时针、G03逆时针插值;圆弧分段数按弧长动态算,固定分段数在大圆弧上会看出棱角。

4.5 大文件拖动卡顿甚至崩溃

现象:小文件流畅,几十 MB 的板子一拖动就卡死或内存暴涨。原因:每帧重画全量图元,或者顶点数据每次重建。解决:上视口裁剪,只提交包围盒与当前视口相交的图元;顶点数组缓存起来,平移缩放只改变换矩阵不重建缓冲;Python 实现要把图元转numpy数组,避免逐条循环。

5. 进阶:把 Gerber 校验接进自动化流程

手工看板只能覆盖抽检,真正省事的是把 Gerber 解析做成脚本,在投板前自动跑一遍规则检查。思路是复用查看器的解析层,把图元导出成结构化数据,再写几条断言。比如最小线宽检查:遍历所有line图元,取对应光圈宽度,低于工艺下限(常见 0.1mm 或 0.15mm,看板厂能力)就报警。最小间距检查复杂一些,需要对不同网络的图元做空间邻近查询,用网格分桶把 O(n²) 降到接近 O(n)。

下面是一个最小线宽检查的骨架,直接接在前面的解析器后面用:

def check_min_trace_width(primitives, apertures, min_mm=0.1): """遍历线段图元,报告低于工艺下限的线宽""" issues = [] for p in primitives: if p[0] != 'line': continue # 实际项目中图元需携带所用光圈 D 码,这里示意取宽度 width = p[-1] if len(p) > 5 else None if width is not None and width < min_mm: issues.append({ 'type': 'trace_too_thin', 'width': width, 'limit': min_mm, 'segment': p[1:5] }) return issues

min_mm要按板厂工艺能力设,普通双面板 0.1mm 是常见下限,高密度板可以到 0.075mm,但价格会上去。segment里存起终点坐标,方便回查看器里定位。真实实现中图元结构要带上光圈 D 码,宽度从apertures里查,而不是像上面这样简化。

再进一步是钻孔与焊盘的对位检查:对每个钻孔坐标,在铜层图元里找最近的闪绘点或线段,算中心距,超过阈值就报。这类检查跑一遍几秒钟,比人眼扫一遍靠谱得多。验证方法也简单:故意在测试板上放一个偏位的孔,看脚本能不能抓出来;抓不出来就调阈值或查坐标单位。

我自己的习惯是,每次投板前先跑一遍自动检查,再人工看三个地方:板框尺寸、钻孔对位、阻焊开窗。自动检查负责兜底,人眼负责判断那些规则写不出来的东西。从那以后我每次导出 Gerber 都强制走一遍解析加断言,宁可多花五分钟,也不想再经历一次打样回来发现线宽不够的返工。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询