目录
- 2.3.1 渲染控件:渲染控件上自定义图形的方法
- 2.3.2 参数控件:参数配置控件绑定模块的方法
- 2.3.3 控件颜色:控件颜色修改方法
- 2.3.4 独立控件:二次开发单独显示Group的方法
- 2.3.5 取流控件:实时取流控件的使用方法
- 2.3.6 渲染控件:渲染控件绘制ROI的方法
- 2.3.7 控件语言:控件设置为英文的方法
- 2.3.8 控件报错:子窗口包含主界面控件及其它控件时报错的解决方法
- 2.3.9 图像传入:给渲染控件传入图像的方法
- 2.3.10 主界面控件:主界面控件添加参数修改记录并将记录保存至本地的方法
- 2.3.11 渲染控件:渲染控件绘制十字方法
2.3.1 渲染控件:渲染控件上自定义图形的方法
描述
环境:VM4.2 + VS2013及以上
现象:VM4.2如何在渲染控件上自定义图形?
解答
VM4.2二次开发相比较VM4.0二次开发,渲染控件上自定义图形有一些更新,除了接口vmRenderControl.DrawShape(),新增加一个接口vmRenderControl.AddShape(),前者是立刻绘制,后者是在下次刷新渲染时自动绘制。所以在VM4.0二次开发回调函数中图像渲染并添加自定义图形时, DrawShape接口函数前需要添加延时,不然回调中的图像渲染还没更新,自定义的图形已经调用DrawShape函数,从而导致自定义图形不能很好的渲染在图像上。在VM4.2二次开发中使用AddShape接口就不要加延时,它会在图像渲染结束后再绘制自定义图形。
手动添加引用VMControls.WPF.dll、WindowsBase.dll,添加后,引用属性【复制本地】改为false;渲染控件需要先绑定图像,再调用渲染控件的AddShape绘图接口;支持直线、圆形、矩形、文本等图形元素绘制;绘制时机:流程运行结束,在流程结果回调函数中绘制。下面绘制了直线和文本,其它图形依次类推。
C#
//绘制直线
VMControls.WPF.LineEx line = new VMControls.WPF.LineEx(new System.Windows.Point(100, 100), new System.Windows.Point(600, 600), stroke: "#FF0000", strokeThickness: 10);
vmRenderControl1.AddShape(line);
//绘制文本
VMControls.WPF.TextEx text = new VMControls.WPF.TextEx("欢迎使用VM4.2二次开发!", new System.Windows.Point(1000, 1000), fontSize: 20, stroke: "#FF0000");
vmRenderControl1.AddShape(text);
问题根因
不熟悉如何绘制自定义图形。
2.3.2 参数控件:参数配置控件绑定模块的方法
描述
环境:VM4.2 + VS2013及以上
现象:如何给参数配置控件绑定指定模块?
解答
- 参数配置控件绑定模块方法(C#),示例代码如下。
C#
// 参数配置控件模块绑定
private void button3_Click(object sender, EventArgs e)
{
try
{
//参数配置
var blobTool = (VMControls.Interface.IVmModule)VmSolution.Instance["流程1.BLOB分析1"];
//参数配置控件
vmParamsConfigControl1.ModuleSource=blobTool;
//参数配置控件带渲染
vmParamsConfigWithRenderControl1.ModuleSource = blobTool;
}
catch (VmException ex)
{
MessageBox.Show(Convert.ToString(ex.errorCode, 16));
}
}
2.参数配置控件绑定模块方法(C++),代码如下。
C++
//参数设置
void CMFCApplication5Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
try
{
auto pObject = (CModuParamsBase*)(*m_pVmSol)[“流程1.圆查找1”];
m_ParamsRender.SetParamsInfo(pObject, "");
}
catch (CVmException ex)
{
CString strTemp;
strTemp.Format(_T("%d"), ex.GetErrorCode());
}
}
3.绑定效果
问题根因
不熟悉控件的资源绑定方法。
2.3.3 控件颜色:控件颜色修改方法
描述
环境:VM4.2 + VS2013及以上
现象:如何修改控件颜色?
解答
- 修改控件背景色,示例代码(C#)如下。注意:渲染控件颜色修改的前提是渲染控件已经绘制到窗口中。
当通过拖拉渲染控件到窗口中时,控件颜色修改只能写在窗口初始化之后,如Load事件中或按钮事件中;
当通过动态定义渲染控件到窗口中时,控件颜色修改只能写在窗口Add渲染控件之后,如this.Controls.Add(vmRenderControl1)之后。
C#
private void button16_Click(object sender, EventArgs e)
{
string str = "#DD22AA";//十六进制颜色码
vmRenderControl1.SetBackground(str);
}
2.修改控件背景色,示例代码(C++)如下。
C++
//修改控件背景色
int CMFCApplication5Dlg::SetBackGroundColor()
{
// TODO: 在此处添加实现代码.
CString str("#DD22AA");//十六进制颜色码
m_RenderCtr.SetBackground(str.GetBuffer());
return 0;
}
3.修改效果
问题根因
不熟悉控件接口。
2.3.4 独立控件:二次开发单独显示Group的方法
描述
环境:VM4.2 + VS2013及以上
现象:如何单独显示Group(.gro后缀)文件?
解答
- 首先需要在界面上拖拽SingleModuleSetConfigControl控件,该控件专门用于显示Group。
2.加载Group文件并绑定到该控件的ModuleSource属性,代码如下。
C#
private void button16_Click(object sender, EventArgs e)
{
vmSingleModuleSetConfigControl1.ModuleSource = VmSolution.LoadIndependentGroup("D://Files//test.gro");
}
3.显示效果
问题根因
不熟悉控件的资源绑定方法。
2.3.5 取流控件:实时取流控件的使用方法
描述
环境:VM4.2 + VS2013及以上
现象:VM4.2新增了一个控件,实时取流控件。
解答
1.在工具箱添加控件后,就可以拖拽实时取流控件VmRealTimeAcqControl到窗体中进行使用。
2.拖拉控件后,还需要将全局相机与控件进行绑定,代码如下所示:
C#
GlobalCameraModuleCs.GlobalCameraModuleTool cameraModu=(GlobalCameraModuleCs.GlobalCameraModuleTool)VmSolution.Instance["全局相机1"];
vmRealTimeAcqControl1.ModuleSource = cameraModu;
vmRealTimeAcqControl1.StartGrabbing();//开始采集
vmRealTimeAcqControl1.Stop Grabbing();//停止采集
问题根因
不熟悉实时取流控件的使用。
2.3.6 渲染控件:渲染控件绘制ROI的方法
描述
环境:VM4.2.0 + VS2013及以上
现象:VM二次开发,如何在渲染控件上绘制ROI,以实现界面快速建模、调整模块ROI?
解答
安装20220914及后续补丁包,注册GAC后,在二次开发软件中注册ROI绘制事件。示例代码如下:
C#
using VMControls.RenderInterface;
using VMControls.Interface;
using VMControls.Winform.Release;
// 注册ROI绘制事件
vmRenderControl1.IsShowCustomROIMenu = true;
vmRenderControl1.OnCustomRoiAddEvent -= VmRenderControl1_OnCustomRoiAddEvent;
vmRenderControl1.OnCustomRoiAddEvent += VmRenderControl1_OnCustomRoiAddEvent;
// ROI绘制事件
private void VmRenderControl1_OnCustomRoiAddEvent(object sender, VMControls.RenderInterface.RoiEventArgs e)
{
roi = e.Roi;
roi.DataChangedCommand = new DelegateCommand<IROI>(OnDataChangedCommandExcute);
if (roi is IRectROI rect) // 绘制的ROI为矩形
{
// Avoid表示ROI类型为屏蔽区
if (!(rect.UseType == ROIUseType.Avoid)) { // To Do Code }
// To Do Code 例如设置模块ROI、例如模板匹配建模等
}
}
// ROI修改事件
private void OnDataChangedCommandExcute(IROI obj)
{
if (roi is IRectROI rect) // 绘制的ROI为矩形
{
if (!(rect.UseType == ROIUseType.Avoid)) //屏蔽区
{ // To Do Code }
// To Do Code 例如设置模块ROI、例如模板匹配建模等
}
}
问题根因
不熟悉渲染控件的相关事件。
2.3.7 控件语言:控件设置为英文的方法
描述
环境:VM4.2+VS2013及以上
现象:如何设置控件为英文?
解答
在VM4.0的二次开发中,控件设置为英文的相关配置文件在debug路径中LangCFG文件中,修改配置文件LanguageSet.cfg。在VM4.2的二次开发中,因为debug中没有进行拷贝操作,所以修改配置文件路径如下图所示,zh-cn表示中文,英文则用en-us。
上图中是手动打开配置文件直接进行修改,也可以通过代码来修改配置文件:
C#
///修改对应cfg文件内容,切换中文
string path2 =Path+ "Development\\V4.x\\ComControls\\Assembly\\LangCFG\\LanguageSet.cfg";
string[] filelines = File.ReadAllLines(path2);
filelines[2] = " <LangSet>zh-cn</LangSet>";
File.WriteAllLines(path2, filelines);
///修改对应文件内容,切换英文
string path2 =Path+ "Development\\V4.x\\ComControls\\Assembly\\LangCFG\\LanguageSet.cfg";
string[] filelines = File.ReadAllLines(path2);
filelines[2] = " <LangSet>en-us</LangSet>";
File.WriteAllLines(path2, filelines);
注意:切换后VM二次开发需要重新启动才会生效
问题根因
不熟悉如何修改VM4.2二次开发控件的语言
2.3.8 控件报错:子窗口包含主界面控件及其它控件时报错的解决方法
描述
环境:VM4.0及以上 + VS2013及以上
现象:子窗口包含主界面控件(VmMainViewConfigControl)及其它控件时,打开子窗口报错如下所示。
解答
将子窗口中的VM控件的属性【TopStop】都改为false即可。
问题根因
主界面控件机制问题,VM4.3将会改善。
2.3.9 图像传入:给渲染控件传入图像的方法
描述
环境:VM4.0及以上 + VS2013及以上
现象:VM二次开发如何将在渲染控件上显示本地图像?
解答
1.可以通过模块的方式,再将渲染控件绑定模块或流程来显示本地图像,也可以通过VmRnderControl控件的ImageSource属性来设置图像。
2.首先需要继承IImaageData接口实现图像数据类。示例代码如下:
C#
public class ImageSource : VMControls.RenderInterface.IImageData
{
public ImageSource(int width, int height, byte[] buffer, VMPixelFormat pixelformat)
{
Width = width;
Height = height;
PixelFormat = pixelformat == VMPixelFormat.VM_PIXEL_MONO_08 ? "Gray8" : "Rgb24";
int channels = pixelformat == VMPixelFormat.VM_PIXEL_MONO_08 ? 1 : 3;
if (buffer.Length != width * height * channels)
throw new Exception("buffer is error");
Buffer = new byte[buffer.Length];
Array.Copy(buffer, Buffer, buffer.Length);
}
public int Width { get; set; }
public int Height { get; set; }
public byte[] Buffer { get; set; }
public string MemoryAddress
{
get
{
GCHandle gCHandle = GCHandle.Alloc(Buffer, GCHandleType.WeakTrackResurrection);
IntPtr bufferAddress = GCHandle.ToIntPtr(gCHandle);
return bufferAddress.ToString();
}
}
public string PixelFormat { get; }
}
3.使用OpenCV等接口获取本地图像数据流并转换成ImageSource类型显示,示例代码如下:
C#
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFile = new OpenFileDialog();
if (openFile.ShowDialog() == DialogResult.OK)
{
pictureBox1.Image = Image.FromFile(openFile.FileName);
var mat = Cv2.ImRead(openFile.FileName);
byte[] imageByte = new byte[mat.Width * mat.Height * mat.Channels()];
ImageSource imageSource = null;
if (mat.Channels() == 1)
{
imageSource = new ImageSource(mat.Width, mat.Height, imageByte, VMPixelFormat.VM_PIXEL_MONO_08);
}
else
{
//OpenCV为BGR VM 为RGB通道
Cv2.CvtColor(mat,mat,ColorConversionCodes.BGR2RGB);
Marshal.Copy(mat.Data, imageByte, 0, imageByte.Length);
imageSource = new ImageSource(mat.Width, mat.Height, imageByte, VMPixelFormat.VM_PIXEL_RGB24_C3);
}
if(imageSource!=null)
vmRenderControl1.ImageSource = imageSource;
}
}
注意事项:灰度图读取到的如果是三通道需先转成单通道图像,彩色图需要交换下R和G通道,即用Cv2.CvtColor转换一下。
问题根因
不熟ImageSource属性及接口。
2.3.10 主界面控件:主界面控件添加参数修改记录并将记录保存至本地的方法
描述
环境:VM4.2 + VS2013及以上
现象:在VisionMaster软件里,修改模块参数值时,右下角的状态栏会显示修改记录并且记录至本地日志,而在VM二次开发里不会显示修改和记录日志。
解答
当前VM二次开发默认不支持,要支持需手动添加代码Apps.XmlParser.ParamTab.NameValueItem.logManager = new Apps.XmlUI.UILogManager(false);加载到程序初始化函数里。其中,添加引用集Apps.XmlParser.dll和Apps.XmlUI.dll在VM安装路径“VisionMaster4.2.0\Development\V4.x\ComControls\Assembly”下。
示例代码如下:
C#
public Form1()
{
InitializeComponent();
Apps.XmlParser.ParamTab.NameValueItem.logManager = new Apps.XmlUI.UILogManager(false);
}
添加后,控件日志显示如下:
并且,在二次开发应用程序exe同级下的log/UI/SystemLog.log就会记录模块参数修改的日志。
注:若没有该log,请将VisionMaster路径“VisionMaster4.2.0\Development\V4.x
\ComControls\Assembly”下的第一个文件夹“3rdLib”拷贝替换至二次开发应用程序exe同级路径下。
问题根因
某些功能接口不对外开放,需手动添加。
2.3.11 渲染控件:渲染控件绘制十字方法
描述
环境:VM4.2 + VS2013及以上
现象:如何在vmRenderControl控件上显示十字线?
解答
- 使用控件AddShape()接口显示十字线(渲染控件渲染时机为流程执行结束回调,适合静态显示),示例代码如下;
C#
/// <summary>
/// 流程工作状态回调
/// </summary>
/// <param name="workStatusInfo"></param>
private void VmSolution_OnWorkStatusEvent(VM.PlatformSDKCS.ImvsSdkDefine.IMVS_MODULE_WORK_STAUS workStatusInfo)
{
if (workStatusInfo.nWorkStatus == 0 && workStatusInfo.nProcessID == 10000)//流程空闲且为流程1
{
if (vmRenderControl1.ImageSource != null)
{
var width = vmRenderControl1.ImageSource.Width;
var height = vmRenderControl1.ImageSource.Height;
var lineY = new LineEx(new System.Windows.Point(width / 2, 0), new System.Windows.Point(width / 2, height), stroke: "#4400FF");
var lineX = new LineEx(new System.Windows.Point(0, height / 2), new System.Windows.Point(width, height / 2), stroke: "#4400FF");
renderControl.vmRenderControl1.AddShape(lineX);
renderControl.vmRenderControl1.AddShape(lineY);
}
}
}
- 使用几何创建模块生成直线的方式创建十字线(推荐);
最终二次开发渲染控件显示效果如图所示:
问题根因
不熟悉渲染控件的使用。