Is there a computationally fast way to save figures as pictures?

99 vues (au cours des 30 derniers jours)
Scott
Scott le 12 Déc 2012
Commenté : Walter Roberson le 19 Jan 2022
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'?

Réponses (4)

Jan
Jan le 12 Déc 2012
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 commentaire
Arthur
Arthur le 12 Déc 2012
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

Connectez-vous pour commenter.


Biraj Khanal
Biraj Khanal le 19 Jan 2022
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 commentaire
Walter Roberson
Walter Roberson le 19 Jan 2022
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.

Connectez-vous pour commenter.


Walter Roberson
Walter Roberson le 12 Déc 2012
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 commentaires
Biraj Khanal
Biraj Khanal le 6 Jan 2022
Modifié(e) : Biraj Khanal le 6 Jan 2022
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
Walter Roberson le 6 Jan 2022
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.

Connectez-vous pour commenter.


Yair Altman
Yair Altman le 8 Juin 2015
There are two additional alternatives that you could try:
You can use export_fig's parameters to control the export speed. For example, using '-painters' often improves the speed.
  1 commentaire
Fredrik Gustavsson
Fredrik Gustavsson le 6 Juil 2018
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.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Printing and Saving dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by