MATLAB Answers

Why does the screensaver get captured when I use GETFRAME on a MATLAB figure window while creating a movie using MATLAB 7.1 (R14SP3)?

Asked by MathWorks Support Team on 13 May 2011
Latest activity Edited by Chris MacMinn
on 11 Mar 2015

I am creating an AVI movie by using GETFRAME to capture the figure window. However, if my screensaver gets activated while my code is executing, the screensaver gets captured instead of the MATLAB figure window.

  0 Comments

1 Answer

Answer by MathWorks Support Team on 13 May 2011
 Accepted answer

This is the expected behavior of GETFRAME. GETFRAME captures the information that is visible on the screen, and hence will capture the screensaver image, or any other window or part of the window that is visible on top of the figure window.

To work around this issue, you may use any of the following alternatives.

1. You may directly use ADDFRAME to add the figure data to the AVI-file using the following algorithm:

 - Create an AVI object using AVIFILE.
 - Draw plots.
 - Use ADDFRAME with the handle to the figure to add the frame to the AVI object.

2. Alternatively, you could capture the figure data using the following algorithm:

 - Create an AVI object using AVIFILE.
 - Draw plots.
 - Use PRINT to export the figure to an image file.
 - Use IMREAD to read the image into MATLAB workspace.
 - Use IM2FRAME to create a frame.

3. Lastly, you may use HARDCOPY to copy the figure. HARDCOPY is an undocumented feature of MATLAB.

For example, for the "ZBuffer" renderer, you may use the following function to capture the figure data:

function cdata = zbuffer_cdata(hfig)
% Get CDATA from hardcopy using zbuffer
% Need to have PaperPositionMode be auto 
orig_mode = get(hfig, 'PaperPositionMode');
set(hfig, 'PaperPositionMode', 'auto');
cdata = hardcopy(hfig, '-Dzbuffer', '-r0');
% Restore figure to original state
set(hfig, 'PaperPositionMode', orig_mode); % end

For the "OpenGL" renderer you can write a similar code. This technique will not work for the "painters" renderer.

Next, replace the use of GETFRAME from your code with IM2FRAME as follows:

F = im2frame(zbuffer_cdata(gcf));

  3 Comments

DKM
on 13 Feb 2015

It seems that using newer versions of MATLAB will run into problems with this. In R2014b, references to HARDCOPY are met with a warning message advising that we use PRINT instead since HARDCOPY will be removed in a future release. Since the time of this answer, AVIFILE has also been removed (and ADDFRAME with it), and replaced with the VideoWriter class, which appears to require the use of GETFRAME, thus running into the original issue again.

It appears the only way around this issue is now Alternative 2, using PRINT to export a file, then reading that file back into MATLAB and calling IM2FRAME. This is pretty time consuming.

Are there any new ways to do this that have been introduced to replace the very useful ways that keep getting phased out?

Chris MacMinn
on 10 Mar 2015

I will second this comment. GETFRAME is totally unacceptable. I wrote a workaround using HARDCOPY (Alternative 3), but this is now being phased out. Alternative 2 should work fine, but outputting and then reading a file seems like a really slow and inefficient way to accomplish this.

Chris MacMinn
on 11 Mar 2015

UPDATE: I have just learned from Mathworks Support that as of R2014b the PRINT command offers a new output option '-RGBImage' that provides the desired functionality. Example:

CDATA = PRINT(fig,'-RGBImage');

The output is an image matrix that can be fed to IM2FRAME and added to a movie. See my fig2frame function for a convenient implementation of this.


Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply today