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

72 visualizaciones (últimos 30 días)
Scott
Scott el 12 de Dic. de 2012
Comentada: Walter Roberson el 19 de En. de 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'?

Respuestas (4)

Jan
Jan el 12 de Dic. de 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 comentario
Arthur
Arthur el 12 de Dic. de 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

Iniciar sesión para comentar.


Biraj Khanal
Biraj Khanal el 19 de En. de 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 comentario
Walter Roberson
Walter Roberson el 19 de En. de 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.

Iniciar sesión para comentar.


Walter Roberson
Walter Roberson el 12 de Dic. de 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 comentarios
Biraj Khanal
Biraj Khanal el 6 de En. de 2022
Editada: Biraj Khanal el 6 de En. de 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 el 6 de En. de 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.

Iniciar sesión para comentar.


Yair Altman
Yair Altman el 8 de Jun. de 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 comentario
Fredrik Gustavsson
Fredrik Gustavsson el 6 de Jul. de 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.

Iniciar sesión para comentar.

Categorías

Más información sobre Printing and Saving en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by