Skip to content

Commit

Permalink
feat: convert and compress images to avif
Browse files Browse the repository at this point in the history
  • Loading branch information
bodobraegger committed May 2, 2024
1 parent 0ac1b12 commit e4ef389
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 14 deletions.
9 changes: 6 additions & 3 deletions scripts/img-compress-cli.ts
Original file line number Diff line number Diff line change
@@ -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'))
6 changes: 3 additions & 3 deletions scripts/img-compress-staged.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -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')
Expand Down
22 changes: 15 additions & 7 deletions scripts/img-compress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/components/ListImages.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type image = {
const imageSrcs = reactive<image[]>([]);
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')){
Expand Down

0 comments on commit e4ef389

Please sign in to comment.