Make figure without white border
285 次查看(过去 30 天)
显示 更早的评论
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.
0 个评论
采纳的回答
Chad Greene
2017-2-8
export_fig removes the border by default.
1 个评论
Sim
2022-1-5
编辑:Sim
2022-1-5
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
更多回答(6 个)
atilla Maia
2018-12-19
编辑:KSSV
2024-2-1
I have tried many suggestions. This one works for me:
f = figure;
F= getframe(f);
img = F.cdata;
imwrite(img, filename) ;
0 个评论
Gyaneshwar dubacharla
2020-8-9
移动:Image Analyst
2023-8-20
Use this command from MATLAB - exportgraphics(gca,fname.emf,'BackgroundColor','none')
1 个评论
Hajra Afzal
2021-4-26
移动:Image Analyst
2023-8-20
@Gyaneshwar dubacharla exportgraphics(gca,fname.emf,'BackgroundColor','none') worked for me. Thankyou for sharing. I faced quite a hassle before implementing this command.
0 个评论
Thomas
2023-8-20
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 个评论
DGM
2023-8-20
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')
Chris
2024-8-16
编辑:Chris
2024-8-16
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:
- create an image that is the size of my monitor,
- save the figure as a PNG file,
- load it back in using imread,
- crop the image matrix down to the height and width I want using the associated row/column ranges,
- 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.
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!