Effacer les filtres
Effacer les filtres

Make figure without white border

234 vues (au cours des 30 derniers jours)
Anders Brakestad
Anders Brakestad le 8 Fév 2017
Modifié(e) : Chris le 16 Août 2024 à 23:23
I have a piece of code that plots a surface, and I feel it is ready for being included into the report. The only thing is that the figure has a quite large white border which substantially increases the size of it. I would like to have the unnecessary white space reduced to a minimum.
I did try
set(gca,'LooseInset',get(gca,'TightInset'))
But this cuts off my z-axis label. Is there an easy way to achieve this? With LaTeX, we can simply use the standalone documentclass with PGFplots/tikz, but I don't think there's a simple keyword or option to do this with matlab. I'm using R2016b.

Réponse acceptée

Chad Greene
Chad Greene le 8 Fév 2017
export_fig removes the border by default.
  1 commentaire
Sim
Sim le 5 Jan 2022
Modifié(e) : Sim le 5 Jan 2022
Hi, I have used both the following functions to save a figure as a PDF file:
print (figure_name, '-dpdf','-opengl','-r600', [path, plot_name{:}] )
export_fig([path, plot_name{:}], '-pdf', '-opengl','-r600');
Result:
Even though the matlab built-in function print does not crop the white margins in a PDF figure (right?), it mantains a very good resolution/quality of the saved PDF figure. The file exchange export_fig crops instead the white space in a figure automatically, but it reduces a bit the quality of the saved PDF figure, resulting in slightly blurry contours (after zooming in).
This is just my experience, but if you know a reason for the loss of quality in a PDF figure by using export_fig, please let me know!
All the best

Connectez-vous pour commenter.

Plus de réponses (6)

atilla Maia
atilla Maia le 19 Déc 2018
Modifié(e) : KSSV le 1 Fév 2024
I have tried many suggestions. This one works for me:
f = figure;
F= getframe(f);
img = F.cdata;
imwrite(img, filename) ;

Gyaneshwar dubacharla
Gyaneshwar dubacharla le 9 Août 2020
Déplacé(e) : Image Analyst le 20 Août 2023
Use this command from MATLAB - exportgraphics(gca,fname.emf,'BackgroundColor','none')

Hajra Afzal
Hajra Afzal le 26 Avr 2021
Déplacé(e) : Image Analyst le 20 Août 2023
@Gyaneshwar dubacharla exportgraphics(gca,fname.emf,'BackgroundColor','none') worked for me. Thankyou for sharing. I faced quite a hassle before implementing this command.

Jose Marques
Jose Marques le 8 Sep 2017
You can "imwrite" too.

