1 %EXPORT_FIG Exports figures suitable
for publication
5 % [im alpha] = export_fig
7 % export_fig filename -format1 -format2
8 % export_fig ... -nocrop
9 % export_fig ... -transparent
10 % export_fig ... -native
11 % export_fig ... -m<val>
12 % export_fig ... -r<val>
13 % export_fig ... -a<val>
14 % export_fig ... -q<val>
15 % export_fig ... -<renderer>
16 % export_fig ... -<colorspace>
17 % export_fig ... -append
18 % export_fig ... -bookmark
19 % export_fig(..., handle)
21 % This
function saves a figure or single axes to one or more vector and/or
22 % bitmap file formats, and/or outputs a rasterized version to the
23 % workspace, with the following properties:
24 % - Figure/axes reproduced as it appears on screen
25 % - Cropped borders (optional)
26 % - Embedded fonts (vector formats)
27 % - Improved line and grid line styles
28 % - Anti-aliased graphics (bitmap formats)
29 % - Render images at native resolution (optional
for bitmap formats)
30 % - Transparent background supported (pdf, eps, png)
31 % - Semi-transparent patch objects supported (png only)
32 % - RGB, CMYK or grayscale output (CMYK only with pdf, eps, tiff)
33 % - Variable image compression, including lossless (pdf, eps, jpg)
34 % - Optionally append to file (pdf, tiff)
35 % - Vector formats: pdf, eps
36 % - Bitmap formats: png, tiff, jpg, bmp, export to workspace
38 % This
function is especially suited to exporting figures
for use in
39 % publications and presentations, because of the high quality and
40 % portability of media produced.
42 % Note that the background color and figure dimensions are reproduced
43 % (the latter approximately, and ignoring cropping & magnification) in the
44 % output file. For transparent background (and semi-transparent patch
45 % objects), use the -transparent option or
set the figure
'Color' property 46 % to
'none'. To make axes transparent
set the axes
'Color' property to
47 %
'none'. Pdf, eps and png are the only file formats to support a
48 % transparent background, whilst the png format alone supports transparency
51 % The choice of renderer (opengl, zbuffer or painters) has a large impact
52 % on the quality of output. Whilst the
default value (opengl
for bitmaps,
53 % painters
for vector formats) generally gives good results,
if you aren
't 54 % satisfied then try another renderer. Notes: 1) For vector formats (eps, 55 % pdf), only painters generates vector graphics. 2) For bitmaps, only 56 % opengl can render transparent patch objects correctly. 3) For bitmaps, 57 % only painters will correctly scale line dash and dot lengths when 58 % magnifying or anti-aliasing. 4) Fonts may be substitued with Courier when 61 % When exporting to vector format (pdf & eps) and bitmap format using the 62 % painters renderer, this function requires that ghostscript is installed 63 % on your system. You can download this from: 64 % http://www.ghostscript.com 65 % When exporting to eps it additionally requires pdftops, from the Xpdf 66 % suite of functions. You can download this from: 67 % http://www.foolabs.com/xpdf 70 % filename - string containing the name (optionally including full or 71 % relative path) of the file the figure is to be saved as. If 72 % a path is not specified, the figure is saved in the current 73 % directory. If no name and no output arguments are specified, 74 % the default name, 'export_fig_out
', is used. If neither a 75 % file extension nor a format are specified, a ".png" is added 76 % and the figure saved in that format. 77 % -format1, -format2, etc. - strings containing the extensions of the 78 % file formats the figure is to be saved as. 79 % Valid options are: '-pdf
', '-eps
', '-png
', 80 % '-tif
', '-jpg
' and '-bmp
'. All combinations 81 % of formats are valid. 82 % -nocrop - option indicating that the borders of the output are not to 84 % -transparent - option indicating that the figure background is to be 85 % made transparent (png, pdf and eps output only). 86 % -m<val> - option where val indicates the factor to magnify the 87 % on-screen figure pixel dimensions by when generating bitmap 88 % outputs. Default: '-m1
'. 89 % -r<val> - option val indicates the resolution (in pixels per inch) to 90 % export bitmap and vector outputs at, keeping the dimensions 91 % of the on-screen figure. Default: '-r864
' (for vector output 92 % only). Note that the -m option overides the -r option for 93 % bitmap outputs only. 94 % -native - option indicating that the output resolution (when outputting 95 % a bitmap format) should be such that the vertical resolution 96 % of the first suitable image found in the figure is at the 97 % native resolution of that image. To specify a particular 98 % image to use, give it the tag 'export_fig_native
'. Notes: 99 % This overrides any value set with the -m and -r options. It 100 % also assumes that the image is displayed front-to-parallel 101 % with the screen. The output resolution is approximate and 102 % should not be relied upon. Anti-aliasing can have adverse 103 % effects on image quality (disable with the -a1 option). 104 % -a1, -a2, -a3, -a4 - option indicating the amount of anti-aliasing to 105 % use for bitmap outputs. '-a1
' means no anti- 106 % aliasing; '-a4
' is the maximum amount (default). 107 % -<renderer> - option to force a particular renderer (painters, opengl 108 % or zbuffer) to be used over the default: opengl for 109 % bitmaps; painters for vector formats. 110 % -<colorspace> - option indicating which colorspace color figures should 111 % be saved in: RGB (default), CMYK or gray. CMYK is only 112 % supported in pdf, eps and tiff output. 113 % -q<val> - option to vary bitmap image quality (in pdf, eps and jpg 114 % files only). Larger val, in the range 0-100, gives higher 115 % quality/lower compression. val > 100 gives lossless 116 % compression. Default: '-q95
' for jpg, ghostscript prepress 117 % default for pdf & eps. Note: lossless compression can 118 % sometimes give a smaller file size than the default lossy 119 % compression, depending on the type of images. 120 % -append - option indicating that if the file (pdfs only) already 121 % exists, the figure is to be appended as a new page, instead 122 % of being overwritten (default). 123 % -bookmark - option to indicate that a bookmark with the name of the 124 % figure is to be created in the output file (pdf only). 125 % handle - The handle of the figure, axes or uipanels (can be an array of 126 % handles, but the objects must be in the same figure) to be 127 % saved. Default: gcf. 130 % im - MxNxC uint8 image array of the figure. 131 % alpha - MxN single array of alphamatte values in range [0,1], for the 132 % case when the background is transparent. 134 % Some helpful examples and tips can be found at: 135 % http://sites.google.com/site/oliverwoodford/software/export_fig 137 % See also PRINT, SAVEAS. 139 % Copyright (C) Oliver Woodford 2008-2014 141 % The idea of using ghostscript is inspired by Peder Axensten's SAVEFIG
142 % (fex
id: 10889) which is itself inspired by EPS2PDF (fex
id: 5782).
143 % The idea
for using pdftops came from the MATLAB newsgroup (
id: 168171).
144 % The idea of editing the EPS file to change line styles comes from Jiro
145 % Doke
's FIXPSLINESTYLE (fex id: 17928). 146 % The idea of changing dash length with line width came from comments on 147 % fex id: 5743, but the implementation is mine :) 148 % The idea of anti-aliasing bitmaps came from Anders Brun's MYAA (fex
id:
150 % The idea of appending figures in pdfs came from Matt C in comments on the
153 % Thanks to Roland Martin
for pointing out the colour MATLAB
154 % bug/feature with colorbar axes and transparent backgrounds.
155 % Thanks also to Andrew Matthews
for describing a bug to
do with the figure
156 % size changing in -nodisplay mode. I couldn
't reproduce it, but included a 158 % Thanks to Tammy Threadgill for reporting a bug where an axes is not 159 % isolated from gui objects. 161 % 23/02/12: Ensure that axes limits don't change during printing
162 % 14/03/12: Fix bug in fixing the axes limits (thanks to Tobias Lamour
for 164 % 02/05/12: Incorporate patch of Petr Nechaev (many thanks), enabling
165 % bookmarking of figures in pdf files.
166 % 09/05/12: Incorporate patch of Arcelia Arrieta (many thanks), to keep
168 % 12/12/12: Add support
for isolating uipanels. Thanks to michael
for 170 % 25/09/13: Add support
for changing resolution in vector formats. Thanks
171 % to Jan Jaap Meijer
for suggesting it.
172 % 07/05/14: Add support
for '~' at start of path. Thanks to Sally Warner
175 function [im, alpha] = export_fig(varargin)
176 % Make sure the figure is rendered correctly _now_ so that properties like
177 % axes limits are up-to-date.
179 % Parse the input arguments
180 [fig, options] = parse_args(nargout, varargin{:});
181 % Isolate the subplot,
if it is one
182 cls = all(ismember(
get(fig,
'Type'), {
'axes',
'uipanel'}));
184 % Given handles of one or more axes, so isolate them from the rest
185 fig = isolate_axes(fig);
187 % Check we have a figure
188 if ~isequal(
get(fig,
'Type'),
'figure');
189 error(
'Handle must be that of a figure, axes or uipanel');
191 % Get the old InvertHardcopy mode
192 old_mode =
get(fig,
'InvertHardcopy');
194 % Hack the font units where necessary (due to a font rendering bug in
195 % print?). This may not work perfectly in all cases. Also it can change the
196 % figure layout
if reverted, so use a copy.
197 magnify = options.magnify * options.aa_factor;
198 if isbitmap(options) && magnify ~= 1
199 fontu = findobj(fig,
'FontUnits',
'normalized');
201 % Some normalized font units found
204 set(fig,
'Visible',
'off');
205 fontu = findobj(fig,
'FontUnits',
'normalized');
208 set(fontu,
'FontUnits',
'points');
211 % MATLAB
"feature": axes limits and tick marks can change when printing
212 Hlims = findall(fig,
'Type',
'axes');
214 % Record the old axes limit and tick modes
215 Xlims = make_cell(
get(Hlims,
'XLimMode'));
216 Ylims = make_cell(
get(Hlims,
'YLimMode'));
217 Zlims = make_cell(
get(Hlims,
'ZLimMode'));
218 Xtick = make_cell(
get(Hlims,
'XTickMode'));
219 Ytick = make_cell(
get(Hlims,
'YTickMode'));
220 Ztick = make_cell(
get(Hlims,
'ZTickMode'));
222 % Set all axes limit and tick modes to manual, so the limits and ticks can
't change 223 set(Hlims, 'XLimMode
', 'manual
', 'YLimMode
', 'manual
', 'ZLimMode
', 'manual
', 'XTickMode
', 'manual
', 'YTickMode
', 'manual
', 'ZTickMode
', 'manual
'); 224 % Set to print exactly what is there 225 set(fig, 'InvertHardcopy
', 'off
'); 227 switch options.renderer 229 renderer = '-opengl
'; 231 renderer = '-zbuffer
'; 233 renderer = '-painters
'; 235 renderer = '-opengl
'; % Default for bitmaps 237 % Do the bitmap formats first 239 % Get the background colour 240 if options.transparent && (options.png || options.alpha) 241 % Get out an alpha channel 242 % MATLAB "feature": black colorbar axes can change to white and vice versa! 243 hCB = findobj(fig, 'Type
', 'axes
', 'Tag
', 'Colorbar
'); 248 yCol = get(hCB, 'YColor
'); 249 xCol = get(hCB, 'XColor
'); 251 yCol = cell2mat(yCol); 252 xCol = cell2mat(xCol); 257 % MATLAB "feature": apparently figure size can change when changing 258 % colour in -nodisplay mode 259 pos = get(fig, 'Position
'); 260 % Set the background colour to black, and set size in case it was 262 tcol = get(fig, 'Color
'); 263 set(fig, 'Color
', 'k
', 'Position
', pos); 264 % Correct the colorbar axes colours 265 set(hCB(yCol==0), 'YColor
', [0 0 0]); 266 set(hCB(xCol==0), 'XColor
', [0 0 0]); 267 % Print large version to array 268 B = print2array(fig, magnify, renderer); 269 % Downscale the image 270 B = downsize(single(B), options.aa_factor); 271 % Set background to white (and set size) 272 set(fig, 'Color
', 'w
', 'Position
', pos); 273 % Correct the colorbar axes colours 274 set(hCB(yCol==3), 'YColor
', [1 1 1]); 275 set(hCB(xCol==3), 'XColor
', [1 1 1]); 276 % Print large version to array 277 A = print2array(fig, magnify, renderer); 278 % Downscale the image 279 A = downsize(single(A), options.aa_factor); 280 % Set the background colour (and size) back to normal 281 set(fig, 'Color
', tcol, 'Position
', pos); 282 % Compute the alpha map 283 alpha = round(sum(B - A, 3)) / (255 * 3) + 1; 286 A = B ./ A(:,:,[1 1 1]); 288 % Convert to greyscale 289 if options.colourspace == 2 293 % Crop the background 295 [alpha, v] = crop_background(alpha, 0); 296 A = A(v(1):v(2),v(3):v(4),:); 299 % Compute the resolution 300 res = options.magnify * get(0, 'ScreenPixelsPerInch
') / 25.4e-3; 302 imwrite(A, [options.name '.png
'], 'Alpha
', double(alpha), 'ResolutionUnit
', 'meter
', 'XResolution
', res, 'YResolution
', res); 306 % Return only one channel for greyscale 308 A = check_greyscale(A); 313 % Clear the alpha bit 314 options.alpha = false; 316 % Get the non-alpha image 318 alph = alpha(:,:,ones(1, size(A, 3))); 319 A = uint8(single(A) .* alph + 255 * (1 - alph)); 323 % Store the new image 327 % Print large version to array 328 if options.transparent 329 % MATLAB "feature": apparently figure size can change when changing 330 % colour in -nodisplay mode 331 pos = get(fig, 'Position
'); 332 tcol = get(fig, 'Color
'); 333 set(fig, 'Color
', 'w
', 'Position
', pos); 334 A = print2array(fig, magnify, renderer); 335 set(fig, 'Color
', tcol, 'Position
', pos); 338 [A, tcol] = print2array(fig, magnify, renderer); 340 % Crop the background 342 A = crop_background(A, tcol); 344 % Downscale the image 345 A = downsize(A, options.aa_factor); 346 if options.colourspace == 2 347 % Convert to greyscale 350 % Return only one channel for greyscale 351 A = check_greyscale(A); 359 alpha = zeros(size(A, 1), size(A, 2), 'single
'); 364 res = options.magnify * get(0, 'ScreenPixelsPerInch
') / 25.4e-3; 365 imwrite(A, [options.name '.png
'], 'ResolutionUnit
', 'meter
', 'XResolution
', res, 'YResolution
', res); 368 imwrite(A, [options.name '.bmp
']); 370 % Save jpeg with given quality 372 quality = options.quality; 377 imwrite(A, [options.name '.jpg
'], 'Mode
', 'lossless
'); 379 imwrite(A, [options.name '.jpg
'], 'Quality
', quality); 382 % Save tif images in cmyk if wanted (and possible) 384 if options.colourspace == 1 && size(A, 3) == 3 387 K_ = 255 ./ max(255 - K, 1); 388 C = (A(:,:,1) - K) .* K_; 389 M = (A(:,:,2) - K) .* K_; 390 Y = (A(:,:,3) - K) .* K_; 391 A = uint8(cat(3, C, M, Y, K)); 394 append_mode = {'overwrite
', 'append
'}; 395 imwrite(A, [options.name '.tif
'], 'Resolution
', options.magnify*get(0, 'ScreenPixelsPerInch
'), 'WriteMode
', append_mode{options.append+1}); 398 % Now do the vector formats 400 % Set the default renderer to painters 402 renderer = '-painters
'; 404 % Generate some filenames 405 tmp_nam = [tempname '.eps
']; 407 pdf_nam = [options.name '.pdf
']; 409 pdf_nam = [tempname '.pdf
']; 411 % Generate the options for print 412 p2eArgs = {renderer, sprintf('-r%d
', options.resolution)}; 413 if options.colourspace == 1 414 p2eArgs = [p2eArgs {'-cmyk
'}]; 417 p2eArgs = [p2eArgs {'-loose
'}]; 421 print2eps(tmp_nam, fig, p2eArgs{:}); 422 % Remove the background, if desired 423 if options.transparent && ~isequal(get(fig, 'Color
'), 'none
') 424 eps_remove_background(tmp_nam, 1 + using_hg2(fig)); 426 % Add a bookmark to the PDF if desired 428 fig_nam = get(fig, 'Name
'); 430 warning('export_fig:EmptyBookmark
', 'Bookmark requested
for figure with no name. Bookmark will be empty.
'); 432 add_bookmark(tmp_nam, fig_nam); 435 eps2pdf(tmp_nam, pdf_nam, 1, options.append, options.colourspace==2, options.quality); 445 % Generate an eps from the pdf 446 pdf2eps(pdf_nam, [options.name '.eps
']); 461 % Close the created figure 464 % Reset the hardcopy mode 465 set(fig, 'InvertHardcopy
', old_mode); 466 % Reset the axes limit and tick modes 467 for a = 1:numel(Hlims) 468 set(Hlims(a), 'XLimMode
', Xlims{a}, 'YLimMode
', Ylims{a}, 'ZLimMode
', Zlims{a}, 'XTickMode
', Xtick{a}, 'YTickMode
', Ytick{a}, 'ZTickMode
', Ztick{a}); 473 function [fig, options] = parse_args(nout, varargin) 474 % Parse the input arguments 476 fig = get(0, 'CurrentFigure
'); 477 options = struct('name
', 'export_fig_out
', ... 479 'transparent
', false, ... 480 'renderer
', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters 487 'colourspace
', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray 490 'alpha
', nout == 2, ... 493 'resolution
', [], ... 494 'bookmark
', false, ... 496 native = false; % Set resolution to native of an image 498 % Go through the other arguments 500 if all(ishandle(varargin{a})) 502 elseif ischar(varargin{a}) && ~isempty(varargin{a}) 503 if varargin{a}(1) == '-
' 504 switch lower(varargin{a}(2:end)) 506 options.crop = false; 507 case {'trans
', 'transparent
'} 508 options.transparent = true; 510 options.renderer = 1; 512 options.renderer = 2; 514 options.renderer = 3; 528 options.colourspace = 0; 530 options.colourspace = 1; 531 case {'gray
', 'grey
'} 532 options.colourspace = 2; 533 case {'a1
', 'a2
', 'a3
', 'a4
'} 534 options.aa_factor = str2double(varargin{a}(3)); 536 options.append = true; 538 options.bookmark = true; 542 val = str2double(regexp(varargin{a}, '(?<=-(m|M|r|R|q|Q))(\d*\.)?\d+(e-?\d+)?
', 'match
')); 544 error('option %s not recognised
', varargin{a}); 546 switch lower(varargin{a}(2)) 548 options.magnify = val; 550 options.resolution = val; 552 options.quality = max(val, 0); 556 [p, options.name, ext] = fileparts(varargin{a}); 558 options.name = [p filesep options.name]; 561 case {'.tif
', '.tiff
'} 563 case {'.jpg
', '.jpeg
'} 574 options.name = varargin{a}; 580 % Set default anti-aliasing now we know the renderer 581 if options.aa_factor == 0 582 options.aa_factor = 1 + 2 * (~using_hg2(fig) | (options.renderer == 3)); 585 % Convert user dir '~
' to full path 586 if numel(options.name) > 2 && options.name(1) == '~
' && (options.name(2) == '/
' || options.name(2) == '\
') 587 options.name = fullfile(char(java.lang.System.getProperty('user.home
')), options.name(2:end)); 590 % Compute the magnification and resolution 591 if isempty(options.magnify) 592 if isempty(options.resolution) 594 options.resolution = 864; 596 options.magnify = options.resolution ./ get(0, 'ScreenPixelsPerInch
'); 598 elseif isempty(options.resolution) 599 options.resolution = 864; 602 % Check we have a figure handle 604 error('No figure found
'); 607 % Set the default format 608 if ~isvector(options) && ~isbitmap(options) 612 % Check whether transparent background is wanted (old way) 613 if isequal(get(ancestor(fig(1), 'figure
'), 'Color
'), 'none
') 614 options.transparent = true; 617 % If requested, set the resolution to the native vertical resolution of the 618 % first suitable image found 619 if native && isbitmap(options) 620 % Find a suitable image 621 list = findobj(fig, 'Type
', 'image
', 'Tag
', 'export_fig_native
'); 623 list = findobj(fig, 'Type
', 'image
', 'Visible
', 'on
'); 626 % Check height is >= 2
627 height = size(
get(hIm,
'CData'), 1);
631 % Account
for the image filling only part of the axes, or vice
633 yl =
get(hIm,
'YData');
635 yl = [yl(1)-0.5 yl(1)+height+0.5];
640 yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1));
642 hAx = get(hIm, 'Parent');
643 yl2 = get(hAx, 'YLim');
644 % Find the pixel height of the axes
645 oldUnits = get(hAx, 'Units');
646 set(hAx, 'Units', 'pixels');
647 pos = get(hAx, 'Position');
648 set(hAx, 'Units', oldUnits);
652 % Found a suitable image
653 % Account for stretch-to-fill being disabled
654 pbar = get(hAx, 'PlotBoxAspectRatio');
655 pos = min(pos(4), pbar(2)*pos(3)/pbar(1));
656 % Set the magnification to give native resolution
657 options.magnify = (height * diff(yl2)) / (pos * diff(yl));
663 function A = downsize(A, factor)
664 % Downsample an image
670 % Faster, but requires image processing toolbox
671 A = imresize(A, 1/factor, 'bilinear');
673 % No image processing toolbox - resize manually
674 % Lowpass filter - use Gaussian as is separable, so faster
675 % Compute the 1d Gaussian filter
676 filt = (-factor-1:factor+1) / (factor * 0.6);
677 filt = exp(-filt .* filt);
678 % Normalize the filter
679 filt = single(filt / sum(filt));
681 padding = floor(numel(filt) / 2);
683 A(:,:,a) = conv2(filt, filt', single(A([ones(1, padding) 1:end repmat(end, 1, padding)],[ones(1, padding) 1:end repmat(end, 1, padding)],a)), 'valid');
686 A = A(1+floor(mod(end-1, factor)/2):factor:end,1+floor(mod(end-1, factor)/2):factor:end,:);
690 function A = rgb2grey(A)
691 A = cast(reshape(reshape(single(A), [], 3) * single([0.299; 0.587; 0.114]), size(A, 1), size(A, 2)), class(A));
694 function A = check_greyscale(A)
695 % Check if the image is greyscale
696 if size(A, 3) == 3 && ...
697 all(reshape(A(:,:,1) == A(:,:,2), [], 1)) && ...
698 all(reshape(A(:,:,2) == A(:,:,3), [], 1))
699 A = A(:,:,1); % Save only one channel for 8-bit output
703 function [A, v] = crop_background(A, bcol)
704 % Map the foreground pixels
706 if isscalar(bcol) && c > 1
707 bcol = bcol(ones(1, c));
712 if ~all(A(:,l,a) == bcol(a))
724 if ~all(A(:,r,a) == bcol(a))
736 if ~all(A(t,:,a) == bcol(a))
748 if ~all(A(b,:,a) == bcol(a))
757 % Crop the background, leaving one boundary pixel to avoid bleeding on
759 v = [max(t-1, 1) min(b+1, h) max(l-1, 1) min(r+1, w)];
760 A = A(v(1):v(2),v(3):v(4),:);
763 function eps_remove_background(fname, count)
764 % Remove the background of an eps file
766 fh = fopen(fname, 'r+');
768 error('Not able to open file %s.', fname);
770 % Read the file line by line
775 break; % Quit, no rectangle found
777 % Check if the line contains the background rectangle
778 if isequal(regexp(l, ' *0 +0 +\d+ +\d+ +r[fe] *[\n\r]+', 'start'), 1)
779 % Set the line to whitespace and quit
780 l(1:regexp(l, '[\n\r]', 'start', 'once')-1) = ' ';
781 fseek(fh, -numel(l), 0);
791 function b = isvector(options)
792 b = options.pdf || options.eps;
795 function b = isbitmap(options)
796 b = options.png || options.tif || options.jpg || options.bmp || options.im || options.alpha;
800 function A = make_cell(A)
806 function add_bookmark(fname, bookmark_text)
807 % Adds a bookmark to the temporary EPS file after %%EndPageSetup
809 fh = fopen(fname,
'r');
811 error(
'File %s not found.', fname);
814 fstrm = fread(fh,
'*char')
'; 821 % Include standard pdfmark prolog to maximize compatibility 822 fstrm = strrep(fstrm, '%%BeginProlog
', sprintf('%%%%BeginProlog\n/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
')); 824 fstrm = strrep(fstrm, '%%EndPageSetup
', sprintf('%%%%EndPageSetup\n[ /Title (%s) /OUT pdfmark
',bookmark_text)); 826 % Write out the updated file 827 fh = fopen(fname, 'w
'); 829 error('Unable to open %s
for writing.
', fname); 832 fwrite(fh, fstrm, 'char*1
');