Crop white margins in a PDF file

190 views (last 30 days)
Hi, I know this question has been asked already, but - so far - I did not find a suitable and easy solution.
I have a PDF file in a folder, which is actually a graph/figure.
I would like to programmatically read that PDF file and remove the margins/white space around my graph/figure.
Is there any simple but efficient way to do so (without changing figure ratio, size or quality)?
Something like this:
filename = open('mypdffile.pdf')
crop_margins(filename)
  2 Comments
DGM
DGM on 6 Jan 2022
Edited: DGM on 6 Jan 2022
It would help if you provide an example of the file.
Unless you know for certain that it's not, I'd suspect that the padding is actually part of the image. Accumulating extra padding when saving plots is a very common problem.
If the padding is part of the image, then removing it will change the size of the image. Should the cropped image be rescaled to retain the original geometry?
Sim
Sim on 6 Jan 2022
Edited: Sim on 6 Jan 2022
Hi, thanks a lot for your reply @DGM!
(Step A) Here you are an example similar to my figure (in terms of dimensions):
fig = figure('position',[0 0 1300 800],'Color',[1 1 1]); % I would like to maintain these numbers "[0 0 1300 800]"
plot(1:150, 1:150)
xlim = [2594642 2663804]; % Fixed numbers (I cannot change these numbers)
ylim = [1160539 1204675]; % Fixed numbers (I cannot change these numbers)
print (fig(:), '-dpdf','-loose','-opengl','-r600', [path, 'plot_name'] )
which gives this wrong output:
plot_name.pdf
(Step B) By following the Print PDF to a Specific size? I was able to save the entire figure into a PDF file
fig = figure('position',[0 0 1300 800],'Color',[1 1 1]);
plot(1:150, 1:150)
xlim = [2594642 2663804];
ylim = [1160539 1204675];
% FROM: Print PDF to a Specific size?
% URL: https://ch.mathworks.com/matlabcentral/answers/471164-print-pdf-to-a-specific-size
% ANSWER: Sergi Tarroc on 17 Jun 2021
fig.Units = 'centimeters'; % set figure units to cm
fig.PaperUnits = 'centimeters'; % set pdf printing paper units to cm
fig.PaperSize = [fig.Position(3) fig.Position(4)] % assign to the pdf printing paper the size of the figure
print (fig(:), '-dpdf','-loose','-opengl','-r600', [path, 'plot_name'] )
Resulting in this
(Step C) Then, I tried to manually remove the margins playing with "fig.Position"
fig.PaperSize = [fig.Position(3)-8 fig.Position(4)-3.5]
By using the following code
fig = figure('position',[0 0 1300 800],'Color',[1 1 1]);
plot(1:150, 1:150)
xlim = [2594642 2663804];
ylim = [1160539 1204675];
fig.Units = 'centimeters'; % set figure units to cm
fig.PaperUnits = 'centimeters'; % set pdf printing paper units to cm
fig.PaperSize = [fig.Position(3)-8 fig.Position(4)-3.5] % assign to the pdf printing paper the size of the figure
print (fig(:), '-dpdf','-loose','-opengl','-r600', [path, 'plot_name'] )
I got this output
However:
(1) What I used was a manual (and silly?) workaround to remove white margins around my figure - Should I set every time and for each figure (I have figures with different sizes) a tailored cropping?
(2) This method of cropping the white margins looks like not symmetric and I did not find a way to equally/symmetrically remove the margins - Any idea on how to get a simmetric crop for all the 4 margins?
Therefore, I was asking about any automatic way to remove white margins from PDF files (alternatevily to remove those white spaces before/during the usage of the print function).
Note 1: I tried to use a variety of alternative solutions, but without success:
  1. exportgraphics (to use this function I tried to pass from R2019b to R2021b, but I get some errors in the installation...). FROM: https://ch.mathworks.com/help/matlab/creating_plots/save-figure-with-minimal-white-space.html
  2. set(gca,'LooseInset',get(gca,'TightInset')); (it might be a good solution, but it crops too much...maybe I did not use it in the correct way?!) FROM: https://ch.mathworks.com/matlabcentral/answers/320030-how-can-i-get-rid-of-the-large-invisible-border-of-my-matlab-figure-without-cropping-it
  3. print(..., '-loose') (I did not see any difference by applying '-loose') FROM: https://ch.mathworks.com/matlabcentral/answers/411480-how-to-save-figure-in-pdf-without-margins
  4. crop (this does not work for PDF files!)
  5. export_fig (it reduces the quality/resolution of the saved PDF file!)
Note 2: Yes please, I would like to keep same geometry, aspect ratio and quality after cropping the white margins :)

Sign in to comment.

Accepted Answer

Richard Quist
Richard Quist on 6 Jan 2022
One of the following should help.
1. Use external tool to modify previously generated PDF file
MATLAB does not provide a way to read in a PDF file and edit/crop it. You may be able to use an external tool such as ghostscript to do this.
2. Use exportgraphics
In R2020a and above you should be able to use exportgraphics to do this.
exportgraphics(fig, 'output.pdf', 'ContentType', 'vector');
If you are getting errors during installation or when running that command you should contact tech support.
3. Use print with a tiledlayout
If you are using R2020b or later you could place your plot inside a tiledlayout container with tight padding and then use the print command to generate the PDF. Something like the following:
fig = figure;
% set whatever figure properties are needed
tl = tiledlayout(fig, 1, 1, 'padding', 'tight');
ax = nexttile;
% additional code to create your plot inside ax
bar(ax, magic(4));
% make sure PDF paper size is sized properly
fig.PaperSize = fig.PaperPosition(3:4);
% print the figure
print(fig, '-dpdf', 'output.pdf');
  3 Comments
Tim Baur
Tim Baur on 2 Feb 2022
With option 3, the printing process always cuts off the right box line of the axes.
Do you have a solution for that problem, too?
Of course, I could used "compact" instead of "tight" padding but then again, the white space remains.
Richard Quist
Richard Quist on 2 Feb 2022
@Tim Baur: that looks like a clipping issue with the renderer.
You could try adjusting the size of the tiledlayout object, making it a tiny bit smaller to avoid the clipping. For example, set the OuterPosition property when creating it:
tl = tiledlayout(fig, 1, 1, 'padding', 'tight', 'OuterPosition',[0 0 .995 1]);
Or you could do this after the tiledlayout object has been created:
tl.OuterPosition(3) = .995;
You may need to tweak that value to get the results you want.
I hope that helps!

Sign in to comment.

More Answers (0)

Categories

Find more on Printing and Saving in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!