[WPF]C#调用C++代码(通过C++/CLI)

用途

通过使用C++ + Opencv 编写算法,然后用WPF(C#)编写程序界面,实现交互

可以参考MSDN文档:https://docs.microsoft.com/en-us/cpp/windows/pin-ptr-cpp-cli?view=vs-2017

项目结构 

代码

CLR部分: 

CLRLibrary.h文件 

#pragma once

using namespace System;
using namespace System::Collections::Generic;
#include<opencv2opencv.hpp>   
#include<opencv2highguihighgui.hpp>
namespace CLRLibrary {
	
	public ref class Class1
	{
	public:
		List<Byte>^ ErodeImage(System::String^ filename);
		int Rows;
		int Cols;

	};
}

 CLRLibrary.cpp文件

#include "stdafx.h"
using namespace System;
using namespace System::Runtime::InteropServices;
#include "CLRLibrary.h"
#include "H:CPPWPF_CPPCLI_DemoConsoleLibraryErodeClass.h"
#include<opencv2opencv.hpp>   
#include<opencv2highguihighgui.hpp>
using namespace cv;
Mat ErodeAction(const char* filename)
{
	Mat img = imread(filename);
	Mat out;
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); //第一个参数MORPH_RECT表示矩形的卷积核,当然还可以选择椭圆形的、交叉型的
	//膨胀操作
	dilate(img, out, element);
	
	return out;
}
//Erode The Image Func
List<Byte>^ CLRLibrary::Class1::ErodeImage(System::String ^ filename)
{
	//将String^转换成const char*
	IntPtr ip = Marshal::StringToHGlobalAnsi(filename);
	const char* str = static_cast<const char*>(ip.ToPointer());
	Mat result=ErodeAction(str);
	List<Byte>^ ret=gcnew List<Byte>();
	for (int i = 0; i < result.rows; i++)
	{
		for (int j = 0; j < result.cols; j++)
		{
			//RBG
			ret->Add(result.at<Vec3b>(i, j)[0]);
			ret->Add(result.at<Vec3b>(i, j)[1]);
			ret->Add(result.at<Vec3b>(i, j)[2]);
		}
	}
	Rows = result.rows;
	Cols = result.cols;

	return ret;
}

 WPF部分:

MainWindow.xaml:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        Loaded="MainWindow_OnLoaded">
    <Grid>
        <Image Name="Box"></Image>
    </Grid>
</Window>

 MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CLRLibrary;
using Color = System.Drawing.Color;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 将BitMap转换成ImageSource
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static ImageSource ChangeBitmapToImageSource(Bitmap bitmap)
        {
            //Bitmap bitmap = icon.ToBitmap();  
            IntPtr hBitmap = bitmap.GetHbitmap();


            ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                hBitmap,
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());

            return wpfBitmap;
        }


        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            var drawClass=new Class1();

            List<byte> RGBData=drawClass.ErodeImage("D:/Background/1.jpg");
             
            Bitmap map = new Bitmap(drawClass.Cols, drawClass.Rows);
            int temp = 0;
            for (int i = 0; i < drawClass.Rows; i++)
            {
                for (int j = 0; j < drawClass.Cols; j++)
                {
                    var color = Color.FromArgb(RGBData[temp], RGBData[temp + 1], RGBData[temp + 2]);
                    temp += 3;
                    map.SetPixel(j, i, color);
                }
            }
            Box.Source = ChangeBitmapToImageSource(map);
        }

    }
}

运行效果图

项目所有代码全在上面,如果有需要源码的或者需要交流的可以加我QQ或者微信。

关于更多的C++/CLI代码可以参考我上面给的MSDN文档链接,基本用得到的语法都能从上面找到。

原文地址:https://www.cnblogs.com/lizhenghao126/p/11053558.html