是否可以只删除只有填充而没有描边的形状?

问题描述 投票:0回答:1

我只想保留此地图上没有填充的形状:https://commons.wikimedia.org/wiki/File:Antarctica_in_the_World_(yellow).svg 显然,我不想手动删除所有其他的...

是否可以只删除只有填充而没有描边的形状? 也许通过编辑文件的代码?我不知道该怎么做,但我知道如果需要的话如何使用正则表达式。

谢谢您的帮助。

svg fill inkscape stroke
1个回答
1
投票

您可能会使用 inkscape 的命令行,但我认为自定义 java 脚本更方便,因为您可以立即预览输出。

/**
* fetch data asynchronously
*/
( async()=>{
  let url="https://upload.wikimedia.org/wikipedia/commons/b/b6/Antarctica_in_the_World_%28yellow%29.svg"
  let fetchedData = await (fetch(url));
  let markup = await fetchedData.text()
  // remove tabs and newlines
   markup = markup.replaceAll('\t', '').replace(/[\n\r\t]/g, "")
  
  // parse svg
  let svg = new DOMParser().parseFromString(markup, 'text/html').querySelector('svg')
  
  /**
  * cleanup:
  * remove AI metadata 
  * and forreignObjects
  */
  let remove = svg.querySelectorAll('foreignObject, #adobe_illustrator_pgf')
  remove.forEach(el=>{
    el.remove()
  })
  
  // unwrap switch
  let switchEl = svg.querySelector('switch');
  let switchCnt = switchEl.children[0]
  switchEl.parentNode.insertBefore(switchCnt, switchEl)
  switchEl.remove()
  
  let paths = svg.querySelectorAll('path, polygon, polyline')
  paths.forEach(path=>{
    let stroke = path.getAttribute('stroke')
    let fill = path.getAttribute('fill')
    if(fill &&!stroke){
      path.remove()
    }
  })
  
  // remove empty groups
  let groups = svg.querySelectorAll('g')
  groups.forEach(g=>{
    if(!g.querySelectorAll('path, polygon, rect, circle, ellipse, line, polyline, text').length){
      g.remove()
    }
  })

  
  // render preview
  preview.append(svg)
  
  // cleanup whitespace and create download
  let markupNew = new XMLSerializer().serializeToString(svg)
  .replace(/\ {2,}/g, " ")
  .replace(/[\n\r\t]/g, "")
  .replaceAll('>', '>\n')
  
  let blob = new Blob([markupNew], {type:'image/svg+xml'})
  output.value = markupNew;
  fileSize.textContent = +(blob.size /1024/1024).toFixed(3)+' KB'
  btnDownload.href = URL.createObjectURL(blob)

  
})()
svg {
  width: 100%;
  height: auto;
}

textarea {
  width: 100%;
  min-height: 10em;
  display: block;
}
<p><a id="btnDownload" href="" download="new.svg">Download</a> <span id="fileSize"></span> </p>
<div id="preview"></div>
<h3>Output</h3>
<textarea id="output"></textarea>

如何运作

  1. 我们正在获取 svg 文件
  2. 通过
    new DOMParser()
  3. 解析它的标记
  4. 查询所有
    path
    polygon
    元素(地图中的形状通常可以是路径或多边形)
  5. 循环遍历所有路径元素并通过
    element.getAttribute()
    检查它们的填充和描边属性:如果路径有填充但没有描边属性,我们可以删除此项
  6. 创建一个 blob 和一个对象 URL 以添加下载链接(在 SO 片段中不起作用)

清理(可选)

此外,我们可以删除一些专有的 Adobe Illustrator 元数据(用于预览图像、编辑器设置和资源等)。
我们还可以删除空组或未使用的定义。
这样我们就可以显着减小文件大小。

测试:codepen 示例

© www.soinside.com 2019 - 2024. All rights reserved.