print_convert

PURPOSE ^

PRINT_CONVERT: print figures with anti-aliasing and trim them

SYNOPSIS ^

function print_convert(filename, varargin)

DESCRIPTION ^

PRINT_CONVERT: print figures with anti-aliasing and trim them
  PRINT_CONVERT(FILENAME,OPT) prints current figure to FILENAME, which
  must include extenstion.

  OPT is either a string specifying dpi in the format '-r150' or a struct
  with (some of) these fields:
   opt.resolution   = 150;              % 150 dpi (default: 125)
   opt.pagesize     = [width, height];  % in current PageUnits or 'auto'
                                        % to match the size on the screen
                                        % (default: [8, 6] inches)
   opt.jpeg_quality = 85;               % jpeg quality (default: 85)
   opt.imwrite_opts = {'BitDepth',8};   % options to IMWRITE (default: '')
   opt.horz_cut     = 20;               % remove horizontal gaps larger
                                        % than 50 pixels (default: 20)
   opt.horz_space   = 10;               % replace the removed horizontal
                                        % gaps with 10 px of background
                                        % (default: 10)
   opt.vert_cut     = 20;               % remove vertical gaps larger
                                        % than 50 pixels (default: 20)
   opt.vert_space   = 10;               % replace the removed vertical
                                        % gaps with 10 px of background
                                        % (default: 10)
   opt.supersampling_factor = 2;        % anti-aliasing (default: 1 for
                                        % images, 2 for graphs). Higher is
                                        % smoother.
   opt.crop_slack   = [top,bot,left,right] %don't crop right to boundary
   opt.figno        = number            % print figure, otherwise gca

  Note that opt.imwrite_opts takes precedence over opt.jpeq_quality.

  print_convert has pre-version 3.7 options, which are deprecated

  Examples
   print_convert('outname.png')         % uses default options
   print_convert outname.png
   print_convert outname.png -r150      % set dpi=150
   print_convert outname.png -p10x20    % pagesize 10x20
   print_convert outname.png -pauto     % pagesize = size on screen
   print_convert outname.png -ssf2 -ssf1% supersampling_factor=2,1
   print_convert('outname.png',opts);   % use options

 See also IMWRITE

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function print_convert(filename, varargin)
0002 %PRINT_CONVERT: print figures with anti-aliasing and trim them
0003 %  PRINT_CONVERT(FILENAME,OPT) prints current figure to FILENAME, which
0004 %  must include extenstion.
0005 %
0006 %  OPT is either a string specifying dpi in the format '-r150' or a struct
0007 %  with (some of) these fields:
0008 %   opt.resolution   = 150;              % 150 dpi (default: 125)
0009 %   opt.pagesize     = [width, height];  % in current PageUnits or 'auto'
0010 %                                        % to match the size on the screen
0011 %                                        % (default: [8, 6] inches)
0012 %   opt.jpeg_quality = 85;               % jpeg quality (default: 85)
0013 %   opt.imwrite_opts = {'BitDepth',8};   % options to IMWRITE (default: '')
0014 %   opt.horz_cut     = 20;               % remove horizontal gaps larger
0015 %                                        % than 50 pixels (default: 20)
0016 %   opt.horz_space   = 10;               % replace the removed horizontal
0017 %                                        % gaps with 10 px of background
0018 %                                        % (default: 10)
0019 %   opt.vert_cut     = 20;               % remove vertical gaps larger
0020 %                                        % than 50 pixels (default: 20)
0021 %   opt.vert_space   = 10;               % replace the removed vertical
0022 %                                        % gaps with 10 px of background
0023 %                                        % (default: 10)
0024 %   opt.supersampling_factor = 2;        % anti-aliasing (default: 1 for
0025 %                                        % images, 2 for graphs). Higher is
0026 %                                        % smoother.
0027 %   opt.crop_slack   = [top,bot,left,right] %don't crop right to boundary
0028 %   opt.figno        = number            % print figure, otherwise gca
0029 %
0030 %  Note that opt.imwrite_opts takes precedence over opt.jpeq_quality.
0031 %
0032 %  print_convert has pre-version 3.7 options, which are deprecated
0033 %
0034 %  Examples
0035 %   print_convert('outname.png')         % uses default options
0036 %   print_convert outname.png
0037 %   print_convert outname.png -r150      % set dpi=150
0038 %   print_convert outname.png -p10x20    % pagesize 10x20
0039 %   print_convert outname.png -pauto     % pagesize = size on screen
0040 %   print_convert outname.png -ssf2 -ssf1% supersampling_factor=2,1
0041 %   print_convert('outname.png',opts);   % use options
0042 %
0043 % See also IMWRITE
0044 
0045 % (C) Andy Adler and Bartlomiej Grychtol 2010-2021. License: GPL v2 or v3.
0046 % $Id: print_convert.m 6689 2024-03-19 16:04:23Z bgrychtol $
0047 %
0048 %  Compatibility with pre-3.7 features:
0049 %  ------------------------------------
0050 %  PRINT_CONVERT(FILENAME, OPTIONS, PAGEHWR)
0051 %
0052 %  FILENAME : filename to print to file type is the extension
0053 %  OPTIONS  : specify dpi as '-density N'
0054 %
0055 %   print_convert('outname.png','-density 150') % resolution to 150 dpi
0056 
0057 if ischar(filename) && strcmp(filename,'UNIT_TEST'); do_unit_test; return; end
0058 
0059 pp = parse_options(filename, varargin{:});
0060 
0061 
0062 % change properties
0063 pp = set_prop(pp,'InvertHardCopy','off');
0064 pp = set_prop(pp,'Color','w');
0065 pp = set_pagesize(pp);
0066 
0067 % revert changed properties at exit
0068 cleanupObj = onCleanup(@() set(pp.figno, pp.old{:})); % current state of pp.old only!
0069 
0070 % print to array
0071 im = print(pp.figno,'-RGBImage',pp.resolution);
0072 
0073 im = bitmap_downsize(im, pp.factor);
0074 im = crop_image(im,pp);
0075 try
0076    imwrite(im,pp.filename,pp.imwrite_opts{:});
0077 catch e
0078    eidors_msg(['Call to IMWRITE failed.'...
0079                'Probably opt.imwrite_opts is incorrect for %s files.'],...
0080                upper(pp.fmt), 1);
0081    disp('opt.imwrite_opts:');
0082    disp(pp.imwrite_opts);
0083    rethrow(e);
0084 end
0085 
0086 % place file in clipboard
0087 if pp.clip
0088    copy2clipboard(pp)
0089 end
0090 
0091 function pp = set_pagesize(pp)
0092 if ~isfield(pp, 'pagesize') % no user definition
0093     pos = [0.25 0.25 8 6]; % Matlab's default before R2016a
0094     if isfield(pp, 'aspect_ratio') % old interface
0095         pos(4) = pos(3) * pp.aspect_ratio;
0096     end
0097     pp = set_prop(pp,   'PaperUnits','inches',...
0098                         'PaperPositionMode','manual', ...
0099                         'PaperPosition', pos);
0100 elseif ischar(pp.pagesize)
0101     switch pp.pagesize
0102         case 'auto'
0103             pp = set_prop(pp, 'PaperPositionMode', 'auto');
0104         otherwise
0105             warning('Page size %s not understood', pp.pagesize);
0106     end
0107 else
0108     pos = [0 0 pp.pagesize];
0109     pp = set_prop(pp, ...
0110         'PaperPositionMode','manual', ...
0111         'PaperSize', pp.pagesize+1, ... % big enough
0112         'PaperPosition', pos);
0113 end
0114 
0115 function pp = set_prop(pp, varargin)
0116     prop = {};
0117     for i = 1:2:numel(varargin)
0118         prop(1, end+1) = varargin(i);
0119         prop{2, end  } = get(pp.figno, varargin{i});
0120     end
0121     pp.old = [fliplr(prop), pp.old]; % store in reverse order to revert correctly
0122     set(pp.figno, varargin{:})
0123 
0124 
0125 function copy2clipboard(pp)
0126    if isunix()
0127       cmd = sprintf(['xclip -selection ' ...
0128           'clipboard -t image/%s -i %s'], ...
0129             pp.fmt, pp.filename);
0130       [status] = system(cmd);
0131       if status ~=0
0132           warning 'calling xclip to clipboard failed';
0133       end
0134    else
0135       cmd = 'Powershell -command Set-Clipboard -Path ';
0136       status = system([cmd pp.filename]);
0137       if status ~=0
0138         warning 'Powershell Set-Clipboard failed';
0139       end
0140    end
0141 
0142 function im = crop_image(im,pp)
0143    tu = pp.crop_slack(1);
0144    bu = pp.crop_slack(2) + 1; %remove starting one more
0145    lu = pp.crop_slack(3);
0146    ru = pp.crop_slack(4) + 1;
0147 
0148    szim = size(im);
0149    bdr = squeeze(mean(double(im(1,:,:)),2));
0150 
0151    isbdr = true(szim(1),szim(2));
0152    for i=1:szim(3);
0153      isbdr = isbdr & (im(:,:,i) == bdr(i));
0154    end
0155 
0156    horz = [true,all(isbdr,1),true];
0157    horzpt = find(diff(horz)) - 1; % first 'true'
0158    if isempty(horzpt)
0159       eidors_msg('Image is blank. Cropping aborted.',1);
0160       return
0161    end
0162    im(:,horzpt(end)+ru:end,:)= []; % remove higher first
0163    if pp.horz_cut >0;
0164       horz_e_pt = find(diff(horz)==-1) -1; horz_e_pt(1) = [];
0165       horz_s_pt = find(diff(horz)==+1)   ; horz_s_pt(end) = [];
0166       idx = find(horz_e_pt - horz_s_pt > pp.horz_cut);
0167       for i=fliplr(idx) % remove higher first
0168         im(:,horz_s_pt(i)+pp.horz_space:horz_e_pt(i),:)= [];
0169       end
0170    end
0171    im(:,1:horzpt(1)-lu ,:)= [];
0172 
0173    vert = [true,all(isbdr,2)',true];
0174    vertpt = find(diff(vert)) - 1; % first 'true'
0175    im(vertpt(end)+bu:end,:,:)= [];
0176    if pp.vert_cut >0;
0177       vert_e_pt = find(diff(vert)==-1) -1; vert_e_pt(1) = [];
0178       vert_s_pt = find(diff(vert)==+1)   ; vert_s_pt(end) = [];
0179       idx = find(vert_e_pt - vert_s_pt > pp.vert_cut);
0180       for i=fliplr(idx) % remove higher first
0181         im(vert_s_pt(i)+pp.vert_space:vert_e_pt(i),:,:)= [];
0182       end
0183    end
0184    im(1:vertpt(1)-tu ,:,:)= [];
0185 
0186 
0187 % factor = 1 if all plots only contain images, 2 otherwise
0188 function f = default_factor
0189    f = 1; % default for images
0190    sp = get(gcf,'Children'); % subplots
0191    for i = 1:length(sp)
0192       obj = get(sp(i),'Children');
0193       tp  = get(obj,'Type');
0194       if ~all(strcmp(tp,'image'))
0195          f = 2;
0196          return;
0197       end
0198    end
0199 
0200 function fmt = parse_format(filename)
0201     ext = lower(regexp(filename,'(?<=\.).+$','match'));
0202     if isempty(ext); error('no filename extension detected (%s)',filename); end
0203     switch ext{1}
0204        case {'jpg', 'jpeg'}
0205           fmt = 'jpg';
0206        case {'j2c', 'j2k', 'jp2'}
0207           fmt = 'jp2';
0208        case {'tif','tiff'}
0209           fmt = 'tif';
0210        otherwise
0211           fmt = ext{1};
0212     end
0213 
0214 function pp = parse_options(filename,varargin)
0215 
0216    pp.fmt = parse_format(filename);
0217    if strcmp(filename, ['{clipboard}.',pp.fmt])
0218       pp.clip = true;
0219       pp.filename = [tempname(),'.',pp.fmt];
0220    else
0221       pp.clip = false;
0222       pp.filename = filename;
0223    end
0224 
0225    pp.jpeg_quality = 85; % default jpeg quality
0226    pp.imwrite_opts = {}; % initial
0227    pp.horz_cut = 20;
0228    pp.horz_space = 10;
0229    pp.vert_cut = 20;
0230    pp.vert_space = 10;
0231    pp.factor = default_factor;
0232    pp.resolution = sprintf('-r%d',125 * pp.factor);
0233    pp.crop_slack = [0,0,0,0];
0234    pp.figno = get(gcf,'Number');
0235    pp.old = {};
0236 
0237 
0238 % Old options
0239    if nargin == 1
0240       return;
0241    end
0242 
0243    opt = varargin{1};
0244    if ischar(opt)
0245       for i = 1:length(varargin); opt = varargin{i}; parseok=false;
0246           val =regexp(opt,'-density (\d+)','tokens');
0247           if ~isempty(val);
0248              pp.resolution = sprintf('-r%d', str2double(val{1}{1}) * pp.factor);
0249              parseok=true;
0250           end
0251 
0252           val =regexp(opt,'-r(\d+)','tokens');
0253           if ~isempty(val);
0254              pp.resolution = sprintf('-r%d', str2double(val{1}{1}) * pp.factor);
0255              parseok=true;
0256           end
0257 
0258           if strcmp(opt,'-pauto')
0259              pp.pagesize = 'auto';
0260              parseok=true;
0261           end
0262 
0263           val =regexp(opt,'-p(\d+)x(\d+)','tokens');
0264           if ~isempty(val);
0265              pp.pagesize = [str2num(val{1}{1}), str2num(val{1}{2})];
0266              parseok=true;
0267           end
0268 
0269           val =regexp(opt,'-ssf(\d+)','tokens');
0270           if ~isempty(val);
0271              pp.supersampling_factor = str2num(val{1}{1});
0272              parseok=true;
0273           end
0274 
0275           if ~parseok
0276              eidors_msg('print_convert: option (%s) not understood',opt,0)
0277           end
0278       end
0279    elseif isstruct(opt)
0280      if isfield(opt,'figno');
0281         pp.figno = opt.figno;
0282      end
0283      if isfield(opt,'supersampling_factor')
0284         pp.factor = opt.supersampling_factor;
0285      end
0286      if isfield(opt,'resolution');
0287          pp.resolution = sprintf('-r%d', opt.resolution * pp.factor);
0288      else
0289          pp.resolution = sprintf('-r%d',125 * pp.factor);
0290      end
0291      if isfield(opt,'pagesize');
0292          pp.pagesize = opt.pagesize;
0293      end
0294      % TODO, this code can copy from opt to pp
0295      if isfield(opt,'jpeg_quality')
0296         pp.jpeg_quality = opt.jpeg_quality;
0297      end
0298      if strcmp(pp.fmt,'jpg')
0299         pp.imwrite_opts = {'quality',pp.jpeg_quality};
0300      end
0301      if isfield(opt,'imwrite_opts');
0302         pp.imwrite_opts = opt.imwrite_opts;
0303         if strcmp(pp.fmt,'jpg') && ~any(strcmpi(pp.imwrite_opts,'quality'))
0304            pp.imwrite_opts(end+1:end+2) = {'quality',pp.jpeg_quality};
0305         end
0306      end
0307 
0308      if isfield(opt,'horz_cut');
0309          pp.horz_cut = opt.horz_cut;
0310      end
0311      if isfield(opt,'vert_cut');
0312          pp.vert_cut = opt.vert_cut;
0313      end
0314      if isfield(opt,'vert_space');
0315         if opt.vert_space >= pp.vert_cut;
0316            warning('Option vert_space must be smaller than vert_cut. Ingoring');
0317         else
0318            pp.vert_space = opt.vert_space;
0319         end
0320      end
0321      if isfield(opt,'horz_space');
0322         if opt.horz_space >= pp.horz_cut;
0323            warning('Option vert_space must be smaller than vert_cut. Ingoring');
0324         else
0325            pp.horz_space = opt.horz_space;
0326         end
0327      end
0328      if isfield(opt,'crop_slack');
0329         pp.crop_slack = opt.crop_slack;
0330      end
0331    else
0332       error('Can''t parse options');
0333    end
0334 
0335 
0336 function do_unit_test
0337    fprintf('Doing UNIT_TEST for print_convert\n');
0338    fid = fopen('print_convert_test.html','w');
0339    fprintf(fid,'<HTML><BODY>\n');
0340    for i=1:26;
0341      switch i;
0342        case {9,10}; typ = 'jpg';
0343        otherwise; typ = 'png';
0344      end
0345      fprintf(fid,...
0346      '<H1>%02d</H1><table border=1><tr><td><img src="pc%02d.%s"></table>\n',i,i,typ);
0347    end
0348    fprintf(fid,'</BODY></HTML>\n');
0349    fclose(fid);
0350    eidors_msg('TO VIEW OUTPUT, OPEN FILE print_convert_test.html',1);
0351 
0352    im = mk_image( ng_mk_cyl_models(1,[16,.5],.05),1);
0353    clf; show_fem(im);
0354    print_convert pc01.png
0355 
0356    im = mk_image( mk_common_model('b2c2',8), 1:256);
0357    clf; show_fem(im);
0358    print_convert pc02.png
0359 
0360 
0361    clf; subplot(221); show_fem(im);
0362         subplot(224); show_slices(im);
0363    print_convert pc03.png
0364 
0365    print_convert pc04.png '-density 50'
0366    print_convert pc05.png '-r100'
0367 
0368    print_convert pc05.png '-p10x20'
0369    print_convert pc05.png '-pauto'
0370    print_convert pc06.png '-r100' '-p10x20'
0371 
0372 % No longer supported ... not useful
0373 %  print_convert('pc06.png', '-r100' , 1/8)
0374 %  print_convert('pc06.png', '-r100' , 3/1)
0375 
0376    opt.resolution = 100;
0377    print_convert('pc07.png', opt);
0378    opt.pagesize = [8,2];
0379    print_convert('pc08.png', opt);
0380 
0381    print_convert('pc09a.jpg');
0382 
0383    opt.pagesize = [8,6];
0384    print_convert('pc09.jpg', opt);
0385 
0386 
0387    opt.imwrite_opts = {'Quality',20};
0388    print_convert('pc10.jpg', opt);
0389 
0390    opt.imwrite_opts = {'Quality',100};
0391    print_convert('pc10b.jpg', opt);
0392 
0393    opt.imwrite_opts = {};
0394    opt.horz_cut = 50;
0395    print_convert('pc11.png', opt);
0396 
0397    opt.vert_cut = 50;
0398    print_convert('pc12.png', opt);
0399 
0400    clf; subplot(331); show_fem(im);
0401         subplot(335); show_slices(im);
0402         subplot(339); show_slices(im);
0403    opt.vert_cut = 30;
0404    print_convert('pc13.png', opt);
0405 
0406    im = mk_image( ng_mk_cyl_models(1,[16,.5],.05),1);
0407    clf; show_fem(im);
0408    clear opt; opt.supersampling_factor = 1;
0409    print_convert('pc14.png', opt);
0410 
0411    clear opt; opt.supersampling_factor = 2;
0412    print_convert('pc15.png', opt);
0413 
0414    clear opt; opt.supersampling_factor = 3;
0415    print_convert('pc16.png', opt);
0416 
0417    clear opt; opt.supersampling_factor = 4;
0418    print_convert('pc17.png', opt);
0419 
0420    clear opt; opt.supersampling_factor = 8;
0421    print_convert('pc18.png', opt);
0422 
0423

Generated on Sun 29-Dec-2024 11:41:59 by m2html © 2005