code.gitea.io/gitea@v1.22.3/tools/generate-images.js (about) 1 #!/usr/bin/env node 2 import imageminZopfli from 'imagemin-zopfli'; // eslint-disable-line i/no-unresolved 3 import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node'; // eslint-disable-line i/no-unresolved 4 import {optimize} from 'svgo'; 5 import {readFile, writeFile} from 'node:fs/promises'; 6 import {argv, exit} from 'node:process'; 7 8 function doExit(err) { 9 if (err) console.error(err); 10 exit(err ? 1 : 0); 11 } 12 13 async function generate(svg, path, {size, bg}) { 14 const outputFile = new URL(path, import.meta.url); 15 16 if (String(outputFile).endsWith('.svg')) { 17 const {data} = optimize(svg, { 18 plugins: [ 19 'preset-default', 20 'removeDimensions', 21 { 22 name: 'addAttributesToSVGElement', 23 params: {attributes: [{width: size}, {height: size}]}, 24 }, 25 ], 26 }); 27 await writeFile(outputFile, data); 28 return; 29 } 30 31 const {objects, options} = await loadSVGFromString(svg); 32 const canvas = new Canvas(); 33 canvas.setDimensions({width: size, height: size}); 34 const ctx = canvas.getContext('2d'); 35 ctx.scale(options.width ? (size / options.width) : 1, options.height ? (size / options.height) : 1); 36 37 if (bg) { 38 canvas.add(new Rect({ 39 left: 0, 40 top: 0, 41 height: size * (1 / (size / options.height)), 42 width: size * (1 / (size / options.width)), 43 fill: 'white', 44 })); 45 } 46 47 canvas.add(util.groupSVGElements(objects, options)); 48 canvas.renderAll(); 49 50 let png = Buffer.from([]); 51 for await (const chunk of canvas.createPNGStream()) { 52 png = Buffer.concat([png, chunk]); 53 } 54 55 png = await imageminZopfli({more: true})(png); 56 await writeFile(outputFile, png); 57 } 58 59 async function main() { 60 const gitea = argv.slice(2).includes('gitea'); 61 const logoSvg = await readFile(new URL('../assets/logo.svg', import.meta.url), 'utf8'); 62 const faviconSvg = await readFile(new URL('../assets/favicon.svg', import.meta.url), 'utf8'); 63 64 await Promise.all([ 65 generate(logoSvg, '../public/assets/img/logo.svg', {size: 32}), 66 generate(logoSvg, '../public/assets/img/logo.png', {size: 512}), 67 generate(faviconSvg, '../public/assets/img/favicon.svg', {size: 32}), 68 generate(faviconSvg, '../public/assets/img/favicon.png', {size: 180}), 69 generate(logoSvg, '../public/assets/img/avatar_default.png', {size: 200}), 70 generate(logoSvg, '../public/assets/img/apple-touch-icon.png', {size: 180, bg: true}), 71 gitea && generate(logoSvg, '../public/assets/img/gitea.svg', {size: 32}), 72 ]); 73 } 74 75 try { 76 doExit(await main()); 77 } catch (err) { 78 doExit(err); 79 }