Home > data-vis > supporting_functions > export_fig > im2gif.m

im2gif

PURPOSE ^

IM2GIF Convert a multiframe image to an animated GIF file

SYNOPSIS ^

function im2gif(A, varargin)

DESCRIPTION ^

IM2GIF Convert a multiframe image to an animated GIF file

 Examples:
   im2gif infile
   im2gif infile outfile
   im2gif(A, outfile)
   im2gif(..., '-nocrop')
   im2gif(..., '-nodither')
   im2gif(..., '-ncolors', n)
   im2gif(..., '-loops', n)
   im2gif(..., '-delay', n) 
   
 This function converts a multiframe image to an animated GIF.

 To create an animation from a series of figures, export to a multiframe
 TIFF file using export_fig, then convert to a GIF, as follows:

    for a = 2 .^ (3:6)
       peaks(a);
       export_fig test.tif -nocrop -append
    end
    im2gif('test.tif', '-delay', 0.5);

IN:
   infile - string containing the name of the input image.
   outfile - string containing the name of the output image (must have the
             .gif extension). Default: infile, with .gif extension.
   A - HxWxCxN array of input images, stacked along fourth dimension, to
       be converted to gif.
   -nocrop - option indicating that the borders of the output are not to
             be cropped.
   -nodither - option indicating that dithering is not to be used when
               converting the image.
   -ncolors - option pair, the value of which indicates the maximum number
              of colors the GIF can have. This can also be a quantization
              tolerance, between 0 and 1. Default/maximum: 256.
   -loops - option pair, the value of which gives the number of times the
            animation is to be looped. Default: 65535.
   -delay - option pair, the value of which gives the time, in seconds,
            between frames. Default: 1/15.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 %IM2GIF Convert a multiframe image to an animated GIF file
