实时图像
写了一个关于实时图像滚动显示的例子,做个记录。
滚动算法:
难点:
将内存数据绘制到界面,需要用到QImage和QPixmap,使用QImage转换一下,具体参见代码。这个费了好大劲才弄出来(网上的资料大都很简单,处理个QImage打开保存啊等等操作,项目实用性不强。)
from PIL import Image
import numpy as np
import threading
import time
class GraphicWidget(QWidget):
def __init__(self):
super(GraphicWidget,self).__init__()
self.threadStop = False
self.drawWidth = 1080
self.drawHeight = 800
self.imgWholeData = None
self.imgScreenData = np.zeros([self.drawHeight,self.drawWidth],np.uint8)
self.imgTotalLines = 0
self.imgWidth = 0
self.threadStop = True
pass
def doscroll(self):
if self.threadStop:
img = Image.open("d:/test2.png")
self.imgWholeData = np.array(img)
self.imgTotalLines, self.imgWidth = self.imgWholeData.shape
scrollThread = threading.Thread(target = self.scroll)
scrollThread.start()
def stop(self):
self.threadStop = True
def scroll(self):
step = 5
srcStartLine = 0
srcEndLine = step
destEndLine = step
self.threadStop = False
while not self.threadStop:
if destEndLine > self.drawHeight:
destEndLine = self.drawHeight
if srcEndLine > self.drawHeight:
srcStartLine = srcEndLine - self.drawHeight
if srcEndLine > self.imgTotalLines:
print("scroll end")
self.threadStop = True
break
if srcStartLine < self.drawHeight:
self.imgScreenData = np.zeros([self.drawHeight,self.drawWidth],np.uint8)
self.imgScreenData[0:destEndLine] = self.imgWholeData[srcStartLine:srcEndLine]
self.update()
destEndLine = destEndLine + step
srcEndLine = srcEndLine + step
time.sleep(0.005)
pass
def paintEvent(self,event):
try:
painter = QPainter()
destRect = QRect(0,0,self.drawWidth,self.drawHeight)
srcRect = QRect(0,0,self.drawWidth,self.drawHeight)
img = QImage(self.imgScreenData.data, self.drawWidth, self.drawHeight, QImage.Format_Indexed8)
pix = QPixmap.fromImage(img)
painter.begin(self)
painter.drawPixmap(destRect, pix, srcRect)
painter.end()
except Exception as e:
print(e)
raise
Pass
经验证,图像“拖尾”比较严重,图像滚动平滑效果比不上用DirectX做的效果,但是刷新效率很高,QT这块做的比C#好很多。
下次,实用Opengl做一个,看看效果咋样。