Skip to content

Instantly share code, notes, and snippets.

@nickmessing
Last active November 3, 2016 11:33
Show Gist options
  • Save nickmessing/346de130710745ad6507441c379aa0be to your computer and use it in GitHub Desktop.
Save nickmessing/346de130710745ad6507441c379aa0be to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
/*
requirements:
Node
inkscape
Graphicsmagic
*/
'use strict'
const fs = require('fs')
const path = require('path')
const childProcess = require('child_process')
const gm = require('gm')
const PNG = require('png-js')
const files = fs.readdirSync(__dirname).filter(el => el.match(/\.svg$/))
console.log(childProcess.execSync(`rm -rf "${path.join(__dirname, 'out')}"`).toString('utf8'))
fs.mkdirSync(path.join(__dirname, 'out'))
function svgToPdf (descriptor) {
const { svgLocation, tmpPdfLocation } = descriptor
return new Promise((resolve, reject) => {
childProcess.exec(`inkscape -A "${tmpPdfLocation}" "${svgLocation}"`, err => {
if (err) {
return reject(err)
}
console.log(`Converted ${svgLocation} to ${tmpPdfLocation}`)
resolve(descriptor)
})
})
}
function getSizes (descriptor) {
const { tmpPdfLocation, size } = descriptor
return new Promise((resolve, reject) => {
gm(tmpPdfLocation).size((err, sizings) => {
if (err) {
return reject(err)
}
const { width, height } = sizings
const coefficientWidth = (size[0] / width)
const coefficientHeight = (size[1] / height)
const coefficient = coefficientHeight < coefficientWidth ? coefficientHeight : coefficientWidth
const newWidth = Math.round(width * coefficient)
const newHeight = Math.round(height * coefficient)
descriptor.newWidth = newWidth
descriptor.newHeight = newHeight
descriptor.width = width
descriptor.height = height
console.log(`Got sizes for ${tmpPdfLocation}`)
resolve(descriptor)
})
})
}
function getColors (descriptor) {
const { tmpPdfLocation, newWidth, newHeight, pngLocation} = descriptor
return new Promise((resolve, reject) => {
gm(tmpPdfLocation)
.resize(newWidth, newHeight)
.write(pngLocation, err => {
if (err) {
return reject(err)
}
fs.readFile(pngLocation, (err, file) => {
if (err) {
return reject(err)
}
(new PNG(file)).decode(pixels => {
const colors = {
r: pixels[12].toString(16),
g: pixels[13].toString(16),
b: pixels[14].toString(16),
a: (255 - pixels[15]).toString(16)
}
if (colors.r.length < 2) {
colors.r = '0' + colors.r
}
if (colors.g.length < 2) {
colors.g = '0' + colors.g
}
if (colors.b.length < 2) {
colors.b = '0' + colors.b
}
if (colors.a.length < 2) {
colors.a = '0' + colors.a
}
descriptor.colors = colors
console.log(`Got colors for ${tmpPdfLocation}`)
resolve(descriptor)
})
})
})
})
}
function generateTmpPng (descriptor) {
const { size, colors, tmpPngLocation } = descriptor
return new Promise((resolve, reject) => {
gm(size[0], size[1], `#${colors.r}${colors.g}${colors.b}${colors.a}`)
.write(tmpPngLocation, err => {
if (err) {
return reject(err)
}
console.log(`Generated ${tmpPngLocation}`)
resolve(descriptor)
})
})
}
function compose (descriptor) {
const { tmpPngLocation, pngLocation, size, newWidth, width, height, newHeight } = descriptor
return new Promise((resolve, reject) => {
gm(tmpPngLocation)
.composite(pngLocation)
.geometry(`+${Math.round( (size[0] - newWidth) * (width > height ? 1 : 0.5) )}+${Math.round((size[1] - newHeight) / 2)}`)
.write(pngLocation, err => {
if (err) {
return reject(err)
}
console.log(`Composed ${pngLocation}`)
resolve(descriptor)
})
})
}
function clean (descriptor) {
const { tmpPngLocation, tmpPdfLocation } = descriptor
return new Promise((resolve, reject) => {
fs.unlink(tmpPngLocation, err => {
if (err) {
return reject(err)
}
fs.unlink(tmpPdfLocation, err => {
if (err) {
return reject(err)
}
})
console.log(`Removed ${tmpPngLocation} and ${tmpPdfLocation}`)
resolve(descriptor)
})
})
}
files.forEach(file => {
[
[996, 172],
[3984, 688],
[100, 100],
[400, 400]
].forEach(size => {
let svgLocation = path.join(__dirname, file)
let pngLocation = path.join(__dirname, 'out', `${size[0]}x${size[1]}_${file.replace(/svg$/, 'png')}`)
let tmpPngLocation = path.join(__dirname, 'out', `tmp_${size[0]}x${size[1]}_${file.replace(/svg$/, 'png')}`)
let tmpPdfLocation = path.join(__dirname, 'out', `tmp_${size[0]}x${size[1]}_${file.replace(/svg$/, 'pdf')}`)
let descriptor = {
svgLocation,
pngLocation,
tmpPngLocation,
tmpPdfLocation,
size
}
svgToPdf(descriptor)
.then(getSizes)
.then(getColors)
.then(generateTmpPng)
.then(compose)
.then(clean)
.then(({ size, svgLocation }) => console.log(`Finished ${size[0]}x${size[1]} for ${svgLocation}`))
.catch(console.error.bind(console, 'ERR'))
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment