【问题标题】:Implement svg version of css background-size:cover not working perfectly实现 svg 版本的 css background-size:cover 不能正常工作
【发布时间】:2019-02-06 23:12:53
【问题描述】:

我正在使用 Imagemagick 从预先计算的 svg 生成图像。 svg 来自编译从我们构建的编辑器中捕获的一些信息。在编辑器上,我们使用 css 样式来预览实时更改。

现在,当我们要渲染实际图像时,我们利用基本信息生成一个实际的 svg,然后使用 imagemagick 库将其转换为平面图像。

除了使用 svg 模式实现 css 背景样式的部分外,一切都很完美。 下面是css代码

background-repeat: repeat;
background-size: cover;
background-position: -134px -2px;

下面是生成的svg示例

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
        <svg  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" overflow="visible" fill="#000">
            <defs>
                <pattern id="bg_40b043e9944a4239b118e0b938054afb" x="-67%" y="-1%" width="100%" height="100%">
                <image preserveAspectRatio="xMinYMin slice" width="200" height="200" xlink:href="imagedata" />
                </pattern>
            </defs><rect width="100%" height="100%" fill="url(#bg_40b043e9944a4239b118e0b938054afb)" /></svg>

需要考虑的细节

  1. 父 svg 为 200x200
  2. 原始背景位置为 x:-134px 和 y:-2px,但转换为百分比分别为 -67% 和 -1%。
  3. 没有定位,一切都很完美。

考虑到上述情况,我认为问题出在图案图像 x,y 偏移量(我猜)和宽度/高度上。 下面是背景的 svg 和 css 版本的输出

来自 svg 的渲染图像 Rendered image from svg

带有 css 的 html 版本的快照。 Snapshot of the html version with css 用于背景的图像 The image used for the background

第二个结果是我们始终想要实现的。

用于生成第一张图片的完整 svg

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
        <svg  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" overflow="visible" fill="#000">
        <defs><pattern id="bg_40b043e9944a4239b118e0b938054afb" x="-67%" y="-1%" width="100%" height="100%"><image preserveAspectRatio="xMinYMin slice" width="200" height="200" xlink:href="https://i.stack.imgur.com/YHz1i.jpg"  /></pattern></defs><svg preserveAspectRatio="none" viewBox="0 0 200 200" x="0%" y="0%"><g opacity="1" fill-opacity="1" fill="url(#bg_40b043e9944a4239b118e0b938054afb)" stroke="none" stroke-width="0" stroke-dasharray="0" stroke-dashoffset="0"><rect width="100%" height="100%"   /><svg class="layer" overflow="visible" preserveAspectRatio="none" id="layer_1535228794723_0887552009010049"  width="160.4065" height="38.7969" x="16.75" y="66"><g id="translateLayer" ><g id="effectLayer" fill="#000" stroke="#c01d1d" stroke-width="2" stroke-dasharray="1" stroke-linecap="butt" stroke-linejoin="round"><svg width="100%" height="100%" viewBox="0 -26.09375 144.59375 29.6875" preserveAspectRatio="none" overflow="hidden"><g  font-size="25" font-family="ABeeZee" font-style="Normal" font-stretch="Normal" font-weight="400"><text y="-3"><tspan x="0">T</tspan><tspan x="14">e</tspan><tspan x="27">x</tspan><tspan x="40">t</tspan><tspan x="50"> </tspan><tspan x="57">o</tspan><tspan x="72">k</tspan><tspan x="85"> </tspan><tspan x="92">h</tspan><tspan x="107">e</tspan><tspan x="121">r</tspan><tspan x="131">e</tspan></text></g></svg></g></g></svg></g></svg></svg>

感谢任何帮助!

【问题讨论】:

  • 您的 Imagemagick 版本、日期和平台是什么。 convert -version。您在 Imagemagick 中使用的是什么 SVG 渲染器。它可以使用自己的内部 MSVG/XML 或 RSVG 委托或 Inkscape 以获得更高的质量和准确性。检查convert -list format 并查看SVG 的行并查看它使用的是哪个渲染器。如果它说 XML,那么我建议您安装 RSVG 或更好的 Inkscape。在您的系统上安装 Inkscape 意味着您不必像使用 RSVG 那样重新编译 Imagemagick,前提是您使用的是现代版本的 Imagemagick。
  • 您上面的 SVG 文件不会像您显示的任何图像那样呈现,无论是通过 Imagemagick convert with RSVG 在我的 Chrome 浏览器中显示。那是用于创建两个图像的同一个 SVG 文件吗?请发布用于生成其他两个示例结果的实际 SVG 文件。
  • @fmw42 用于该模式的图像是 base64 编码的并且很大,所以我剥离了它们。其次,我认为这与 imagemagick 库无关。使用 svg 模式实现 css background-size:cover;background-position:x y 的正确方法。会完美呈现
  • @fmw42 我已更新以包含完整的 svg 文件
  • @WebICT By Leo。 ImageMagick with RSVG abort traps on your SVG file for me using IM 6.9.10.11 Q16 Mac OSX 并生成仅带有红色文本的图像。我的 GraphicConverter 工具完全显示它,但粉红色背景区域的颜色错误。将 ImageMagick 与它的内部 MSVG 一起使用,会产生一个只有背景而没有文本的输出。也许您的 SVG 文件不符合正确的 SVG 语法。

标签: php css svg


【解决方案1】:

只有明确输入背景图片的大小,才能实现您想要的效果。 CSS 可以将图像沿其固有大小平铺,因为图像本身就是它的主题。在 SVG 中,pattern 是图像的父元素,tile 的大小与图像的大小是独立设置的。

第二个复杂因素来自widthheight 的百分比与引用&lt;rect&gt; 的宽度和高度相关。和 100% 都导致瓷砖具有与矩形相同的大小。这也意味着,无论您设置什么,图块的纵横比与 引用 元素的纵横比具有固定关系,而不是包含的图像。

您需要保留图像为图案设置的纵横比。最稳定的方法是使用用户空间坐标,因为当&lt;rect&gt; 的纵横比发生变化时,百分比总是会发生变化。

设置patternUnits="userSpaceOnUse",保留图片的原始大小(图片偏移量需要做相应的缩放),然后你需要设置一个patternTransform=scale(...)来适应你的&lt;rect&gt;的图案平铺尺寸@ 987654328@ 可以。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     width="200" height="200" overflow="visible" fill="#000">
  <defs>
    <pattern id="bg_40b043e9944a4239b118e0b938054afb"
         patternUnits="userSpaceOnUse" x="-2010" y="-30" width="4500" height="3000"
         patternTransform="scale(0.0667)">
      <image width="4500" height="3000" xlink:href="https://i.stack.imgur.com/YHz1i.jpg"  />
    </pattern>
  </defs>
  <rect width="100%" height="100%" fill="url(#bg_40b043e9944a4239b118e0b938054afb)" />
</svg>

(这实际上与您的 CSS 引用的结果相同。)

【讨论】:

  • 请问您是如何得出 patterntransForm 的比例值的? @ccprog
  • 图像的高度小于其宽度,因此要覆盖视口,高度定义了最小比例:视口高度/图像高度 = 200 / 3000。
猜你喜欢
  • 2023-03-16
  • 2011-12-13
  • 2012-07-09
  • 1970-01-01
  • 2016-03-06
  • 2011-06-13
  • 2023-01-11
  • 1970-01-01
  • 2012-05-04
相关资源
最近更新 更多