jankovicsandras / imagetracerjs

Simple raster image tracer and vectorizer written in JavaScript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Transparency issue

monkeyArms opened this issue · comments

First, thank you for the great library.

I've found an input image that has some transparent regions which are not being rendered correctly in 1.2.5:

compare

The output svg contains most of the transparent regions, but is missing a few. I've opened the svg in Illustrator and the "holes" are being traced, they are just being generated as transparent paths instead of being subtracted from the outer paths.

Here is the source png:
tranparency issue

Here are my settings:

ImageTracer.imageToSVG(
	pngFile,
	function ( svgStr )
	{
		console.log(svgStr);
	},
	{
		ltres:             1,
		qtres:             1,
		pathomit:          8,
		rightangleenhance: false,
		blurradius:        0,
		pal: [
			{
				"r": 0,
				"g": 0,
				"b": 0,
				"a": 0
			},
			{
				"r": 123,
				"g": 219,
				"b": 217,
				"a": 255
			},
			{
				"r": 219,
				"g": 131,
				"b": 248,
				"a": 255
			},
			{
				"r": 230,
				"g": 210,
				"b": 147,
				"a": 255
			},
			{
				"r": 114,
				"g": 159,
				"b": 204,
				"a": 255
			}
		]
	}
);

I've also tried the default settings, a variety of combinations of custom and auto-palettes, and all results tend to have the same issues.

Hi,

Thanks for reporting the issue, I'm working on it.

Hi,

I found what the problem is: the hole handling ( ca. from Line 559 )
is based on a simple bounding-box based solution, but it seems it's not working for complex shapes. The hole is assigned to the wrong parent shape sometimes with this approach.

issue31

I try to find a better solution for this, but it's possible that the only real solution is a point-in-polygon test ( "is the hole startpoint in this shape?" ) on all relevant paths. This would be much slower than the current method.

I plan to implement the point-in-polygon test in the next version, but keep the bounding-box method as an option.

Hello,

It would be awesome to have the option of using the more computationally expensive and accurate algorithm.

This probably is not helpful but in case it is, the following is the most efficient ray-casting algorithm js I've found for a point-in-polygon test. It is a JS port from C, and we've been using it for a few years without issue:

	/**
	 * detect if an [x,y] coordinate is within a polygon defined by an array of [x,y] coordinates
	 * ray-casting algorithm based on:
	 * @see http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html (now defunct)
	 * @see https://web.archive.org/web/20160112180422/https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
	 *
	 * @param {array} point - [x,y]
	 * @param {array} polyArray - an array of [x,y] coordinates
	 * @returns {boolean}
	 */
	pointIsInPoly:
		function ( point, polyArray )
		{
			const x    = point[0],
				  y    = point[1]
			;
			let inside = false,
				i, j, xi, yi, xj, yj, intersect
			;

			for (i = 0, j = polyArray.length - 1; i < polyArray.length; j = i++) {

				xi        = polyArray[i][0];
				yi        = polyArray[i][1];
				xj        = polyArray[j][0];
				yj        = polyArray[j][1];
				intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);

				if (intersect) {
					inside = !inside;
				}
			}

			return inside;
		}

I very much appreciate your work on this - let me know if you accept pull requests or if there is another way I could contribute.

Hi,

This should be fixed in version 1.2.6, please test.

It seems to be working great here, passing all tests. Thank you so much.