c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题

这篇具有很好参考价值的文章主要介绍了c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

关于C#如何调用Python,网上提供了很多解决方案,有用ironPython的,也有把python代码打包成exe的,还有通过process类调用python的,但这些方案或多或少都有一些缺陷,比如ironPython无法调用第三方库,打包成exe运行速度太慢等。本文主要针对Process类调用python分发给别人使用时候需要安装python环境的问题提出一个解决方案。


提示:以下是本篇文章正文内容,下面案例可供参考

一、问题分析

C#如何调用Python,有一个很经典的解决方案,就是使用C#的Process类创建一个进程,这个进程实际上是为了Python解释器所开辟的,通过这个进程就可以完美调用Python代码了。这个方案的原理其实就相当于你自己使用python解释器去执行一段python代码,只不过“使用Python解释器”这个过程不是手动执行的,而是C#通过process类自动执行。关键代码见下

            Process P = new Process();
            //当前debug目录路径
            string curPath = System.Environment.CurrentDirectory;
            //需要调用的python代码文件
            string path =  curPath + "\\" + sArgName;
            //python解释器的路径
            P.StartInfo.FileName = curPath + "\\" + "python3\\python.exe";
            //传递的参数,注意,参数数组从0开始索引,第0个参数永远是python代码路径
            //从第一个参数开始是函数的形参
            string sArguments = path;

这里有两个问题:
第一个,当python代码中调用了第三方库,python解释器如何知道去哪里找到第三方库的位置。
第二,当分发给一个没有装过Python的用户使用时,怎样可以不让用户下载Python,而是可以直接使用。

二、解决方案

第一个问题

如果Python代码中引用了第三库,那么Python解释器会从它的同级目录、环境变量以及手动添加的目录中寻找相应的库。从python的安装目录我们就可以明白这一点,下图是笔者的python安装目录
c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题
当你调用了Python.exe时,其会在同级目录中的LIB文件夹中的site-packages文件夹搜索对应的第三方库,找到了则会成功运行,反之则报错。

第二个问题

分发给用户时,若用户没有安装python环境,则在你电脑能运行的代码,在用户那边会因为找不到相应的模块而报错。一般的解决方案是给用户安装一个python环境,但这样无疑会影响用户体验,最好的解决方案是在分发过去的工程文件中将python环境配置好。
从第一个问题中可以得到启发,python解释器会在同级目录中找寻第三方库以及其他依赖的文件,那我们可以在工程文件中新建一个python文件夹,然后再其中配置python的环境。具体操作很简单,只需要把安装python解释器的那一个文件夹的东西全都复制过去就行。当然,这样的话,文件夹可能会很大,这一般是因为site-packages中的第三方库较多。只需要在复制的时候只保留site-packages中的相关库,其他无关的全都删除就可减小空间,比如笔者的demo中需要c#调用python的opencv去显示图片,那么site-packages中需要保留opencv和numpy库就行。见下图
c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题
c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题
c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题

三、结果及源码

 private void button2_Click(object sender, EventArgs e)
        {
            //打开图片文件
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "请选择图片文件";
            ofd.InitialDirectory = @"C:\Users\17116\Desktop";
            ofd.Filter = "图片文件|*.*";
            ofd.ShowDialog();
            url = ofd.FileName;
            string[] strArr = new string[2];//参数列表
            string sArgName = "main.py";//调用的.py文件名
            //strArr[0] = textBox1.Text;
            //strArr[1] = textBox2.Text;
            strArr[0] = url;
            RunpythonScript(sArgName, strArr);//运行python
        }

        public static void RunpythonScript(string sArgName, params string[] teps)
        {
            Process P = new Process();
            //当前debug目录路径
            string curPath = System.Environment.CurrentDirectory;
            //需要调用的python代码文件
            string path =  curPath + "\\" + sArgName;
            //python解释器的路径
            P.StartInfo.FileName = curPath + "\\" + "python3\\python.exe";
            //传递的参数,注意,参数数组从0开始索引,第0个参数永远是python代码路径
            //从第一个参数开始是函数的形参
            string sArguments = path;
            foreach (string sigter in teps)
            {
                sArguments += " " + sigter;//传递参数,两次之后为 路径 参数一 参数二
            }
            P.StartInfo.Arguments = sArguments;//启动python需要的命令语句
            P.StartInfo.UseShellExecute = false;
            P.StartInfo.RedirectStandardOutput = true;
            P.StartInfo.RedirectStandardInput = true;
            P.StartInfo.RedirectStandardError = true;
            P.StartInfo.CreateNoWindow = true;
            P.Start();
            P.BeginOutputReadLine();//在应用程序的output流上异步读取数据
            P.OutputDataReceived += new DataReceivedEventHandler(P_OutputDataReceived);//事件触发器,有新的数据就读取
            P.WaitForExit();
        }
        //用于C#和python之间字符串类型数据的传递
        static void P_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            //if (!string.IsNullOrEmpty(e.Data))//如果字符串存在
            //{
            //    MessageBox.Show(Convert.ToString(e.Data));//显示结果
            //}

        }

main.py中的python代码

import cv2
import sys

def add(a,b):
    return (float(a) + float(b))

def imgshow(path):
    img = cv2.imread(path)
    cv2.imshow("img",img)
    cv2.waitKey()

imgshow(sys.argv[1])
# print(add(sys.argv[1],sys.argv[2]))

# if __name__ == '__main__':
#     print(add(sys.argv[1],sys.argv[2]))

