我在matlab中编写了一个相当大的数据采集程序,该程序在相当紧的时间计划上接收输入数据,并在GUI上实时绘制。我的问题是,我需要一种方法,为程序的用户查看GUI在网络上远程监控他们的数据。我的解决方案是每隔5秒左右拍摄一次GUI图形的快照,并将该图像托管在web服务器上。
但是这会导致两个不可接受的问题:
-
print函数实在是太慢了——每次保存需要3-4秒,程序随后在每次调用'print'后落后于其他例程。
-
由于某些原因,打印功能会导致GUI暂时扭曲,改变一些组件的位置并复制其他组件。它只持续了一秒钟左右,但它仍然使我的解决方案不切实际。
有办法解决这两个问题吗?
EDIT:***对于任何感兴趣的人,我发现最好的解决方案是使用一个名为Minicap的外部工具包。
文件格式差别很大。这是一个样本散点图
n = 1e4;
hfig = figure;
hax = plot(1:n, rand(1, n), '+');
…还有一些保存到不同格式的时间。
tic; print(hfig, 'test.bmp', '-dbmp'); toc %4.1s
tic; print(hfig, 'test.bmp', '-dbmp256'); toc %2.0s
tic; print(hfig, 'test.png', '-dpng'); toc %1.9s
tic; print(hfig, 'test.tiff', '-dtiff'); toc %0.45s
tic; print(hfig, 'test.jpg', '-djpeg'); toc %0.44s
tic; print(hfig, 'test.wmf', '-dmeta'); toc %0.42s
tiff
, jpeg
和wmf
首先是联合的,尽管tiff文件很大,jpeg质量很差,wmf也有问题,如果你不是在Windows平台上。
对于栅格格式,分辨率也会影响计时。
tic; print(hfig, 'test600.png', '-dpng', '-r600'); toc %4.2s
tic; print(hfig, 'test72.png', '-dpng', '-r72'); toc %0.31s
另一个加快打印速度的方法是删除你不需要的部分。透明度是计算密集型的,图例也是。对数据进行抽样而不是全部绘图也会节省时间。
对于将来遇到这个问题的人,我在Windows平台上找到的解决方案是一个名为Minicap的小程序,它允许用户使用系统命令轻松捕获和保存屏幕截图。
需要有图形的底层Windows句柄,可以使用由超级用户Yair M. Altman编写的公开可用的matlab函数gethwnd()
来访问。
然后你可以快速,高分辨率的截图一个图形,并保存到磁盘,像下面这样:
winHandle = gethwnd(matlabFigHandle);
cmndstr = sprintf('%s','MiniCap.exe -save ','"',snapShotFileNamePath,'"',...
' -compress 9', ' -capturehwnd ', num2str(winHandle),' -exit');
system(cmndstr);
您的解决方案必须是纯Matlab吗?使用平台工具包获取包含GUI的窗口的快照,并将其写入磁盘。这是非常快的,因为它将在一个单独的线程应该处理线程问题。
您可能不应该一直捕获,而应该只在web上实际发出请求时捕获。即使这样,也不要捕获每个请求,只在最后一个快照超过5秒的情况下才进行捕获。这对提高性能大有帮助
您可以将您的图形saveas()
作为.fig
文件(应该相当快)使用MATLAB实例进行计算,然后使用不同的MATLAB实例(可能在不同的计算机上)将其print
为所需的格式。通过这种方式,您可以避免其他例程的延迟,并且打印引起的失真不会发生在您的"主"MATLAB实例上。
请注意,print
是一个.m文件,您可以查看该文件,以查看是否有任何可以针对特定情况丢弃的内容。例如,它叫private/prepare.m
,我认为它会导致你所说的扭曲/位置变化……也许你可以摆弄一下这个?
Update:数据有通过web界面吗?如果用户基础足够小,也许您可以尝试教他们使用远程桌面软件,例如VNC、Teamviewer或Windows内置的终端服务器来远程查看他们的数据。