Code Monkey home page Code Monkey logo

node-potrace's Introduction

node-potrace

A NodeJS-compatible fork of Potrace in JavaScript with some additions, which is in turn a port of the original Potrace — a tool for tracing bitmaps.

Node.js CI

Example and demo

Original image Potrace output Posterized output

(Example image inherited from online demo of the browser version)

Usage

Install

npm install potrace

Basic usage

var potrace = require('potrace'),
    fs = require('fs');

potrace.trace('./path/to/image.png', function(err, svg) {
  if (err) throw err;
  fs.writeFileSync('./output.svg', svg);
});

You can also provide a configuration object as a second argument.

var params = {
  background: '#49ffd2',
  color: 'blue',
  threshold: 120
};

potrace.trace('./path/to/image.png', params, function(err, svg) {
  /*...*/
});

If you want to run Potrace algorithm multiple times on the same image with different threshold setting and merge results together in a single file - posterize method does exactly that.

potrace.posterize('./path/to/image.png', { threshold: 180, steps: 4 }, function(err, svg) {
  /*...*/
});

// or if you know exactly where you want to break it on different levels

potrace.posterize('./path/to/image.png', { steps: [40, 85, 135, 180] }, function(err, svg) {
  /*...*/
});

Advanced usage and configuration

Both trace and posterize methods return instances of Potrace and Posterizer classes respectively to a callback function as third argument.

You can also instantiate these classes directly:

var potrace = require('potrace');

// Tracing

var trace = new potrace.Potrace();

// You can also pass configuration object to the constructor
trace.setParameters({
  threshold: 128,
  color: '#880000'
});

trace.loadImage('path/to/image.png', function(err) {
  if (err) throw err;

  trace.getSVG(); // returns SVG document contents
  trace.getPathTag(); // will return just <path> tag
  trace.getSymbol('traced-image'); // will return <symbol> tag with given ID
});

// Posterization

var posterizer = new potrace.Posterize();

posterizer.loadImage('path/to/image.png', function(err) {
  if (err) throw err;
  
  posterizer.setParameter({
    color: '#ccc',
    background: '#222',
    steps: 3,
    threshold: 200,
    fillStrategy: potrace.Posterize.FILL_MEAN
  });
  
  posterizer.getSVG();
  // or
  posterizer.getSymbol('posterized-image');
});

Callback function provided to loadImage methods will be executed in context of the Potrace/Posterizer instance, so if it doesn't go against your code style - you can just do

new potrace.Potrace()
  .loadImage('path/to/image.bmp', function() {
    if (err) throw err;
    this.getSymbol('foo');
  });

Jimp module is used on the back end, so first argument accepted by loadImage method could be anything Jimp can read: a Buffer, local path or a url string. Supported formats are: PNG, JPEG or BMP. It also could be a Jimp instance (provided bitmap is not modified)

Parameters

Potrace class expects following parameters:

  • turnPolicy - how to resolve ambiguities in path decomposition. Possible values are exported as constants: TURNPOLICY_BLACK, TURNPOLICY_WHITE, TURNPOLICY_LEFT, TURNPOLICY_RIGHT, TURNPOLICY_MINORITY, TURNPOLICY_MAJORITY. Refer to this document for more information (page 4)
    (default: TURNPOLICY_MINORITY)
  • turdSize - suppress speckles of up to this size
    (default: 2)
  • alphaMax - corner threshold parameter
    (default: 1)
  • optCurve - curve optimization
    (default: true)
  • optTolerance - curve optimization tolerance
    (default: 0.2)
  • threshold - threshold below which color is considered black. Should be a number in range 0..255 or THRESHOLD_AUTO in which case threshold will be selected automatically using Algorithm For Multilevel Thresholding
    (default: THRESHOLD_AUTO)
  • blackOnWhite - specifies colors by which side from threshold should be turned into vector shape
    (default: true)
  • color - Fill color. Will be ignored when exporting as <symbol>. (default: COLOR_AUTO, which means black or white, depending on blackOnWhite property)
  • background - Background color. Will be ignored when exporting as <symbol>. By default is not present (COLOR_TRANSPARENT)

Posterizer class has same methods as Potrace, in exception of .getPathTag(). Configuration object is extended with following properties:

  • fillStrategy - determines how fill color for each layer should be selected. Possible values are exported as constants:
    • FILL_DOMINANT - most frequent color in range (used by default),
    • FILL_MEAN - arithmetic mean (average),
    • FILL_MEDIAN - median color,
    • FILL_SPREAD - ignores color information of the image and just spreads colors equally in range 0..<threshold> (or <threshold>..255 if blackOnWhite is set to false),
  • rangeDistribution - how color stops for each layer should be selected. Ignored if steps is an array. Possible values are:
    • RANGES_AUTO - Performs automatic thresholding (using Algorithm For Multilevel Thresholding). Preferable method for already posterized sources, but takes long time to calculate 5 or more thresholds (exponential time complexity)
      (used by default)
    • RANGES_EQUAL - Ignores color information of the image and breaks available color space into equal chunks
  • steps - Specifies desired number of layers in resulting image. If a number provided - thresholds for each layer will be automatically calculated according to rangeDistribution parameter. If an array provided it expected to be an array with precomputed thresholds for each layer (in range 0..255)
    (default: STEPS_AUTO which will result in 3 or 4, depending on threshold value)
  • threshold - Breaks image into foreground and background (and only foreground being broken into desired number of layers). Basically when provided it becomes a threshold for last (least opaque) layer and then steps - 1 intermediate thresholds calculated. If steps is an array of thresholds and every value from the array is lower (or larger if blackOnWhite parameter set to false) than threshold - threshold will be added to the array, otherwise just ignored.
    (default: Potrace.THRESHOLD_AUTO)
  • all other parameters that Potrace class accepts