点击图中的选择图片按钮,c#就会调用main.py文件,并通过opencv显示图片
c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题
c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题

四、总结

本文通过process类调用python,可以使用python的第三方库,并且分发给用户的时候也不需要安装python环境。但还有一个不足之处:图片等非字符串类型的数据传输问题。这是两个不同的进程,如何把python处理好的图片数据直接加载进c#的内存中,而不是通过文件的读取方式(这样会很慢),是后续的完善方向。
最后再列举几个还没实验过的C#调用python的思路:
1.使用 Python.NET 库:Python.NET 是一个用于在 .NET 平台上运行 Python 代码的库,它提供了 C# 和 Python 之间的接口。您可以使用 Python.NET 库,在 C# 程序中调用 Python 代码。

2.使用 Pyjion:Pyjion 是一个开源的 JIT 编译器,它可以将 Python 代码编译为 .NET 的机器码。您可以使用 Pyjion,在 C# 程序中调用编译后的 Python 代码。
P.S.需要完整代码的可以在这个链接下载,博主也需要一些积分来下载资源,感兴趣的希望能多多支持一下。完整代码下载文章来源地址https://www.toymoban.com/news/detail-452050.html

到了这里,关于c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何通过python写接口自动化脚本对一个需要调用第三方支付的报名流程进行测试?

    对于需要调用第三方支付的报名流程进行接口自动化测试,可以通过以下步骤来编写Python代码: 1. 确认API需求 首先,需要确认报名流程的API需求和预期功能。这涉及到对业务需求的理解和API设计的分析。 2. 安装依赖库 在Python程序中,需要安装requests库(用于发送HTTP请求)和

    2024年02月10日
    浏览(68)
  • 解决Python安装第三方库慢的问题

    1. 阿里源: https://mirrors.aliyun.com/pypi/simple/ 2. 清华源: https://pypi.tuna.tsinghua.edu.cn/simple/ 3. 豆瓣源: http://pypi.douban.com/simple/ 4. 中科大源: https://pypi.mirrors.ustc.edu.cn/simple/

    2024年02月04日
    浏览(60)
  • [软件工具]opencv-svm快速训练助手教程解决opencv C++ SVM模型训练与分类实现任务支持C# python调用

    opencv中已经提供了svm算法可以对图像实现多分类,使用svm算法对图像分类的任务多用于场景简单且对时间有要求的场景,因为opencv的svm训练一般只需要很短时间就可以完成训练任务。但是目前网上没有一个工具很好解决训练问题,大部分需要自己编程去实现训练任务,这个对

    2024年02月06日
    浏览(54)
  • 微信小程序 - 完美解决 web-view 公众号文章或第三方网站分享转发后,打开提示 “无法打开该页面,不支持打开” 或 “页面不存在”(IOS 苹果系统打开是空白页,安卓系统会有提示)超详细排查

    由于出现这种问题的原因有很多种,绝对不像其他文章教程那样无效,本文提供了超级详细的排查思路与解决方案。 本文从 [初步排查] 到 [代码排查],完美解决 因各种原因导致 webview 页面分享后,用户打不开提示错误 这类问题, 您只需要按照排查步骤一步一步的走,从检

    2024年02月02日
    浏览(79)
  • AndroidStudio调用第三方so库

    背景         最近公司设备换了新的触摸屏(为I2C接口),该触摸屏有个app,app中可以显示触摸屏固件的版本。我需要做的是在自己的app中读取到触摸屏固件版本。         反编译了apk,得到了源码,发现对方app是通过jni调用so库的方式获取到的触摸屏固件版本。所以

    2024年04月26日
    浏览(36)
  • Flutter 与第三方 Native-SDK 的交互代理方案

    场景 在使用 Flutter 进行功能模块或者整体项目的开发时,如果需要(阶段性)频繁地和某个第三方 Native-SDK 进行交互,而该 Native-SDK 没有实现 Flutter 插件版本的情况下,如果直接把这部分交互 API 加入到原有的 channel 类里面,会使得该 channel 类变得臃肿,造成代码维护及迭代

    2024年02月02日
    浏览(38)
  • SpringBoot案例 调用第三方接口传输数据

    最近再写调用三方接口传输数据的项目,这篇博客记录项目完成的过程,方便后续再碰到类似的项目可以快速上手 项目结构: 这里主要介绍HttpClient发送POST请求工具类和定时器的使用,mvc三层架构编码不做探究 pom.xml application-dev.yml Constast utils scheduled 该定时任务每10秒执行一

    2024年02月12日
    浏览(57)
  • 仅仅是调用第三方接口那么简单吗?

    最近有个项目需要本地处理之后,然后调用第三方接口,本来开始觉得很简单得事情,不就是调用第三方接口吗?但是却一波三折。 首先有了下面的第一版的设计。 这个设计很简单,也是最容易想到的。主要有下面几步 1、本地处理; 2、调用第三方接口; 3、本地日志打印

    2024年02月06日
    浏览(63)
  • 我调用第三方接口遇到的13大坑

    在实际工作中,我们经常需要在项目中调用第三方API接口,获取数据,或者上报数据,进行数据交换和通信。 那么,调用第三方API接口会遇到哪些问题?如何解决这些问题呢? 这篇文章就跟大家一起聊聊第三方API接口的话题,希望对你会有所帮助。   一般我们在第一次对接

    2023年04月16日
    浏览(56)
  • uniapp小程序调用第三方地图导航

    效果    

    2024年02月15日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包