11% ANIMATE Create an animation
22%
3- % Helper class for creating animations. Creates a movie file or saves snapshots
4- % of a figure as individual PNG format frames numbered 0000.png, 0001.png and so
5- % on.
3+ % Helper class for creating animations as MP4, animated GIF or a folder of images.
64%
75% Example::
86%
1513%
1614% will save the frames in an MP4 movie file using VideoWriter.
1715%
18- % Alternatively::
16+ % Alternatively, to createa of images in PNG format frames named 0000.png,
17+ % 0001.png and so on in a folder called 'frames'
1918%
20- % anim = Animate('movie ');
19+ % anim = Animate('frames ');
2120% for i=1:100
2221% plot(...);
2322% anim.add();
2423% end
2524% anim.close();
2625%
2726% To convert the image files to a movie you could use a tool like ffmpeg
28- % ffmpeg -r 10 -i movie/%04d.png out.mp4
27+ % ffmpeg -r 10 -i frames/%04d.png out.mp4
28+ %
29+ % Notes::
30+ % - MP4 movies cannot be generated under Linux, a limitation of MATLAB VideoWriter.
2931%
3032
3133% Copyright (C) 1993-2019 Peter I. Corke
5658 properties
5759 frame
5860 dir
59- resolution
6061 video % video writing object
62+ opt
6163 profile
62- fps
63- bgcolor
6464 end
6565
6666 methods
6767 function a = Animate(filename , varargin )
6868 % ANIMATE.ANIMATE Create an animation class
6969 %
70- % A = ANIMATE(NAME, OPTIONS) initializes an animation, and creates
70+ % ANIM = ANIMATE(NAME, OPTIONS) initializes an animation, and creates
7171 % a movie file or a folder holding individual frames.
7272 %
73- % A = ANIMATE({NAME, OPTIONS}) as above but arguments are passed as a cell array,
73+ % ANIM = ANIMATE({NAME, OPTIONS}) as above but arguments are passed as a cell array,
7474 % which allows a single argument to a higher-level option like 'movie',M to express
7575 % options as well as filename.
7676 %
8080 % 'fps',F Frame rate (default 30)
8181 % 'bgcolor',C Set background color of axes, 3 vector or MATLAB
8282 % color name.
83+ % 'inner' inner frame of axes; no axes, labels, ticks.
8384 %
8485 % A profile can also be set by the file extension given:
8586 %
86- % none Create a folder full of frames
87+ % none Create a folder full of frames in PNG format frames named
88+ % 0000.png, 0001.png and so on
8789 % .gif Create animated GIF
8890 % .mp4 Create MP4 movie (not on Linux)
8991 % .avi Create AVI movie
9092 % .mj2 Create motion jpeg file
9193 %
9294 % Notes::
95+ % - MP4 movies cannot be generated under Linux, a limitation of MATLAB VideoWriter.
96+ % - if no extension or profile is given a folder full of frames is created.
9397 % - if a profile is given a movie is created, see VideoWriter for allowable
9498 % profiles.
95- % - if the file has an extension a movie is created .
99+ % - if the file has an extension it specifies the profile .
96100 % - if an extension of '.gif' is given an animated GIF is created
97- % - otherwise a folder full of frames is created.
101+ % - if NAME is [] then an Animation object is created but the add() and close()
102+ % methods do nothing.
98103 %
99104 % See also VideoWriter.
100105
105110 opt.resolution = [];
106111 opt.profile = [];
107112 opt.fps = 30 ;
108- bgcolor = [];
113+ opt.bgcolor = [];
114+ opt.inner = false ;
109115
110116 if iscell(filename ) && length(varargin ) == 0
111117 varargin = filename(2 : end );
112118 filename = filename{1 };
113119 end
114120 [opt ,args ] = tb_optparse(opt , varargin );
115- a.resolution = opt . resolution ;
121+ a.opt = opt ;
116122 a.frame = 0 ;
117123
118124 [p ,f ,e ] = fileparts(filename );
140146 fprintf(' Animate: saving video --> %s with profile ''%s''\n ' , filename , profile );
141147 if strcmp(profile , ' GIF' )
142148 a.video = filename ;
143- a.fps = opt .fps ;
144149 else
145150 a.video = VideoWriter(filename , profile , args{: });
146151 a.video.FrameRate = opt .fps ;
165170 function add(a , fh )
166171 % ANIMATE.ADD Adds current plot to the animation
167172 %
168- % A.ADD() adds the current figure in PNG format to the animation
169- % folder with a unique sequential filename.
173+ % A.ADD() adds the current figure to the animation.
170174 %
171175 % A.ADD(FIG) as above but captures the figure FIG.
172176 %
177+ % Notes::
178+ % - the frame is added to the output file or as a new sequentially
179+ % numbered image in a folder.
180+ % - if the filename was given as [] in the constructor then no
181+ % action is taken.
182+ %
173183 % See also print.
174184
175185 if isempty(a .dir ) && isempty(a .video )
@@ -180,30 +190,37 @@ function add(a, fh)
180190 fh = gcf ;
181191 end
182192
183- if ~isempty(a .bgcolor )
184- fh.Color = a .bgcolor ;
193+ if ~isempty(a .opt . bgcolor )
194+ fh.Color = a .opt . bgcolor ;
185195 end
186196 ax = gca ;
187197 ax.Units = ' pixels' ;
188198 switch a .profile
189199 case ' FILES'
190- if isempty(a .resolution )
200+ if isempty(a .opt . resolution )
191201 print(fh , ' -dpng' , fullfile(a .dir , sprintf(' %04d .png' , a .frame )));
192202 else
193- print(fh , ' -dpng' , sprintf(' -r%d ' , a .resolution ), fullfile(a .dir , sprintf(' %04d .png' , a .frame )));
203+ print(fh , ' -dpng' , sprintf(' -r%d ' , a .opt . resolution ), fullfile(a .dir , sprintf(' %04d .png' , a .frame )));
194204 end
195205 case ' GIF'
196- im = frame2im(getframe(fh )); % get the frame
206+ if a .opt .inner
207+ im = frame2im( getframe(fh , ax .Position ) ); % get the frame
208+ else
209+ im = frame2im(getframe(fh )); % get the frame
210+ end
197211 [A , map ] = rgb2ind(im , 256 );
198212 if a .frame == 0
199- imwrite(A , map , a .video , ' gif' , ' LoopCount' ,Inf , ' DelayTime' , 1 / a .fps );
213+ imwrite(A , map , a .video , ' gif' , ' LoopCount' ,Inf , ' DelayTime' , 1 / a .opt . fps );
200214 else
201- imwrite(A , map , a .video , ' gif' , ' WriteMode' ,' append' , ' DelayTime' , 1 / a .fps );
215+ imwrite(A , map , a .video , ' gif' , ' WriteMode' ,' append' , ' DelayTime' , 1 / a .opt . fps );
202216 end
203217 otherwise
204218
205- im = frame2im( getframe(fh , ax .Position ) ); % get the frame
206-
219+ if a .opt .inner
220+ im = frame2im( getframe(fh , ax .Position ) ); % get the frame
221+ else
222+ im = frame2im(getframe(fh )); % get the frame
223+ end
207224 % crop so that height/width are multiples of two, by default MATLAB pads
208225 % with black which gives lines at the edge
209226 w = numcols(im ); h = numrows(im );
@@ -219,8 +236,11 @@ function add(a, fh)
219236 function out = close(a )
220237 % ANIMATE.CLOSE Closes the animation
221238 %
222- % A.CLOSE() closes the video file.
239+ % A.CLOSE() ends the animation process and closes any output file.
223240 %
241+ % Notes::
242+ % - if the filename was given as [] in the constructor then no
243+ % action is taken.
224244 %
225245 if isempty(a .profile )
226246 out = [];
0 commit comments