【问题标题】:How to convert an closed path SVG to a 0-1 array如何将封闭路径 SVG 转换为 0-1 数组
【发布时间】:2016-02-17 21:56:21
【问题描述】:

假设有一个 svg,中间有一个封闭的填充矩形,周围有一个 2 点的空白。

<path d="M2 2 H 3 V 3 H 2 Z" fill="transparent" stroke="black"/>

所以我想将其表示为一个二维矩阵,其中所有空白区域都表示为 0,而黑色空间(覆盖区域)表示为 1。所以对于这个示例,它应该是 -

 [
   [0, 0, 0, 0],
   [0, 1, 1, 1],
   [0, 1, 1, 1],
   [0, 1, 1, 1]
 ]

这是一条简单的路径,但我正在尝试找到一种适用于包括贝塞尔曲线在内的复杂路径的方法。实际上,我正在尝试将 SVG 世界地图转换为 0-1 矩阵,以便可以在其上运行一些 AI 算法。

【问题讨论】:

  • 这是不可能的。好吧,这不是“不可能”,但是...在 0-1 矩阵中转换简单路径的想法还不错,但是贝塞尔曲线简直是“奇怪”。你怎么能/你会定义你想要保持的曲线精度?例如,在一个小区域上定义一条曲线,起点和终点可能就足够了,但是如果曲线很宽并且您希望它保持良好的精度,您可能需要几个点来用您的矩阵来表示它。 ..
  • 可以说每个数组元素代表一个 1 * 1 px 的
    。如果svg path passes across that pixelthat pixel (/ part of that px) falls under the closed area 则它得到1 的值,否则0
  • 是的,知道了,但是精度呢?贝塞尔曲线可以代表无限多的点……这就是 svg,矢量点!您可以根据需要调整其大小,这种格式并没有真正的“像素大小”限制......
  • 绘制画布路径并读取像素值。

标签: algorithm image-processing svg


【解决方案1】:

实施了@Robert Longson 的建议。 1) 在画布中绘制 svg 2) 将 ImageData 作为 CanvasContext Array 3) 迭代该数组并形成您的矩阵。 4) getImageData返回的数组是一个平面数组,consecutive 4 array index对应canvas的一个点,分别是r、g、b和alpha(rgba)该点的颜色。

这是一个有效的反应组件。

import React, { Component } from 'react';

export default class IndexPage extends Component {

  constructor(properties) {
    super(properties);
    this.canvasWidth = 1052;
    this.canvasHeight = 580;
  }

  componentDidMount() {
    const mapCanvas = this.refs.canvas;
    const ctx = mapCanvas.getContext('2d');
    const img = new Image();
    img.onload = function() {
      ctx.drawImage(img, 0, 0);
      this.arrayFromSvg();
    }.bind(this);
    img.src = 'World.svg';
  }

  render() {
    return ( < div >
     < div styles={{
        width: this.canvasWidth,
        height: this.canvasHeight
      }
      } >
        < canvas width = {
      this.canvasWidth
      }
      height = {
      this.canvasHeight
      }
      ref = "canvas" >
        < /canvas> < /div >
        < /div>
      );
  }

  arrayFromSvg() {
    const mapCanvas = this.refs.canvas;
    const ctx = mapCanvas.getContext('2d');
    const canvasWidth = mapCanvas.width;
    const canvasHeight = mapCanvas.height;
    const imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight).data;
    const imageToMat = [];

    for (let row = 0, count = -1; row < canvasWidth; row++) {
      imageToMat[row] = [];
      // imageToMat[row][col] = 'rgba(' + imageData[++count] + ', ' + imageData[++count] + ', ' + imageData[++count] + ', ' + imageData[++count] + ')';
      for (let col = 0; col < canvasHeight; col++) {
        if (imageData[++count] + imageData[++count] + imageData[++count] + imageData[++count] > 0) {
          imageToMat[row][col] = 1;
        } else {
          imageToMat[row][col] = 0;
        }
      }
    }
    console.log(imageToMat);
  }
}

【讨论】:

    猜你喜欢
    • 2017-12-19
    • 2020-05-15
    • 1970-01-01
    • 2015-09-21
    • 2014-05-14
    • 2019-04-14
    • 2011-12-06
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多