Notes:

  • When number of steps is greater than 10 - an extra layer could be added to ensure presence of darkest/brightest colors if needed to ensure presence of probably-important-at-this-point details like shadows or line art.
  • With big number of layers produced image will be looking brighter overall than original due to math error at the rendering phase because of how layers are composited.
  • With default configuration steps, threshold and rangeDistribution settings all set to auto, resulting in a 4 thresholds/color stops being calculated with Multilevel Thresholding algorithm mentioned above. Calculation of 4 thresholds takes 3-5 seconds on average laptop. You may want to explicitly limit number of steps to 3 to moderately improve processing speed.

Thanks to

License

The GNU General Public License version 2 (GPLv2). Please see License File for more information.

node-potrace's People

Contributors

arcanis avatar ertrzyiks avatar iwasawafag avatar iwsfg avatar karlhorky avatar markacola avatar privatenumber avatar tooolbox avatar wendorf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

node-potrace's Issues

Can this run in the browser?

It is not exactly clear in the Readme if this can run in the browser too. From the source code, it looks like it should be possible, but I might have missed something.

If it is possible to run it in the browse, maybe we could update the Readme to clarify?

Typo in README

Hi,

The Advanced usage and configuration section of the README has a small typo in the demo code. There is a missing r in the Posterizer's constructor name.

// current 
var posterizer = new potrace.Posterize();
// corrected
var posterizer = new potrace.Posterizer();

Path Direction Issue

Hey,

We have been using the "web" version of this library in our application, and now we're trying to achieve the same functionality by using this package, but the generated path is different.

Here's an example where we feed a simple ring shape to both versions:

Screenshot 2020-10-30 at 13 09 20
This package generates a path that consists of two circles, both with a counter-clockwise direction.

Screenshot 2020-10-30 at 13 09 30
On the other hand, the web version produces these circles, but one of them has a clockwise direction.

Based on some research, the difference in the direction of the paths is what creates the "cutout" shapes that we want, and that's what the "web" version produces.

Any ideas on how to fix this?

The configuration we're using is:
turnPolicy: 'minority', turdSize: 3, optCurve: true, alphaMax: 1, optTolerance: 2

Cannot read property 'bitmap' of undefined

Hello, I'm using gatsby-plugin-sharp, and I've got the following error message when generating thumbnails:

TypeError: Cannot read property 'bitmap' of undefined
    at Potrace._processLoadedImage (/Users/svengaubert/workspace/fullstackrocket/gatsby-stripe-netlify-cms-tailwindcss/node_modules/potrace/lib/Potrace.js:1002:35)
    at Jimp.<anonymous> (/Users/svengaubert/workspace/fullstackrocket/gatsby-stripe-netlify-cms-tailwindcss/node_modules/potrace/lib/Potrace.js:1050:14)
    at Timeout._onTimeout (/Users/svengaubert/workspace/fullstackrocket/gatsby-stripe-netlify-cms-tailwindcss/node_modules/@jimp/core/dist/index.js:354:25)
Error: Unsupported MIME type: image/webp

After some investigations, it seems JIMP doesn't support webp and sends back the error "Error: Unsupported MIME type: image/webp". But potrace doesn't check this error, and directly pass a null image to _processLoadedImage, as we can see here:

self._processLoadedImage(img);

Would it be possible to check the error before calling _processLoadedImage ?

Thanks

Handle PNG alpha

Hello,

Love this package.
My only issue is that alpha channel in png images are treated as #ffffff white, so doing a trace on a png image with white in it will treat the two colors the same. Preferably I would only want to trace the outline of the PNG (i.e. only use the alpha channel).

Is there a way to do this or could it be added?

Errant line when tracing along antialiased edge

I've encountered an odd issue when tracing a seemingly normal image. An errant line appears along the right side of the "S" where the image ends.

This is the original image:
original image

This is the SVG created from the trace:
traced SVG

Any ideas on why this is happening? I'm thinking it has something to do with the antialiased edge of the "S" butting up against the edge of the image, but I would think that is a pretty typical use-case, and I've only seen it happen with this one particular image so far.

I am able correct for this by first adding a pixel of whitespace around the edges of the image, and then the trace works as expected, but I would prefer to not have to do that if it can be avoided.

Whole image as a single path, how to avoid it?

