【问题标题】:How can I scale a raster image to user space units in SVG?如何将光栅图像缩放到 SVG 中的用户空间单位?
【发布时间】:2018-11-14 14:36:33
【问题描述】:

我的问题

给定一个我知道多少像素 (px) 对应于一厘米 (cm) 的光栅图像和一个 SVG 路径,我在其中将用户空间单位定义为取决于浏览器宽度的视图框内的毫米:如何缩放图像,使其始终具有与 SVG 路径相同的每厘米像素比率?

背景

我有代表织物纹理的光栅图像,我想将这些图像与代表一件衣服的一部分的 svg 形状相匹配。我想将织物覆盖在形状上,因为它需要逼真的形状和图像的比例必须匹配。这一切都是动态完成的,这意味着我想为一般情况解决这个问题,而不仅仅是针对一个特定的图像和形状组合。

示例

我已经将我的通用代码和通用代码改编为这个特定的 JS Fiddle 来说明问题并显示我到目前为止的进度以及我遇到的问题: http://jsfiddle.net/nx3vrz94/16/

 <svg id="svgView-1" style="width:90vw" viewBox="0 0 635 334" >
 <path fill-opacity="1" fill="url(#fabric1001)" d="M0 0 L635 0 L334 290 Z " id="1"></path>

 <!--
Image: 1440x1080
horizontally: 
2,5 cm = 51 pixel
= 20,4 pixel per cm
 -->
 <defs>
   <pattern id="fabric1001" 
   patternContentUnits="objectBoundingBox" 
   viewBox="0 0 1 1" 
   preserveAspectRatio="xMidYMid slice" 
   width="100%" height="100%">
   <image xlink:href="https://cdn.shopify.com/s/files/1/0081/1076/8185/products/3.jpg?v=1540031315"         
           x="0" y="0"
           width="1" 
           height="1"
           preserveAspectRatio="xMidYMid slice" />
  </pattern>

 </defs>
</svg>

到目前为止,我设法将图像添加为图案,然后使用 URL 引用填充形状。我不明白的是如何告诉 SVG 该图像中的 20.4 像素对应于 10 个用户空间单位?

【问题讨论】:

  • 你使用模式的方式,它的内容从不重复(从不重复显示)。您是否希望以可能发生重复的方式使用它?您的示例图片不适合这种用途。
  • @ccprog 感谢您的评论。示例图像就是这样,一个测试图像我可以用来得到这个正确的。对于实际使用,图像会更好,并且不会包含校准图案。我不认为我会使用平铺,因为现在每个图像在真实空间中都更大,然后任何路径都将是(如果有意义的话)

标签: image svg


【解决方案1】:

让您的生活更轻松,不要尝试先将图像适合模式,然后再将该模式反复(至少在概念上)适合路径,这样您总共有三个隐式大小转换来跟踪的,当您只需要正确调整图像大小时。

如果我理解正确,您的用户空间单位应该等于 1 毫米。那么,当

  • 2.04 图像像素等于 1mm 等于 1 个用户空间单位
  • 您的图片需要缩放 1 / 2.04
  • 将图像从 1440 × 1080 缩放到 706 × 529(四舍五入,preserveAspectRatio 将负责其余部分)

除了在路径内填充“图案”填充外,您还可以使用剪辑路径从图像中剪切路径形状。 - 这实际上和从一块布上剪下一个部分的过程是一样的,顺便说一句……

<svg id="svgView-1" style="width:90vw" viewBox="0 0 635 334" >
    <clipPath id="clip">
         <path d="M0 0 L635 0 L334 290 Z "></path>
    </clipPath>
    <image xlink:href="https://cdn.shopify.com/s/files/1/0081/1076/8185/products/3.jpg?v=1540031315"         
           x="0" y="0"
           width="706" height="529"
           preserveAspectRatio="xMidYMid slice"
           clip-path="url(#clip)"/>
</svg>

【讨论】:

  • 感谢您的回答。我喜欢你不做这么多尺寸转换的想法。不幸的是,我认为您提出的解决方案并不完全符合我的需要。当我全屏打开它时,路径(22.7)的每厘米像素值与织物光栅图像(21.6)不同。不幸的是,当视图大小发生变化时,将 svg 与路径元素一起缩放是一项硬性要求。
  • 使用路径填充的原因是我想显示空路径,然后用户可以选择一个织物来填充它。一张图说一千多字,所以我截取了整个应用程序到目前为止:imgur.com/a/3gTSZ9g
  • 坦率地说,我不明白你的要求。 “将 svg 与路径元素一起缩放”似乎表明:无论 SVG 以何种尺寸显示,图像的每个细节都应相对于路径的轮廓保持在同一位置。这就是发生的事情。您如何计算这些“每厘米像素”值?
  • 抱歉,显然我说错了,我的意思是路径元素和光栅图像应始终以相同的方式缩放,这意味着现实世界单位中的任何长度(例如 2.5 厘米)都应对应于相同的数量路径和光栅图像中的像素。相应地,我通过获取路径的像素宽度并将其除以以厘米为单位的宽度(用户空间单位/ 10)来获得路径的每厘米像素值。对于光栅图像,我测量一个黑色方块占据的像素宽度,然后将其除以已知的真实世界宽度 2.5 厘米。
  • 那我无法复制你的号码。对我来说,如果我改变屏幕上图形的比例,图像的位置相对于路径永远不会改变。左上角显示的内容保留在左上角,与右下角相同。三个角之间的距离始终代表相同的真实世界距离,并且始终被相同数量的图像内容占用。纵横比被保留,因此所有测量都使用相同的因子进行缩放。据我所知,这正是您所要求的。
猜你喜欢
  • 1970-01-01
  • 2017-11-18
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 2015-01-05
  • 2018-07-30
相关资源
最近更新 更多