Is there a computationally fast way to save figures as pictures?
85 次查看(过去 30 天)
显示 更早的评论
I'm looking for a way to save figures as pictures computationally fast. I'm making a ton of plots, and I need to save each one. Are there any other options other than 'print' or 'saveas'?
0 个评论
回答(4 个)
Jan
2012-12-12
You can remove the overhead from the print() command and call the underlying hardcopy directly. But this will crash Matlab under certain conditions, e.g. if the drawmode of plot objects is not 'normal', etc. But even then writing to disk will be the bottleneck.
But feel free to expermient with this - carefully:
drawnow;
fig_Renderer = get(FigH, 'Renderer');
fig_Paperposmode = get(FigH, 'PaperPositionMode');
fig_PaperOrient = get(FigH, 'PaperOrientation');
fig_Invhardcopy = get(FigH, 'InvertHardcopy');
set(FigH, ...
'PaperPositionMode', 'auto', ...
'PaperOrientation', 'portrait', ...
'InvertHardcopy', 'off');
% Simulate PRINT command (save time for writing and reading image file):
% Set units of axes and text from PIXELS to POINTS to keep their sizes
% independent from from the output resolution:
% See: graphics/private/preparehg.m
root_SHH = get(0, 'ShowHiddenHandles');
set(0, 'ShowHiddenHandles', 'on');
text_axes_H = [findobj(FigH, 'Type', 'axes'); ...
findobj(FigH, 'Type', 'text')];
pixelObj = findobj(text_axes_H, 'Units', 'pixels');
fontPixelObj = findobj(text_axes_H, 'FontUnits', 'pixels');
set(pixelObj, 'Units', 'points');
set(fontPixelObj, 'FontUnits', 'points');
% Set image driver:
if strcmpi(fig_Renderer, 'painters')
imageDriver = '-dzbuffer';
else
imageDriver = ['-d', fig_Renderer];
end
fig_ResizeFcn = get(FigH, 'ResizeFcn');
set(FigH, 'ResizeFcn', '');
% "Normal" is the only erasemode, which can be rendered!
% See: NOANIMATE.
if isMatlabVer('>=', [7, 8]) % Faster method for modern FINDOBJ:
EraseModeH = findobj(FigH, 'EraseMode', 'normal', '-not');
else
EraseModeH = [ ...
findobj(FigH, 'EraseMode', 'xor'); ...
findobj(FigH, 'EraseMode', 'none'); ...
findobj(FigH, 'EraseMode', 'background')];
end
EraseMode = get(EraseModeH, {'EraseMode'});
set(EraseModeH, 'EraseMode', 'normal');
% Get image as RGB array:
high = hardcopy(FigH, imageDriver, ResolutionStr);
% Restore units of axes and text objects, and EraseMode:
set(pixelObj, 'Units', 'pixels');
set(fontPixelObj, 'FontUnits', 'pixels');
set(EraseModeH, {'EraseMode'}, EraseMode);
set(0, 'ShowHiddenHandles', root_SHH);
set(FigH, 'ResizeFcn', fig_ResizeFcn);
Now high contains the RGB values, such that IMWRITE can create a file from it. PNG files offer a fair compromise between time needed for compressing and for writing to disk.
1 个评论
Arthur
2012-12-12
Hello!
So, can i create an other function e rename it with 'print'?
I've plot a lot of plot too and i've used to do like this: for i=1:end name = ['Fig_',num2str(i)]; saveas(gcf,[name],'jpg'); close all; end
And it is to slow when a plot about a hundred plots
thanks
Biraj Khanal
2022-1-19
I had a similar issue when saving many plots at a time to generate a report. The computation time is crazy when you use exportgraphics or print.One nifty solution could be to use getframe. When you create a figure, you can get the screenshot of the figure even without having it pop up in your screen by turning the visibility off. I just used it to save the image as png. Ofcourse you do not get vector graphics like this, but it was decent enough for me to make a pdf and zoom the plots to 500% and still see clearly ( surely depends on the size though) .
F=getframe(gcf)
imwrite(F.cdata,'out.png')
1 个评论
Walter Roberson
2022-1-19
Unfortunately it turns out that if your x or y limits change as you proceed, that the exact size of the axis can wobble a little, depending on the exact content of the final tick mark.
My memory is telling me that when I investigated, I found that it could be up to 2 pixels narrower than usual, or up to 4 pixels wider than usual -- but I would have to find the relevant posting to be sure those are the correct bounds.
For individual images being written out this might not matter, but if you are creating a movie or an animated GIF, this is a problem, as those require that every frame be exactly the same width.
You can work around this partly by recording the size of the first frame and using imresize() to resize the following frames to the same size. That will satisfy the same-size requirements. It can, however, lead to visual oddities where objects could wobble by 1 pixel visually between frames, or where the right hand or top axes could wiggle back and forth.
Walter Roberson
2012-12-12
In addition to what Jan wrote: if you are not doing any transparency and are not doing 3D work, consider switching to the 'painters' renderer. If you are doing 3D work but not transparency, consider switching to 'zbuffer' as the renderer.
2 个评论
Biraj Khanal
2022-1-6
编辑:Biraj Khanal
2022-1-6
I do not understand how renderer can help. I am doing some 2D plots with about 500 data points in both axes. MATLAB , even though the doc says selects the renderer acccording to the data complexity, always seems to select openGL for some reason. When I manually changed it to painters and tried to export the graphics, I could not see significant difference in speed. Moreover, when I run a simple code like the one below in a loop, I could see that painters is at times slower than openGL. Could someone help me understand this?
%% plotting and exporting with openGL
clc; clear;
plot(rand(200,200));
tic
exportgraphics(gca,'plot.emf');
toc
%% plotting and exporting with painters
plot(rand(200,200));
set(gcf,'renderer','painters');
tic
exportgraphics(gca,'plot2.emf');
toc
Walter Roberson
2022-1-6
When I wrote this answer in 2012, painters was the fastest renderer, because it used a simplified rendering model that did not take into account transparency, or shadows, or self-intersection of surfaces, or anti-aliasing, or handling of multiple objects in the same plane. exportgraphics() did not exist back then, and handle graphics was not yet released, and the many improvements since then to handle graphics internal processing were in the future.
Yair Altman
2015-6-8
There are two additional alternatives that you could try:
- screencapture utility (bitmap only)
- export_fig utility (bitmap/vector output with multiple settable options, but slower than screencapture)
You can use export_fig's parameters to control the export speed. For example, using '-painters' often improves the speed.
1 个评论
Fredrik Gustavsson
2018-7-6
Will any of the above utilities, apart from hardcopy, print figures with 'visible' 'off'? I use hardcopy for this purpose but currently I can't get the uicontrols to print, only axes graphics.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Printing and Saving 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!