0002 %
0003 % Examples:
0004 %   im2gif infile
0005 %   im2gif infile outfile
0006 %   im2gif(A, outfile)
0007 %   im2gif(..., '-nocrop')
0008 %   im2gif(..., '-nodither')
0009 %   im2gif(..., '-ncolors', n)
0010 %   im2gif(..., '-loops', n)
0011 %   im2gif(..., '-delay', n)
0012 %
0013 % This function converts a multiframe image to an animated GIF.
0014 %
0015 % To create an animation from a series of figures, export to a multiframe
0016 % TIFF file using export_fig, then convert to a GIF, as follows:
0017 %
0018 %    for a = 2 .^ (3:6)
0019 %       peaks(a);
0020 %       export_fig test.tif -nocrop -append
0021 %    end
0022 %    im2gif('test.tif', '-delay', 0.5);
0023 %
0024 %IN:
0025 %   infile - string containing the name of the input image.
0026 %   outfile - string containing the name of the output image (must have the
0027 %             .gif extension). Default: infile, with .gif extension.
0028 %   A - HxWxCxN array of input images, stacked along fourth dimension, to
0029 %       be converted to gif.
0030 %   -nocrop - option indicating that the borders of the output are not to
0031 %             be cropped.
0032 %   -nodither - option indicating that dithering is not to be used when
0033 %               converting the image.
0034 %   -ncolors - option pair, the value of which indicates the maximum number
0035 %              of colors the GIF can have. This can also be a quantization
0036 %              tolerance, between 0 and 1. Default/maximum: 256.
0037 %   -loops - option pair, the value of which gives the number of times the
0038 %            animation is to be looped. Default: 65535.
0039 %   -delay - option pair, the value of which gives the time, in seconds,
0040 %            between frames. Default: 1/15.
0041 
0042 % Copyright (C) Oliver Woodford 2011
0043 
0044 function im2gif(A, varargin)
0045 
0046 % Parse the input arguments
0047 [A, options] = parse_args(A, varargin{:});
0048 
0049 if options.crop ~= 0
0050     % Crop
0051     A = crop_borders(A, A(ceil(end/2),1,:,1));
0052 end
0053 
0054 % Convert to indexed image
0055 [h, w, c, n] = size(A);
0056 A = reshape(permute(A, [1 2 4 3]), h, w*n, c);
0057 map = unique(reshape(A, h*w*n, c), 'rows');
0058 if size(map, 1) > 256
0059     dither_str = {'dither', 'nodither'};
0060     dither_str = dither_str{1+(options.dither==0)};
0061     if options.ncolors <= 1
0062         [B, map] = rgb2ind(A, options.ncolors, dither_str);
0063         if size(map, 1) > 256
0064             [B, map] = rgb2ind(A, 256, dither_str);
0065         end
0066     else
0067         [B, map] = rgb2ind(A, min(round(options.ncolors), 256), dither_str);
0068     end
0069 else
0070     if max(map(:)) > 1
0071         map = double(map) / 255;
0072         A = double(A) / 255;
0073     end
0074     B = rgb2ind(im2double(A), map);
0075 end
0076 B = reshape(B, h, w, 1, n);
0077 
0078 % Bug fix to rgb2ind
0079 map(B(1)+1,:) = im2double(A(1,1,:));
0080 
0081 % Save as a gif
0082 imwrite(B, map, options.outfile, 'LoopCount', round(options.loops(1)), 'DelayTime', options.delay);
0083 end
0084 
0085 %% Parse the input arguments
0086 function [A, options] = parse_args(A, varargin)
0087 % Set the defaults
0088 options = struct('outfile', '', ...
0089                  'dither', true, ...
0090                  'crop', true, ...
0091                  'ncolors', 256, ...
0092                  'loops', 65535, ...
0093                  'delay', 1/15);
0094 
0095 % Go through the arguments
0096 a = 0;
0097 n = numel(varargin);
0098 while a < n
0099     a = a + 1;
0100     if ischar(varargin{a}) && ~isempty(varargin{a})
0101         if varargin{a}(1) == '-'
0102             opt = lower(varargin{a}(2:end));
0103             switch opt
0104                 case 'nocrop'
0105                     options.crop = false;
0106                 case 'nodither'
0107                     options.dither = false;
0108                 otherwise
0109                     if ~isfield(options, opt)
0110                         error('Option %s not recognized', varargin{a});
0111                     end
0112                     a = a + 1;
0113                     if ischar(varargin{a}) && ~ischar(options.(opt))
0114                         options.(opt) = str2double(varargin{a});
0115                     else
0116                         options.(opt) = varargin{a};
0117                     end
0118             end
0119         else
0120             options.outfile = varargin{a};
0121         end
0122     end
0123 end
0124 
0125 if isempty(options.outfile)
0126     if ~ischar(A)
0127         error('No output filename given.');
0128     end
0129     % Generate the output filename from the input filename
0130     [path, outfile] = fileparts(A);
0131     options.outfile = fullfile(path, [outfile '.gif']);
0132 end
0133 
0134 if ischar(A)
0135     % Read in the image
0136     A = imread_rgb(A);
0137 end
0138 end
0139 
0140 %% Read image to uint8 rgb array
0141 function [A, alpha] = imread_rgb(name)
0142 % Get file info
0143 info = imfinfo(name);
0144 % Special case formats
0145 switch lower(info(1).Format)
0146     case 'gif'
0147         [A, map] = imread(name, 'frames', 'all');
0148         if ~isempty(map)
0149             map = uint8(map * 256 - 0.5); % Convert to uint8 for storage
0150             A = reshape(map(uint32(A)+1,:), [size(A) size(map, 2)]); % Assume indexed from 0
0151             A = permute(A, [1 2 5 4 3]);
0152         end
0153     case {'tif', 'tiff'}
0154         A = cell(numel(info), 1);
0155         for a = 1:numel(A)
0156             [A{a}, map] = imread(name, 'Index', a, 'Info', info);
0157             if ~isempty(map)
0158                 map = uint8(map * 256 - 0.5); % Convert to uint8 for storage
0159                 A{a} = reshape(map(uint32(A{a})+1,:), [size(A) size(map, 2)]); % Assume indexed from 0
0160             end
0161             if size(A{a}, 3) == 4
0162                 % TIFF in CMYK colourspace - convert to RGB
0163                 if isfloat(A{a})
0164                     A{a} = A{a} * 255;
0165                 else
0166                     A{a} = single(A{a});
0167                 end
0168                 A{a} = 255 - A{a};
0169                 A{a}(:,:,4) = A{a}(:,:,4) / 255;
0170                 A{a} = uint8(A(:,:,1:3) .* A{a}(:,:,[4 4 4]));
0171             end
0172         end
0173         A = cat(4, A{:});
0174     otherwise
0175         [A, map, alpha] = imread(name);
0176         A = A(:,:,:,1); % Keep only first frame of multi-frame files
0177         if ~isempty(map)
0178             map = uint8(map * 256 - 0.5); % Convert to uint8 for storage
0179             A = reshape(map(uint32(A)+1,:), [size(A) size(map, 2)]); % Assume indexed from 0
0180         elseif size(A, 3) == 4
0181             % Assume 4th channel is an alpha matte
0182             alpha = A(:,:,4);
0183             A = A(:,:,1:3);
0184         end
0185 end
0186 end

Generated on Tue 23-May-2017 20:00:55 by m2html © 2005