Halcon:在 HWindow 上显示文字
2023 年 7 月 12 日 · 3 分钟读完
目录
视觉项目里通常用 HWindow 显示处理后的图像,再叠加一些检测结果(OK/NG、尺寸、耗时)。实现时遇到了些小问题,网上的答案也不全,自己总结一下。
两种显示方式
下面的 HalconWindow 是 HWindowControl.HalconWindow,类型是 HWindow。
1. DispText
public void DispText(HTuple string, string coordSystem, HTuple row, HTuple column,
HTuple color, HTuple genParamName, HTuple genParamValue);
| 参数 | 说明 |
|---|---|
| string | 要显示的文本,传元组时每个元素一行 |
| coordSystem | "window":坐标是窗口坐标,文字固定在窗口上;"image":坐标是图像坐标,缩放平移时文字跟着图像走 |
| row、column | 文字左上角的位置;也可以传 "top"、"bottom"、"left"、"right"、"center" |
| color | 颜色,如 "green"、"#ff0000" |
| genParamName / Value | 其他参数,最常用的是 "box":是否画背景框 |
HalconWindow.DispText(item.Message, "window", item.Y, item.X, item.Color, new HTuple(), new HTuple());

常用的附加参数(genParamName / genParamValue 成对传):"box"(是否画背景框,默认 "true")、"box_color"(框的颜色)、"shadow"(是否带阴影)。字体不在这里设,要先调 SetFont。完整列表以帮助里的 disp_text 为准。
原文这里列了一长串参数(font、size、underline……),是网上搜来的,和
disp_text实际支持的不一致,已删掉。
几个常用场景:
- 结果信息(OK/NG、耗时):用
"window",固定在左上角,不受缩放影响; - 标注某个缺陷的尺寸:用
"image",坐标填缺陷的行列,缩放平移后标注还在缺陷旁边。
2. SetTposition + WriteString
更底层的方式:先设置光标位置,再写字。
HalconWindow.SetColor("green");
HalconWindow.SetFont("Arial-Normal-16");
HalconWindow.SetTposition(12, 12); // 行、列,窗口里当前显示部分的图像坐标
HalconWindow.WriteString("结果:OK");
// 过程式写法:HOperatorSet.WriteString(HalconWindow, item.Message);

两者的区别
| DispText | WriteString | |
|---|---|---|
| 坐标 | 可选窗口坐标或图像坐标 | 当前 part 下的图像坐标 |
| 多行 | 传元组自动换行 | 要自己算每行的位置 |
| 背景框、阴影 | 有,默认带框 | 没有 |
| 颜色 | 参数里直接给 | 要先 SetColor,会影响之后的绘制 |
| 版本 | 较新的版本才是正式算子,之前是 HDevelop 里的外部过程 | 一直都有 |
在较老的版本里,disp_message 是 HDevelop 的一个过程,不是算子,导出成 C# 时会生成一大段过程代码。所以老项目里看到 disp_message 的导出代码很长,是正常的。
遇到的问题
HALCON error #5123: Wrong window type in operator disp_text

程序在自己电脑上好好的,拷到别的电脑上一调用 DispText 就报这个错。原因是程序目录下只放了 halcon.dll 和 halcondotnet.dll。disp_text 依赖 Halcon 的绘图组件 hcanvas.dll,把它从 Halcon 安装目录(bin\x64-win64)拷到自己程序的目录下,就正常了。
所以部署 Halcon 程序时,不能只拷两个 dll。最稳的办法是在目标电脑上装 Halcon 运行时(Runtime),或者把安装目录 bin 下的 dll 都带上。
HALCON error #5137: Wrong font name in operator set_font

加了 hcanvas.dll 之后,SetFont 又报字体名错误。排查发现,有没有 hcanvas.dll,字体字符串的格式不一样:
| 字体格式 | 例子 | |
|---|---|---|
| 有 hcanvas.dll | 字体-样式-大小,两头没有 - |
"Arial-Normal-20" |
| 没有 hcanvas.dll | 老的 Windows 字体描述,两头都有 - |
"-System-*-*-0-0-0-1-GB2312_CHARSET-" |
所以换环境后字体报错,先看看程序目录下有没有 hcanvas.dll。用 QueryFont 可以列出当前环境下可用的字体名。
字被图像盖掉
DispObj(image) 会把整个窗口画成图像,之前写的字就没了。顺序必须是:先显示图像,再显示区域、文字。每次刷新都按这个顺序重画一遍。
文字闪烁
连续采图时每帧都 ClearWindow → DispObj → DispText,中间状态会被看到,表现为闪烁。把一帧的绘制包起来,画完再一次刷新到屏幕:
HOperatorSet.SetSystem("flush_graphic", "false");
HalconWindow.ClearWindow();
HalconWindow.DispObj(image);
HalconWindow.DispObj(region);
HOperatorSet.SetSystem("flush_graphic", "true");
HalconWindow.DispText(info, "window", 12, 12, "green", new HTuple(), new HTuple()); // 打开 flush_graphic 之后的这次绘制会把整帧一起刷到屏幕上
同样的技巧在 HWindow 的缩放与平移 里也用到了。
延伸
- 字体:新版本里跨平台的写法是
"mono-16"、"sans-16"、"serif-16",也可以加样式"sans-Bold-16";格式和 hcanvas.dll 有关,见上文。 - 字的大小跟着缩放变吗:不会。字体大小是屏幕像素,放大图像时字不会变大,所以用
"image"坐标标注时位置跟着走,大小不变。 - HSmartWindowControl:较新的控件,自带鼠标滚轮缩放和拖动,不用自己写缩放代码;但缩放拖动时它会重画窗口,文字和区域要在每次重画时一起重新显示,不能只画一次。
- WinForm 控件盖在上面:想用 Label 叠加在 HWindowControl 上显示文字,是不行的。HWindowControl 是原生窗口,透明背景的 Label 透不过去,还是要用 Halcon 自己画。
原文首发于 blog.csdn.net