MATLAB getframe captures whatever is on screen

15,462

Solution 1

OK, found the solution; instead of

aviobj = addframe(aviobj, getframe(fig));

sending the figure handle directly to addframe is enough:

aviobj = addframe(aviobj, fig);

Solution 2

The Matlab people are apparently phasing out the avifile and addframe functions in future releases, replacing them with VideoWriter and writeVideo respectively. Unfortunately, this means that the accepted answer will no longer work, since writeVideo doesn't accept the figure handle as the argument.

I've played around with it a bit, and for future reference, the same thing can be accomplished using the undocumented hardcopy function. The following code works perfectly for me, with the added benefit of not even having a plot window pop up, so it does everything completely in the background:

fig = figure('Visible','off');
set(fig,'PaperPositionMode','auto');
writerobj = VideoWriter('sample.avi','Uncompressed AVI');
open(writerobj);

for i=1:t
    clf(fig);
    plot(...); % some arbitrary plotting
    hold on;
    plot(...); % some other arbitrary plotting
    axis([0 50 0 50]);
    figinfo = hardcopy(fig,'-dzbuffer','-r0');
    writeVideo(writerobj, im2frame(figinfo));
end

close(writerobj);

Solution 3

You can pass the handle of the desired figure or axis to GETFRAME to ensure that it doesn't capture another window.

Solution 4

I may depend on the renderer you're using. If it's 'painters', then you should be OK, but if it's anything else, such as 'OpenGL', then I think it has to get the frame data from the graphics card, which means that if you have something overlapping the window, then that may end up in the output of getframe.

Share:
15,462
paul simmons
Author by

paul simmons

Updated on June 04, 2022

Comments

  • paul simmons
    paul simmons almost 2 years

    I am trying to create a movie from my MATLAB plot. When I call getframe, it "usually" captures the plot image, but sometimes if there is something else active on the screen (which is normal if I continue to use the computer) it captures whatever window is active. Is there another way to grab the image of the active figure?

    e.g.

    fig = figure;
    aviobj = avifile('sample.avi','compression','None');
    for i=1:t
        clf(fig);
        plot(...); % some arbitrary plotting
        hold on;
        plot(...); % some other arbitrary plotting
        axis([0 50 0 50]);
        aviobj = addframe(aviobj, getframe(fig));
    end
    aviobj = close(aviobj);
    
  • gnovice
    gnovice over 12 years
    @paulsimmons: Can you add a code sample showing what you are doing?
  • paul simmons
    paul simmons over 12 years
    FYI, set(gcf, 'Renderer', 'painters'); aviobj = addframe(aviobj, getframe(gcf)); did not work either...
  • gnovice
    gnovice over 12 years
    @paulsimmons: Are you using gcf or fig when passing the handle? It's fig in the question but gcf in your comment.
  • paul simmons
    paul simmons over 12 years
    well, gcf actually is a function to "Get the Current Figure" and it returns fig in my case
  • gnovice
    gnovice over 12 years
    @paulsimmons: Yes, but if for whatever reason another figure besides fig becomes the current figure while making your movie, then gcf will refer to that one instead.
  • gnovice
    gnovice over 12 years
    It's good that you found a workaround. I just wonder what was causing the problem in the first place. Perhaps a bug report is in order.
  • Stretch
    Stretch about 10 years
    I just tried this and it did not work. I am on R2010b on Mac OSX. The figure window is behind the dock (like everything else on my screen) and the dock appeared in my video.