Skip to content

Commit 43814f9

Browse files
authored
New: Generate original image in other formats (#96)
1 parent 4345c16 commit 43814f9

File tree

5 files changed

+61
-14
lines changed

5 files changed

+61
-14
lines changed

.changeset/gentle-vans-change.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tidaltheory/lens': minor
3+
---
4+
5+
Generate AVIF and WebP formats of original image

src/cli.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { PackageJson } from 'type-fest'
1313
import { loadConfig } from './lib/context.js'
1414
import { getDominantPalette } from './lib/dominant.js'
1515
import { generateFingerprint } from './lib/fingerprint.js'
16+
import { optimiseImage } from './lib/optimise.js'
1617
import { matchThumbnail, writeThumbnail } from './lib/thumbnail.js'
1718
import type { ImageRecord, ImageThumbnails } from './types.js'
1819

@@ -56,12 +57,12 @@ prog.command('add <src>')
5657
let processed = 0
5758

5859
for await (let source of sourceImages) {
59-
let sourceImage: FileHandle
6060
/**
6161
* Check that source image exists.
6262
*/
63+
spinner.text = 'Checking image...'
64+
let sourceImage: FileHandle
6365
try {
64-
spinner.text = 'Checking image...'
6566
sourceImage = await open(source, 'r')
6667
await sourceImage.close()
6768
} catch (error: unknown) {
@@ -89,10 +90,19 @@ prog.command('add <src>')
8990
await mkdir(`${dir}/${imageName}`)
9091
}
9192

93+
spinner.text = 'Optimising original image...'
94+
let formats = {}
9295
try {
93-
spinner.text = 'Optimising original image...'
94-
await sharpImage.withMetadata().toFile(filename)
95-
spinner.succeed('Optimised a copy of original image')
96+
formats = await oraPromise(
97+
optimiseImage(sharpImage, {
98+
dir,
99+
imageName,
100+
fingerprint,
101+
ext,
102+
useFilenameDirectory,
103+
}),
104+
{ successText: 'Optimised a copy of original image' }
105+
)
96106
} catch (error: unknown) {
97107
spinner.fail(String(error))
98108
continue
@@ -153,6 +163,7 @@ prog.command('add <src>')
153163
let entry: ImageRecord = {
154164
path: filename,
155165
dimensions: { width, height },
166+
formats,
156167
colors: dominantPalette,
157168
thumbnails: entryThumbnails,
158169
}

src/lib/optimise.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { Sharp } from 'sharp'
2+
3+
import type { ImageFile, PathParts } from '../types'
4+
5+
export async function optimiseImage(
6+
image: Sharp,
7+
{ dir, imageName, fingerprint, ext, useFilenameDirectory }: PathParts
8+
) {
9+
let filename = useFilenameDirectory
10+
? `${dir}/${imageName}/${fingerprint}`
11+
: `${dir}/${imageName}.${fingerprint}`
12+
let formats: ImageFile['formats'] = {}
13+
14+
await image.withMetadata().toFile(`${filename}${ext}`)
15+
16+
formats.webp = await image
17+
.withMetadata()
18+
.toFile(`${filename}.webp`)
19+
.then(() => `${filename}.webp`)
20+
formats.avif = await image
21+
.withMetadata()
22+
.toFile(`${filename}.avif`)
23+
.then(() => `${filename}.avif`)
24+
25+
return formats
26+
}

src/lib/thumbnail.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import multimatch from 'multimatch'
22
import sharp from 'sharp'
33
import type { Sharp } from 'sharp'
44

5-
import type { ImageDimensions, ImageFile, ThumbnailOption } from '../types'
5+
import type {
6+
ImageDimensions,
7+
ImageFile,
8+
PathParts,
9+
ThumbnailOption,
10+
} from '../types'
611

712
/**
813
* Determine if the source path matches a glob pattern. Returns true if `files`
@@ -14,14 +19,6 @@ export function matchThumbnail(source: string, files?: string | string[]) {
1419
return multimatch([source], files).length > 0
1520
}
1621

17-
interface PathParts {
18-
dir: string
19-
imageName: string
20-
fingerprint: string
21-
ext: string
22-
useFilenameDirectory: boolean
23-
}
24-
2522
/**
2623
* Writes a resized image to the same directory as the source image,
2724
* in the initial format as well as `webp` and `avif`.

src/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,11 @@ export interface LensConfig {
4646
useFilenameDirectory?: boolean
4747
thumbnails?: ThumbnailOption[]
4848
}
49+
50+
export interface PathParts {
51+
dir: string
52+
imageName: string
53+
fingerprint: string
54+
ext: string
55+
useFilenameDirectory: boolean
56+
}

0 commit comments

Comments
 (0)