Skip to content

Instantly share code, notes, and snippets.

@nidorx
Created September 1, 2018 23:08
Show Gist options
  • Save nidorx/b37fa46dc91e10ec750c2086995a5c30 to your computer and use it in GitHub Desktop.
Save nidorx/b37fa46dc91e10ec750c2086995a5c30 to your computer and use it in GitHub Desktop.
Converter ícones de SVG para PNG (node.js + Inkscape + pngquant). Útil para geração de ícones para aplicações Mobile com diferents densidades.
/**
* Converter ícones de SVG para PNG (node.js + Inkscape + pngquant)
*
* Útil para geração de ícones para aplicações Mobile com diferents densidades.
*
* Se o ícone já existir no diretório de saída, não será processado novamente
*
* https://inkscape.org/en/doc/inkscape-man.html
* https://mijingo.com/blog/exporting-svg-from-the-command-line-with-inkscape
*
* - Instalar Inkscape e adicionar no PATH (C:\Program Files\Inkscape)
* - Baixar o pngquant.exe e copiar para o PATH (C:\windows) https://pngquant.org
* - Configurar SVG_PATH_INPUT, PNG_PATH_OUTPUT, BASE_RESOLUTION e DENSITIES
* - Executar no terminal `node convert-svg-2-png.js`
*/
const fs = require('fs');
const path = require('path');
const child_process = require('child_process');
// Diretório de entrada, onde os arquivos .svg estão
const SVG_PATH_INPUT = path.normalize(__dirname + '/icons/');
// Diretório de saída, dos arquivos png
const PNG_PATH_OUTPUT = path.normalize(__dirname + '/src/assets/');
// A resolução base dos ícones
const BASE_RESOLUTION = 24;
// Densidades das imagens geradas, usadas para aplicações Mobile (Ex. edit.png, [email protected], [email protected])
const DENSITIES = [1, 2, 3];
function parseDir(dir) {
const files = fs.readdirSync(dir);
files.forEach(name => {
const pathSVG = path.join(dir, name);
const pathPNG = pathSVG.replace(SVG_PATH_INPUT, PNG_PATH_OUTPUT);
const stats = fs.statSync(pathSVG);
if (stats.isDirectory()) {
// Cria o diretório png
if (!fs.existsSync(pathPNG)) {
fs.mkdirSync(pathSVG.replace(SVG_PATH_INPUT, PNG_PATH_OUTPUT));
}
parseDir(pathSVG);
} else if (name.endsWith('.svg')) {
DENSITIES.forEach((size) => {
const res = size * BASE_RESOLUTION;
const suffix = (size > 1 ? ('@' + (size) + 'x') : '');
const outPath = pathPNG.replace(/(\.svg$)/, suffix + '.png');
if (!fs.existsSync(outPath)) {
// Converte SVG to PNG
child_process.execSync(`inkscape -z -e "${outPath}" -w ${res} -h ${res} "${pathSVG}"`, { stdio: [0, 1, 2] });
// Compressão da imagem, em 3 steps
child_process.execSync(`pngquant -f -v --strip --quality=45-85 -o "${outPath}" "${outPath}"`, { stdio: [0, 1, 2] });
child_process.execSync(`pngquant -f -v --strip --ordered --speed=1 --quality=50-90 -o "${outPath}" "${outPath}"`, { stdio: [0, 1, 2] });
child_process.execSync(`pngquant -f -v --strip --ordered --speed=1 --quality=50-90 -o "${outPath}" "${outPath}"`, { stdio: [0, 1, 2] });
// Redução adicional dos arquivos
// Optipng não trouxe nenhuma vantagem na redução
// child_process.execSync(`optipng -v -clobber -o3 "${outPath}"`, { stdio: [0, 1, 2] });
}
});
}
});
}
parseDir(SVG_PATH_INPUT);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment