├── .gitignore ├── LICENSE ├── README.md ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | #* 2 | *$ 3 | *.BAK 4 | *.Z 5 | *.bak 6 | *.class 7 | *.elc 8 | *.ln 9 | *.log 10 | *.o 11 | *.obj 12 | *.olb 13 | *.old 14 | *.orig 15 | *.project 16 | *.pyc 17 | *.pyo 18 | *.rej 19 | */.git/* 20 | *~ 21 | ,* 22 | .#* 23 | .DS_Store 24 | .del-* 25 | .make.state 26 | .nse_depinfo 27 | .project 28 | .svn 29 | CVS.adm 30 | RCS 31 | RCSLOG 32 | SCCS 33 | _$* 34 | _svn 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Zac Barton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | autotrace 2 | ======== 3 | 4 | A simple interface for converting raster images into vector graphics using AutoTrace. 5 | 6 | More details about AutoTrace can be found [here][1]. 7 | 8 | 9 | Requirements 10 | -------- 11 | 12 | * [AutoTrace][1] 13 | 14 | 15 | Installation 16 | -------- 17 | 18 | $ npm install -g autotrace 19 | 20 | 21 | Output Formats 22 | -------- 23 | Typical output formats include EPS, AI, SVG, DXF, PDF, MIF and Cairo. All supported output formats can be found by running; 24 | 25 | ```sh 26 | autotrace --help 27 | ``` 28 | 29 | Basic Usage 30 | -------- 31 | Convert a PNG to SVG. 32 | 33 | ```javascript 34 | // input file, options and a callback 35 | autotrace('/path/to/image.png', { 36 | outputFile: '/tmp/out.svg' 37 | }, function(err, buffer) { 38 | if (!err) console.log('done'); 39 | }); 40 | 41 | // options and a callback 42 | autotrace({ 43 | inputFile: '/path/to/image.png' 44 | , outputFile: '/tmp/out.eps' 45 | }, function(err, buffer) { 46 | if (!err) console.log('done'); 47 | }); 48 | 49 | // chaining 50 | autotrace() 51 | .inputFile('/path/to/image.png') 52 | .outputFile('/tmp/out.pdf') 53 | .exec(function(err, buffer) { 54 | if (!err) console.log('done'); 55 | }); 56 | ``` 57 | 58 | Streams 59 | -------- 60 | ```javascript 61 | // stream output to a WriteableStream 62 | autotrace('/path/to/image.png') 63 | .outputFormat('svg') 64 | .stream(function(err, stdout, stderr) { 65 | var writeStream = fs.createWriteStream('/tmp/out.svg'); 66 | stdout.pipe(writeStream); 67 | }); 68 | 69 | // without a callback, .stream() returns a stream 70 | // this is just a convenience wrapper for above. 71 | var writeStream = fs.createWriteStream('/tmp/out.pdf'); 72 | autotrace('/path/to/image.png', {outputFormat: 'pdf'}) 73 | .stream() 74 | .pipe(writeStream); 75 | ``` 76 | 77 | API 78 | -------- 79 | 80 | **autotrace(inputFile, options, callback)** 81 | 82 | The first argument can be either a file path or an options object. The only required option is inputFile (when not passing as the first argument); all others are optional. Refer to the above usage section for examples. 83 | 84 | **Options/Methods** - all of AutoTrace's are supported along with some custom ones. 85 | 86 | *AutoTrace* 87 | 88 | # Refer to AutoTrace's help for details. 89 | man autotrace 90 | 91 | * backgroundColor 92 | * centerline 93 | * colorCount 94 | * cornerAlwaysThreshold 95 | * cornerSurround 96 | * cornerThreshold 97 | * despeckleLevel 98 | * despeckleTightness 99 | * dpi 100 | * errorThreshold 101 | * filterIterations 102 | * inputFormat 103 | * lineReversionThreshold 104 | * lineThreshold 105 | * log 106 | * outputFile 107 | * outputFormat 108 | * preserveWidth 109 | * removeAdjacentCorners 110 | * tangentSurround 111 | * reportProgress 112 | * debugArch 113 | * debugBitmap 114 | * version 115 | * widthWeightFactor 116 | 117 | *Custom* 118 | 119 | * inputFile - path to the input file. 120 | * customBin - set a custom path to the AutoTrace binary. 121 | * binArgs - returns an array of the args to be passed to AutoTrace. 122 | * debugExec - returns the full exec + args as a string. Useful for debugging. 123 | 124 | **Methods** 125 | * exec(callback) - start the tracing process. returns (err, buffer). 126 | * stream - stream the results of the tracing. returns (err, stdout, stderr). 127 | 128 | If a callback (e.g. autotrace(file, callback)) is provided the exec method is automatically called for you. 129 | 130 | [1]: http://autotrace.sourceforge.net/ -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var spawn = require('child_process').spawn; 3 | var PassThrough = require('stream').PassThrough; 4 | 5 | module.exports = AutoTrace; 6 | 7 | function AutoTrace(inputFile, options, callback) { 8 | if (!(this instanceof AutoTrace)) { 9 | return new AutoTrace(inputFile, options, callback); 10 | } 11 | 12 | this.args = []; 13 | this.inputFile; 14 | this.bin = 'autotrace'; 15 | 16 | if (options && typeof options === 'object') { 17 | options.inputFile = inputFile; 18 | } else if (inputFile && typeof inputFile === 'object') { 19 | callback = options; 20 | options = inputFile; 21 | } else if (typeof inputFile === 'string') { 22 | callback = options; 23 | options = {inputFile: inputFile}; 24 | } 25 | 26 | this.init(options); 27 | 28 | if (callback) { 29 | return this.exec(callback); 30 | } 31 | 32 | return this; 33 | } 34 | 35 | AutoTrace.prototype.init = function(options) { 36 | for (var i in options) { 37 | if (this[i] && typeof this[i] === 'function') { 38 | this[i](options[i]); 39 | } 40 | } 41 | }; 42 | 43 | AutoTrace.prototype.backgroundColor = function(color) { 44 | this.args.push('-background-color', color); 45 | return this; 46 | }; 47 | 48 | AutoTrace.prototype.centerline = function(value) { 49 | if (!!value) this.args.push('-centerline'); 50 | return this; 51 | }; 52 | 53 | AutoTrace.prototype.colorCount = function(value) { 54 | this.args.push('-color-count', parseInt(value)); 55 | return this; 56 | }; 57 | 58 | AutoTrace.prototype.cornerAlwaysThreshold = function(value) { 59 | this.args.push('-corner-always-threshold', parseFloat(value)); 60 | return this; 61 | }; 62 | 63 | AutoTrace.prototype.cornerSurround = function(value) { 64 | this.args.push('-corner-surround', parseInt(value)); 65 | return this; 66 | }; 67 | 68 | AutoTrace.prototype.cornerThreshold = function(value) { 69 | this.args.push('-corner-threshold', parseFloat(value)); 70 | return this; 71 | }; 72 | 73 | AutoTrace.prototype.despeckleLevel = function(value) { 74 | this.args.push('-despeckle-level', parseInt(value)); 75 | return this; 76 | }; 77 | 78 | AutoTrace.prototype.despeckleTightness = function(value) { 79 | this.args.push('-despeckle-tightness', parseFloat(value)); 80 | return this; 81 | }; 82 | 83 | AutoTrace.prototype.dpi = function(value) { 84 | this.args.push('-dpi', parseInt(value)); 85 | return this; 86 | }; 87 | 88 | AutoTrace.prototype.errorThreshold = function(value) { 89 | this.args.push('-error-threshold', parseFloat(value)); 90 | return this; 91 | }; 92 | 93 | AutoTrace.prototype.filterIterations = function(value) { 94 | this.args.push('-filter-iterations', parseInt(value)); 95 | return this; 96 | }; 97 | 98 | AutoTrace.prototype.inputFormat = function(value) { 99 | this.args.push('-input-format', value); 100 | return this; 101 | }; 102 | 103 | AutoTrace.prototype.lineReversionThreshold = function(value) { 104 | this.args.push('-line-reversion-threshold', parseFloat(value)); 105 | return this; 106 | }; 107 | 108 | AutoTrace.prototype.lineThreshold = function(value) { 109 | this.args.push('-line-threshold', parseFloat(value)); 110 | return this; 111 | }; 112 | 113 | AutoTrace.prototype.log = function(value) { 114 | if (!!value) this.args.push('-log'); 115 | return this; 116 | }; 117 | 118 | AutoTrace.prototype.outputFile = function(file) { 119 | this.args.push('-output-file', file); 120 | return this; 121 | }; 122 | 123 | AutoTrace.prototype.outputFormat = function(format) { 124 | this.args.push('-output-format', format); 125 | return this; 126 | }; 127 | 128 | AutoTrace.prototype.preserveWidth = function(value) { 129 | if (!!value) this.args.push('-preserve-width'); 130 | return this; 131 | }; 132 | 133 | AutoTrace.prototype.removeAdjacentCorners = function(value) { 134 | if (!!value) this.args.push('-remove-adjacent-corners'); 135 | return this; 136 | }; 137 | 138 | AutoTrace.prototype.tangentSurround = function(value) { 139 | this.args.push('-tangent-surround', parseInt(value)); 140 | return this; 141 | }; 142 | 143 | AutoTrace.prototype.reportProgress = function(value) { 144 | if (!!value) this.args.push('-report-progress'); 145 | return this; 146 | }; 147 | 148 | AutoTrace.prototype.debugArch = function(value) { 149 | if (!!value) this.args.push('-debug-arch'); 150 | return this; 151 | }; 152 | 153 | AutoTrace.prototype.debugBitmap = function(value) { 154 | if (!!value) this.args.push('-debug-bitmap'); 155 | return this; 156 | }; 157 | 158 | AutoTrace.prototype.version = function(value) { 159 | if (!!value) this.args.push('-version'); 160 | return this; 161 | }; 162 | 163 | AutoTrace.prototype.widthWeightFactor = function(value) { 164 | this.args.push('-width-weight-factor', parseFloat(value)); 165 | return this; 166 | }; 167 | 168 | /* custom methods */ 169 | AutoTrace.prototype.inputFile = function(file) { 170 | this.inputFile = file; 171 | return this; 172 | }; 173 | 174 | AutoTrace.prototype.binArgs = function() { 175 | return [].concat(this.args, this.inputFile); 176 | }; 177 | 178 | AutoTrace.prototype.customBin = function(path) { 179 | this.bin = path; 180 | return this; 181 | }; 182 | 183 | AutoTrace.prototype.debugExec = function(value) { 184 | if (!!value) console.log(this.bin, this.binArgs().join(' ')); 185 | return this; 186 | }; 187 | 188 | AutoTrace.prototype.exec = function(callback) { 189 | var err = ''; 190 | var buffer = ''; 191 | var trace = spawn(this.bin, this.binArgs()); 192 | 193 | trace.stdout.on('data', function(data) { 194 | buffer += data; 195 | }); 196 | 197 | trace.stderr.on('data', function(data) { 198 | err += data; 199 | }); 200 | 201 | trace.stdout.on('close', function(code) { 202 | if (callback) { 203 | callback(err || code, buffer ? new Buffer(buffer) : null); 204 | } 205 | }); 206 | }; 207 | 208 | AutoTrace.prototype.stream = function(callback) { 209 | var throughStream; 210 | 211 | if (typeof callback !== 'function') { 212 | throughStream = new PassThrough(); 213 | 214 | callback = function(err, stdout, stderr) { 215 | stdout.pipe(throughStream); 216 | }; 217 | } 218 | 219 | var trace = spawn(this.bin, this.binArgs()); 220 | 221 | callback.call(this, null, trace.stdout, trace.stderr); 222 | 223 | return throughStream || this; 224 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "autotrace", 3 | "description": "A simple interface for converting raster images into vector graphics using AutoTrace.", 4 | "version": "0.0.2", 5 | "author": { 6 | "name": "Zac Barton" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/zacbarton/node-autotrace" 11 | }, 12 | "keywords": [ 13 | "bitmap" 14 | , "image" 15 | , "raster" 16 | , "vector" 17 | , "vectorization" 18 | , "convert" 19 | ] 20 | } 21 | --------------------------------------------------------------------------------