由C# bitmap图转换为C++中halconcpp::Image 类的图

简介:很多情况下我们用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版本混乱。

image.png

  • 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的平台一致


    image.png

    即变为


    image.png
  • 修改输出目录和C++输出dll的目录一致


    image.png

3.完整项目结构

image.png

输出


image.png

你可能感兴趣的:(由C# bitmap图转换为C++中halconcpp::Image 类的图)