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

56 visualizzazioni (ultimi 30 giorni)
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'?

Risposte (4)

Jan
Jan il 12 Dic 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 Commento
Arthur
Arthur il 12 Dic 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

Accedi per commentare.


Biraj Khanal
Biraj Khanal il 19 Gen 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 Commento
Walter Roberson
Walter Roberson il 19 Gen 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.

Accedi per commentare.


Walter Roberson
Walter Roberson il 12 Dic 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 Commenti
Biraj Khanal
Biraj Khanal il 6 Gen 2022
Modificato: Biraj Khanal il 6 Gen 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 il 6 Gen 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.

Accedi per commentare.


Yair Altman
Yair Altman il 8 Giu 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 Commento
Fredrik Gustavsson
Fredrik Gustavsson il 6 Lug 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.

Accedi per commentare.

Categorie

Scopri di più su Printing and Saving in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by