jankovicsandras / imagetracerjs

Simple raster image tracer and vectorizer written in JavaScript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SVG string passed to a variable returns undefined

avidsapp opened this issue · comments

I am attempting to trace raster images to be used for three.js extrusions. In order to do so, I need to assign the SVG string to a variable, like:

var svgStr = ImageTracer.imageToSVG('./clipArt/225.png');

I am able to verify an SVG string is created via alert, but when passed to a variable and checking via console.log("svgStr: " + svgStr); , it results in svgStr: undefined.

I have tried several iterations using the different examples provided, but to no avail. I am doing this in React and Typescript. Any help would be appreciated.

Hi,

Can you share a bit more context/code?
You can also try to use tracedata, the geometry directly instead of the SVG string. It's a bit undocumented, sadly, but here's an example: https://github.com/jankovicsandras/imagetracerjs/blob/master/simplify_interop.html

The PNG being tested can be found here. Its SVG code used to compare via exampleSvg below can be found here.

The intention is to convert the PNG to SVG and then load it into the three.js scene via SVGLoader.

var imgd = "";
var svgStr = "";

// Logs svgStr: undefined
// Alerts "<svg width="84" height="84" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.6" ><path ..."
svgStr = ImageTracer.imageToSVG(
    url,
    alert,
);

// Logs svgStr: undefined 
svgStr = ImageTracer.imageToSVG(url);

// Logs svgStr: undefined
svgStr = ImageTracer.imageToSVG(
  url, 
  ImageTracer.appendSVGString, 
  { ltres:0.1, qtres:1, scale:10, strokewidth:5 }
);


// Logs svgStr: undefined
// Alerts <svg width="84" height="84" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.6" ><path ..."
const foo = document.createElement('div');
foo.setAttribute("id", "background-content");
svgStr = ImageTracer.imageToSVG(
  url, 
  function(svgstr){
    ImageTracer.appendSVGString(svgstr, "background-content");
    alert( svgstr );
  }
);

// Logs svgStr: undefined
// Alerts {"layers":[[{"segments":[{"type"...
svgStr = ImageTracer.imageToTracedata(
    url,
    function(tracedata){ alert( JSON.stringify( tracedata ) ); },
    { ltres:0.1, qtres:1, scale:10 }
);

// Logs svgStr: 
// Alerts <svg width="84" height="84" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.6" ><path ..."
ImageTracer.loadImage(
  url,
  function(Canvas){
  
    imgd = ImageTracer.getImgdata( Canvas );
    
    svgStr = ImageTracer.imagedataToSVG( imgd, { scale:5 } );

    alert(svgStr);
    
  }
);

console.log("svgStr: " + svgStr);

// Produces expected results
const exampleSvg = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 54.8 44.4" style="enable-background:new 0 0 54.8 44.4;" xml:space="preserve"><g><g><path d="M51.1,1.7c-0.2-0.3-0.3-0.6-0.5-0.9L50.1,0l-3.4,2L8,24.3l0,0l-7.2,4.2L0,29l0.4,0.9c0.2,0.3,0.3,0.6,0.5,0.9    C8.6,44.1,26.2,48.4,40,40.5C53.9,32.5,58.9,15.1,51.1,1.7z M43.1,6.3C43.1,6.3,43.1,6.3,43.1,6.3c5.2,9.1,1.8,20.9-7.6,26.3    c-9.4,5.4-21.4,2.5-26.6-6.6c0,0,0,0,0,0L43.1,6.3z M39,38.7c-12.9,7.4-29.2,3.4-36.4-9l4.6-2.6c5.8,10,18.9,13.3,29.3,7.3    c10.4-6,14.1-19,8.3-29.1l2.8-1.6l1.7-1C56.6,15.1,51.9,31.3,39,38.7z M34.9,29.6l-2.5-4.3l-1.7,1l2.5,4.3L34.9,29.6z M42.2,18.8    l-4.8-1.3l-0.5,1.9l4.8,1.3L42.2,18.8z M23.4,27.2l-1.9-0.5l-1.3,4.8l1.9,0.5L23.4,27.2z"></path></g></g></svg>';

const loader = new SVGLoader();
const svgData = loader.parse(svgStr);

...

I saw getsvgstring(), but still no luck.

var svgStr = "";
ImageTracer.imageToTracedata(
      url,
      function(tracedata){ 
        // alerts tracedate
        alert( JSON.stringify( tracedata ) );
        svgStr = ImageTracer.getsvgstring(tracedata, options);
        // alerts a proper svg string
        alert(svgStr);
        return svgStr;
      },
      options
);
// "svgStr is type of: string"
console.log("svgStr is a type of: " + typeof(svgStr));
// ""
console.log(svgStr)

Please check the API.

imageToSVG and imageToTracedata do not return anything. (This is because they load the image, which is an asynchronous process that don't return, but calls a callback function when ready.)

So this doesn't work:

svgStr = ImageTracer.imageToSVG(...); // Incorrect

The correct usage is:

ImageTracer.imageToSVG(
	'input.png',
	function(svgstr){ 
            
            // Do your processing here
            alert( svgstr );
            
        },
	'posterized2'// option preset, see https://github.com/jankovicsandras/imagetracerjs/blob/master/options.md
);

or

function next_processing_step( svgstr ){

  // TODO: Three.js processing here
  alert(svgstr);

}

ImageTracer.imageToSVG( 'input.png', next_processing_step );

Thanks for clarifying. This resolved my issue.