从客户端选择一张图片发送给服务器保存。 要求: 客户端:采用Qt5实现界面,先选择一张要发送的图片,然后点击“发送”按钮发送图片文件名和图片,通过thrift RPC方式通信 服务器:将接收到的图片保存。保存成功提示:保存图片成功,保存的文件名称为客户端发送的文件名称。通过thrift RPC方式通信.
时间: 2024-02-09 13:13:19 浏览: 116
上传图片到服务器
客户端需要安装 `thrift` 模块,可以使用以下命令进行安装:
```
pip install thrift
```
客户端需要实现以下功能:
1. 显示界面,包括选择图片按钮、发送图片按钮、图片预览等控件。
2. 点击选择图片按钮后,弹出文件选择对话框,选择要发送的图片文件。
3. 点击发送图片按钮后,将图片文件名和图片数据通过 thrift RPC 调用发送给服务器。
以下是客户端的代码示例:
```python
import sys
import os
import io
import base64
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QFileDialog
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from rpc import ImageService
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 选择图片按钮
self.select_button = QPushButton('选择图片', self)
self.select_button.move(20, 20)
self.select_button.clicked.connect(self.select_image)
# 发送图片按钮
self.send_button = QPushButton('发送图片', self)
self.send_button.move(20, 60)
self.send_button.clicked.connect(self.send_image)
# 图片预览
self.image_label = QLabel(self)
self.image_label.move(150, 20)
self.image_label.resize(300, 300)
self.image_label.setScaledContents(True)
# 保存图片名称
self.filename = ''
def select_image(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
filename, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "Image Files (*.png *.jpg *.bmp)", options=options)
if filename:
self.filename = os.path.basename(filename)
with open(filename, 'rb') as f:
data = f.read()
image_data = base64.b64encode(data).decode('utf-8')
self.image_label.setPixmap(data)
def send_image(self):
if not self.filename:
return
# 通过 thrift RPC 调用发送图片数据
transport = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = ImageService.Client(protocol)
transport.open()
request = {
'filename': self.filename,
'data': self.image_label.pixmap().toImage().bits().tobytes()
}
client.save_image(request)
transport.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
```
服务器需要安装 `thrift` 和 `Pillow` 模块,可以使用以下命令进行安装:
```
pip install thrift Pillow
```
服务器需要实现以下功能:
1. 启动 thrift RPC 服务。
2. 实现保存图片的方法,将接收到的图片数据保存到文件中。
以下是服务器的代码示例:
```python
import io
import base64
import os
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from rpc import ImageService
from PIL import Image
class ImageHandler(ImageService.Iface):
def save_image(self, request):
filename = request['filename']
data = request['data']
# 将图片数据写入文件
with open(filename, 'wb') as f:
f.write(data)
# 打开图片并显示
image = Image.open(io.BytesIO(data))
image.show()
print('保存图片成功:{}'.format(filename))
if __name__ == '__main__':
handler = ImageHandler()
processor = ImageService.Processor(handler)
transport = TSocket.TServerSocket('localhost', 9090)
transport_factory = TTransport.TBufferedTransportFactory()
protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, transport_factory, protocol_factory)
print('Starting the server...')
server.serve()
print('done.')
```
注意,上述代码中的 `rpc` 模块是通过 `thrift` 生成的,需要先编写 `image.thrift` 文件,然后使用 `thrift` 工具生成 Python 代码。
`image.thrift` 文件内容如下:
```
namespace py.rpc
struct ImageData {
1: string filename,
2: binary data,
}
service ImageService {
void save_image(1: ImageData request),
}
```
使用以下命令生成 Python 代码:
```
thrift -r --gen py image.thrift
```
生成的代码会保存在 `gen-py` 目录中。将 `rpc` 目录(包含 `__init__.py` 和 `ImageService.py` 文件)复制到 `gen-py/py` 目录中。
阅读全文