Remove whitespace around exported (saved) figure via imwrite
104 ビュー (過去 30 日間)
古いコメントを表示
I'm trying to save a figure using getframe and imwrite, however, there's a lot of whitespace around the figure I'd like to remove. Basically I want the saved png tight around the title, figure, and colorbar. Any thoughts on how I might do this? My code is below.
% Open figure
set(gca,'xtick',[],'xticklabel',[],'ytick',[],'yticklabel',[],'color','w');
set(gcf,'units','pixel','position',[0,10,650,650],'color','w');
m_proj('Miller Cylindrical','lon',[-92.5 -87.5],'lat',[27.5 32]);
m_grid('xtick',[],'ytick',[],'linestyle','none','backgroundcolor',[0 0 0]);
ax=gca;
colormap(jet(50));
% Set the scale of the colormap for the contours
caxis([0, 50]);
hcb=colorbar('SouthOutside');
hcb.Label.String='Color Bar Label';
axPos = ax.Position;
colorbarpos=hcb.Position;
% Position for SouthOutside colorbar
colorbarpos(2)=0.032+colorbarpos(2);
colorbarpos(4)=0.5*colorbarpos(4);
hcb.Position = colorbarpos;
ax.Position = axPos;
set(hcb,'YTick',[0:1:50],'TickLength',colorbarpos(4)/colorbarpos(3));
set(hcb,'YTickLabel',{'';'1';'';'';'';'5';'';'';'';'';'10';'';'';'';'';'15';'';'';'';'';'20';'';'';'';'';'25';'';'';'';'';'30';'';'';'';'';'35';'';'';'';'';'40';'';'';'';'';'45';'';'';'';'';'50';});
t = title({['\fontsize{12}','Test Plot']},'FontWeight','Bold');
f=getframe(gcf);
imwrite(f.cdata,'test.png','png');
0 件のコメント
採用された回答
Dave B
2021 年 9 月 29 日
編集済み: Dave B
2021 年 9 月 29 日
If/when you upgrade to R2020a+ consider trying exportgraphics(gca, ...) which trims images nice and tight and may be easier than working with imwrite.
In the mean time...you could crop f.cdata based on the rows/columns that are all white (because your figure background is white).
% Open figure
set(gca,'xtick',[],'xticklabel',[],'ytick',[],'yticklabel',[],'color','w');
set(gcf,'units','pixel','position',[0,10,650,650],'color','w');
imagesc(magic(10)) % I didn't have m_proj so I used image as a placeholder
ax=gca;
colormap(jet(50));
% Set the scale of the colormap for the contours
caxis([0, 50]);
hcb=colorbar('SouthOutside');
hcb.Label.String='Color Bar Label';
axPos = ax.Position;
colorbarpos=hcb.Position;
% Position for SouthOutside colorbar
colorbarpos(2)=0.032+colorbarpos(2);
colorbarpos(4)=0.5*colorbarpos(4);
hcb.Position = colorbarpos;
ax.Position = axPos;
set(hcb,'YTick',[0:1:50],'TickLength',colorbarpos(4)/colorbarpos(3));
set(hcb,'YTickLabel',{'';'1';'';'';'';'5';'';'';'';'';'10';'';'';'';'';'15';'';'';'';'';'20';'';'';'';'';'25';'';'';'';'';'30';'';'';'';'';'35';'';'';'';'';'40';'';'';'';'';'45';'';'';'';'';'50';});
t = title({['\fontsize{12}','Test Plot']},'FontWeight','Bold');
f=getframe(gcf);
iswhite=min(f.cdata,[],3)==255;
blankcols=all(iswhite,1);
col_ind = find(~blankcols,1,'first'):find(~blankcols,1,'last');
blankrows=all(iswhite,2);
row_ind = find(~blankrows,1,'first'):find(~blankrows,1,'last');
cropdata = f.cdata(row_ind,col_ind,:);
% demo of pre/post trim (for ML answers, can remove for export)
figure
tiledlayout(1,2,'Padding','none','TileSpacing','tight')
image(nexttile,f.cdata); axis image;xticks([]);yticks([])
image(nexttile,cropdata);axis image;xticks([]);yticks([])
% uncomment this to write the image
% imwrite(cropdata,'test.png','png');
Exported image
0 件のコメント
その他の回答 (1 件)
DGM
2021 年 9 月 29 日
編集済み: DGM
2021 年 9 月 29 日
Is there any reason you're not using print(), saveas(), or exportgraphics()?
Instead of
f=getframe(gcf);
imwrite(f.cdata,'test.png','png');
you could try
saveas(gcf,'testsaveas.png');
or maybe
print('testprint','-dpng');
or exportgraphics(), which I don't have (I guess you don't either).
If none of that changes the padding sufficiently, or if you need to process existing saved figures, you'll have to crop the images. You could use imcrop() if you could determine the correct rect parameter, but that's going to be a pain. MIMT has cropborder(), which has optional automatic cropping modes specifically for tasks like this:
% Open figure
set(gca,'xtick',[],'xticklabel',[],'ytick',[],'yticklabel',[],'color','w');
set(gcf,'units','pixel','position',[0,10,650,650],'color','w');
h = surf(3.2*peaks+23); h.EdgeAlpha = 0.1;
ax=gca;
colormap(jet(50));
% Set the scale of the colormap for the contours
caxis([0, 50]);
hcb=colorbar('SouthOutside');
hcb.Label.String='Color Bar Label';
axPos = ax.Position;
colorbarpos=hcb.Position;
% Position for SouthOutside colorbar
colorbarpos(2)=0.032+colorbarpos(2);
colorbarpos(4)=0.5*colorbarpos(4);
hcb.Position = colorbarpos;
ax.Position = axPos;
set(hcb,'YTick',[0:1:50],'TickLength',colorbarpos(4)/colorbarpos(3));
set(hcb,'YTickLabel',{'';'1';'';'';'';'5';'';'';'';'';'10';'';'';'';'';'15';'';'';'';'';'20';'';'';'';'';'25';'';'';'';'';'30';'';'';'';'';'35';'';'';'';'';'40';'';'';'';'';'45';'';'';'';'';'50';});
t = title({['\fontsize{12}','Test Plot']},'FontWeight','Bold');
f = getframe(gcf);
f = cropborder(f.cdata,[NaN NaN NaN NaN],'threshold',0.0001);
f = addborder(f,10,[1 0 0],'normalized'); % for web demo only!
imwrite(f,'test.png','png');
imshow(f)
In this example, I added a red border so that you can see where the image boundary is against the white website background. You obviously don't need to add a red border to anything.
As mentioned, cropborder() is from MIMT on the FEX:
Cropborder webdocs are here:
0 件のコメント
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!