Skip to content

Instantly share code, notes, and snippets.

@kmxz
Created November 27, 2015 11:33
Show Gist options
  • Save kmxz/ec8991f2df99c68bc36b to your computer and use it in GitHub Desktop.
Save kmxz/ec8991f2df99c68bc36b to your computer and use it in GitHub Desktop.
The designer gave me SVG images exported from PhotoShop, which cannot be supported by Android Studio. So I wrote this script to convert SVG to PNGs of different sizes needed in Android projects.
#!/usr/bin/phantomjs
var fs = require('fs');
var system = require('system');
var webPage = require('webpage');
var args = system.args;
if (args.length != 4) {
console.error('ERROR: Please specify 3 arguments: [input svg file], [res directory] and [output image width (mdpi)].');
phantom.exit();
}
var arg0 = args[1]; // input file
var arg1 = args[2]; // output res/
var arg2 = args[3]; // image width for mdpi
var ratios = {
'drawable-ldpi': 0.75,
'drawable-mdpi': 1,
'drawable-hdpi': 1.5,
'drawable-xhdpi': 2,
'drawable-xxhdpi': 3,
'drawable-xxxhdpi': 4
};
var fileBaseName = arg0.substring(arg0.lastIndexOf('/'), arg0.lastIndexOf('.'));
var outputs = fs.list(arg1).filter(function (name) {
return ratios.hasOwnProperty(name);
});
var content = fs.read(arg0);
var parser = new DOMParser();
var svgDoc = parser.parseFromString(content, 'image/svg+xml');
var root = svgDoc.rootElement;
if (!root || root.tagName.toLowerCase() !== 'svg') {
console.error('ERROR: No valid SVG file supplied.');
phantom.exit();
}
var vb = root.getAttribute('viewBox');
if (!vb) {
console.error('ERROR: ViewBox not specified in SVG.');
phantom.exit();
}
var vbp = vb.split(/\s+/g).map(function (item) { return parseFloat(item); });
var w = parseFloat(root.getAttribute('width'));
var h = parseFloat(root.getAttribute('height'));
if (isNaN(w) || isNaN(h)) {
console.error('ERROR: Width/height not specified in SVG.');
phantom.exit();
}
if (vbp.length !== 4 || vbp[0] !== 0 || vbp[1] !== 0 || vbp[2] !== w || wbp[3] !== h) {
console.warn('WARNING: ViewBox does not match width/height specifications.');
}
var mdpiW = parseFloat(arg2);
if (isNaN(mdpiW)) {
console.error('ERROR: Wrong output width specified.');
phantom.exit();
}
var mdpiH = mdpiW * h / w;
console.log('INFO: source width is ' + w + ', height is ' + h + '.');
var finishedFlags = outputs.map(function () { return false; })
outputs.forEach(function (output, index) {
var ratio = ratios[output];
var tw = Math.round(mdpiW * ratio);
var th = Math.round(mdpiH * ratio);
root.setAttribute('width', tw);
root.setAttribute('height', th);
var xmls = new XMLSerializer();
var page = webPage.create();
page.viewportSize = { width: tw, height: th };
page.open('data:image/svg+xml;base64,' + window.btoa(xmls.serializeToString(svgDoc)), function (status) {
page.render(arg1 + '/' + output + fileBaseName + '.png', { format: 'png' });
finishedFlags[index] = true;
console.log('INFO: Output ' + tw + 'x' + th + ' image to ' + output + fileBaseName + '.png.');
if (finishedFlags.every(function (item) { return item; })) {
phantom.exit();
}
})
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment