【问题标题】:Convert SVG to PNG with sharp edges将 SVG 转换为具有锐利边缘的 PNG
【发布时间】:2019-05-30 12:41:05
【问题描述】:

我需要转换图像以进行对象检测。我从具有多个多边形的 svg 图像开始。示例:

<svg ...>
<rect width = "100%" height = "100%" fill = "rgb(0,0,0)" />
<polygon points="..." fill="rgb(221,221,221)" fill-opacity="1.0" />
<polygon points="..." fill="rgb(100,100,100)" fill-opacity="0.5" />
</svg>

结果是黑色背景,对象 A 的颜色为 rgb(221,221,221),对象 B 的颜色为 rgb(50,50,50),并且两个对象重叠的任何地方都是 rgb(160,160,160)。检测算法(无法修改)通过像素值确定对象。

我已使用inkscape、svgr-convert 或ImageMagikk 成功地将svg 转换为png。但是这些 png 图像的边缘总是很模糊,这会干扰我的对象检测。

有没有什么方法可以让边缘变得清晰? This image shows the conversion adding blurred pixels with incorrect values. I have zoomed into an edge to make it obvious.

编辑:完整图像示例

<svg viewBox="17.874 6.66874 74.0131 70.817" xmlns="http://www.w3.org/2000/svg">
<rect width = "100%" height = "100%" fill="black" fill-opacity="1.000000" stroke="black" stroke-opacity="1.000000" stroke-width ="0.000000"/>
<polygon points="66.499391,34.862972 35.730400,51.495089 68.667463,64.499553 " fill="rgb(221,221,221)" fill-opacity="1.000000" />
<polygon points="47.613765,49.254424 23.219703,52.458598 47.246912,50.965952 48.078815,51.599703 49.620943,52.471096 62.516253,65.471290 65.077318,43.877861 51.086443,12.014429 34.861708,20.532821 " fill="rgb(100,100,100)" fill-opacity="0.500000" />
</svg>

【问题讨论】:

  • ImageMagick 试试convert +antialias input.svg output.png
  • 抗锯齿并没有解决这个问题,它似乎确实在一定程度上降低了效果
  • 也许你可以添加一个完整的、简单的 SVG 来测试,拜托。另请显示您的 ImageMagick 版本,即 identify -version 的输出
  • 版本:ImageMagick 7.0.8-22 Q16 x86_64 2018-12-31 imagemagick.org 版权所有:© 1999-2019 ImageMagick Studio LLC 许可:imagemagick.org/script/license.php 功能:密码 DPC HDRI 模块代表(内置- in): bzlib freetype jng jp2 jpeg lcms ltdl lzma png tiff webp xml zlib
  • 我在想-interpolate integer 会是解决方案,但它也不能解决问题。

标签: svg imagemagick png inkscape librsvg


【解决方案1】:

您需要做的是在读取 SVG 文件时增加密度。您可以按某个因子增加密度并保存该结果,也可以按该因子增加密度,然后按逆因子调整大小。 SVG 的默认密度为 96 dpi。所以在 Imagemagick 6 中,基本命令是:

convert test.svg test.png


相同
convert -density 96 test.svg test1.png


现在您可以将密度增加 4 到 384。

convert -density 384 test.svg test2.png


或者对于需要以原始分辨率保留的带有线条图的较大图像,您可以将尺寸缩小 1/4 或 25%

convert -density 384 test.svg -resize 25% test3.png


对于 Imagemagick 7,将 convert 更改为 magick。

补充:

这是一个使用密度 1200 放大的版本,除非您放大到超过全分辨率,否则看起来会很平滑。

convert -density 1200 test.svg test4.png


【讨论】:

  • 这并不能解决边缘插值像素值的问题。如果放大示例创建的图像,您会看到边缘仍然模糊。
  • 如果您通过像素复制缩放超过图像的完整大小,则缩放将导致锯齿状边缘。您通过缩放看到的是沿着抗锯齿线的像素。像素是离散的,对角线处的线总是在像素级别上呈锯齿状,即使使用抗锯齿也是如此。如果您使用我的最后一种方法并通过设置密度进行放大,您将获得更好的质量。请参阅我作为添加发布的最后一个示例,其中我使用了密度 1200。除非您放大到这个全分辨率大小,否则它是平滑的。
【解决方案2】:

&lt;svg&gt;元素中添加属性(它被所有子元素继承)

shape-rendering="crispEdges"

虽然从我的简短测试来看,Inkscape 似乎不尊重这一点,但 rsvg-convert 确实如此。对于您的 Imagemagick 设置,您应该确保它委托给 librsvg,而不是 Inkscape。

【讨论】:

  • 这成功了!添加了 crispEdges 并直接使用 rsvg 进行转换。感谢您的帮助:)
  • 不错的解决方案,先生!
猜你喜欢
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2017-07-06
  • 1970-01-01
相关资源
最近更新 更多