Mercurial > octave
view scripts/image/movie.m @ 26212:2be1833a93a5
movie.m: New function (patch #9363)
* NEWS: Announce new function.
* scripts/image/movie.m: New function file.
* scripts/image/module.mk: Add movie.m to build system.
* getframe.m: Add movie to seealso links.
* image.txi: Add movie DOCSTRING. Reorganize part of "Representing Images"
section.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Sun, 28 May 2017 13:42:02 +0200 |
parents | |
children | 2730917a7979 |
line wrap: on
line source
## Copyright (C) 2017 Pantxo Diribarne ## ## This file is part of Octave. ## ## Octave is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {} movie (@var{mov}) ## @deftypefnx {} {} movie (@var{mov}, @var{n}) ## @deftypefnx {} {} movie (@var{mov}, @var{n}, @var{fps}) ## @deftypefnx {} {} movie (@var{h}, @dots{}) ## Play a movie defined by an array of frame structures. ## ## The movie @var{mov} must be a struct array of frames with fields ## @qcode{"cdata"} and @qcode{"colormap"}, as returned by the @code{getframe} ## function. By default all images are displayed once, at 12 fps, in the ## current axes. ## ## The optional argument @var{n} is a scalar or vector of integers that ## controls the number of times the movie is displayed and which particular ## frames are shown: ## ## @table @asis ## @item First element: ## ## @table @asis ## @item @var{n}(1) > 0 ## Play the movie @var{n}(1) times. ## ## @item @var{n}(1) < 0 ## Play the movie @code{abs (@var{n}(1)} times alternatively in forward and ## backward order. ## @end table ## ## @item Other elements (if any): ## Indices of the frames in @var{mov} that will be displayed. ## @end table ## ## If the first argument is a handle to a figure or axes @var{h}, the movie is ## played in that figure or axes instead of the current axes. ## ## @seealso{getframe, im2frame, frame2im} ## @end deftypefn function movie (varargin) if (nargin == 0) print_usage (); endif ## Extract possible handle argument hax = []; if (isaxes (varargin{1})) hax = varargin{1}; varargin(1) = []; elseif (isfigure (varargin{1})) hax = get (varargin{1}, "currentaxes"); if (isempty (hax)) hax = axes ("parent", varargin{1}); endif varargin(1) = []; endif ## Extract other arguments n = 1; fps = 12; idx = []; nargs = numel (varargin); if (nargs == 0) print_usage (); elseif (nargs >= 1) mov = varargin{1}; if (! isfield (mov, "cdata") || ! isfield (mov, "colormap")) error ("movie: MOV must be a frame struct array"); endif if (nargs >= 2) n = varargin{2}; if (! isindex (abs (n(1)))) error ("movie: N must be a non-zero integer"); elseif (! isscalar (n)) idx = n(2:end)(:)'; n = n(1); if (! isindex (idx, numel (mov))) error (["movie: All elements N(2:end) must be valid indices ", ... "into the MOV struct array"]); endif endif if (nargs >= 3) fps = varargin{3}; if (! (isnumeric (fps) && isscalar (fps) && fps > 0)) error ("movie: FPS must be a numeric scalar > 0"); endif endif endif endif if (isempty (hax)) hax = gca (); endif ## Build the list of frames to be displayed if (isempty (idx)) idx = (1:numel (mov)); endif if (n > 0) idx = repmat (idx, 1, n); else n = -n; tmp = repmat ([idx fliplr(idx)], 1, fix (n/2)); if (fix (n/2) != n/2) idx = [tmp, idx]; else idx = tmp; endif endif tau = 1/fps; set (hax, "ydir", "reverse", "visible", "off"); tic (); him = image ("parent", hax, "cdata", mov(1).cdata); for ii = idx pause (tau - toc ()); tic (); if (! isempty (mov(ii).colormap)) set (hax, "colormap", mov(ii).colormap) endif set (him, "cdata", mov(ii).cdata); endfor endfunction %!demo %! nframes = 20; %! colors = jet (nframes); %! baseim = ones (20, 20, 3, "uint8"); %! mov(nframes) = struct ("cdata", [], "colormap", []); %! for ii = 1:nframes %! im = baseim * 255; %! im(:,ii,1) = colors(ii,1) * 255; %! im(:,ii,2) = colors(ii,2) * 255; %! im(:,ii,3) = colors(ii,3) * 255; %! mov(ii).cdata = im; %! endfor %! clf (); %! title "Play movie forward 2 times" %! movie (mov, 2); %!demo %! nframes = 20; %! colors = jet (nframes); %! baseim = ones (20, 20, 3, "uint8"); %! mov(nframes) = struct ("cdata", [], "colormap", []); %! for ii = 1:nframes %! im = baseim * 255; %! im(:,ii,1) = colors(ii,1) * 255; %! im(:,ii,2) = colors(ii,2) * 255; %! im(:,ii,3) = colors(ii,3) * 255; %! mov(ii).cdata = im; %! endfor %! clf (); %! title "Play movie forward and backward 5 times at 25 fps" %! movie (mov, -5, 25); %!demo %! nframes = 20; %! colors = jet (nframes); %! baseim = ones (20, 20, 3, "uint8"); %! mov(nframes) = struct ("cdata", [], "colormap", []); %! for ii = 1:nframes %! im = baseim * 255; %! im(:,ii,1) = colors(ii,1) * 255; %! im(:,ii,2) = colors(ii,2) * 255; %! im(:,ii,3) = colors(ii,3) * 255; %! mov(ii).cdata = im; %! endfor %! clf (); %! title "Play downsampled movie 5 times" %! movie (mov, [5 1:3:nframes]); %!demo %! clf (); %! z = sombrero (); %! hs = surf (z); %! axis manual %! nframes = 50; %! mov(nframes) = struct ("cdata", [], "colormap", []); %! for ii = 1:nframes %! set (hs, "zdata", z * sin (2*pi*ii/nframes)); %! mov(ii) = getframe (); %! endfor %! clf (); %! movie (mov, 5, 25); ## Test input validation %!error movie () %!error <MOV must be a frame struct array> movie ({2}) %!error <N must be a non-zero integer> %! movie (struct ("cdata", [], "colormap", []), 2.3); %!error <N must be a non-zero integer> %! movie (struct ("cdata", [], "colormap", []), [2.3 -6]);