首先用命令行调用:
public string ExecuteCommand(string command){string output = string.Empty; // 用于存储命令的输出string error = string.Empty; // 用于存储命令的错误信息try{using (Process p = new Process()) // 使用Process类启动新进程{// 配置进程启动信息p.StartInfo.FileName = "cmd.exe"; // 设置要启动的程序为cmd.exep.StartInfo.Arguments = $"/c {command}"; /c 参数表示执行完命令后关闭cmd窗口p.StartInfo.UseShellExecute = false; // 不使用操作系统shell启动p.StartInfo.RedirectStandardInput = true; // 重定向标准输入p.StartInfo.RedirectStandardOutput = true; // 重定向标准输出p.StartInfo.RedirectStandardError = true; // 重定向错误输出// p.StartInfo.CreateNoWindow = true; // 不显示命令窗口p.StartInfo.CreateNoWindow = false;p.Start(); // 启动进程// 读取命令的输出output = p.StandardOutput.ReadToEnd();// 读取命令的错误信息error = p.StandardError.ReadToEnd();p.WaitForExit(); // 等待进程结束}}catch (Exception ex){// 捕获异常并返回错误信息return $"执行命令时发生错误: {ex.Message}";}// 如果有错误信息,返回错误信息;否则返回命令的输出return string.IsNullOrEmpty(error) ? output : $"错误: {error}";}
接下来 按钮事件:
private void button1_Click(object sender, EventArgs e){try{Bitmap b = new Bitmap("test.bmp");MemoryStream ms = new MemoryStream();b.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); ms.Close();var mmf = MemoryMappedFile.CreateOrOpen("test1", bytes.Length, MemoryMappedFileAccess.ReadWrite);var viewAccessor = mmf.CreateViewAccessor(0, bytes.Length);viewAccessor.Write(0, bytes.Length); ;viewAccessor.WriteArray<byte>(0, bytes, 0, bytes.Length);// MessageBox.Show("write ok" + bytes.Length.ToString());}// 5013504 5014582catch (System.Exception s){// MessageBox.Show(s.Message);}string str = ExecuteCommand(@"python nn.py");// label1.Text = str; }
好了 看程序可以知道 图像已经 内存共享到 text1
接下来:nn.py
import os,sys,time
import mmap
import cv2
import numpy as np
import datetime
from matplotlib import pyplot as plt
from PIL import Imagestarttime = datetime.datetime.now()
byteSize = 5014582
file_name = 'test1'
f = mmap.mmap(0, byteSize, file_name, mmap.ACCESS_READ)
img = cv2.imdecode(np.frombuffer(f, np.uint8), cv2.IMREAD_COLOR)
endtime = datetime.datetime.now()
print(endtime-starttime)rgb_img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
print(rgb_img)
# np.ndarray转IMAGE
a = Image.fromarray(rgb_img)
print(a)
# 显示图片
a.show()
按下按钮就会 读取图像写入共享内存 并 调用python python读取并显示
接下来说一下 传字符串 :
1.Write.py
import mmap
str = 'hello!'
byte = str.encode(encoding='UTF-8')
infoSize= len(str)
file_name = 'global_share_memory'
# python写入共享内存
shmem = mmap.mmap(0, infoSize, file_name, mmap.ACCESS_WRITE)
# 共享数据写入共享内存
shmem.write(byte)
# 让其一直运行,因为进程是活的,死了的进程,共享内存也就没了
while True:pass
Read.py
import mmap# 定义字符串和其字节表示
str = 'hello!'
byte = str.encode()
infoSize = len(str) # 字符串的字节长度
file_name = 'global_share_memory' # 共享内存的名称# 打开共享内存(假设共享内存已经存在)
try:# 使用 ACCESS_READ 模式打开共享内存shmem = mmap.mmap(0, infoSize, file_name, mmap.ACCESS_READ)# 从共享内存读取数据data = shmem.read(infoSize).decode("utf-8")print(data)shmem.close()
except Exception as e:print(f"Error: {e}")import os
os.system("pause")
C#读取:
private void button3_Click(object sender, EventArgs e){long capacity = 16;var mmf = MemoryMappedFile.OpenExisting("global_share_memory");using (MemoryMappedViewAccessor viewAccessor = mmf.CreateViewAccessor(0, capacity)){// 创建一个字节数组来存储读取的数据byte[] bytes = new byte[capacity];// 逐字节读取数据for (int i = 0; i < capacity; i++){bytes[i] = viewAccessor.ReadByte(i);}// 将字节数组转换为字符串(假设数据是 UTF-8 编码)string result = Encoding.UTF8.GetString(bytes);// 输出结果Console.WriteLine("字符串内容: " + result);label1.Text = result;}}
嗯 现在说一下python共享内存传给C#
先python自己写自己读试试:
python写:
import mmap
import numpy as np
from PIL import Image
import os
import structdef write_image_to_shared_memory(image_path, shared_memory_name):# 读取图像并转换为字节流image = Image.open(image_path)image_bytes = np.array(image).tobytes()width, height = image.size # 获取图像的宽度和高度# 将图像尺寸信息附加到字节流header = struct.pack("ii", width, height) # 4 字节宽度 + 4 字节高度data = header + image_bytes# 创建共享内存文件并写入数据with open(shared_memory_name, "wb") as f:f.write(b'\0' * len(data)) # 初始化文件大小with open(shared_memory_name, "r+b") as f:mm = mmap.mmap(f.fileno(), 0)mm.write(data) # 写入数据mm.close()print(f"图像已写入共享内存:{shared_memory_name}")if __name__ == "__main__":image_path = "lena.jpg" # 替换为你的图像路径shared_memory_name = "shared_image_memory"write_image_to_shared_memory(image_path, shared_memory_name)while True:pass
一定要让程序阻塞 停了数据就没有了。
读:
import mmap
import numpy as np
from PIL import Image
import os
import structdef read_image_from_shared_memory(shared_memory_name):try:# 打开共享内存文件with open(shared_memory_name, "r+b") as f:mm = mmap.mmap(f.fileno(), 0) # 映射整个文件data = mm.read() # 读取全部字节mm.close() # 关闭映射# 解析图像尺寸信息width, height = struct.unpack("ii", data[:8]) # 前 8 字节是宽度和高度image_bytes = data[8:] # 剩余部分是图像数据# 将字节流转换为图像image = Image.frombytes("RGB", (width, height), image_bytes)print(f"图像已从共享内存 {shared_memory_name} 成功读取。")return imageexcept Exception as e:print(f"从共享内存读取图像时发生错误:{e}")return Noneif __name__ == "__main__":shared_memory_name = "shared_image_memory" # 共享内存文件名image = read_image_from_shared_memory(shared_memory_name)if image:image.show() # 显示图像image.save("oopppp.jpg")
C#读
private void button3_Click(object sender, EventArgs e){string sharedMemoryName = "shared_image_memory"; // 共享内存文件名// 打开共享内存文件using (FileStream fs = new FileStream(sharedMemoryName, FileMode.Open, FileAccess.Read)){byte[] data = new byte[fs.Length];fs.Read(data, 0, data.Length);// 解析图像尺寸信息int width = BitConverter.ToInt32(data, 0); // 前 4 字节是宽度int height = BitConverter.ToInt32(data, 4); // 接下来的 4 字节是高度byte[] imageBytes = new byte[data.Length - 8];Array.Copy(data, 8, imageBytes, 0, imageBytes.Length);// 创建 Bitmap 对象Bitmap bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);// 将原始像素数据复制到 Bitmap 对象System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height),System.Drawing.Imaging.ImageLockMode.WriteOnly,System.Drawing.Imaging.PixelFormat.Format24bppRgb);IntPtr ptr = bitmapData.Scan0;int bytesPerPixel = 3; // 24 bits per pixelint stride = bitmapData.Stride; // 每行的字节数// 复制数据for (int y = 0; y < height; y++){int rowStart = y * width * bytesPerPixel;IntPtr rowPtr = new IntPtr(ptr.ToInt64() + y * stride);System.Runtime.InteropServices.Marshal.Copy(imageBytes, rowStart, rowPtr, width * bytesPerPixel);}bitmap.UnlockBits(bitmapData);// 保存为 BMP 文件bitmap.Save("output_image.bmp", System.Drawing.Imaging.ImageFormat.Bmp);Console.WriteLine("图像已从共享内存读取并保存为 BMP 文件。");}// 删除共享内存文件// File.Delete(sharedMemoryName);}
这时RGB是取反的 不想改了。RGB转BGR就可以。
下来直接上完整程序:
C#
using System;using System.IO;
using System.Drawing;
using System.IO.MemoryMappedFiles;
using System.Diagnostics;
using System.Windows.Forms;namespace WindowsFormsApp1
{public partial class Form1 : Form{private Label label1;private Button button3;public Form1(){InitializeComponent();}public string _CMD(string strInput){string strOuput;Process p = new Process();p.StartInfo.FileName = "cmd.exe";//设置要启动的应用程序p.StartInfo.UseShellExecute = false;//是否使用操作系统shell启动p.StartInfo.RedirectStandardInput = true;// 接受来自调用程序的输入信息p.StartInfo.RedirectStandardOutput = true;//输出信息p.StartInfo.RedirectStandardError = true;// 输出错误p.StartInfo.CreateNoWindow = true;//不显示程序窗口// p.StartInfo.CreateNoWindow = false; //显示程序窗口p.Start();//启动程序p.StandardInput.WriteLine("@echo off");p.StandardInput.WriteLine(strInput + "&exit");//向cmd窗口发送输入信息p.StandardInput.AutoFlush = true;strOuput = p.StandardOutput.ReadToEnd(); //获取输出信息p.WaitForExit(); //等待程序执行完退出进程p.Close();return strOuput;}public string ExecuteCommand(string command){string output = string.Empty; // 用于存储命令的输出string error = string.Empty; // 用于存储命令的错误信息try{using (Process p = new Process()) // 使用Process类启动新进程{// 配置进程启动信息p.StartInfo.FileName = "cmd.exe"; // 设置要启动的程序为cmd.exep.StartInfo.Arguments = $"/c {command}"; /c 参数表示执行完命令后关闭cmd窗口p.StartInfo.UseShellExecute = false; // 不使用操作系统shell启动p.StartInfo.RedirectStandardInput = true; // 重定向标准输入p.StartInfo.RedirectStandardOutput = true; // 重定向标准输出p.StartInfo.RedirectStandardError = true; // 重定向错误输出p.StartInfo.CreateNoWindow = true; // 不显示命令窗口// p.StartInfo.CreateNoWindow = false;p.Start(); // 启动进程// 读取命令的输出output = p.StandardOutput.ReadToEnd();// 读取命令的错误信息error = p.StandardError.ReadToEnd();p.WaitForExit(); // 等待进程结束}}catch (Exception ex){// 捕获异常并返回错误信息return $"执行命令时发生错误: {ex.Message}";}// 如果有错误信息,返回错误信息;否则返回命令的输出return string.IsNullOrEmpty(error) ? output : $"错误: {error}";}private void InitializeComponent(){this.label1 = new System.Windows.Forms.Label();this.button3 = new System.Windows.Forms.Button();this.SuspendLayout();// // label1// this.label1.AutoSize = true;this.label1.Location = new System.Drawing.Point(186, 296);this.label1.Name = "label1";this.label1.Size = new System.Drawing.Size(76, 21);this.label1.TabIndex = 3;this.label1.Text = "label1";// // button3// this.button3.Location = new System.Drawing.Point(122, 132);this.button3.Name = "button3";this.button3.Size = new System.Drawing.Size(228, 123);this.button3.TabIndex = 6;this.button3.Text = "button3";this.button3.UseVisualStyleBackColor = true;this.button3.Click += new System.EventHandler(this.button3_Click);// // Form1// this.ClientSize = new System.Drawing.Size(1125, 625);this.Controls.Add(this.button3);this.Controls.Add(this.label1);this.Name = "Form1";this.ResumeLayout(false);this.PerformLayout();}private void button3_Click(object sender, EventArgs e){try{Bitmap b = new Bitmap("lena.jpg");MemoryStream ms = new MemoryStream();b.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); ms.Close();var mmf = MemoryMappedFile.CreateOrOpen("test1", bytes.Length, MemoryMappedFileAccess.ReadWrite);var viewAccessor = mmf.CreateViewAccessor(0, bytes.Length);viewAccessor.Write(0, bytes.Length); ;viewAccessor.WriteArray<byte>(0, bytes, 0, bytes.Length);// MessageBox.Show("write ok" + bytes.Length.ToString());}// 5013504 5014582catch (System.Exception s){// MessageBox.Show(s.Message);}string str = ExecuteCommand(@"python nn.py");// 我希望通过命令行 把 高度 宽度 bytes.Length 传输label1.Text = str;string sharedMemoryName = "shared_image_memory"; // 共享内存文件名// 打开共享内存文件using (FileStream fs = new FileStream(sharedMemoryName, FileMode.Open, FileAccess.Read)){byte[] data = new byte[fs.Length];fs.Read(data, 0, data.Length);// 解析图像尺寸信息int width = BitConverter.ToInt32(data, 0); // 前 4 字节是宽度int height = BitConverter.ToInt32(data, 4); // 接下来的 4 字节是高度byte[] imageBytes = new byte[data.Length - 8];Array.Copy(data, 8, imageBytes, 0, imageBytes.Length);// 创建 Bitmap 对象Bitmap bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);// 将原始像素数据复制到 Bitmap 对象System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height),System.Drawing.Imaging.ImageLockMode.WriteOnly,System.Drawing.Imaging.PixelFormat.Format24bppRgb);IntPtr ptr = bitmapData.Scan0;int bytesPerPixel = 3; // 24 bits per pixelint stride = bitmapData.Stride; // 每行的字节数// 复制数据for (int y = 0; y < height; y++){int rowStart = y * width * bytesPerPixel;IntPtr rowPtr = new IntPtr(ptr.ToInt64() + y * stride);System.Runtime.InteropServices.Marshal.Copy(imageBytes, rowStart, rowPtr, width * bytesPerPixel);}bitmap.UnlockBits(bitmapData);// 保存为 BMP 文件bitmap.Save("output_image.bmp", System.Drawing.Imaging.ImageFormat.Bmp);Console.WriteLine("图像已从共享内存读取并保存为 BMP 文件。");}// 删除共享内存文件//File.Delete(sharedMemoryName);}}}
python nn.py
import os,sys,time
import mmap
import cv2
import numpy as np
import datetime
from matplotlib import pyplot as plt
from PIL import Imageimport structstarttime = datetime.datetime.now()
byteSize = 480054
file_name = 'test1'
f = mmap.mmap(0, byteSize, file_name, mmap.ACCESS_READ)
img = cv2.imdecode(np.frombuffer(f, np.uint8), cv2.IMREAD_COLOR)
endtime = datetime.datetime.now()
print(endtime-starttime)rgb_img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
#print(rgb_img)
# np.ndarray转IMAGE
a = Image.fromarray(rgb_img)
#print(a)
# 显示图片
#a.show()def write_image_to_shared_memory(img, shared_memory_name):image= Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))image_bytes = np.array(image).tobytes()width, height = image.size # 获取图像的宽度和高度# 将图像尺寸信息附加到字节流header = struct.pack("ii", width, height) # 4 字节宽度 + 4 字节高度data = header + image_bytes# 创建共享内存文件并写入数据with open(shared_memory_name, "wb") as f:f.write(b'\0' * len(data)) # 初始化文件大小with open(shared_memory_name, "r+b") as f:mm = mmap.mmap(f.fileno(), 0)mm.write(data) # 写入数据mm.close()#print(f"图像已写入共享内存:{shared_memory_name}")if __name__ == "__main__":shared_memory_name = "shared_image_memory"write_image_to_shared_memory(rgb_img, shared_memory_name)endtime = datetime.datetime.now()
print(endtime-starttime)
虽然写在一起没有做成函数 已经可以实现基本功能 C#> python[这里可以写图像处理] >C#
下次 移到VM脚本里面试试 。