简介:很多情况下我们用C#编写软件界面,但是C#容易被反编译,对代码保密性不如C++,在运行性能上也不如C++,所以核心的处理函数一般用C++写。本文的运行逻辑是用C#调用C++代码,C++调用halcon代码,主要针对C#中的bitmap类图转为halconCpp::Image类图。
halcon C++配置
1.创建C++工程,调用halcon代码,并生成dll文件。
按照halcon C++配置配置一下包含目录,库目录,和附加依赖项,项目配置类型设置为"动态库(.dll)"。为了我们调试方便,我们把dll项目的输出目录和C#的输出目录设为一样,这样就不用每次更新都复制粘贴dll文件了,这样也能避免因疏忽而忘记复制dll导致dll版本混乱。
- bitmapToHalconImage.cpp文件
# include "HalconCpp.h"
# include
struct bitmapData
{
byte *data;
int width;
int height;
};
void showImage(const HalconCpp::HImage &img);
void bitmapToHalconImage(bitmapData &data, HalconCpp::HImage &img, int channel);
extern "C" _declspec(dllexport) void createHalconImage(bitmapData data)
{
HalconCpp::HImage img;
//bitmapData由C#中的bitmap图锁定在内存中的数组,包含所有通道
//这里加入通道选择,能更直观的看halcon如何构造一个Himage
int channel = 0;//r=0,g=1,b=2,gray=3,rgb=4;
bitmapToHalconImage(data,img, channel);
showImage(img);
}
void showImage(const HalconCpp::HImage &img)
{
Hlong w, h;
img.GetImageSize(&w, &h);
HalconCpp::HWindow win1(0, 0, w, h);
img.DispImage(win1);
win1.Click();
win1.ClearWindow();
}
void bitmapToHalconImage(bitmapData &data, HalconCpp::HImage &img, int channel)
{
int width = data.width, height = data.height;
byte *imdata = data.data;
int size = width * height;
byte *R;
byte *G;
byte *B;
byte *gray;
switch (channel)
{
//red channel
case 0:
R = new byte[size];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
R[i*width + j] = imdata[i*width * 4 + 4 * j + 2];
}
}
HalconCpp::GenImage1(&img, "byte", width, height, (Hlong)R);
delete[] R;
break;
//green channel
case 1:
G = new byte[size];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
G[i*width + j] = imdata[i*width * 4 + 4 * j + 1];
}
}
HalconCpp::GenImage1(&img, "byte", width, height, (Hlong)G);
delete[] G;
break;
//blue channel
case 2:
B = new byte[size];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
B[i*width + j] = imdata[i*width * 4 + 4 * j];
}
}
HalconCpp::GenImage1(&img, "byte", width, height, (Hlong)B);
delete[] B;
break;
//gray channel
case 3:
gray = new byte[size];
//灰度图转化心理学公式 Grey = 0.299*R + 0.587*G + 0.114*B
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
/*B[i*width + j] = imdata[i*width * 4 + 4 * j];
G[i*width + j] = imdata[i*width * 4 + 4 * j + 1];
R[i*width + j] = imdata[i*width * 4 + 4 * j + 2];*/
gray[i*width + j] = byte(0.299* imdata[i*width * 4 + 4 * j] + 0.587* imdata[i*width * 4 + 4 * j + 1] + 0.114*imdata[i*width * 4 + 4 * j + 2]);
}
}
HalconCpp::GenImage1(&img, "byte", width, height, (Hlong)gray);
delete[] gray;
break;
case 4:
//rgb color image
R = new byte[size];
G = new byte[size];
B = new byte[size];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
B[i*width + j] = imdata[i*width * 4 + 4 * j];
G[i*width + j] = imdata[i*width * 4 + 4 * j + 1];
R[i*width + j] = imdata[i*width * 4 + 4 * j + 2];
}
}
HalconCpp::GenImage3(&img, "byte", width, height, (Hlong)R, (Hlong)G, (Hlong)B);
delete[] R;
delete[] G;
delete[] B;
break;
}//end switch
}
2.创建C#项目
创建C#的控制台应用程序
- callHalcon中的Program.cs文件代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;//包含Dllimport()
namespace callHalcon
{
class Program
{
//定义bitmap结构体和c++中的定义一致
public struct bitmapData
{
public IntPtr data;
public int width;
public int height;
public bitmapData(System.Drawing.Imaging.BitmapData bd)
{
data = bd.Scan0;
width = bd.Width;
height = bd.Height;
}
}
//从dll中导入函数
[DllImport("bitmapToHalconImage.dll", CallingConvention = CallingConvention.Cdecl)]
extern static void createHalconImage(bitmapData data);
static void Main(string[] args)
{
//获取图
Bitmap img = new Bitmap(@"G:/im1.png");//待搜索图
//把bitmap的数据锁到内存
BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
//转换为自定义的结构体类型;
bitmapData mybitmapData = new bitmapData(imgData);
//调用dll中封装的函数
createHalconImage(mybitmapData);
img.UnlockBits(imgData);
}
}
}
-
修改C#的平台和生成dll的平台一致
即变为
-
修改输出目录和C++输出dll的目录一致
3.完整项目结构
输出