zoukankan      html  css  js  c++  java
  • [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文档链接,基本用得到的语法都能从上面找到。

  • 相关阅读:
    C#线程池
    C#.Net前台线程与后台线程的区别
    ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler)(转)
    ASP.NET Core 2.1 : 十四.静态文件与访问授权、防盗链(转)
    ASP.NET Core 2.1 : 十三.httpClient.GetAsync 报SSL错误的问题(转)
    ASP.NET Core 2.1 : 十二.内置日志、使用Nlog将日志输出到文件(转)
    ASP.NET Core 2.1 : 十一. 如何在后台运行一个任务(转)
    ASP.NET Core 2.1 : 十.升级现有Core2.0 项目到2.1(转)
    ASP.NET Core 2.0 : 九.从Windows发布到CentOS的跨平台部署(转)
    ASP.NET Core 2.0 : 八.图说管道,唐僧扫塔的故事(转)
  • 原文地址:https://www.cnblogs.com/lizhenghao126/p/11053558.html
Copyright © 2011-2022 走看看