这里Python 使用 shared_memory
QT 使用 QSharedMemory
简单协议:
前面4个字节是 图片with,height,0,0
后面是图片数据
import sys
import struct
def is_little_endian():
x=0x12345678
y = struct.pack('I',x)
return y[0]==0x78
print(f"is_little_endian:{is_little_endian()}")
from multiprocessing import shared_memory
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 随机颜色 RGBA
def random_color()->tuple:
rgba = np.random.randint(0,255,size=4)
return tuple(rgba)
# 用随机数填充像素
def fill_random_pixels(img):
width, height = img.size
for x in range(width):
for y in range(height):
img.putpixel((x, y), random_color())
if __name__ == "__main__":
# 选择随机图片或者加载本地图片
random_image=False
img_width = 100
img_height = 100
img = Image.new('RGBA', (img_width, img_height))
if random_image:
fill_random_pixels(img)
origin_data = np.array(img)
else:
img_path = "C:\\Users\\mingxingwang\\Pictures\\qt-logo.png"
# 打开图片并转换为numpy数组
img = Image.open(fp=img_path)
img = img.convert("RGBA")
print(f"------------img.size------------:\n{img.size}\n")
img_width,img_height = img.size
origin_data = np.array(img)
origin_data = np.insert(origin_data,0,[img_width,img_height,0,0])
print(f"------------img------------:\n{img}\n")
print(f"------------origin_data------------:\n{origin_data}\n")
print(f"------------origin_data.dtype------------:\n{origin_data.dtype}\n")
#------------- 数据写入共享内存
# 创建共享内存对象
shm_a = shared_memory.SharedMemory(create=True, name="my_share_mem",size=origin_data.nbytes)
#构造关联共享内存的数组
mem_array = np.ndarray(origin_data.shape, dtype=origin_data.dtype, buffer=shm_a.buf)
#copy 数据到共享内存
mem_array[:]=origin_data[:]
print(f"------------mem_array------------:\n{mem_array}\n")
#显示原始图片
origin_image = Image.frombytes(mode='RGBA',size=img.size,data=origin_data)
plt.imshow(origin_image)
plt.show()
#------------- 共享内存获取数据
existing_shm = shared_memory.SharedMemory(name='my_share_mem')
array_from_mem = np.ndarray(origin_data.shape, dtype=origin_data.dtype, buffer=existing_shm.buf)
print(f"------------array_from_mem------------:\n{array_from_mem}\n")
##从共享内存构造图片
img_from_mem = Image.frombytes(mode='RGBA',size=img.size,data=array_from_mem)
##显示从共享内存获取的图片
plt.imshow(img_from_mem)
plt.show()
shm_a.close()
shm_a.unlink()
#include
#include
#include
QSharedMemory *sm;
sm = new QSharedMemory();
// sm->setKey("my_share_mem");
/// 与非Qt 程序通信 setNativeKey
sm->setNativeKey("my_share_mem");
if(!sm->attach())
{
qDebug()<<"attach error";
return;
}
qDebug() << "attach success";
QBuffer buffer;
QImage image;
sm->lock();
buffer.setData((char*)sm->data(),sm->size());
sm->unlock();
sm->detach();
if(!buffer.open(QBuffer::ReadOnly))
{
qDebug()<<"open buffer error";
return;
}
// 按照传输协议,获取图片信息
quint8 img_width , img_height ,other = 0;
buffer.read((char*)&img_width,1);
buffer.read((char*)&img_height,1);
buffer.read((char*)&other,1);
buffer.read((char*)&other,1);
qDebug()<<"img_width:"<<img_width<<"img_height:"<<img_height<<"other:"<<other;
// image bytes = width*height*4 (RGBA8888)
uint len = img_width*img_height*4;
uchar *p=(uchar*)buffer.data().data();
printf("buffer[0]=%d,buffer[1]=%d,buffer[2]=%d,buffer[3]=%d \n",p[0],p[1],p[2],p[3]);
fflush(stdout);
//按照协议,从缓冲区构造图片
image = QImage((uchar*)(p+4),img_width,img_height,QImage::Format_RGBA8888);
qDebug()<<image;