# 2.4 Creating Movies

MATLAB provides two functions for generating movies, getframe and movie. getframe is used to record each frame of the movie, and movie is used to play the movie. Before creating movies, you must first understand what each command does and how the commands work.

getframe is used to record each frame of the movie in the form of a PIXMAP. A PIXMAP is a special format we use to store the width, height,and bitmap of the frame in a column vector. Since this is the case, getframe is often used in a for loop to record multiple frames into a single array. Each iteration through the loop adds another column to the array.

getframe can be used three different ways:

  M = getframe by itself records the event of the current axes.
  M = getframe(H) records the events of H, where H is the handle to an axes or figure.
  M = getframe(H,RECT) records the events in the rectangle defined by RECT relative to the lower-left corner of H.

movie is used to play the movie defined by M, where M is the output from getframe. There are several different ways to play a movie:

  movie(M) plays the movie M once in the current axes.
  movie(M,N) plays the movie N times in the current axes. If N is a positive integer, then the movie is played N times forwards. If N is a negative integer, the movie is played N times forwards and backwards. N can also be a vector of integer values. In this case, the first element of N is the number of times the movie is played, and the remaining elements correspond to the frame. For example, N = [3 1 3 2] plays the first, third, and second frame in that order three times.
  movie(M,N,FPS) plays the movie N times at the rate of FPS frames per second.
  movie(H,M, ...) plays the movie in H, where H is the handle to an axes or figure.
  movie(H,M,N,FPS,LOC) plays the movie in H, N times at the rate of FPS frames per second in the location defined by LOC. LOC is a 4-element vector; however, only the first two elements are used since the width and height are stored in M. The first two elements are the X and Y location relative to H. As a rule of thumb, use the same RECT vector that was used with getframe. This guarantees that the movie is played in the same location as it was recorded.

The method you choose depends on the information you wish to record and where you wish to play the movie. For example, if you are not concerned about the axes limits and labels, then using M = getframe and movie(M) is perfect. This will record the events occurring within the current axes; however, axes limits and labels are not recorded. When the movie is played, using movie(M), it is played in the current axes. If there is not an axis, then one will be created. Below is an example of this method:

    for x = 1:5
      plot(sin(x*pi*[0:0.025:2]))
      M(:,x) = getframe;
    end
    clf
    movie(M)

After running this example, you will notice that the axes limits do not correspond to the plot. This is because the movie was recorded with respect to the box that defines the axes. Everything outside the box is not recorded. When the movie is played, it creates an axis and uses it as a point of reference only. The default limits of an axis are 0 and 1.

The most useful and practical way to use getframe and movie is to record the events with respect to the figure, and to record the entire contents of the figure. By doing this, every change that occurs in the figure will be recorded. This means that axes limits and labels get recorded as well as multiple plots. For example:

    % Define the area to be recorded
    rect = get(gcf,'Position');
    rect(1:2) = [0 0];
    % Generate and record the frames
    for x = 1:5
      t = 0:pi/10:x*pi;
      subplot(211)
      plot(t,sin(t))
      axis([0 5*pi -1 1])
      subplot(212)
      plot(t,cos(t))
      axis([0 5 -1 1])
      M(:,x) = getframe(gcf,rect);
    end
    % Play the movie
    clf
    N = 1;
    FPS = 10;
    movie(gcf,M,N,FPS,RECT)

The first two lines in this example are used to create the rectangle that is used by getframe. This vector uses the same format as Position vectors, therefore, the easiest way to define a rectangle that is the entire figure is to reference the figure's Position. Since the first two elements of the figure's Position vector are the X and Y coordinates of the figure with respect to the lower left corner of the screen, they are zeroed out so that the first two elements are relative to the lower left corner of the FIGURE.

Since the frames are recorded with respect to the figure, it makes sense that the movie should be played with respect to the figure. To play a movie with respect to a figure, you should use all five inputs for movie. If you do not, the movie will be played in the current axes. As stated above, N is the number of times the movie is played, and FPS is the number of frames played per second

Now that you know the basics of how to use getframe and movie, there is one additional piece of information you need. Since the vectors created by getframe are large, it is wise to preallocate memory. This will help reduce the amount of time it takes to record each frame. Below are some examples of how to preallocate memory:

    M = moviein(N);
    M = moviein(N,gcf);
    M = zeros(size(getframe(H,RECT)),N);

moviein is the command that is shipped with MATLAB. It can be used to preallocate memory when frames are being recorded with respect to the current axes or the entire FIGURE. When an arbitrary size rectangle is used, the last method is recommended.

Below are some frequently asked questions that we receive in Technical Support:

- How do I play a movie backwards and can I control the order the frames are played?

  N controls the number of times as movie is played, as well as the order of frames. To play a movie N times forward and N times backwards, use -N in the movie command. To specify the order of the frames, specify a vector of integer values for N. The first element is the number of times the movies is played, and the remaining elements correspond to the frames. For example, if a movie consist of five frames, to play it once backwards, set N = [1 5 4 3 2 1].

- How much memory does the movie require?

  getframe creates a huge vector for each frame. The size of the vector created by getframe is independent of the data in the axes/figure. Remember, getframe is creating a pixel-by-pixel map of the area. Since this is the case, the size of the vector is dependent only on the size of the area recorded. The larger the area, the larger the vector.
  On X machines, the X server must have enough memory to load all the frames at once. One of the most common problems people have with movies is that they run out of memory and don't know why.
  On PCs and MACs, you need approximately twice the amount of memory as the movie data in order to play the movie. For example, if M is 2M-bytes, then you need at least 4M-bytes to play the movie.

- How do I record the events of the entire screen?

  In the Reference Guide, we say that the ROOT, 0, is a valid input for getframe. This was only supported in the very first release of MATLAB 4.0. It was not very stable, so it was removed. This was the functionality that let users record the entire screen.

- Can I play sound with the movie?

  You cannot play sound at the same time movies are played.

- Why does the movie pause when it is played?

  There are several reasons why a movie may pause when it is played. First, since movies are very memory intensive, it may be necessary to swap information in and out of memory to play the movie. The second reason is the load on the network or CPU. If someone logs onto your machine, this may cause a momentary delay in the playback, and if the load is very high on the network, then communication between the client and XServer will be affected.

(c) Copyright 1994 by The MathWorks, Inc.