source: issm/trunk-jpl/externalpackages/export_fig/export_fig.m@ 19571

Last change on this file since 19571 was 19571, checked in by Mathieu Morlighem, 10 years ago

CHG: new version of export_fig

File size: 54.8 KB
Line 
1function [imageData, alpha] = export_fig(varargin)
2%EXPORT_FIG Exports figures in a publication-quality format
3%
4% Examples:
5% imageData = export_fig
6% [imageData, alpha] = export_fig
7% export_fig filename
8% export_fig filename -format1 -format2
9% export_fig ... -nocrop
10% export_fig ... -transparent
11% export_fig ... -native
12% export_fig ... -m<val>
13% export_fig ... -r<val>
14% export_fig ... -a<val>
15% export_fig ... -q<val>
16% export_fig ... -p<val>
17% export_fig ... -d<gs_option>
18% export_fig ... -depsc
19% export_fig ... -<renderer>
20% export_fig ... -<colorspace>
21% export_fig ... -append
22% export_fig ... -bookmark
23% export_fig ... -clipboard
24% export_fig ... -update
25% export_fig ... -nofontswap
26% export_fig(..., handle)
27%
28% This function saves a figure or single axes to one or more vector and/or
29% bitmap file formats, and/or outputs a rasterized version to the workspace,
30% with the following properties:
31% - Figure/axes reproduced as it appears on screen
32% - Cropped borders (optional)
33% - Embedded fonts (vector formats)
34% - Improved line and grid line styles
35% - Anti-aliased graphics (bitmap formats)
36% - Render images at native resolution (optional for bitmap formats)
37% - Transparent background supported (pdf, eps, png)
38% - Semi-transparent patch objects supported (png only)
39% - RGB, CMYK or grayscale output (CMYK only with pdf, eps, tiff)
40% - Variable image compression, including lossless (pdf, eps, jpg)
41% - Optionally append to file (pdf, tiff)
42% - Vector formats: pdf, eps
43% - Bitmap formats: png, tiff, jpg, bmp, export to workspace
44%
45% This function is especially suited to exporting figures for use in
46% publications and presentations, because of the high quality and
47% portability of media produced.
48%
49% Note that the background color and figure dimensions are reproduced
50% (the latter approximately, and ignoring cropping & magnification) in the
51% output file. For transparent background (and semi-transparent patch
52% objects), use the -transparent option or set the figure 'Color' property
53% to 'none'. To make axes transparent set the axes 'Color' property to
54% 'none'. PDF, EPS and PNG are the only formats that support a transparent
55% background, while only PNG format supports transparency of patch objects.
56%
57% The choice of renderer (opengl, zbuffer or painters) has a large impact
58% on the quality of output. The default value (opengl for bitmaps, painters
59% for vector formats) generally gives good results, but if you aren't
60% satisfied then try another renderer. Notes: 1) For vector formats (EPS,
61% PDF), only painters generates vector graphics. 2) For bitmaps, only
62% opengl can render transparent patch objects correctly. 3) For bitmaps,
63% only painters will correctly scale line dash and dot lengths when
64% magnifying or anti-aliasing. 4) Fonts may be substitued with Courier when
65% using painters.
66%
67% When exporting to vector format (PDF & EPS) and bitmap format using the
68% painters renderer, this function requires that ghostscript is installed
69% on your system. You can download this from:
70% http://www.ghostscript.com
71% When exporting to eps it additionally requires pdftops, from the Xpdf
72% suite of functions. You can download this from:
73% http://www.foolabs.com/xpdf
74%
75% Inputs:
76% filename - string containing the name (optionally including full or
77% relative path) of the file the figure is to be saved as. If
78% a path is not specified, the figure is saved in the current
79% directory. If no name and no output arguments are specified,
80% the default name, 'export_fig_out', is used. If neither a
81% file extension nor a format are specified, a ".png" is added
82% and the figure saved in that format.
83% -format1, -format2, etc. - strings containing the extensions of the
84% file formats the figure is to be saved as.
85% Valid options are: '-pdf', '-eps', '-png',
86% '-tif', '-jpg' and '-bmp'. All combinations
87% of formats are valid.
88% -nocrop - option indicating that the borders of the output are not to
89% be cropped.
90% -transparent - option indicating that the figure background is to be
91% made transparent (png, pdf and eps output only).
92% -m<val> - option where val indicates the factor to magnify the
93% on-screen figure pixel dimensions by when generating bitmap
94% outputs (does not affect vector formats). Default: '-m1'.
95% -r<val> - option val indicates the resolution (in pixels per inch) to
96% export bitmap and vector outputs at, keeping the dimensions
97% of the on-screen figure. Default: '-r864' (for vector output
98% only). Note that the -m option overides the -r option for
99% bitmap outputs only.
100% -native - option indicating that the output resolution (when outputting
101% a bitmap format) should be such that the vertical resolution
102% of the first suitable image found in the figure is at the
103% native resolution of that image. To specify a particular
104% image to use, give it the tag 'export_fig_native'. Notes:
105% This overrides any value set with the -m and -r options. It
106% also assumes that the image is displayed front-to-parallel
107% with the screen. The output resolution is approximate and
108% should not be relied upon. Anti-aliasing can have adverse
109% effects on image quality (disable with the -a1 option).
110% -a1, -a2, -a3, -a4 - option indicating the amount of anti-aliasing to
111% use for bitmap outputs. '-a1' means no anti-
112% aliasing; '-a4' is the maximum amount (default).
113% -<renderer> - option to force a particular renderer (painters, opengl or
114% zbuffer). Default value: opengl for bitmap formats or
115% figures with patches and/or transparent annotations;
116% painters for vector formats without patches/transparencies.
117% -<colorspace> - option indicating which colorspace color figures should
118% be saved in: RGB (default), CMYK or gray. CMYK is only
119% supported in pdf, eps and tiff output.
120% -q<val> - option to vary bitmap image quality (in pdf, eps and jpg
121% files only). Larger val, in the range 0-100, gives higher
122% quality/lower compression. val > 100 gives lossless
123% compression. Default: '-q95' for jpg, ghostscript prepress
124% default for pdf & eps. Note: lossless compression can
125% sometimes give a smaller file size than the default lossy
126% compression, depending on the type of images.
127% -p<val> - option to pad a border of width val to exported files, where
128% val is either a relative size with respect to cropped image
129% size (i.e. p=0.01 adds a 1% border). For EPS & PDF formats,
130% val can also be integer in units of 1/72" points (abs(val)>1).
131% val can be positive (padding) or negative (extra cropping).
132% If used, the -nocrop flag will be ignored, i.e. the image will
133% always be cropped and then padded. Default: 0 (i.e. no padding).
134% -append - option indicating that if the file (pdfs only) already
135% exists, the figure is to be appended as a new page, instead
136% of being overwritten (default).
137% -bookmark - option to indicate that a bookmark with the name of the
138% figure is to be created in the output file (pdf only).
139% -clipboard - option to save output as an image on the system clipboard.
140% Note: background transparency is not preserved in clipboard
141% -d<gs_option> - option to indicate a ghostscript setting. For example,
142% -dMaxBitmap=0 or -dNoOutputFonts (Ghostscript 9.15+).
143% -depsc - option to use EPS level-3 rather than the default level-2 print
144% device. This solves some bugs with Matlab's default -depsc2 device
145% such as discolored subplot lines on images (vector formats only).
146% -update - option to download and install the latest version of export_fig
147% -nofontswap - option to avoid font swapping. Font swapping is automatically
148% done in vector formats (only): 11 standard Matlab fonts are
149% replaced by the original figure fonts. This option prevents this.
150% handle - The handle of the figure, axes or uipanels (can be an array of
151% handles, but the objects must be in the same figure) to be
152% saved. Default: gcf.
153%
154% Outputs:
155% imageData - MxNxC uint8 image array of the exported image.
156% alpha - MxN single array of alphamatte values in the range [0,1],
157% for the case when the background is transparent.
158%
159% Some helpful examples and tips can be found at:
160% https://github.com/altmany/export_fig
161%
162% See also PRINT, SAVEAS, ScreenCapture (on the Matlab File Exchange)
163
164%{
165% Copyright (C) Oliver Woodford 2008-2014, Yair Altman 2015-
166
167% The idea of using ghostscript is inspired by Peder Axensten's SAVEFIG
168% (fex id: 10889) which is itself inspired by EPS2PDF (fex id: 5782).
169% The idea for using pdftops came from the MATLAB newsgroup (id: 168171).
170% The idea of editing the EPS file to change line styles comes from Jiro
171% Doke's FIXPSLINESTYLE (fex id: 17928).
172% The idea of changing dash length with line width came from comments on
173% fex id: 5743, but the implementation is mine :)
174% The idea of anti-aliasing bitmaps came from Anders Brun's MYAA (fex id:
175% 20979).
176% The idea of appending figures in pdfs came from Matt C in comments on the
177% FEX (id: 23629)
178
179% Thanks to Roland Martin for pointing out the colour MATLAB
180% bug/feature with colorbar axes and transparent backgrounds.
181% Thanks also to Andrew Matthews for describing a bug to do with the figure
182% size changing in -nodisplay mode. I couldn't reproduce it, but included a
183% fix anyway.
184% Thanks to Tammy Threadgill for reporting a bug where an axes is not
185% isolated from gui objects.
186%}
187%{
188% 23/02/12: Ensure that axes limits don't change during printing
189% 14/03/12: Fix bug in fixing the axes limits (thanks to Tobias Lamour for reporting it).
190% 02/05/12: Incorporate patch of Petr Nechaev (many thanks), enabling bookmarking of figures in pdf files.
191% 09/05/12: Incorporate patch of Arcelia Arrieta (many thanks), to keep tick marks fixed.
192% 12/12/12: Add support for isolating uipanels. Thanks to michael for suggesting it.
193% 25/09/13: Add support for changing resolution in vector formats. Thanks to Jan Jaap Meijer for suggesting it.
194% 07/05/14: Add support for '~' at start of path. Thanks to Sally Warner for suggesting it.
195% 24/02/15: Fix Matlab R2014b bug (issue #34): plot markers are not displayed when ZLimMode='manual'
196% 25/02/15: Fix issue #4 (using HG2 on R2014a and earlier)
197% 25/02/15: Fix issue #21 (bold TeX axes labels/titles in R2014b)
198% 26/02/15: If temp dir is not writable, use the user-specified folder for temporary EPS/PDF files (Javier Paredes)
199% 27/02/15: Modified repository URL from github.com/ojwoodford to /altmany
200% Indented main function
201% Added top-level try-catch block to display useful workarounds
202% 28/02/15: Enable users to specify optional ghostscript options (issue #36)
203% 06/03/15: Improved image padding & cropping thanks to Oscar Hartogensis
204% 26/03/15: Fixed issue #49 (bug with transparent grayscale images); fixed out-of-memory issue
205% 26/03/15: Fixed issue #42: non-normalized annotations on HG1
206% 26/03/15: Fixed issue #46: Ghostscript crash if figure units <> pixels
207% 27/03/15: Fixed issue #39: bad export of transparent annotations/patches
208% 28/03/15: Fixed issue #50: error on some Matlab versions with the fix for issue #42
209% 29/03/15: Fixed issue #33: bugs in Matlab's print() function with -cmyk
210% 29/03/15: Improved processing of input args (accept space between param name & value, related to issue #51)
211% 30/03/15: When exporting *.fig files, then saveas *.fig if figure is open, otherwise export the specified fig file
212% 30/03/15: Fixed edge case bug introduced yesterday (commit #ae1755bd2e11dc4e99b95a7681f6e211b3fa9358)
213% 09/04/15: Consolidated header comment sections; initialize output vars only if requested (nargout>0)
214% 14/04/15: Workaround for issue #45: lines in image subplots are exported in invalid color
215% 15/04/15: Fixed edge-case in parsing input parameters; fixed help section to show the -depsc option (issue #45)
216% 21/04/15: Bug fix: Ghostscript croaks on % chars in output PDF file (reported by Sven on FEX page, 15-Jul-2014)
217% 22/04/15: Bug fix: Pdftops croaks on relative paths (reported by Tintin Milou on FEX page, 19-Jan-2015)
218% 04/05/15: Merged fix #63 (Kevin Mattheus Moerman): prevent tick-label changes during export
219% 07/05/15: Partial fix for issue #65: PDF export used painters rather than opengl renderer (thanks Nguyenr)
220% 08/05/15: Fixed issue #65: bad PDF append since commit #e9f3cdf 21/04/15 (thanks Robert Nguyen)
221% 12/05/15: Fixed issue #67: exponent labels cropped in export, since fix #63 (04/05/15)
222% 28/05/15: Fixed issue #69: set non-bold label font only if the string contains symbols (\beta etc.), followup to issue #21
223% 29/05/15: Added informative error message in case user requested SVG output (issue #72)
224% 09/06/15: Fixed issue #58: -transparent removed anti-aliasing when exporting to PNG
225% 19/06/15: Added -update option to download and install the latest version of export_fig
226% 07/07/15: Added -nofontswap option to avoid font-swapping in EPS/PDF
227% 16/07/15: Fixed problem with anti-aliasing on old Matlab releases
228% 11/09/15: Fixed issue #103: magnification must never become negative; also fixed reported error msg in parsing input params
229%}
230
231 if nargout
232 [imageData, alpha] = deal([]);
233 end
234 hadError = false;
235 displaySuggestedWorkarounds = true;
236
237 % Ensure the figure is rendered correctly _now_ so that properties like axes limits are up-to-date
238 drawnow;
239 pause(0.05); % this solves timing issues with Java Swing's EDT (http://undocumentedmatlab.com/blog/solving-a-matlab-hang-problem)
240
241 % Parse the input arguments
242 fig = get(0, 'CurrentFigure');
243 [fig, options] = parse_args(nargout, fig, varargin{:});
244
245 % Ensure that we have a figure handle
246 if isequal(fig,-1)
247 return; % silent bail-out
248 elseif isempty(fig)
249 error('No figure found');
250 end
251
252 % Isolate the subplot, if it is one
253 cls = all(ismember(get(fig, 'Type'), {'axes', 'uipanel'}));
254 if cls
255 % Given handles of one or more axes, so isolate them from the rest
256 fig = isolate_axes(fig);
257 else
258 % Check we have a figure
259 if ~isequal(get(fig, 'Type'), 'figure');
260 error('Handle must be that of a figure, axes or uipanel');
261 end
262 % Get the old InvertHardcopy mode
263 old_mode = get(fig, 'InvertHardcopy');
264 end
265
266 % Hack the font units where necessary (due to a font rendering bug in print?).
267 % This may not work perfectly in all cases.
268 % Also it can change the figure layout if reverted, so use a copy.
269 magnify = options.magnify * options.aa_factor;
270 if isbitmap(options) && magnify ~= 1
271 fontu = findall(fig, 'FontUnits', 'normalized');
272 if ~isempty(fontu)
273 % Some normalized font units found
274 if ~cls
275 fig = copyfig(fig);
276 set(fig, 'Visible', 'off');
277 fontu = findall(fig, 'FontUnits', 'normalized');
278 cls = true;
279 end
280 set(fontu, 'FontUnits', 'points');
281 end
282 end
283
284 try
285 % MATLAB "feature": axes limits and tick marks can change when printing
286 Hlims = findall(fig, 'Type', 'axes');
287 if ~cls
288 % Record the old axes limit and tick modes
289 Xlims = make_cell(get(Hlims, 'XLimMode'));
290 Ylims = make_cell(get(Hlims, 'YLimMode'));
291 Zlims = make_cell(get(Hlims, 'ZLimMode'));
292 Xtick = make_cell(get(Hlims, 'XTickMode'));
293 Ytick = make_cell(get(Hlims, 'YTickMode'));
294 Ztick = make_cell(get(Hlims, 'ZTickMode'));
295 Xlabel = make_cell(get(Hlims, 'XTickLabelMode'));
296 Ylabel = make_cell(get(Hlims, 'YTickLabelMode'));
297 Zlabel = make_cell(get(Hlims, 'ZTickLabelMode'));
298 end
299
300 % Set all axes limit and tick modes to manual, so the limits and ticks can't change
301 % Fix Matlab R2014b bug (issue #34): plot markers are not displayed when ZLimMode='manual'
302 set(Hlims, 'XLimMode', 'manual', 'YLimMode', 'manual');
303 set_tick_mode(Hlims, 'X');
304 set_tick_mode(Hlims, 'Y');
305 if ~using_hg2(fig)
306 set(Hlims,'ZLimMode', 'manual');
307 set_tick_mode(Hlims, 'Z');
308 end
309 catch
310 % ignore - fix issue #4 (using HG2 on R2014a and earlier)
311 end
312
313 % Fix issue #21 (bold TeX axes labels/titles in R2014b when exporting to EPS/PDF)
314 try
315 if using_hg2(fig) && isvector(options)
316 % Set the FontWeight of axes labels/titles to 'normal'
317 % Fix issue #69: set non-bold font only if the string contains symbols (\beta etc.)
318 texLabels = findall(fig, 'type','text', 'FontWeight','bold');
319 symbolIdx = ~cellfun('isempty',strfind({texLabels.String},'\'));
320 set(texLabels(symbolIdx), 'FontWeight','normal');
321 end
322 catch
323 % ignore
324 end
325
326 % Fix issue #42: non-normalized annotations on HG1 (internal Matlab bug)
327 annotationHandles = [];
328 try
329 if ~using_hg2(fig)
330 annotationHandles = findall(fig,'Type','hggroup','-and','-property','Units','-and','-not','Units','norm');
331 originalUnits = get(annotationHandles,'Units');
332 set(annotationHandles,'Units','norm');
333 end
334 catch
335 % should never happen, but ignore in any case - issue #50
336 end
337
338 % Fix issue #46: Ghostscript crash if figure units <> pixels
339 oldFigUnits = get(fig,'Units');
340 set(fig,'Units','pixels');
341
342 % Set to print exactly what is there
343 set(fig, 'InvertHardcopy', 'off');
344 % Set the renderer
345 switch options.renderer
346 case 1
347 renderer = '-opengl';
348 case 2
349 renderer = '-zbuffer';
350 case 3
351 renderer = '-painters';
352 otherwise
353 renderer = '-opengl'; % Default for bitmaps
354 end
355
356 try
357 % Do the bitmap formats first
358 if isbitmap(options)
359 if abs(options.bb_padding) > 1
360 displaySuggestedWorkarounds = false;
361 error('For bitmap output (png,jpg,tif,bmp) the padding value (-p) must be between -1<p<1')
362 end
363 % Get the background colour
364 if options.transparent && (options.png || options.alpha)
365 % Get out an alpha channel
366 % MATLAB "feature": black colorbar axes can change to white and vice versa!
367 hCB = findall(fig, 'Type','axes', 'Tag','Colorbar');
368 if isempty(hCB)
369 yCol = [];
370 xCol = [];
371 else
372 yCol = get(hCB, 'YColor');
373 xCol = get(hCB, 'XColor');
374 if iscell(yCol)
375 yCol = cell2mat(yCol);
376 xCol = cell2mat(xCol);
377 end
378 yCol = sum(yCol, 2);
379 xCol = sum(xCol, 2);
380 end
381 % MATLAB "feature": apparently figure size can change when changing
382 % colour in -nodisplay mode
383 pos = get(fig, 'Position');
384 % Set the background colour to black, and set size in case it was
385 % changed internally
386 tcol = get(fig, 'Color');
387 set(fig, 'Color', 'k', 'Position', pos);
388 % Correct the colorbar axes colours
389 set(hCB(yCol==0), 'YColor', [0 0 0]);
390 set(hCB(xCol==0), 'XColor', [0 0 0]);
391
392 % The following code might cause out-of-memory errors
393 try
394 % Print large version to array
395 B = print2array(fig, magnify, renderer);
396 % Downscale the image
397 B = downsize(single(B), options.aa_factor);
398 catch
399 % This is more conservative in memory, but kills transparency (issue #58)
400 B = single(print2array(fig, magnify/options.aa_factor, renderer));
401 end
402
403 % Set background to white (and set size)
404 set(fig, 'Color', 'w', 'Position', pos);
405 % Correct the colorbar axes colours
406 set(hCB(yCol==3), 'YColor', [1 1 1]);
407 set(hCB(xCol==3), 'XColor', [1 1 1]);
408
409 % The following code might cause out-of-memory errors
410 try
411 % Print large version to array
412 A = print2array(fig, magnify, renderer);
413 % Downscale the image
414 A = downsize(single(A), options.aa_factor);
415 catch
416 % This is more conservative in memory, but kills transparency (issue #58)
417 A = single(print2array(fig, magnify/options.aa_factor, renderer));
418 end
419
420 % Set the background colour (and size) back to normal
421 set(fig, 'Color', tcol, 'Position', pos);
422 % Compute the alpha map
423 alpha = round(sum(B - A, 3)) / (255 * 3) + 1;
424 A = alpha;
425 A(A==0) = 1;
426 A = B ./ A(:,:,[1 1 1]);
427 clear B
428 % Convert to greyscale
429 if options.colourspace == 2
430 A = rgb2grey(A);
431 end
432 A = uint8(A);
433 % Crop the background
434 if options.crop
435 %[alpha, v] = crop_borders(alpha, 0, 1);
436 %A = A(v(1):v(2),v(3):v(4),:);
437 [alpha, vA, vB] = crop_borders(alpha, 0, options.bb_padding);
438 if ~any(isnan(vB)) % positive padding
439 B = repmat(uint8(zeros(1,1,size(A,3))),size(alpha));
440 B(vB(1):vB(2), vB(3):vB(4), :) = A(vA(1):vA(2), vA(3):vA(4), :); % ADDED BY OH
441 A = B;
442 else % negative padding
443 A = A(vA(1):vA(2), vA(3):vA(4), :);
444 end
445 end
446 if options.png
447 % Compute the resolution
448 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;
449 % Save the png
450 imwrite(A, [options.name '.png'], 'Alpha', double(alpha), 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);
451 % Clear the png bit
452 options.png = false;
453 end
454 % Return only one channel for greyscale
455 if isbitmap(options)
456 A = check_greyscale(A);
457 end
458 if options.alpha
459 % Store the image
460 imageData = A;
461 % Clear the alpha bit
462 options.alpha = false;
463 end
464 % Get the non-alpha image
465 if isbitmap(options)
466 alph = alpha(:,:,ones(1, size(A, 3)));
467 A = uint8(single(A) .* alph + 255 * (1 - alph));
468 clear alph
469 end
470 if options.im
471 % Store the new image
472 imageData = A;
473 end
474 else
475 % Print large version to array
476 if options.transparent
477 % MATLAB "feature": apparently figure size can change when changing
478 % colour in -nodisplay mode
479 pos = get(fig, 'Position');
480 tcol = get(fig, 'Color');
481 set(fig, 'Color', 'w', 'Position', pos);
482 A = print2array(fig, magnify, renderer);
483 set(fig, 'Color', tcol, 'Position', pos);
484 tcol = 255;
485 else
486 [A, tcol] = print2array(fig, magnify, renderer);
487 end
488 % Crop the background
489 if options.crop
490 A = crop_borders(A, tcol, options.bb_padding);
491 end
492 % Downscale the image
493 A = downsize(A, options.aa_factor);
494 if options.colourspace == 2
495 % Convert to greyscale
496 A = rgb2grey(A);
497 else
498 % Return only one channel for greyscale
499 A = check_greyscale(A);
500 end
501 % Outputs
502 if options.im
503 imageData = A;
504 end
505 if options.alpha
506 imageData = A;
507 alpha = zeros(size(A, 1), size(A, 2), 'single');
508 end
509 end
510 % Save the images
511 if options.png
512 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;
513 imwrite(A, [options.name '.png'], 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);
514 end
515 if options.bmp
516 imwrite(A, [options.name '.bmp']);
517 end
518 % Save jpeg with given quality
519 if options.jpg
520 quality = options.quality;
521 if isempty(quality)
522 quality = 95;
523 end
524 if quality > 100
525 imwrite(A, [options.name '.jpg'], 'Mode', 'lossless');
526 else
527 imwrite(A, [options.name '.jpg'], 'Quality', quality);
528 end
529 end
530 % Save tif images in cmyk if wanted (and possible)
531 if options.tif
532 if options.colourspace == 1 && size(A, 3) == 3
533 A = double(255 - A);
534 K = min(A, [], 3);
535 K_ = 255 ./ max(255 - K, 1);
536 C = (A(:,:,1) - K) .* K_;
537 M = (A(:,:,2) - K) .* K_;
538 Y = (A(:,:,3) - K) .* K_;
539 A = uint8(cat(3, C, M, Y, K));
540 clear C M Y K K_
541 end
542 append_mode = {'overwrite', 'append'};
543 imwrite(A, [options.name '.tif'], 'Resolution', options.magnify*get(0, 'ScreenPixelsPerInch'), 'WriteMode', append_mode{options.append+1});
544 end
545 end
546
547 % Now do the vector formats
548 if isvector(options)
549 % Set the default renderer to painters
550 if ~options.renderer
551 if isempty(findall(fig,'-property','FaceAlpha','-and','-not','FaceAlpha',1)) && ...
552 isempty(findall(fig,'type','patch'))
553 renderer = '-painters';
554 else
555 % This is *MUCH* slower, but more accurate for patches and transparent annotations (issue #39)
556 renderer = '-opengl';
557 end
558 end
559 % Generate some filenames
560 tmp_nam = [tempname '.eps'];
561 try
562 % Ensure that the temp dir is writable (Javier Paredes 30/1/15)
563 fid = fopen(tmp_nam,'w');
564 fwrite(fid,1);
565 fclose(fid);
566 delete(tmp_nam);
567 isTempDirOk = true;
568 catch
569 % Temp dir is not writable, so use the user-specified folder
570 [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU>
571 fpath = fileparts(options.name);
572 tmp_nam = fullfile(fpath,[fname fext]);
573 isTempDirOk = false;
574 end
575 if isTempDirOk
576 pdf_nam_tmp = [tempname '.pdf'];
577 else
578 pdf_nam_tmp = fullfile(fpath,[fname '.pdf']);
579 end
580 if options.pdf
581 pdf_nam = [options.name '.pdf'];
582 try copyfile(pdf_nam, pdf_nam_tmp, 'f'); catch, end % fix for issue #65
583 else
584 pdf_nam = pdf_nam_tmp;
585 end
586 % Generate the options for print
587 p2eArgs = {renderer, sprintf('-r%d', options.resolution)};
588 if options.colourspace == 1 % CMYK
589 % Issue #33: due to internal bugs in Matlab's print() function, we can't use its -cmyk option
590 %p2eArgs{end+1} = '-cmyk';
591 end
592 if ~options.crop
593 % Issue #56: due to internal bugs in Matlab's print() function, we can't use its internal cropping mechanism,
594 % therefore we always use '-loose' (in print2eps.m) and do our own cropping (in crop_borders)
595 %p2eArgs{end+1} = '-loose';
596 end
597 if any(strcmpi(varargin,'-depsc'))
598 % Issue #45: lines in image subplots are exported in invalid color.
599 % The workaround is to use the -depsc parameter instead of the default -depsc2
600 p2eArgs{end+1} = '-depsc';
601 end
602 try
603 % Generate an eps
604 print2eps(tmp_nam, fig, [options.bb_padding, options.crop, options.fontswap], p2eArgs{:});
605 % Remove the background, if desired
606 if options.transparent && ~isequal(get(fig, 'Color'), 'none')
607 eps_remove_background(tmp_nam, 1 + using_hg2(fig));
608 end
609 % Fix colorspace to CMYK, if requested (workaround for issue #33)
610 if options.colourspace == 1 % CMYK
611 % Issue #33: due to internal bugs in Matlab's print() function, we can't use its -cmyk option
612 change_rgb_to_cmyk(tmp_nam);
613 end
614 % Add a bookmark to the PDF if desired
615 if options.bookmark
616 fig_nam = get(fig, 'Name');
617 if isempty(fig_nam)
618 warning('export_fig:EmptyBookmark', 'Bookmark requested for figure with no name. Bookmark will be empty.');
619 end
620 add_bookmark(tmp_nam, fig_nam);
621 end
622 % Generate a pdf
623 eps2pdf(tmp_nam, pdf_nam_tmp, 1, options.append, options.colourspace==2, options.quality, options.gs_options);
624 % Ghostscript croaks on % chars in the output PDF file, so use tempname and then rename the file
625 try movefile(pdf_nam_tmp, pdf_nam, 'f'); catch, end
626 catch ex
627 % Delete the eps
628 delete(tmp_nam);
629 rethrow(ex);
630 end
631 % Delete the eps
632 delete(tmp_nam);
633 if options.eps
634 try
635 % Generate an eps from the pdf
636 % since pdftops can't handle relative paths (e.g., '..\'), use a temp file
637 eps_nam_tmp = strrep(pdf_nam_tmp,'.pdf','.eps');
638 pdf2eps(pdf_nam, eps_nam_tmp);
639 movefile(eps_nam_tmp, [options.name '.eps'], 'f');
640 catch ex
641 if ~options.pdf
642 % Delete the pdf
643 delete(pdf_nam);
644 end
645 try delete(eps_nam_tmp); catch, end
646 rethrow(ex);
647 end
648 if ~options.pdf
649 % Delete the pdf
650 delete(pdf_nam);
651 end
652 end
653 end
654
655 % Revert the figure or close it (if requested)
656 if cls || options.closeFig
657 % Close the created figure
658 close(fig);
659 else
660 % Reset the hardcopy mode
661 set(fig, 'InvertHardcopy', old_mode);
662 % Reset the axes limit and tick modes
663 for a = 1:numel(Hlims)
664 try
665 set(Hlims(a), 'XLimMode', Xlims{a}, 'YLimMode', Ylims{a}, 'ZLimMode', Zlims{a},...
666 'XTickMode', Xtick{a}, 'YTickMode', Ytick{a}, 'ZTickMode', Ztick{a},...
667 'XTickLabelMode', Xlabel{a}, 'YTickLabelMode', Ylabel{a}, 'ZTickLabelMode', Zlabel{a});
668 catch
669 % ignore - fix issue #4 (using HG2 on R2014a and earlier)
670 end
671 end
672 % Revert the tex-labels font weights
673 try set(texLabels, 'FontWeight','bold'); catch, end
674 % Revert annotation units
675 for handleIdx = 1 : numel(annotationHandles)
676 try
677 oldUnits = originalUnits{handleIdx};
678 catch
679 oldUnits = originalUnits;
680 end
681 try set(annotationHandles(handleIdx),'Units',oldUnits); catch, end
682 end
683 % Revert figure units
684 set(fig,'Units',oldFigUnits);
685 end
686
687 % Output to clipboard (if requested)
688 if options.clipboard
689 % Delete the output file if unchanged from the default name ('export_fig_out.png')
690 if strcmpi(options.name,'export_fig_out')
691 try
692 fileInfo = dir('export_fig_out.png');
693 if ~isempty(fileInfo)
694 timediff = now - fileInfo.datenum;
695 ONE_SEC = 1/24/60/60;
696 if timediff < ONE_SEC
697 delete('export_fig_out.png');
698 end
699 end
700 catch
701 % never mind...
702 end
703 end
704
705 % Save the image in the system clipboard
706 % credit: Jiro Doke's IMCLIPBOARD: http://www.mathworks.com/matlabcentral/fileexchange/28708-imclipboard
707 try
708 error(javachk('awt', 'export_fig -clipboard output'));
709 catch
710 warning('export_fig -clipboard output failed: requires Java to work');
711 return;
712 end
713 try
714 % Import necessary Java classes
715 import java.awt.Toolkit.*
716 import java.awt.image.BufferedImage
717 import java.awt.datatransfer.DataFlavor
718
719 % Get System Clipboard object (java.awt.Toolkit)
720 cb = getDefaultToolkit.getSystemClipboard();
721
722 % Add java class (ImageSelection) to the path
723 if ~exist('ImageSelection', 'class')
724 javaaddpath(fileparts(which(mfilename)), '-end');
725 end
726
727 % Get image size
728 ht = size(imageData, 1);
729 wd = size(imageData, 2);
730
731 % Convert to Blue-Green-Red format
732 try
733 imageData2 = imageData(:, :, [3 2 1]);
734 catch
735 % Probably gray-scaled image (2D, without the 3rd [RGB] dimension)
736 imageData2 = imageData(:, :, [1 1 1]);
737 end
738
739 % Convert to 3xWxH format
740 imageData2 = permute(imageData2, [3, 2, 1]);
741
742 % Append Alpha data (unused - transparency is not supported in clipboard copy)
743 alphaData2 = uint8(permute(255*alpha,[3,2,1])); %=255*ones(1,wd,ht,'uint8')
744 imageData2 = cat(1, imageData2, alphaData2);
745
746 % Create image buffer
747 imBuffer = BufferedImage(wd, ht, BufferedImage.TYPE_INT_RGB);
748 imBuffer.setRGB(0, 0, wd, ht, typecast(imageData2(:), 'int32'), 0, wd);
749
750 % Create ImageSelection object from the image buffer
751 imSelection = ImageSelection(imBuffer);
752
753 % Set clipboard content to the image
754 cb.setContents(imSelection, []);
755 catch
756 warning('export_fig -clipboard output failed: %s', lasterr); %#ok<LERR>
757 end
758 end
759
760 % Don't output the data to console unless requested
761 if ~nargout
762 clear imageData alpha
763 end
764 catch err
765 % Display possible workarounds before the error message
766 if displaySuggestedWorkarounds
767 if ~hadError, fprintf(2, 'export_fig error. '); end
768 fprintf(2, 'Please ensure:\n');
769 fprintf(2, ' that you are using the <a href="https://github.com/altmany/export_fig/archive/master.zip">latest version</a> of export_fig\n');
770 fprintf(2, ' and that you have <a href="http://www.ghostscript.com">Ghostscript</a> installed\n');
771 try
772 if options.eps
773 fprintf(2, ' and that you have <a href="http://www.foolabs.com/xpdf">pdftops</a> installed\n');
774 end
775 catch
776 % ignore - probably an error in parse_args
777 end
778 fprintf(2, ' and that you do not have <a href="matlab:which export_fig -all">multiple versions</a> of export_fig installed by mistake\n');
779 fprintf(2, ' and that you did not made a mistake in the <a href="matlab:help export_fig">expected input arguments</a>\n');
780 fprintf(2, '\nIf the problem persists, then please <a href="https://github.com/altmany/export_fig/issues">report a new issue</a>.\n\n');
781 end
782 rethrow(err)
783 end
784end
785
786function [fig, options] = parse_args(nout, fig, varargin)
787 % Parse the input arguments
788 % Set the defaults
789 options = struct(...
790 'name', 'export_fig_out', ...
791 'crop', true, ...
792 'transparent', false, ...
793 'renderer', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters
794 'pdf', false, ...
795 'eps', false, ...
796 'png', false, ...
797 'tif', false, ...
798 'jpg', false, ...
799 'bmp', false, ...
800 'clipboard', false, ...
801 'colourspace', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray
802 'append', false, ...
803 'im', nout == 1, ...
804 'alpha', nout == 2, ...
805 'aa_factor', 0, ...
806 'bb_padding', 0, ...
807 'magnify', [], ...
808 'resolution', [], ...
809 'bookmark', false, ...
810 'closeFig', false, ...
811 'quality', [], ...
812 'update', false, ...
813 'fontswap', true, ...
814 'gs_options', {{}});
815 native = false; % Set resolution to native of an image
816
817 % Go through the other arguments
818 skipNext = false;
819 for a = 1:nargin-2
820 if skipNext
821 skipNext = false;
822 continue;
823 end
824 if all(ishandle(varargin{a}))
825 fig = varargin{a};
826 elseif ischar(varargin{a}) && ~isempty(varargin{a})
827 if varargin{a}(1) == '-'
828 switch lower(varargin{a}(2:end))
829 case 'nocrop'
830 options.crop = false;
831 case {'trans', 'transparent'}
832 options.transparent = true;
833 case 'opengl'
834 options.renderer = 1;
835 case 'zbuffer'
836 options.renderer = 2;
837 case 'painters'
838 options.renderer = 3;
839 case 'pdf'
840 options.pdf = true;
841 case 'eps'
842 options.eps = true;
843 case 'png'
844 options.png = true;
845 case {'tif', 'tiff'}
846 options.tif = true;
847 case {'jpg', 'jpeg'}
848 options.jpg = true;
849 case 'bmp'
850 options.bmp = true;
851 case 'rgb'
852 options.colourspace = 0;
853 case 'cmyk'
854 options.colourspace = 1;
855 case {'gray', 'grey'}
856 options.colourspace = 2;
857 case {'a1', 'a2', 'a3', 'a4'}
858 options.aa_factor = str2double(varargin{a}(3));
859 case 'append'
860 options.append = true;
861 case 'bookmark'
862 options.bookmark = true;
863 case 'native'
864 native = true;
865 case 'clipboard'
866 options.clipboard = true;
867 options.im = true;
868 options.alpha = true;
869 case 'svg'
870 msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ...
871 ' 1. saveas(gcf,''filename.svg'')\n' ...
872 ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ...
873 ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n'];
874 error(sprintf(msg)); %#ok<SPERR>
875 case 'update'
876 % Download the latest version of export_fig into the export_fig folder
877 try
878 zipFileName = 'https://github.com/altmany/export_fig/archive/master.zip';
879 folderName = fileparts(which(mfilename('fullpath')));
880 targetFileName = fullfile(folderName, datestr(now,'yyyy-mm-dd.zip'));
881 urlwrite(zipFileName,targetFileName);
882 catch
883 error('Could not download %s into %s\n',zipFileName,targetFileName);
884 end
885
886 % Unzip the downloaded zip file in the export_fig folder
887 try
888 unzip(targetFileName,folderName);
889 catch
890 error('Could not unzip %s\n',targetFileName);
891 end
892 case 'nofontswap'
893 options.fontswap = false;
894 otherwise
895 try
896 wasError = false;
897 if strcmpi(varargin{a}(1:2),'-d')
898 varargin{a}(2) = 'd'; % ensure lowercase 'd'
899 options.gs_options{end+1} = varargin{a};
900 else
901 val = str2double(regexp(varargin{a}, '(?<=-(m|M|r|R|q|Q|p|P))-?\d*.?\d+', 'match'));
902 if isempty(val) || isnan(val)
903 % Issue #51: improved processing of input args (accept space between param name & value)
904 val = str2double(varargin{a+1});
905 if isscalar(val) && ~isnan(val)
906 skipNext = true;
907 end
908 end
909 if ~isscalar(val) || isnan(val)
910 wasError = true;
911 error('option %s is not recognised or cannot be parsed', varargin{a});
912 end
913 switch lower(varargin{a}(2))
914 case 'm'
915 % Magnification may never be negative
916 if val <= 0
917 wasError = true;
918 error('Bad magnification value: %g (must be positive)', val);
919 end
920 options.magnify = val;
921 case 'r'
922 options.resolution = val;
923 case 'q'
924 options.quality = max(val, 0);
925 case 'p'
926 options.bb_padding = val;
927 end
928 end
929 catch err
930 % We might have reached here by raising an intentional error
931 if wasError % intentional raise
932 rethrow(err)
933 else % unintentional
934 error(['Unrecognized export_fig input option: ''' varargin{a} '''']);
935 end
936 end
937 end
938 else
939 [p, options.name, ext] = fileparts(varargin{a});
940 if ~isempty(p)
941 options.name = [p filesep options.name];
942 end
943 switch lower(ext)
944 case {'.tif', '.tiff'}
945 options.tif = true;
946 case {'.jpg', '.jpeg'}
947 options.jpg = true;
948 case '.png'
949 options.png = true;
950 case '.bmp'
951 options.bmp = true;
952 case '.eps'
953 options.eps = true;
954 case '.pdf'
955 options.pdf = true;
956 case '.fig'
957 % If no open figure, then load the specified .fig file and continue
958 if isempty(fig)
959 fig = openfig(varargin{a},'invisible');
960 varargin{a} = fig;
961 options.closeFig = true;
962 else
963 % save the current figure as the specified .fig file and exit
964 saveas(fig(1),varargin{a});
965 fig = -1;
966 return
967 end
968 case '.svg'
969 msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ...
970 ' 1. saveas(gcf,''filename.svg'')\n' ...
971 ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ...
972 ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n'];
973 error(sprintf(msg)); %#ok<SPERR>
974 otherwise
975 options.name = varargin{a};
976 end
977 end
978 end
979 end
980
981 % Quick bail-out if no figure found
982 if isempty(fig), return; end
983
984 % Do border padding with repsect to a cropped image
985 if options.bb_padding
986 options.crop = true;
987 end
988
989 % Set default anti-aliasing now we know the renderer
990 if options.aa_factor == 0
991 try isAA = strcmp(get(ancestor(fig, 'figure'), 'GraphicsSmoothing'), 'on'); catch, isAA = false; end
992 options.aa_factor = 1 + 2 * (~(using_hg2(fig) && isAA) | (options.renderer == 3));
993 end
994
995 % Convert user dir '~' to full path
996 if numel(options.name) > 2 && options.name(1) == '~' && (options.name(2) == '/' || options.name(2) == '\')
997 options.name = fullfile(char(java.lang.System.getProperty('user.home')), options.name(2:end));
998 end
999
1000 % Compute the magnification and resolution
1001 if isempty(options.magnify)
1002 if isempty(options.resolution)
1003 options.magnify = 1;
1004 options.resolution = 864;
1005 else
1006 options.magnify = options.resolution ./ get(0, 'ScreenPixelsPerInch');
1007 end
1008 elseif isempty(options.resolution)
1009 options.resolution = 864;
1010 end
1011
1012 % Set the default format
1013 if ~isvector(options) && ~isbitmap(options)
1014 options.png = true;
1015 end
1016
1017 % Check whether transparent background is wanted (old way)
1018 if isequal(get(ancestor(fig(1), 'figure'), 'Color'), 'none')
1019 options.transparent = true;
1020 end
1021
1022 % If requested, set the resolution to the native vertical resolution of the
1023 % first suitable image found
1024 if native && isbitmap(options)
1025 % Find a suitable image
1026 list = findall(fig, 'Type','image', 'Tag','export_fig_native');
1027 if isempty(list)
1028 list = findall(fig, 'Type','image', 'Visible','on');
1029 end
1030 for hIm = list(:)'
1031 % Check height is >= 2
1032 height = size(get(hIm, 'CData'), 1);
1033 if height < 2
1034 continue
1035 end
1036 % Account for the image filling only part of the axes, or vice
1037 % versa
1038 yl = get(hIm, 'YData');
1039 if isscalar(yl)
1040 yl = [yl(1)-0.5 yl(1)+height+0.5];
1041 else
1042 if ~diff(yl)
1043 continue
1044 end
1045 yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1));
1046 end
1047 hAx = get(hIm, 'Parent');
1048 yl2 = get(hAx, 'YLim');
1049 % Find the pixel height of the axes
1050 oldUnits = get(hAx, 'Units');
1051 set(hAx, 'Units', 'pixels');
1052 pos = get(hAx, 'Position');
1053 set(hAx, 'Units', oldUnits);
1054 if ~pos(4)
1055 continue
1056 end
1057 % Found a suitable image
1058 % Account for stretch-to-fill being disabled
1059 pbar = get(hAx, 'PlotBoxAspectRatio');
1060 pos = min(pos(4), pbar(2)*pos(3)/pbar(1));
1061 % Set the magnification to give native resolution
1062 options.magnify = abs((height * diff(yl2)) / (pos * diff(yl))); % magnification must never be negative: issue #103
1063 break
1064 end
1065 end
1066end
1067
1068function A = downsize(A, factor)
1069 % Downsample an image
1070 if factor == 1
1071 % Nothing to do
1072 return
1073 end
1074 try
1075 % Faster, but requires image processing toolbox
1076 A = imresize(A, 1/factor, 'bilinear');
1077 catch
1078 % No image processing toolbox - resize manually
1079 % Lowpass filter - use Gaussian as is separable, so faster
1080 % Compute the 1d Gaussian filter
1081 filt = (-factor-1:factor+1) / (factor * 0.6);
1082 filt = exp(-filt .* filt);
1083 % Normalize the filter
1084 filt = single(filt / sum(filt));
1085 % Filter the image
1086 padding = floor(numel(filt) / 2);
1087 for a = 1:size(A, 3)
1088 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');
1089 end
1090 % Subsample
1091 A = A(1+floor(mod(end-1, factor)/2):factor:end,1+floor(mod(end-1, factor)/2):factor:end,:);
1092 end
1093end
1094
1095function A = rgb2grey(A)
1096 A = cast(reshape(reshape(single(A), [], 3) * single([0.299; 0.587; 0.114]), size(A, 1), size(A, 2)), class(A)); %#ok<ZEROLIKE>
1097end
1098
1099function A = check_greyscale(A)
1100 % Check if the image is greyscale
1101 if size(A, 3) == 3 && ...
1102 all(reshape(A(:,:,1) == A(:,:,2), [], 1)) && ...
1103 all(reshape(A(:,:,2) == A(:,:,3), [], 1))
1104 A = A(:,:,1); % Save only one channel for 8-bit output
1105 end
1106end
1107
1108function eps_remove_background(fname, count)
1109 % Remove the background of an eps file
1110 % Open the file
1111 fh = fopen(fname, 'r+');
1112 if fh == -1
1113 error('Not able to open file %s.', fname);
1114 end
1115 % Read the file line by line
1116 while count
1117 % Get the next line
1118 l = fgets(fh);
1119 if isequal(l, -1)
1120 break; % Quit, no rectangle found
1121 end
1122 % Check if the line contains the background rectangle
1123 if isequal(regexp(l, ' *0 +0 +\d+ +\d+ +r[fe] *[\n\r]+', 'start'), 1)
1124 % Set the line to whitespace and quit
1125 l(1:regexp(l, '[\n\r]', 'start', 'once')-1) = ' ';
1126 fseek(fh, -numel(l), 0);
1127 fprintf(fh, l);
1128 % Reduce the count
1129 count = count - 1;
1130 end
1131 end
1132 % Close the file
1133 fclose(fh);
1134end
1135
1136function b = isvector(options)
1137 b = options.pdf || options.eps;
1138end
1139
1140function b = isbitmap(options)
1141 b = options.png || options.tif || options.jpg || options.bmp || options.im || options.alpha;
1142end
1143
1144% Helper function
1145function A = make_cell(A)
1146 if ~iscell(A)
1147 A = {A};
1148 end
1149end
1150
1151function add_bookmark(fname, bookmark_text)
1152 % Adds a bookmark to the temporary EPS file after %%EndPageSetup
1153 % Read in the file
1154 fh = fopen(fname, 'r');
1155 if fh == -1
1156 error('File %s not found.', fname);
1157 end
1158 try
1159 fstrm = fread(fh, '*char')';
1160 catch ex
1161 fclose(fh);
1162 rethrow(ex);
1163 end
1164 fclose(fh);
1165
1166 % Include standard pdfmark prolog to maximize compatibility
1167 fstrm = strrep(fstrm, '%%BeginProlog', sprintf('%%%%BeginProlog\n/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse'));
1168 % Add page bookmark
1169 fstrm = strrep(fstrm, '%%EndPageSetup', sprintf('%%%%EndPageSetup\n[ /Title (%s) /OUT pdfmark',bookmark_text));
1170
1171 % Write out the updated file
1172 fh = fopen(fname, 'w');
1173 if fh == -1
1174 error('Unable to open %s for writing.', fname);
1175 end
1176 try
1177 fwrite(fh, fstrm, 'char*1');
1178 catch ex
1179 fclose(fh);
1180 rethrow(ex);
1181 end
1182 fclose(fh);
1183end
1184
1185function set_tick_mode(Hlims, ax)
1186 % Set the tick mode of linear axes to manual
1187 % Leave log axes alone as these are tricky
1188 M = get(Hlims, [ax 'Scale']);
1189 if ~iscell(M)
1190 M = {M};
1191 end
1192 M = cellfun(@(c) strcmp(c, 'linear'), M);
1193 set(Hlims(M), [ax 'TickMode'], 'manual');
1194 %set(Hlims(M), [ax 'TickLabelMode'], 'manual'); % this hides exponent label in HG2!
1195end
1196
1197function change_rgb_to_cmyk(fname) % convert RGB => CMYK within an EPS file
1198 % Do post-processing on the eps file
1199 try
1200 % Read the EPS file into memory
1201 fstrm = read_write_entire_textfile(fname);
1202
1203 % Replace all gray-scale colors
1204 fstrm = regexprep(fstrm, '\n([\d.]+) +GC\n', '\n0 0 0 ${num2str(1-str2num($1))} CC\n');
1205
1206 % Replace all RGB colors
1207 fstrm = regexprep(fstrm, '\n[0.]+ +[0.]+ +[0.]+ +RC\n', '\n0 0 0 1 CC\n'); % pure black
1208 fstrm = regexprep(fstrm, '\n([\d.]+) +([\d.]+) +([\d.]+) +RC\n', '\n${sprintf(''%.4g '',[1-[str2num($1),str2num($2),str2num($3)]/max([str2num($1),str2num($2),str2num($3)]),1-max([str2num($1),str2num($2),str2num($3)])])} CC\n');
1209
1210 % Overwrite the file with the modified contents
1211 read_write_entire_textfile(fname, fstrm);
1212 catch
1213 % never mind - leave as is...
1214 end
1215end
Note: See TracBrowser for help on using the repository browser.