Thomas
Thomas le 20 Août 2023
Maybe this way?
fig_1 = figure(1);
clf();
n = 512;
m = 2 * n + 1;
j = ones(1, m);
i = (-n : n) / n;
i = i .* i;
ii = i' * j;
img = real(sqrt(1 - (ii' + ii)));
imshow(img);
hold on;
lw = .01 * m;
x = 4 * lw + (m - 8 * lw) * [.25 .25 .50 .75 .25 .75 .25 .75 .75];
y = 4 * lw + (m - 8 * lw) * [1.0 .50 .00 .50 .50 1.0 1.0 .50 1.0];
plot(x, y, LineWidth = lw, Color=[1 0 0]);
title("ball with santa's house");
hold off;
new_bordersize = 2; % must not be greater than the original border
img = remove_border(frame2im(getframe(fig_1)), new_bordersize);
imwrite(img, "ball_with_santas_house.tiff");
%%REMOVE_BORDER
function img = remove_border(img, new_bordersize)
%REMOVE_BORDER
% default value for new_bordersize is zero.
if ~exist("new_bordersize", "var")
new_bordersize = 0;
end
% get the border color
col = img(1, 1);
% get the image size
[h, w, ~] = size(img);
% search from left for the first column that not contains only the border-color
x0 = 0;
while x0 < w
x0 = x0 + 1;
if ~all(img(:, x0) == col)
break;
end
end
% search from rigth for the first column that not contains only the border-color
x1 = w + 1;
while 1 < x1
x1 = x1 - 1;
if ~all(img(:, x1) == col)
break;
end
end
% search from bottom for the first row that not contains only the border-color
y0 = 0;
while y0 < h
y0 = y0 + 1;
if ~all(img(y0, :) == col)
break;
end
end
% search from top for the first row that not contains only the border-color
y1 = h + 1;
while 1 < y1
y1 = y1 - 1;
if ~all(img(y1, :) == col)
break;
end
end
% calculate the sub image size to cut out
x0 = max(0, x0 - new_bordersize);
x1 = min(w, x1 + new_bordersize);
y0 = max(0, y0 - new_bordersize - 7);
y1 = min(h, y1 + new_bordersize);
% return the new image
img = img(y0 : y1, x0 : x1, :);
end
  1 commentaire
DGM
DGM le 20 Août 2023
Trimming after the fact is not ideal, but it is often the only option left.
That said, the whole trimming process can be simplified. In this example, I use an image with a non-white background for sake of demonstration. While I'm reading the image from a file for simplicity, the same applies to an image as captured using getframe()/frame2im().
The original padding is removed and new padding added. In this case, the result demonstrates that the new padding is not constrained by the original amount of padding.
% inputs
inpict = imread('stuffthings.png');
padwidth = [50 0]; % [y x]
% create a mask of non-BG pixels
mask = ~all(inpict == inpict(1,1,:),3);
% find ROI geometry
mkr = any(mask,2);
mkc = any(mask,1);
r1 = find(mkr,1,'first');
r2 = find(mkr,1,'last');
c1 = find(mkc,1,'first');
c2 = find(mkc,1,'last');
% crop original image to extents
roipict = inpict(r1:r2,c1:c2,:,:);
% re-pad as specified
% doing this with IPT or base tools is clumsy, but it's fine
% doing the padding this way instead of shifting subscripts
% allows the output padding to be unconstrained by the original image size
szo = size(roipict,1:2)+2*padwidth;
outpict = zeros(szo,class(roipict));
for c = 1:size(inpict,3)
outpict(:,:,c) = padarray(roipict(:,:,c),padwidth,inpict(1,1,c),'both');
end
imshow(inpict,'border','tight')
figure
imshow(outpict,'border','tight')
Of course, there are more convenient ways. If I were doing it with MIMT, this simplifies to:
% inputs
inpict = imread('stuffthings.png');
padwidth = [100 10]; % [y x]
% create a mask of non-BG pixels
bg = inpict(1,1,:);
mask = ~all(inpict == bg,3);
% crop original image to extents
[~,rr,cc] = crop2box(mask);
outpict = inpict(rr,cc,:,:);
% re-pad as specified
outpict = addborder(outpict,padwidth,ctflop(bg));
imshow(outpict,'border','tight')
... or more simply:
% inputs
inpict = imread('stuffthings.png');
padwidth = [100 10]; % [y x]
% crop uniform border vectors
outpict = cropborder(inpict,NaN(1,4));
% re-pad as specified
bg = inpict(1,1,:);
outpict = addborder(outpict,padwidth,ctflop(bg));
imshow(outpict,'border','tight')

Connectez-vous pour commenter.


Chris
Chris le 16 Août 2024 à 23:11
Modifié(e) : Chris le 16 Août 2024 à 23:23
This is by no means the most elegant solution, but in my case I was saving figures as *.png files and then cropping them down once I'd inserted them onto a PowerPoint slide. After about 60 of these I found this thread. Since I'm the only one doing this work and I'm always working on the same monitor, I developed the following workflow:
  1. create an image that is the size of my monitor,
  2. save the figure as a PNG file,
  3. load it back in using imread,
  4. crop the image matrix down to the height and width I want using the associated row/column ranges,
  5. save it out again overwriting the original PNG using imwrite.
The code looks like this:
test = rand(100,1);
f = figure('units','normalized');
plot(test,'LineWidth',3)
legend('Random Noise')
set(gca,'LineWidth',2,'YLim',[-0.1, 1.1],'FontSize',64)
set(f,'Position',[0,0.0333,1.0000,0.9132])
saveas(f,'test','png')
im = imread('test.png');
imwrite(im(100:2025,461:5000,:),'test.png')
The difference in the saved images goes from this:
->||<-
To this:
->||<-
I've been working on a large monitor and haven't noticed any negative impact on the image quality.

Catégories

En savoir plus sur Visual Exploration dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by