欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > python C# 内存共享互传 图像 以及字符串

python C# 内存共享互传 图像 以及字符串

2025/2/12 11:02:46 来源:https://blog.csdn.net/u014584014/article/details/145577935  浏览:    关键词:python C# 内存共享互传 图像 以及字符串

首先用命令行调用:

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脚本里面试试 。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com