【问题标题】:How to save figure with transparent background如何保存透明背景的图形
【发布时间】:2013-04-14 14:51:22
【问题描述】:

我在 Matlab 中有一个绘图,并通过以下方式将背景设置为透明:

set(gcf, 'Color', 'None');
set(gca, 'Color', 'None');

当我尝试(从查看器)保存图像时,我将其保存为“.png”,但它以白色背景保存。我怎样才能用透明背景保存它?

【问题讨论】:

    标签: image matlab visualization


    【解决方案1】:

    令人失望的是,MATLAB 默认的saveasprint 命令不能很好地处理透明的事情。您必须使用一些背景保存它,然后通过imread/imwrite 或其他工具进行转换。

    有些工具可能会有所帮助:

    我更喜欢矢量图形,所以在需要透明度时使用 svg 导出。如果确实有位图,请使用imwrite(bitmapData, 'a.png', 'png', 'transparency', backgroundColor)

    【讨论】:

    • 我接受了这一点,但作为查看器中的一个旁注,我去编辑->复制图形并粘贴到 powerpoint 中,它似乎保留了透明度
    • @Aly 我猜这是因为它是通过emf 格式复制的。也许保存为 emf 将保持透明度。 (我自己没有测试过)
    【解决方案2】:

    自 MATLAB 2014b 版本以来,情况发生了变化。新实现的图形系统(所谓的 HG2,用于 Handle Graphics 版本 2)在透明度方面做得更好。

    现在它至少可以正确地将透明度保存到 SVG!

    【讨论】:

    • PNG 怎么样?
    • 你有示例代码来保存 SVG 的透明度吗?
    【解决方案3】:

    所以我仍然想要一些简单的东西,不需要我安装任何其他东西(不允许使用公司电脑:/)。我偶然发现this link,声明:

    你要做的就是以下

    1) 在 matlab 文件中添加命令以使用透明背景格式化您的图形

     set(gcf, 'color', 'none');
     set(gca, 'color', 'none');
    

    并以eps格式保存或导出生成的图形。 (比如 Bspline.eps)

    2) 在记事本中打开 Bspline.eps

    3) 查看第一行。例如%!PS-Adobe-3.0 EPSF-3.0。最后一个数字 3.0 表示 Postscript 级别。对于级别 3,搜索字符串 rf。你会在这样的一行中找到(四个数字后跟rf

    0 0 3025 2593 rf %使用 % 注释该行。

    (对于第 2 级,搜索字符串 pr 而不是 rf

    保存文件。

    现在您可以使用 eps 文件,也可以将其转换为 pdf 然后使用。 无论如何它都会有透明的背景

    额外

    对我来说,这是两行 re 和两行,尽管我的 %!PS-Adobe-3.0 EPSF-3.0 紧随其后。但结果是 Figure 现在是透明的。

    【讨论】:

    • 2018 年 3 月,我只是通过注释掉您所说的两条 re 行来手动编辑背景以使其透明。如果修复如此简单,而且确实如此,为什么 TMW 在生成 eps 图像时不提供透明背景选项?
    • 在 2014a 生成的 eps 无花果中,c0 1 j 1 sg 0 0 12252 11412 rf 6 w 有必要的rf
    • 在2017b中,看起来是这样的序列,当然有换行符:1 GC N 0 0 576 756 re f GR GS [1 0 0 1 18 18] CT 1 GC N 0 0 576 756 re f GR
    【解决方案4】:

    作为Memming 答案的补充。带有exportgraphics 的 Matlab 2020 支持透明背景,但仅适用于矢量化输出(不适用于渲染内容)。对于以透明度导出渲染数据,您仍然不能以透明度保存它。但是,您可以通过保存具有两种不同背景颜色(例如白色和黑色)的渲染数据,然后加载两个临时图像,求解一个简单的方程系统,从而检索透明度和原始颜色数据,然后将其全部保存到一个 RGBA png 文件。

    关键是要意识到Matlab保存的渲染输出是透明度乘以图像数据+(1-透明度)乘以背景颜色。从单个输出中无法恢复图像数据和透明度,但可以从具有不同背景颜色的两个输出中恢复。如果 Matlab 在渲染输出中支持透明背景颜色会更容易,但这种方式也可以。

    示例脚本:

    % create example data
    g = -10:0.1:10;
    [x, y, z] = ndgrid(g, g, g);
    v = (x.^2 + y.^2 - 10).^2 + (z.^2 - 5).^2;
    
    % render in 3D with transparency
    fig = figure();
    
    % one surface fully opaque
    fv = isosurface(x, y, z, v, 20);
    p = patch(fv, 'FaceColor', [1, 0, 0], 'FaceAlpha', 1, 'EdgeColor', 'none');
    
    % another surface with transparency
    fv = isosurface(x, y, z, v, 80);
    p = patch(fv, 'FaceColor', [0, 1, 1], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
    
    fig.Children.Color = 'none'; % transparent background of figure axis
    view([40 40]);
    pbaspect([1,1,1]);
    camlight;
    lighting('gouraud');
    
    % save figure in different ways
    
    % save as vector format, doesn't produce nice output see for example https://stackoverflow.com/questions/61631063
    exportgraphics(fig, 'test.pdf', 'ContentType', 'vector', 'BackGroundColor', 'none');
    % prints warning: Warning: Vectorized content might take a long time to create,
    % or it might contain unexpected results. Set 'ContentType' to 'image' for better performance.
    
    % save as rendered output with transparent background not work
    exportgraphics(fig, 'test.png', 'ContentType', 'image', 'BackGroundColor', 'none');
    % prints warning: Warning: Background transparency is not supported; using white instead.
    
    % now our solution, export with two background colors
    exportgraphics(fig, 'test1.png', 'ContentType', 'image', 'BackgroundColor', 'k'); % black background
    exportgraphics(fig, 'test2.png', 'ContentType', 'image', 'BackgroundColor', 'w'); % white background
    
    % load exported images back in and scale to [0,1]
    u = imread('test1.png');
    u = double(u) / 255;
    v = imread('test2.png');
    v = double(v) / 255;
    
    % recover transparency as a
    a = 1 - v + u;
    a = mean(a, 3);
    a = max(0, min(1, a));
    m = a > eps;
    
    % recover rgb
    c = zeros(size(u));
    for i = 1 : 3
        ui = u(:, :, i);
        ci = c(:, :, i);
        ci(m) = ui(m) ./ a(m);
        c(:, :, i) = ci;
    end
    c = max(0, min(1, c));
    
    % store again
    imwrite(uint8(c*255), 'test.transparent.png', 'Alpha', a);
    
    % temporary files test1.png and test2.png can now be deleted
    

    这是两张具有白色和黑色背景的临时图像。

    这是生成的透明图像。要查看该图像,请保存图像并使用合适的查看器查看它。

    最后一条评论:对于高质量的生产图形,您可能希望关闭(将 Visible 属性设置为关闭)所有具有透明度的渲染部件并将轴和标签保存为矢量化输出,然后反转可见性,即关闭所有轴和标签,仅显示具有透明度的渲染部分并使用两种不同的背景颜色保存它们,然后重建透明度并覆盖矢量化轴和标签以及具有透明度的渲染部分并将它们组合起来。从 Matlab 2020b 开始,Matlab 无法自行完成。

    【讨论】:

      【解决方案5】:

      可以这样操作,Matlab2020a或更高版本有效!

      x = 0:.1:2*pi;
      y = sin(x);
      
      figure;
      plot(x,y,'LineWidth',4);
      
      % save to transparented image
      set(gcf, 'color', 'none');    
      set(gca, 'color', 'none');
      exportgraphics(gcf,'transparent.emf',...   % since R2020a
          'ContentType','vector',...
          'BackgroundColor','none')
      

      【讨论】:

        【解决方案6】:

        根据Matlab人员exportgraphics(gca,'plot.png','BackgroundColor','none') 和类似的应该在 2020a 版本中工作,但是当你尝试时,在大多数情况下你会得到漂亮的错误:

        警告:不支持背景透明度;改用白色。

        我还收到警告:当将“ContentType”参数设置为“矢量”以进行图像输出时,它会被忽略。试试星崔码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-23
          • 2020-11-09
          • 2014-08-23
          • 1970-01-01
          • 2011-06-02
          • 1970-01-01
          • 1970-01-01
          • 2014-10-05
          相关资源
          最近更新 更多