2024-03-06 22:04:26 +01:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
import { globby } from 'globby'
|
|
|
|
import { spawnSync } from 'node:child_process'
|
|
|
|
import { getFileNameWithoutExtension } from '../src/lib/Helper.mjs'
|
|
|
|
|
|
|
|
// This script should be run from the root of the application
|
|
|
|
const root = new URL('..', import.meta.url)
|
|
|
|
|
2024-03-06 22:24:27 +01:00
|
|
|
const imageDirectories = ['static/imgs/ricing_competitions', 'static/plugins-data/logos']
|
2024-03-06 22:04:26 +01:00
|
|
|
const generatedPrefix = 'generated_'
|
|
|
|
// This value seems to work well
|
|
|
|
const maxBrightness = 65535
|
|
|
|
|
|
|
|
const brightnessThreshold = maxBrightness * 0.5
|
|
|
|
|
|
|
|
/** All files which have no `generated_` version */
|
|
|
|
const filePaths = await globby(imageDirectories, {
|
|
|
|
cwd: root,
|
|
|
|
expandDirectories: {
|
|
|
|
extensions: ['svg', 'webp', 'jpg', 'png', 'gif', 'bmp', 'jpeg']
|
|
|
|
},
|
|
|
|
gitignore: false
|
2024-09-08 19:11:28 +02:00
|
|
|
}).then((filePaths) =>
|
|
|
|
filePaths
|
|
|
|
.filter((filePath) => {
|
|
|
|
const isGenerated = getFileNameWithoutExtension(filePath).startsWith(generatedPrefix)
|
|
|
|
|
|
|
|
if (isGenerated) return false
|
|
|
|
|
|
|
|
const fileName = getFileNameWithoutExtension(filePath)
|
|
|
|
const fileDirectory = filePath.split('/').slice(0, -2).join('/') + '/'
|
|
|
|
const generatedFilePath = `${fileDirectory}${generatedPrefix}${fileName}.webp`
|
|
|
|
|
|
|
|
const isAlreadyBlurred = filePaths.includes(generatedFilePath)
|
|
|
|
|
|
|
|
return !isAlreadyBlurred
|
|
|
|
})
|
2024-03-06 22:04:26 +01:00
|
|
|
.map((filePath) => new URL(filePath, root))
|
2024-09-08 19:11:28 +02:00
|
|
|
)
|
2024-03-06 22:04:26 +01:00
|
|
|
|
2024-03-07 19:36:15 +01:00
|
|
|
for (const filePathUrl of filePaths) {
|
|
|
|
const extension = filePathUrl.pathname.split('.').at(-1)
|
|
|
|
const generatedFileName =
|
|
|
|
generatedPrefix + getFileNameWithoutExtension(filePathUrl.href) + '.webp'
|
|
|
|
const outPath = decodeURIComponent(new URL('.', filePathUrl).pathname + generatedFileName)
|
|
|
|
const filePath = decodeURIComponent(filePathUrl.pathname)
|
2024-03-06 22:04:26 +01:00
|
|
|
|
|
|
|
const currentBrightness = Number(
|
2024-03-07 19:36:15 +01:00
|
|
|
exec(`convert "${filePath}" -colorspace Gray -format "%[mean]" info: `)
|
2024-03-06 22:04:26 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Boost the brightness if the image is very dark
|
|
|
|
const brightnessIncrease = Math.max(1 - (currentBrightness / brightnessThreshold) * 50, 0)
|
|
|
|
|
|
|
|
// Nessecary to do it like that for Zx
|
|
|
|
const svgCommands = extension === 'svg' ? '-background none -resize 2500x2500' : ''
|
|
|
|
|
|
|
|
exec(
|
2024-03-07 19:36:15 +01:00
|
|
|
`magick convert ${svgCommands} -brightness-contrast ${brightnessIncrease}x40 -modulate 100,1000,100 "${filePath}" "${outPath}"`
|
2024-03-06 22:04:26 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Modify colors with LUT
|
|
|
|
// spawnSync(`magick "${outPath}" "./scripts/hald-clut.color.io.png" -hald-clut "${outPath}"`)
|
|
|
|
// Also make them smaller to reduce file size
|
|
|
|
exec(
|
|
|
|
`magick convert -modulate 100,250,100 -scale 10% -gaussian-blur 0x20 -resize 500% -quality 50 "${outPath}" "${outPath}" `
|
|
|
|
)
|
|
|
|
|
2024-03-07 19:36:15 +01:00
|
|
|
console.log(`Blurred ${filePath}\nOutpath: ${outPath}\n`)
|
2024-03-06 22:04:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function exec(command) {
|
2024-03-07 19:36:15 +01:00
|
|
|
// the try-catch is kinda stupid, but otherwise Node will not give any meaningful info
|
|
|
|
try {
|
|
|
|
const { stdout, error, stderr } = spawnSync(command, {
|
|
|
|
shell: true,
|
|
|
|
stdio: ['inherit', 'inherit', 'pipe']
|
|
|
|
})
|
|
|
|
|
|
|
|
if (error) throw error
|
|
|
|
|
2024-06-20 21:52:15 +02:00
|
|
|
const stdError = stderr.toString().trim()
|
|
|
|
|
|
|
|
if (stdError && !stdError.includes('WARNING')) throw new Error(stdError)
|
|
|
|
|
2024-03-07 19:36:15 +01:00
|
|
|
return stdout
|
|
|
|
} catch (error) {
|
|
|
|
throw new Error(error)
|
|
|
|
}
|
2024-03-06 22:04:26 +01:00
|
|
|
}
|