sapy February 2016

How to convert an closed path SVG to a 0-1 array

Lets say there is a svg with a closed filled rectangle in the middle and around that there's a white space of 2 points .

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

So I want to represent this a 2-d matrix where all the white space are represented as 0 and black spaces (covered area) is represented as 1. so for this example it should be-

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

It's a simple path , but I'm trying to find a way where it would work for complex paths including bezier curve. Actually I'm trying to convert an SVG world map to 0-1 matrix so that I can run some AI algorithms on it .

Answers


sapy February 2016

Implemented @Robert Longson suggestion. 1) Draw the svg in canvas 2) Get ImageData as CanvasContext Array 3) Iterate on that array and form your matrix. 4) Array returned by getImageData is a flat array and consecutive 4 array index correspond to one point of canvas and they are r, g, b and alpha (rgba) of the color of that point.

Here's a working react component .

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] + 

Post Status

Asked in February 2016
Viewed 3,054 times
Voted 12
Answered 1 times

Search




Leave an answer