Now in the resulting SVG there is always only 1 "path" object, is it possible to make as many objects as possible, as I understand it, the original library has options that control this moment

SVG options:
--group - group related paths together
--flat - whole image as a single path

Colors in Posterizer output

Sorry, I don't know if the service was designed only to return grayscale or I if I am doing something wrong.

I tried different options, but still, the output from colourful png is always grayscale.

node-potrace results are different from online demo.

On the surface node-potrace works fantastic, but it gets a bit complicated when I want to convert the traced svg icons into fonts. The online demo generates icons that are font friendly but icons generated by node-potrace icons are coming out distorted and weird when converted into fonts. They come out fine as svgs but are unusable as fonts.

I'm using Webfont to convert the icons to fonts and Fontdrop.info to preview the fonts.

  • Function i'm using: potrace.trace()
  • Function parameters: default parameters

Examples

Source Image We Feed To Potrace
Source Image


Online Demo

Resulting SVG

<svg xmlns="http://www.w3.org/2000/svg" id="svg" version="1.1" width="500" height="500"><path d="M262.500 22.903 C 260.300 23.925,256.873 26.503,254.884 28.631 C 246.083 38.046,45.363 279.860,43.774 282.961 C 40.413 289.520,42.061 300.220,47.298 305.834 C 48.509 307.132,51.300 309.163,53.500 310.347 C 57.492 312.495,57.677 312.501,141.750 312.782 C 216.220 313.032,226.000 313.241,226.000 314.580 C 226.000 315.413,221.965 348.361,217.034 387.798 C 207.167 466.704,207.278 464.242,213.271 471.513 C 220.382 480.139,234.177 481.418,242.374 474.212 C 246.333 470.732,454.516 220.376,456.226 217.039 C 459.587 210.480,457.939 199.780,452.702 194.166 C 451.491 192.868,448.830 190.949,446.790 189.903 C 443.229 188.077,439.672 188.000,358.540 188.000 C 274.013 188.000,274.000 188.000,274.000 185.952 C 274.000 184.826,278.035 151.639,282.966 112.202 C 292.833 33.296,292.722 35.758,286.729 28.487 C 280.911 21.429,270.724 19.081,262.500 22.903 M234.924 160.633 C 228.141 214.833,228.143 214.677,234.191 221.564 C 240.661 228.933,235.139 228.444,318.126 229.000 L 392.753 229.500 326.255 309.295 C 289.681 353.183,259.576 388.910,259.355 388.689 C 259.134 388.468,261.709 366.273,265.076 339.367 C 271.859 285.167,271.857 285.323,265.809 278.436 C 259.339 271.067,264.861 271.556,181.874 271.000 L 107.247 270.500 173.745 190.705 C 210.319 146.817,240.424 111.090,240.645 111.311 C 240.866 111.532,238.291 133.727,234.924 160.633 " stroke="none" fill="black" fill-rule="evenodd"/></svg>

Resulting Icon As Font
Icon as font ✔️


Node-Potrace

Resulting SVG

<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500" version="1.1">
<path d="M 265.648 22.027 C 264.080 22.497, 261.380 23.869, 259.648 25.076 C 255.085 28.258, 48.021 276.899, 44.750 283.124 C 40.642 290.943, 41.483 298.064, 47.296 304.684 C 54.062 312.391, 48.330 311.953, 142.875 311.978 L 227.250 312 226.738 314.750 C 226.456 316.262, 222.253 349.478, 217.398 388.562 C 207.388 469.143, 207.484 464.915, 215.488 472.623 C 222.806 479.670, 232.293 480.543, 240.368 474.912 C 244.921 471.738, 451.987 223.087, 455.250 216.876 C 459.358 209.057, 458.517 201.936, 452.704 195.316 C 445.938 187.609, 451.670 188.047, 357.125 188.022 L 272.750 188 273.262 185.250 C 273.544 183.737, 277.747 150.522, 282.602 111.438 C 290.695 46.287, 291.320 40.007, 290.111 35.938 C 288.334 29.957, 281.778 23.685, 275.701 22.155 C 270.502 20.846, 269.625 20.835, 265.648 22.027 M 174.079 189.309 C 137.185 233.576, 107 270.065, 107 270.397 C 107 270.729, 139.318 271, 178.818 271 C 239.152 271, 251.430 271.236, 255.596 272.473 C 263.761 274.897, 270.010 283.028, 269.989 291.200 C 269.983 293.565, 267.296 316.850, 264.018 342.946 C 260.740 369.041, 258.234 390.568, 258.450 390.783 C 258.886 391.219, 393 230.561, 393 229.603 C 393 229.271, 360.682 229, 321.182 229 C 260.848 229, 248.570 228.764, 244.404 227.527 C 236.239 225.103, 229.990 216.972, 230.011 208.800 C 230.017 206.435, 232.704 183.150, 235.982 157.054 C 239.260 130.959, 241.766 109.432, 241.550 109.217 C 241.334 109.001, 210.972 145.042, 174.079 189.309" stroke="none" fill="black" fill-rule="evenodd"/>
</svg>

Resulting Icon As Font
Icon as font


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.