diff --git a/package.json b/package.json index a8d4246..e03ca8c 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "chalk": "5", "clipanion": "3.2.1", "esm-utils": "^4.2.1", + "exifr": "^7.1.3", "fast-glob": "^3.3.2", "figures": "^6.1.0", "fs-extra": "11.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7cf940..07c0868 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ dependencies: esm-utils: specifier: ^4.2.1 version: 4.2.1 + exifr: + specifier: ^7.1.3 + version: 7.1.3 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -2241,6 +2244,10 @@ packages: strip-final-newline: 3.0.0 dev: true + /exifr@7.1.3: + resolution: {integrity: sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==} + dev: false + /expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} diff --git a/src/commands/compress.ts b/src/commands/compress.ts index 0a8075f..ca73e48 100644 --- a/src/commands/compress.ts +++ b/src/commands/compress.ts @@ -38,6 +38,11 @@ const getDurationDisplay = humanizer({ language: lang, fallbacks: ['en'], round: const AllOWED_CODEC = ['mozjpeg', 'webp', 'avif', 'jxl', 'mozjpeg-raw'] as const type Codec = typeof AllOWED_CODEC extends ReadonlyArray ? T : never +enum FileModeOutputType { + AppendBase = 'append-base', + NewDir = 'new-dir', +} + const DEFAULT_CONCURRENCY = process.env.UV_THREADPOOL_SIZE ? Number(process.env.UV_THREADPOOL_SIZE) : Math.round(cpus().length * 1.5) // 受限于 UV_THREADPOOL_SIZE, 再大到 libuv 那里都得排队 @@ -85,11 +90,11 @@ export class CompressCommand extends Command { }) output = Option.String('-o,--output', { - description: 'output patterns, can optional use special `append-base` or `separate-dir`', + description: `output patterns; optional use special value \`${FileModeOutputType.AppendBase}\` or \`${FileModeOutputType.NewDir}\``, }) codec = Option.String('-C,--codec', 'mozjpeg' satisfies Codec, { - description: `Allowed codec: ${AllOWED_CODEC.map((c) => `\`${c}\``).join(' or ')}`, + description: `Allowed: ${AllOWED_CODEC.map((c) => `\`${c}\``).join(' or ')}`, }) metadata = Option.Boolean('--metadata', true, { @@ -256,10 +261,9 @@ export class CompressCommand extends Command { // special output let { output } = this const q = lossless ? 'lossless' : `q${quality}` - if (output === 'append-base') { + if (output === FileModeOutputType.AppendBase) { output = `:dir/:file.${codec}-${q}.:ext` - } - if (output === 'separate-dir') { + } else if (output === FileModeOutputType.NewDir) { output = `:dir-${codec}-${q}/:name.:ext` } diff --git a/src/commands/info.ts b/src/commands/info.ts index 8cdbd43..62aba7e 100644 --- a/src/commands/info.ts +++ b/src/commands/info.ts @@ -1,4 +1,5 @@ import { Command, Option, Usage } from 'clipanion' +import exifr from 'exifr' import path from 'path' import { decode, metadata } from '../index.js' @@ -11,18 +12,34 @@ export class InfoCommand extends Command { file = Option.String({ required: true }) + verbose = Option.Boolean('-v,--verbose', false, { + description: 'show verbose info', + }) + execute(): Promise { return main(this) } } -export async function main(argv: { file: string }) { - let { file } = argv +export async function main({ file, verbose }: { file: string; verbose: boolean }) { if (file) file = path.resolve(file) const meta = await metadata(file) - console.log('metadata: %o', meta) + console.log('\nmetadata: %o', meta) const decoded = await decode(file) - console.log('decoded info: %s', decoded) + console.log('\n\ndecoded info: %s', decoded) + + const _orientation = await exifr.orientation(file) + console.log('\n\nexifr orientation: %o', _orientation) + + if (verbose) { + const all = await exifr.parse(file, { + tiff: true, + ifd1: true, + mergeOutput: true, + translateValues: false, + }) + console.log('\n\nexifr all: ', all) + } } diff --git a/src/compress.ts b/src/compress.ts index 2ffabf6..b52e638 100644 --- a/src/compress.ts +++ b/src/compress.ts @@ -73,7 +73,7 @@ export async function sharpMozjpegCompress( }) if (keepMetadata) { - img = img.withMetadata() + img = img.keepMetadata() } const buf = await img.toBuffer() @@ -97,7 +97,7 @@ function sharpTargetFormatFactory( let img = (await getSharpInstance(file))[targetFormat](options) if (keepMetadata) { - img = img.withMetadata() + img = img.keepMetadata() } const buf = await img.toBuffer() diff --git a/tsconfig.json b/tsconfig.json index dec143c..93b678d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "esModuleInterop": true, "declaration": true, "strictNullChecks": true, + "noImplicitThis": true, "skipLibCheck": true }, "ts-node": {