将 Surface 转换为矢量化 SVG 而不是嵌入的 PNG

Posted

技术标签:

【中文标题】将 Surface 转换为矢量化 SVG 而不是嵌入的 PNG【英文标题】:Convert Surface to vectorized SVG instead of embedded PNG 【发布时间】:2020-05-23 19:34:36 【问题描述】:

对于上下文,我正在尝试gtk custom drawing example。我想将Surface(在我的情况下为 xlib 表面)转储到 SVG 文件中,并获取实际的矢量图像,而不是嵌入的 PNG。

例如:

cairo_surface_t *svg_surface;
svg_surface = cairo_svg_surface_create("/path/myfile.svg", 200, 200);
cairo_t *cr;
cr = cairo_create(svg_surface);
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
cairo_surface_flush(svg_surface);
cairo_surface_finish(svg_surface);

生成一个包含如下内容的 SVG:

<svg ...>
<image ... xlink:href="data:image/png;base64,iVBORw0K...>
</svg>

绘制成SVG,例如:

cairo_move_to(svg_surface, 0, 0)
cairo_line_to(svg_surface, 100, 100)
cairo_stroke(svg_surface)

生产:

<svg ...>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 10 10 L 100 100 "/>
</svg>

有没有办法将原始表面绘制成 SVG,并获得这样的输出,而不是嵌入的 PNG?

我知道我可以记录在原始表面中完成的所有绘图操作,然后将它们重播到 SVG 中,但我希望有更好的方法来做到这一点。如果不是,根本原因是什么?

【问题讨论】:

【参考方案1】:

我知道我可以记录在原始表面中完成的所有绘图操作,然后将它们重播到 SVG 中,但我希望有更好的方法来做到这一点。如果不是,根本原因是什么?

xlib 表面是指 X11 服务器上的可绘制对象(窗口或像素图)。一个drawable包含像素,所以这就是你可以从中得到的全部。

做你想做的事需要记录所有停止的绘图操作,这将导致无限的内存使用。

您可以使用 cairo 记录表面来获取这样的日志,但这只会记录对这个表面执行的绘图操作,而不是另一个表面。如果可以的话,我建议您在想要获取 SVG 时再次调用执行实际绘图的代码。

【讨论】:

感谢您的解释。看来我想要一个记录表面。 我刚试了一下录音面。它生成矢量化图像,这很棒。它使用更多的 CPU,但现在没关系。 写了你最后的建议,我不能再次调用我的代码,因为我不存储绘制的内容,但如果我需要的话,我可以实现自己的记录表面。

以上是关于将 Surface 转换为矢量化 SVG 而不是嵌入的 PNG的主要内容,如果未能解决你的问题,请参考以下文章

如何在保留图层的同时将 SVG 转换为 PNG?

如何将 SVG 文件转换为 HTML5 的画布?

Android 安装包优化Android 中使用 SVG 图片 ( 批量转换 SVG 格式图片为 Vector Asset 矢量图资源 )

Font Awesome矢量版,十六进制版,WPF字体使用

sh 将给定文件夹内的所有图像从彩色转换为灰度,调整它的黑白抖动级别并将其追踪到SVG矢量f

如何将 SVG 文件转换为 JPEG?