diff --git a/scripts/img-compress-cli.ts b/scripts/img-compress-cli.ts index e3161a2..5e0da87 100644 --- a/scripts/img-compress-cli.ts +++ b/scripts/img-compress-cli.ts @@ -1,6 +1,9 @@ import process from 'node:process' import { compressImages } from './img-compress' -const files = process.argv.slice(2) - -compressImages(files) +const files = process.argv.slice(2).filter(i => i.match(/\.(png|jpe?g|webp|avif)$/i)) +if (files.length === 0) { + console.error('No files specified') + process.exit(1) +} +compressImages(files, process.argv.includes('--convert2avif')) diff --git a/scripts/img-compress-staged.ts b/scripts/img-compress-staged.ts index 7837313..cc09ef2 100644 --- a/scripts/img-compress-staged.ts +++ b/scripts/img-compress-staged.ts @@ -8,7 +8,7 @@ const stagedFiles = (await git.diff(['--cached', '--name-only'])) .map(i => i.trim()) .filter(Boolean) -const images = stagedFiles.filter(i => i.match(/\.(png|jpe?g|webp)$/i)) +const images = stagedFiles.filter(i => i.match(/\.(png|jpe?g|webp|avif)$/i)) if (images.length > 0) { console.log('Images to compress:\n', images) const { confirm } = await prompts({ @@ -17,10 +17,10 @@ if (images.length > 0) { message: `Compress ${images.length} images?`, }) - compressImages(images) - if (!confirm) process.exit(0) + + compressImages(images, process.argv.includes('--convert2avif')) } else { console.log('No images to compress') diff --git a/scripts/img-compress.ts b/scripts/img-compress.ts index c77353a..577cbb8 100644 --- a/scripts/img-compress.ts +++ b/scripts/img-compress.ts @@ -4,7 +4,7 @@ import c from 'picocolors' const maxSize = 1440 -export async function compressImages(files: string[]) { +export async function compressImages(files: string[], convert2avif: boolean) { await Promise.all(files.map(async (file) => { const buffer = await fs.readFile(file) let image = sharp(buffer) @@ -13,17 +13,25 @@ export async function compressImages(files: string[]) { throw new Error(`Could not determine format of ${file}`) if (!width || !height) throw new Error(`Could not determine size of ${file}`) - if (format !== 'jpeg' && format !== 'png' && format !== 'webp') + if (format !== 'jpeg' && format !== 'png' && format !== 'webp' && format !== 'avif') throw new Error(`Unsupported format ${format} of ${file}`) if (width > maxSize || height > maxSize) image = image.resize(maxSize) - image = image[format]({ - quality: 100, //format === 'png' ? 100 : 80, - compressionLevel: 9, - }) - + + + if(convert2avif) { + image.toFormat('avif', {quality: 85, compression: 'av1'}); + file = file.replace(/\.(jpe?g|png|webp)$/, '.avif'); + } + else { + image = image[format]({ + quality: 100, //format === 'png' ? 100 : 80, + compressionLevel: 9, + }) + } + const outBuffer = await image.withMetadata().toBuffer() const size = buffer.byteLength const outSize = outBuffer.byteLength diff --git a/src/components/ListImages.vue b/src/components/ListImages.vue index dde3839..b4eeb81 100644 --- a/src/components/ListImages.vue +++ b/src/components/ListImages.vue @@ -14,7 +14,7 @@ type image = { const imageSrcs = reactive([]); const folders = [] as folder[]; -const imageModules = import.meta.glob('/public/**/**.{png,jpg,jpeg,gif,svg}'); +const imageModules = import.meta.glob('/public/**/**.{avif,gif,jpg,jpeg,png,svg,webp}'); for (let path in imageModules) { path = path.replace('/public', '') if(!path.includes('logos')){