Update utils.mjs

This commit is contained in:
lowlighter
2021-02-27 12:50:06 +01:00
parent 3eb0e301a6
commit a02cbd874d
3 changed files with 65 additions and 73 deletions

View File

@@ -56,8 +56,8 @@
console.debug(`metrics/compute/${login} > render`)
let rendered = await ejs.render(image, {...data, s:imports.s, f:imports.format, style, fonts}, {views, async:true})
if (q["config.twemoji"])
rendered = await imports.svgemojis(rendered)
const {resized, mime} = await imports.svgresize(rendered, {paddings:q["config.padding"] || conf.settings.padding, convert})
rendered = await imports.svg.twemojis(rendered)
const {resized, mime} = await imports.svg.resize(rendered, {paddings:q["config.padding"] || conf.settings.padding, convert})
rendered = resized
//Additional SVG transformations

View File

@@ -86,16 +86,6 @@
.replace(/'/g, u["'"] ? "'" : "'")
}
/**Expand url */
export async function urlexpand(url) {
try {
return (await axios.get(url)).request.res.responseUrl
}
catch {
return url
}
}
/**Run command */
export async function run(command, options, {prefixed = true} = {}) {
const prefix = {win32:"wsl"}[process.platform] ?? ""
@@ -128,20 +118,22 @@
return false
}
/**Render svg */
export async function svgresize(svg, {paddings, convert}) {
/**SVG utils */
export const svg = {
/**Render and resize svg */
async resize(rendered, {paddings, convert}) {
//Instantiate browser if needed
if (!svgresize.browser) {
svgresize.browser = await puppeteer.launch({headless:true, executablePath:process.env.PUPPETEER_BROWSER_PATH, args:["--no-sandbox", "--disable-extensions", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]})
console.debug(`metrics/svgresize > started ${await svgresize.browser.version()}`)
if (!svg.resize.browser) {
svg.resize.browser = await puppeteer.launch({headless:true, executablePath:process.env.PUPPETEER_BROWSER_PATH, args:["--no-sandbox", "--disable-extensions", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]})
console.debug(`metrics/svg/resize > started ${await svg.resize.browser.version()}`)
}
//Format padding
const [pw = 1, ph] = (Array.isArray(paddings) ? paddings : `${paddings}`.split(",").map(x => x.trim())).map(padding => `${padding}`.substring(0, padding.length-1)).map(value => 1+Number(value)/100)
const padding = {width:pw, height:ph ?? pw}
console.debug(`metrics/svgresize > padding width*${padding.width}, height*${padding.height}`)
console.debug(`metrics/svg/resize > padding width*${padding.width}, height*${padding.height}`)
//Render through browser and resize height
const page = await svgresize.browser.newPage()
await page.setContent(svg, {waitUntil:["load", "domcontentloaded", "networkidle2"]})
const page = await svg.resize.browser.newPage()
await page.setContent(rendered, {waitUntil:["load", "domcontentloaded", "networkidle2"]})
await page.addStyleTag({content:"body { margin: 0; padding: 0; }"})
await wait(1)
let mime = "image/svg+xml"
@@ -164,27 +156,27 @@
}, padding)
//Convert if required
if (convert) {
console.debug(`metrics/svgresize > convert to ${convert}`)
console.debug(`metrics/svg/resize > convert to ${convert}`)
resized = await page.screenshot({type:convert, clip:{x:0, y:0, width, height}, omitBackground:true})
mime = `image/${convert}`
}
//Result
await page.close()
return {resized, mime}
}
},
/**Render twemojis */
export async function svgemojis(svg) {
async twemojis(rendered) {
//Load emojis
const emojis = new Map()
for (const {text:emoji, url} of twemojis.parse(svg)) {
for (const {text:emoji, url} of twemojis.parse(rendered)) {
if (!emojis.has(emoji))
emojis.set(emoji, (await axios.get(url)).data.replace(/^<svg /, '<svg class="twemoji" '))
}
//Apply replacements
for (const [emoji, twemoji] of emojis)
svg = svg.replace(new RegExp(emoji, "g"), twemoji)
return svg
rendered = rendered.replace(new RegExp(emoji, "g"), twemoji)
return rendered
},
}
/**Wait */
@@ -193,17 +185,17 @@
}
/**Create gif from puppeteer browser */
export async function puppeteergif({page, width, height, frames, scale = 1, quality = 80, x = 0, y = 0, delay = 150}) {
export async function record({page, width, height, frames, scale = 1, quality = 80, x = 0, y = 0, delay = 150}) {
//Register images frames
const images = []
for (let i = 0; i < frames; i++) {
images.push(await page.screenshot({type:"png", clip:{width, height, x, y}}))
await wait(delay/1000)
if (i%10 === 0)
console.debug(`metrics/puppeteergif > processed ${i}/${frames} frames`)
console.debug(`metrics/record > processed ${i}/${frames} frames`)
}
console.debug(`metrics/puppeteergif > processed ${frames}/${frames} frames`)
console.debug(`metrics/record > processed ${frames}/${frames} frames`)
//Post-processing
console.debug("metrics/puppeteergif > applying post-processing")
console.debug("metrics/record > applying post-processing")
return Promise.all(images.map(async buffer => (await jimp.read(buffer)).scale(scale).quality(quality).getBase64Async("image/png")))
}

View File

@@ -32,7 +32,7 @@
//Generate gif
console.debug(`metrics/compute/${login}/plugins > skyline > generating frames`)
const framed = await imports.puppeteergif({page, width, height, frames, scale:quality})
const framed = await imports.record({page, width, height, frames, scale:quality})
//Close puppeteer
await browser.close()