【问题标题】:SVG and DPI, absolute units and user units: Inkscape vs. Firefox vs. ImageMagickSVG 和 DPI,绝对单位和用户单位:Inkscape vs. Firefox vs. ImageMagick
【发布时间】:2017-01-07 18:33:08
【问题描述】:

我尝试自动生成一个 SVG 文件,旨在以特定尺寸 (A4) 打印。我希望在其中使用一条路径,它只允许“用户单位”,而不是“绝对单位”。

在我看来,不可能“发布”具有绝对单位(例如文档大小)和路径任何地方的 SVG 文件,因为我无法让它在查看器中正常工作。

有没有办法让渲染保持一致,比如指定“默认 DPI”?

或者换一种说法:我可以让下面的示例在不放弃绝对单位的情况下在所有查看器中呈现相同的内容吗?

相关:有没有办法强制以下任何应用程序以与其他应用程序相同的方式呈现图像? (例如,我尝试了“转换”的 -density 选项,但我无法使输出与 Inkscape 或 Firefox 的输出相匹配。)


例子:

我创建了一个 SVG 文件,其中包含三个黑色正方形(矩形)和一个红色对角线(路径):

  • 左:用户单位的正方形和对角线
  • 中间:正方形和对角线英寸(在我看来是最合乎逻辑的选择,但不允许)
  • 右:正方形以毫米为单位,对角线以用户单位为单位

在不同的查看器中呈现不同的效果:

  • Inkscape:90 DPI,所有正方形大小相同,红色对角线匹配
  • Firefox:96 DPI?,后正方形变大(或对角变短)
  • 转换:72 DPI,后面的正方形变小(或对角线变长)

Code:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1"
   width="200mm"
   height="100mm"
   >
  <g transform="translate(50,50)">
    <rect
       width="100."
       height="100."
       x="10"
       y="10" />
    <path style="stroke: #ff0000" d="M 10 10 L 110 110" />
  </g>
  <g transform="translate(200,50)">
    <rect
       width="1.111in"
       height="1.111in"
       x="0.1111in"
       y="0.1111in" />
    <path style="stroke: #ff0000" d="M 0.1111in 0.1111in L 1.111in 1.111in" />
  </g>
  <g transform="translate(350,50)">
    <rect
       width="1.111in"
       height="1.111in"
       x="0.1111in"
       y="0.1111in" />
    <path style="stroke: #ff0000" d="M 10 10 L 110 110" />
  </g>
</svg>

Inkscape(我的默认“查看器”):

火狐(注意红线没有到达右下角。我做了截图并随意裁剪):

ImageMagick(转换,除了给出文件名外没有其他选项):

【问题讨论】:

标签: svg


【解决方案1】:

路径标签中的所有维度都以用户为单位。

您不能在 path 标记中指定绝对单位,这就是为什么中间方块中的路径不会呈现的原因。

我发现的最简单的方法是使用 viewbox 设置单位:

  • 以英寸为单位设置宽度和高度。
  • 然后将viewbox设置为相同。
  • 这会将用户单位设置为一英寸。
  • 然后以英寸为单位指定所有尺寸(注意:我在路径标记中使用小写 l 来指定相对移动)

这在 Inkscape 和 Firefox 中正确显示。

<svg
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    width="8in"
    height="4in"
    viewBox="0 0 8 4">

    <g transform="translate(4,0.5)">
        <rect
            width="1.111"
            height="1.111"
            x="0.1111"
            y="0.1111" />
        <path d="M 0.1111,0.1111 l 1.111 1.111" style="stroke: #ff0000;stroke-width:0.01"  />
    </g>
</svg>

【讨论】:

  • 这确实似乎按预期工作! inkscape、ff 和 convert 生成的图像看起来都一样,但大小不同,对应于默认 dpi 中的 96:90:72 比例。至少在inkscape中这很容易改变,有人知道如何转换以产生相同的效果吗? inkscape 和 convert 都可以创建 pdf,打印一个 1.1111 英寸大小的框。
  • 也许我不明白 convert 的 -density 选项。这有效:要将默认 dpi 从 72 更改为 FFs 96,您必须指定 sqrt(96*72)=83.1 作为密度(对于输入文件)。所以 'convert -density 83.1 inputfile.svg outputfile.png' 给出的图像与 firefox 相同。
  • @BlackShift ImageMagick 的convert 命令采用-density XX 参数(在指定输入文件之前)来设置分辨率。
  • @Caleb 是的,我不明白为什么我应该指定 sqrt(96*72)=83.1 作为输入密度,让转换生成与 Firefox 屏幕截图相同的 png 图像(一盒108 像素,包括 1 像素边界)。至少对于 FF 45.0.2 和 ImageMagick 6.7.2-7,可能在较新的版本中有所不同。
  • 我想我明白为什么会这样,但是如果我将viewBox设置为匹配宽度和高度,并且然后使用绝对单位,为什么它不匹配用户单位(在 Inkscape 和 Firefox 中)?是否还有一些不透明的默认 DPI 转换在幕后进行?
【解决方案2】:

我使用Apache Batik 将SVG 文件嵌入到使用iText 的PDF 文件中时遇到了类似的问题。 iText 使用 PDF 标准 72 DPI,而 Batik 使用 96。

要使图像在 PDF 文件中正确显示,即缩放,您需要将 SVG 标头中的 width=x cm height=y cm 除以 1.33 (96/72)。

【讨论】:

    猜你喜欢
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 2008-10-26
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多