Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
shakiba committed Sep 23, 2014
0 parents commit 9e2da76
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
/.settings/
/.project
/node_modules/
/npm-debug.log
/exported
15 changes: 15 additions & 0 deletions README.md
@@ -0,0 +1,15 @@
## svgexport

svgexport is a CLI for exporting SVG files to PNG/JPEG images using Node.js and PhantomJS.

#### Installation
```
npm install svgexport -g
```

#### Usage
```
svgexport datafile
```

See test/test.json for datafile example.
28 changes: 28 additions & 0 deletions package.json
@@ -0,0 +1,28 @@
{
"name": "svgexport",
"version": "0.1.3",
"description": "",
"author": "Ali Shakiba",
"keywords": [
"svg",
"export",
"rasterize",
"png",
"jpeg",
"jpg"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/shakiba/svgexport.git"
},
"dependencies": {
"phantomjs": ">= 0.2.0",
"async": "~0.9.0"
},
"main": "svgexport.js",
"bin": {
"svgexport" : "svgexport-cli.js"
},
"preferGlobal": "true"
}
2 changes: 2 additions & 0 deletions svgexport-cli.js
@@ -0,0 +1,2 @@
#!/usr/bin/env node
require('svgexport');
166 changes: 166 additions & 0 deletions svgexport.js
@@ -0,0 +1,166 @@
var webpage = null;
try {
webpage = require('webpage');
} catch (e) {
}

if (!webpage) {

var path = require('path');

if (process.argv.length !== 3) {
console.error('Usage: svgexport datafile');
process.exit();
}

var data = path.resolve(process.cwd(), process.argv[2]);
var base = path.dirname(data);
data = require(data);

var commands = [];

if (!Array.isArray(data)) {
data = [ data ];
}
data.forEach(function(entry) {
if (!Array.isArray(entry.dest)) {
entry.dest = [ entry.dest ];
}
entry.dest.forEach(function(dest) {
dest = dest.split(/\s+/);
var c = {};
c.src = entry.src;
c.src = path.resolve(base, c.src);
c.file = dest.shift();
c.file = path.resolve(base, c.file);
c.format = /.(jpeg|jpg)$/.test(c.file) ? 'jpeg' : 'png';
c.quality = 100;
c.scale = 1;
var param = dest.shift();
var match;
if (param && (match = /^(\d+)\%$/i.exec(param))) {
quality = match[1];
param = dest.shift();
}
if (match = /^(\d+):(\d+)$/i.exec(param)) {
c.left = 0;
c.top = 0;
c.width = match[1];
c.height = match[2];
} else if (match = /^(\d+):(\d+):(\d+):(\d+)$/i.exec(param)) {
c.left = match[1];
c.top = match[2];
c.width = match[3];
c.height = match[4];
} else {
console.log("Invalid output!");
return;
}
param = dest.shift();
if (param) {
if (match = /^(\d+)x$/i.exec(param)) {
c.scale = match[1];
c.left *= c.scale;
c.top *= c.scale;
c.width *= c.scale;
c.height *= c.scale;
} else if (match = /^(\d+)w$/i.exec(param)) {
var width = match[1];
c.scale = width / c.width;
c.left *= c.scale;
c.top *= c.scale;
c.width = width;
c.height *= c.scale;
} else if (match = /^(\d+)h$/i.exec(param)) {
var height = match[1];
c.scale = height / c.height;
c.left *= c.scale;
c.top *= c.scale;
c.width *= c.scale;
c.height = height;
} else if (match = /^(\d+):(\d+)$/i.exec(param)) {
var height = match[1];
var width = match[2];
var scalex = width / c.width;
var scaley = height / c.height;
c.scale = Math.max(scalex, scaley);
c.left = c.left * c.scale + (c.width * c.scale - width) / 2;
c.top = c.top * c.scale + (c.height * c.scale - height) / 2;
c.width = width;
c.height = height;
}
}

commands.push(c);
});
});

commands = JSON.stringify(commands);

var execFile = require('child_process').execFile;
var phantom = path.resolve(__dirname,
'./node_modules/phantomjs/bin/phantomjs');
execFile(process.execPath, [ phantom, __filename, commands ], function(err,
stdout, stderr) {
if (err) {
console.log(err);
} else if (stdout.length > 0) {
console.log(stdout.toString().trim());
} else if (stderr.length > 0) {
console.log(stderr.toString().trim());
}
});

} else {

try {
if (phantom.args.length !== 1) {
console.error('Error: Invalid commands!');
phantom.exit();
}

var async = require('async');

var commands = JSON.parse(phantom.args[0]);

if (!Array.isArray(commands)) {
commands = [ commands ];
}

async.each(commands, function(cmd, done) {
var page = webpage.create();
page.open(cmd.src, function(status) {
if (status !== 'success') {
console.error('Error: Unable to load ' + cmd.src + ' (' + status
+ ')');
done();
return;
}

page.clipRect = cmd;
page.zoomFactor = cmd.scale;
setTimeout(function() {
page.render(cmd.file, {
format : cmd.format,
quality : cmd.quality
});
console.log(strcmd(cmd));
done();
}, 0);
});
}, function(err) {
err && console.log(err);
phantom.exit();
});
} catch (e) {
console.error(e);
phantom.exit();
}
}

function strcmd(cmd) {
return cmd.src + ' ' + cmd.file + ' ' + cmd.format + ' ' + cmd.quality + '%'
+ ' ' + cmd.scale + 'x' + ' ' + cmd.left / cmd.scale + ':'
+ cmd.top / cmd.scale + ':' + cmd.width / cmd.scale + ':'
+ cmd.height / cmd.scale + ' ' + cmd.width + ':' + cmd.height;
}
14 changes: 14 additions & 0 deletions test/test.json
@@ -0,0 +1,14 @@
[ {
"src" : "test.svg",
"dest" : [
"../exported/32h.png 16:16 32h",
"../exported/32w.png 16:16 32w",
"../exported/2x.png 16:16 2x",
"../exported/32-32.png 16:16 32:32",
"../exported/64-32.png 16:16 64:32",
"../exported/32-64.png 16:16 32:64",
"../exported/offset.png 8:8:8:8 32:32",
"../exported/jpeg-low.png 1% 16:16 320:320",
"../exported/jpeg-high.jpg 100% 16:16 320:320"
]
} ]
19 changes: 19 additions & 0 deletions test/test.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9e2da76

Please sign in to comment.