Python+OpenCV+mss實現區域網跨平臺桌面演示
阿新 • • 發佈:2018-11-12
整體思路
server.py:用mss截圖,然後zlib壓縮後socket傳送
client:socket接收,zlib解壓縮,然後使用OpenCV播放
簡單介紹mss
An ultra fast cross-platform multiple screenshots module in pure Python using ctypes.
具體去官網:https://github.com/BoboTiG/python-mss
直接上程式碼
server.py
from socket import socket from threading import Thread from zlib import compress from mss import mss # 截圖大小 WIDTH = int(1366 / 1) HEIGHT = int(768 / 1) def send_screenshot(conn): with mss() as sct: rect = {'top': 0, 'left': 0, 'width': WIDTH, 'height': HEIGHT} while 'recording': img = sct.grab(rect) # 壓縮等級 (0-9) # 並不一定是壓縮level越高越好,這裡要綜合考慮壓縮佔用時間和網路傳輸時間 pixels = compress(img.bgra, 1) # 壓縮對比 # level:0 size:4196683 # level:1 size:248329 # level:2 size:246512 # level:9 size:196212 size = len(pixels) size_len = (size.bit_length() + 7) // 8 conn.send(bytes([size_len])) size_bytes = size.to_bytes(size_len, 'big') conn.send(size_bytes) conn.sendall(pixels) def main(host='0.0.0.0', port=5000): sock = socket() sock.bind((host, port)) try: sock.listen(5) print('Server started.') while 'connected': conn, addr = sock.accept() print('Client connected IP:', addr) thread = Thread(target=send_screenshot, args=(conn,)) thread.start() finally: sock.close() if __name__ == '__main__': main()
client.py
from socket import socket from zlib import decompress import cv2 import numpy from PIL import Image # 截圖大小 WIDTH = int(1366 / 1) HEIGHT = int(768 / 1) def recvall(conn, length): buf = b'' while len(buf) < length: data = conn.recv(length - len(buf)) if not data: return data buf += data return buf # host為server的ip def main(host='10.100.40.52', port=5000): watching = True sock = socket() sock.connect((host, port)) try: while watching: size_len = int.from_bytes(sock.recv(1), byteorder='big') size = int.from_bytes(sock.recv(size_len), byteorder='big') # 解壓縮 bgra = decompress(recvall(sock, size)) img = Image.frombytes("RGB", (WIDTH, HEIGHT), bgra, "raw", "BGRX") np_ar = numpy.array(img, dtype=numpy.uint8) # 因為OpenCV模式色彩預設是BGR(紅色和藍色互換了) # 這裡就是把BGR改成RGB np_ar = numpy.flip(np_ar[:, :, :3], 2) cv2.imshow("OpenCV show", np_ar) if cv2.waitKey(25) & 0xFF == ord("q"): cv2.destroyAllWindows() break finally: sock.close() if __name__ == '__main__': main()