@mediaproc/image 1.3.6 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -9
- package/dist/cli.js +9 -14
- package/dist/cli.js.map +1 -1
- package/dist/commands/affine.d.ts +1 -1
- package/dist/commands/affine.d.ts.map +1 -1
- package/dist/commands/affine.js +79 -84
- package/dist/commands/affine.js.map +1 -1
- package/dist/commands/auto-enhance.d.ts.map +1 -1
- package/dist/commands/auto-enhance.js +3 -7
- package/dist/commands/auto-enhance.js.map +1 -1
- package/dist/commands/auto-orient.d.ts.map +1 -1
- package/dist/commands/auto-orient.js +2 -6
- package/dist/commands/auto-orient.js.map +1 -1
- package/dist/commands/batch.d.ts.map +1 -1
- package/dist/commands/batch.js +8 -13
- package/dist/commands/batch.js.map +1 -1
- package/dist/commands/blur.d.ts.map +1 -1
- package/dist/commands/blur.js +37 -18
- package/dist/commands/blur.js.map +1 -1
- package/dist/commands/boolean.d.ts.map +1 -1
- package/dist/commands/boolean.js +25 -16
- package/dist/commands/boolean.js.map +1 -1
- package/dist/commands/border.d.ts.map +1 -1
- package/dist/commands/border.js +21 -14
- package/dist/commands/border.js.map +1 -1
- package/dist/commands/clahe.d.ts.map +1 -1
- package/dist/commands/clahe.js +27 -13
- package/dist/commands/clahe.js.map +1 -1
- package/dist/commands/composite.d.ts.map +1 -1
- package/dist/commands/composite.js +26 -11
- package/dist/commands/composite.js.map +1 -1
- package/dist/commands/compress.d.ts.map +1 -1
- package/dist/commands/compress.js +57 -37
- package/dist/commands/compress.js.map +1 -1
- package/dist/commands/convert.d.ts.map +1 -1
- package/dist/commands/convert.js +41 -21
- package/dist/commands/convert.js.map +1 -1
- package/dist/commands/convolve.d.ts.map +1 -1
- package/dist/commands/convolve.js +38 -16
- package/dist/commands/convolve.js.map +1 -1
- package/dist/commands/crop.d.ts.map +1 -1
- package/dist/commands/crop.js +9 -15
- package/dist/commands/crop.js.map +1 -1
- package/dist/commands/dilate.d.ts.map +1 -1
- package/dist/commands/dilate.js +9 -15
- package/dist/commands/dilate.js.map +1 -1
- package/dist/commands/dominant-color.d.ts.map +1 -1
- package/dist/commands/dominant-color.js +4 -11
- package/dist/commands/dominant-color.js.map +1 -1
- package/dist/commands/erode.d.ts.map +1 -1
- package/dist/commands/erode.js +24 -16
- package/dist/commands/erode.js.map +1 -1
- package/dist/commands/extend.d.ts.map +1 -1
- package/dist/commands/extend.js +9 -15
- package/dist/commands/extend.js.map +1 -1
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +23 -10
- package/dist/commands/extract.js.map +1 -1
- package/dist/commands/flatten.d.ts.map +1 -1
- package/dist/commands/flatten.js +36 -17
- package/dist/commands/flatten.js.map +1 -1
- package/dist/commands/flip.d.ts.map +1 -1
- package/dist/commands/flip.js +10 -16
- package/dist/commands/flip.js.map +1 -1
- package/dist/commands/flop.d.ts.map +1 -1
- package/dist/commands/flop.js +9 -15
- package/dist/commands/flop.js.map +1 -1
- package/dist/commands/gamma.d.ts.map +1 -1
- package/dist/commands/gamma.js +10 -16
- package/dist/commands/gamma.js.map +1 -1
- package/dist/commands/grayscale.d.ts.map +1 -1
- package/dist/commands/grayscale.js +10 -16
- package/dist/commands/grayscale.js.map +1 -1
- package/dist/commands/grid.d.ts.map +1 -1
- package/dist/commands/grid.js +45 -19
- package/dist/commands/grid.js.map +1 -1
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/info.js +4 -9
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/linear.d.ts.map +1 -1
- package/dist/commands/linear.js +9 -14
- package/dist/commands/linear.js.map +1 -1
- package/dist/commands/median.d.ts.map +1 -1
- package/dist/commands/median.js +41 -20
- package/dist/commands/median.js.map +1 -1
- package/dist/commands/metadata-cmd.d.ts.map +1 -1
- package/dist/commands/metadata-cmd.js +4 -10
- package/dist/commands/metadata-cmd.js.map +1 -1
- package/dist/commands/mirror.d.ts.map +1 -1
- package/dist/commands/mirror.js +26 -11
- package/dist/commands/mirror.js.map +1 -1
- package/dist/commands/modulate.d.ts.map +1 -1
- package/dist/commands/modulate.js +10 -16
- package/dist/commands/modulate.js.map +1 -1
- package/dist/commands/negate.d.ts.map +1 -1
- package/dist/commands/negate.js +10 -16
- package/dist/commands/negate.js.map +1 -1
- package/dist/commands/normalize.d.ts.map +1 -1
- package/dist/commands/normalize.js +10 -16
- package/dist/commands/normalize.js.map +1 -1
- package/dist/commands/optimize.d.ts.map +1 -1
- package/dist/commands/optimize.js +62 -24
- package/dist/commands/optimize.js.map +1 -1
- package/dist/commands/palette.d.ts.map +1 -1
- package/dist/commands/palette.js +59 -18
- package/dist/commands/palette.js.map +1 -1
- package/dist/commands/pixelate.d.ts.map +1 -1
- package/dist/commands/pixelate.js +27 -18
- package/dist/commands/pixelate.js.map +1 -1
- package/dist/commands/recomb.d.ts.map +1 -1
- package/dist/commands/recomb.js +39 -19
- package/dist/commands/recomb.js.map +1 -1
- package/dist/commands/resize.d.ts.map +1 -1
- package/dist/commands/resize.js +32 -18
- package/dist/commands/resize.js.map +1 -1
- package/dist/commands/rotate.d.ts.map +1 -1
- package/dist/commands/rotate.js +40 -20
- package/dist/commands/rotate.js.map +1 -1
- package/dist/commands/sepia.d.ts.map +1 -1
- package/dist/commands/sepia.js +46 -13
- package/dist/commands/sepia.js.map +1 -1
- package/dist/commands/sharpen.d.ts.map +1 -1
- package/dist/commands/sharpen.js +39 -19
- package/dist/commands/sharpen.js.map +1 -1
- package/dist/commands/smart-crop.d.ts.map +1 -1
- package/dist/commands/smart-crop.js +4 -9
- package/dist/commands/smart-crop.js.map +1 -1
- package/dist/commands/split.d.ts.map +1 -1
- package/dist/commands/split.js +44 -13
- package/dist/commands/split.js.map +1 -1
- package/dist/commands/stack.d.ts.map +1 -1
- package/dist/commands/stack.js +48 -33
- package/dist/commands/stack.js.map +1 -1
- package/dist/commands/stats.d.ts.map +1 -1
- package/dist/commands/stats.js +4 -10
- package/dist/commands/stats.js.map +1 -1
- package/dist/commands/threshold.d.ts.map +1 -1
- package/dist/commands/threshold.js +21 -17
- package/dist/commands/threshold.js.map +1 -1
- package/dist/commands/thumbnail.d.ts.map +1 -1
- package/dist/commands/thumbnail.js +38 -19
- package/dist/commands/thumbnail.js.map +1 -1
- package/dist/commands/tint.d.ts.map +1 -1
- package/dist/commands/tint.js +37 -19
- package/dist/commands/tint.js.map +1 -1
- package/dist/commands/trim.d.ts.map +1 -1
- package/dist/commands/trim.js +22 -18
- package/dist/commands/trim.js.map +1 -1
- package/dist/commands/unflatten.d.ts.map +1 -1
- package/dist/commands/unflatten.js +23 -19
- package/dist/commands/unflatten.js.map +1 -1
- package/dist/commands/vignette.d.ts.map +1 -1
- package/dist/commands/vignette.js +30 -13
- package/dist/commands/vignette.js.map +1 -1
- package/dist/commands/watermark.d.ts.map +1 -1
- package/dist/commands/watermark.js +34 -17
- package/dist/commands/watermark.js.map +1 -1
- package/dist/register.d.ts +1 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +3 -12
- package/dist/register.js.map +1 -1
- package/dist/utils/colorUtils.js +1 -1
- package/dist/utils/colorUtils.js.map +1 -1
- package/package.json +1 -21
package/dist/commands/clahe.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName, createStandardHelp
|
|
3
|
+
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName, createStandardHelp } from '@mediaproc/core';
|
|
4
4
|
import { createSharpInstance } from '../utils/sharp.js';
|
|
5
|
+
import path from 'node:path';
|
|
5
6
|
export function claheCommand(imageCmd) {
|
|
6
7
|
imageCmd
|
|
7
8
|
.command('clahe <input>')
|
|
@@ -10,12 +11,13 @@ export function claheCommand(imageCmd) {
|
|
|
10
11
|
.option('-h, --height <size>', 'Tile height in pixels (default: 3)', parseInt, 3)
|
|
11
12
|
.option('--max-slope <value>', 'Maximum slope for contrast limiting (default: 3)', parseFloat, 3)
|
|
12
13
|
.option('-o, --output <path>', 'Output file path')
|
|
14
|
+
.option('-q, --quality <quality>', 'Quality (1-100)', parseInt)
|
|
13
15
|
.option('--dry-run', 'Show what would be done without executing')
|
|
14
16
|
.option('-v, --verbose', 'Verbose output')
|
|
15
|
-
.option('--explain', '
|
|
17
|
+
.option('--explain [mode]', 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.')
|
|
16
18
|
.option('--help', 'Display help for clahe command')
|
|
17
19
|
.action(async (input, options) => {
|
|
18
|
-
if (options.help) {
|
|
20
|
+
if (options.help || !input) {
|
|
19
21
|
createStandardHelp({
|
|
20
22
|
commandName: 'clahe',
|
|
21
23
|
emoji: '✨',
|
|
@@ -26,8 +28,9 @@ export function claheCommand(imageCmd) {
|
|
|
26
28
|
{ flag: '-h, --height <size>', description: 'Tile height in pixels (default: 3)' },
|
|
27
29
|
{ flag: '--max-slope <value>', description: 'Maximum slope for contrast limiting 1-5 (default: 3)' },
|
|
28
30
|
{ flag: '-o, --output <path>', description: 'Output file path' },
|
|
31
|
+
{ flag: '-q, --quality <quality>', description: 'Output quality (1-100). Optional. Applies to JPEG/WEBP/AVIF. For PNG, maps to compression level (higher quality = lower compression). Ignored for other formats.' },
|
|
29
32
|
{ flag: '--dry-run', description: 'Preview changes without executing' },
|
|
30
|
-
{ flag: '--explain', description: '
|
|
33
|
+
{ flag: '--explain [mode]', description: 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.' },
|
|
31
34
|
{ flag: '-v, --verbose', description: 'Show detailed output' }
|
|
32
35
|
],
|
|
33
36
|
examples: [
|
|
@@ -97,13 +100,8 @@ export function claheCommand(imageCmd) {
|
|
|
97
100
|
const outputPath = outputPaths.get(inputFile);
|
|
98
101
|
console.log(chalk.dim(` ${index + 1}. ${getFileName(inputFile)} → ${getFileName(outputPath)}`));
|
|
99
102
|
});
|
|
100
|
-
showPluginBranding('Image', '../../package.json');
|
|
101
103
|
return;
|
|
102
104
|
}
|
|
103
|
-
if (options.explain) {
|
|
104
|
-
console.log(chalk.gray('Explain mode is not yet available.'));
|
|
105
|
-
console.log(chalk.cyan('Planned for v0.8.x.'));
|
|
106
|
-
}
|
|
107
105
|
let successCount = 0;
|
|
108
106
|
let failCount = 0;
|
|
109
107
|
for (const [index, inputFile] of inputFiles.entries()) {
|
|
@@ -111,13 +109,30 @@ export function claheCommand(imageCmd) {
|
|
|
111
109
|
const fileName = getFileName(inputFile);
|
|
112
110
|
spinner.start(`Processing ${index + 1}/${inputFiles.length}: ${fileName}...`);
|
|
113
111
|
try {
|
|
114
|
-
|
|
112
|
+
let pipeline = createSharpInstance(inputFile)
|
|
115
113
|
.clahe({
|
|
116
114
|
width: options.width || 3,
|
|
117
115
|
height: options.height || 3,
|
|
118
116
|
maxSlope: options.maxSlope || 3
|
|
119
|
-
})
|
|
120
|
-
|
|
117
|
+
});
|
|
118
|
+
// Apply quality/compressionLevel if requested
|
|
119
|
+
const outputExt = path.extname(outputPath).toLowerCase();
|
|
120
|
+
if (options.quality !== undefined) {
|
|
121
|
+
if (outputExt === '.jpg' || outputExt === '.jpeg') {
|
|
122
|
+
pipeline = pipeline.jpeg({ quality: options.quality });
|
|
123
|
+
}
|
|
124
|
+
else if (outputExt === '.webp') {
|
|
125
|
+
pipeline = pipeline.webp({ quality: options.quality });
|
|
126
|
+
}
|
|
127
|
+
else if (outputExt === '.avif') {
|
|
128
|
+
pipeline = pipeline.avif({ quality: options.quality });
|
|
129
|
+
}
|
|
130
|
+
else if (outputExt === '.png') {
|
|
131
|
+
pipeline = pipeline.png({ compressionLevel: options.quality });
|
|
132
|
+
}
|
|
133
|
+
// Ignore for other formats
|
|
134
|
+
}
|
|
135
|
+
await pipeline.toFile(outputPath);
|
|
121
136
|
spinner.succeed(chalk.green(`✓ ${fileName} processed`));
|
|
122
137
|
successCount++;
|
|
123
138
|
}
|
|
@@ -134,7 +149,6 @@ export function claheCommand(imageCmd) {
|
|
|
134
149
|
if (failCount > 0) {
|
|
135
150
|
console.log(chalk.red(` ✗ Failed: ${failCount}`));
|
|
136
151
|
}
|
|
137
|
-
showPluginBranding('Image', '../../package.json');
|
|
138
152
|
}
|
|
139
153
|
catch (error) {
|
|
140
154
|
spinner.fail(chalk.red('Failed to apply CLAHE'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clahe.js","sourceRoot":"","sources":["../../src/commands/clahe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"clahe.js","sourceRoot":"","sources":["../../src/commands/clahe.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../../src/commands/composite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../../src/commands/composite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAsNxD"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import * as fs from 'fs';
|
|
4
|
-
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName, createStandardHelp
|
|
4
|
+
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName, createStandardHelp } from '@mediaproc/core';
|
|
5
5
|
import { createSharpInstance } from '../utils/sharp.js';
|
|
6
|
+
import path from 'path';
|
|
6
7
|
export function compositeCommand(imageCmd) {
|
|
7
8
|
imageCmd
|
|
8
9
|
.command('composite <input>')
|
|
9
10
|
.description('Overlay/composite one image on top of another')
|
|
10
11
|
.requiredOption('--overlay <path>', 'Overlay image to composite')
|
|
11
12
|
.option('-o, --output <path>', 'Output file path')
|
|
13
|
+
.option('-q, --quality <quality>', 'Quality (1-100)', parseInt)
|
|
12
14
|
.option('--gravity <position>', 'Position: center, north, south, east, west, northeast, northwest, southeast, southwest', 'center')
|
|
13
15
|
.option('--blend <mode>', 'Blend mode: over, multiply, screen, overlay, darken, lighten, add, saturate, etc.', 'over')
|
|
14
16
|
.option('--left <pixels>', 'X position in pixels (overrides gravity)', parseInt)
|
|
@@ -17,10 +19,10 @@ export function compositeCommand(imageCmd) {
|
|
|
17
19
|
.option('--tile', 'Tile the overlay across the image')
|
|
18
20
|
.option('--dry-run', 'Show what would be done without executing')
|
|
19
21
|
.option('-v, --verbose', 'Verbose output')
|
|
20
|
-
.option('--explain', '
|
|
22
|
+
.option('--explain [mode]', 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.')
|
|
21
23
|
.option('--help', 'Display help for composite command')
|
|
22
24
|
.action(async (input, options) => {
|
|
23
|
-
if (options.help) {
|
|
25
|
+
if (options.help || !input) {
|
|
24
26
|
createStandardHelp({
|
|
25
27
|
commandName: 'composite',
|
|
26
28
|
emoji: '🎨',
|
|
@@ -34,9 +36,10 @@ export function compositeCommand(imageCmd) {
|
|
|
34
36
|
{ flag: '--left <pixels>', description: 'X position in pixels (overrides gravity)' },
|
|
35
37
|
{ flag: '--top <pixels>', description: 'Y position in pixels (overrides gravity)' },
|
|
36
38
|
{ flag: '--opacity <value>', description: 'Opacity 0-1 (default: 1)' },
|
|
39
|
+
{ flag: '-q, --quality <quality>', description: 'Output quality (1-100). Optional. Applies to JPEG/WEBP/AVIF. For PNG, maps to compression level (higher quality = lower compression). Ignored for other formats.' },
|
|
37
40
|
{ flag: '--tile', description: 'Tile the overlay across the entire image' },
|
|
38
41
|
{ flag: '--dry-run', description: 'Preview changes without executing' },
|
|
39
|
-
{ flag: '--explain', description: '
|
|
42
|
+
{ flag: '--explain [mode]', description: 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.' },
|
|
40
43
|
{ flag: '-v, --verbose', description: 'Show detailed output' }
|
|
41
44
|
],
|
|
42
45
|
examples: [
|
|
@@ -125,13 +128,8 @@ export function compositeCommand(imageCmd) {
|
|
|
125
128
|
inputFiles.forEach(f => console.log(chalk.dim(` - ${f}`)));
|
|
126
129
|
console.log(chalk.dim(` Overlay: ${options.overlay}`));
|
|
127
130
|
console.log(chalk.dim(` Position: ${options.left !== undefined && options.top !== undefined ? `${options.left}x${options.top}` : options.gravity}`));
|
|
128
|
-
showPluginBranding('Image', '../../package.json');
|
|
129
131
|
return;
|
|
130
132
|
}
|
|
131
|
-
if (options.explain) {
|
|
132
|
-
console.log(chalk.gray('Explain mode is not yet available.'));
|
|
133
|
-
console.log(chalk.cyan('Planned for v0.8.x.'));
|
|
134
|
-
}
|
|
135
133
|
// Preload and prepare overlay buffer once
|
|
136
134
|
let overlayBuffer = await createSharpInstance(options.overlay).toBuffer();
|
|
137
135
|
if (options.opacity !== undefined && options.opacity < 1) {
|
|
@@ -161,7 +159,25 @@ export function compositeCommand(imageCmd) {
|
|
|
161
159
|
try {
|
|
162
160
|
const fileName = getFileName(inputFile);
|
|
163
161
|
const outputPath = outputPaths.get(inputFile);
|
|
164
|
-
|
|
162
|
+
let pipeline = createSharpInstance(inputFile).composite([compositeOptions]);
|
|
163
|
+
// Apply quality/compressionLevel if requested
|
|
164
|
+
const outputExt = path.extname(outputPath).toLowerCase();
|
|
165
|
+
if (options.quality !== undefined) {
|
|
166
|
+
if (outputExt === '.jpg' || outputExt === '.jpeg') {
|
|
167
|
+
pipeline = pipeline.jpeg({ quality: options.quality });
|
|
168
|
+
}
|
|
169
|
+
else if (outputExt === '.webp') {
|
|
170
|
+
pipeline = pipeline.webp({ quality: options.quality });
|
|
171
|
+
}
|
|
172
|
+
else if (outputExt === '.avif') {
|
|
173
|
+
pipeline = pipeline.avif({ quality: options.quality });
|
|
174
|
+
}
|
|
175
|
+
else if (outputExt === '.png') {
|
|
176
|
+
pipeline = pipeline.png({ compressionLevel: options.quality });
|
|
177
|
+
}
|
|
178
|
+
// Ignore for other formats
|
|
179
|
+
}
|
|
180
|
+
await pipeline.toFile(outputPath);
|
|
165
181
|
spinner.succeed(chalk.green(`✓ ${fileName} composited`));
|
|
166
182
|
successCount++;
|
|
167
183
|
}
|
|
@@ -178,7 +194,6 @@ export function compositeCommand(imageCmd) {
|
|
|
178
194
|
if (failCount > 0) {
|
|
179
195
|
console.log(chalk.red(` ✗ Failed: ${failCount}`));
|
|
180
196
|
}
|
|
181
|
-
showPluginBranding('Image', '../../package.json');
|
|
182
197
|
}
|
|
183
198
|
catch (error) {
|
|
184
199
|
spinner.fail(chalk.red('Processing failed'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composite.js","sourceRoot":"","sources":["../../src/commands/composite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"composite.js","sourceRoot":"","sources":["../../src/commands/composite.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../../src/commands/compress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../../src/commands/compress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAqNvD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName, createStandardHelp
|
|
3
|
+
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName, createStandardHelp } from '@mediaproc/core';
|
|
4
4
|
import { createSharpInstance } from '../utils/sharp.js';
|
|
5
5
|
import { stat } from 'node:fs/promises';
|
|
6
6
|
export function compressCommand(imageCmd) {
|
|
@@ -8,14 +8,14 @@ export function compressCommand(imageCmd) {
|
|
|
8
8
|
.command('compress <input>')
|
|
9
9
|
.description('Compress images with advanced quality control')
|
|
10
10
|
.option('-o, --output <path>', 'Output file path')
|
|
11
|
-
.option('-q, --quality <quality>', 'Compression quality (1-100
|
|
11
|
+
.option('-q, --quality <quality>', 'Compression quality (1-100)', parseInt)
|
|
12
12
|
.option('--lossy', 'Use lossy compression for better size reduction')
|
|
13
13
|
.option('--dry-run', 'Show what would be done without executing')
|
|
14
14
|
.option('-v, --verbose', 'Verbose output')
|
|
15
|
-
.option('--explain', '
|
|
15
|
+
.option('--explain [mode]', 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.')
|
|
16
16
|
.option('--help', 'Display help for compress command')
|
|
17
17
|
.action(async (input, options) => {
|
|
18
|
-
if (options.help) {
|
|
18
|
+
if (options.help || !input) {
|
|
19
19
|
createStandardHelp({
|
|
20
20
|
commandName: 'compress',
|
|
21
21
|
emoji: '🗜️',
|
|
@@ -23,10 +23,10 @@ export function compressCommand(imageCmd) {
|
|
|
23
23
|
usage: ['compress <input>', 'compress <input> -q <quality>', 'compress <input> --lossy'],
|
|
24
24
|
options: [
|
|
25
25
|
{ flag: '-o, --output <path>', description: 'Output file path (default: <input>-compressed.<ext>)' },
|
|
26
|
-
{ flag: '-q, --quality <quality>', description: 'Compression quality 1-100 (
|
|
26
|
+
{ flag: '-q, --quality <quality>', description: 'Compression quality 1-100 (optional, only applies to JPEG, WEBP, AVIF; for PNG, mapped to compression level)' },
|
|
27
27
|
{ flag: '--lossy', description: 'Enable lossy compression for maximum reduction' },
|
|
28
28
|
{ flag: '--dry-run', description: 'Preview changes without executing' },
|
|
29
|
-
{ flag: '--explain', description: '
|
|
29
|
+
{ flag: '--explain [mode]', description: 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.' },
|
|
30
30
|
{ flag: '-v, --verbose', description: 'Show detailed output' }
|
|
31
31
|
],
|
|
32
32
|
examples: [
|
|
@@ -99,15 +99,12 @@ export function compressCommand(imageCmd) {
|
|
|
99
99
|
console.log(chalk.cyan(`\n📋 Dry run: ${fileName}`));
|
|
100
100
|
console.log(chalk.gray(` Input: ${inputPath}`));
|
|
101
101
|
console.log(chalk.gray(` Output: ${outputFile}`));
|
|
102
|
-
|
|
102
|
+
if (typeof options.quality !== 'undefined') {
|
|
103
|
+
console.log(chalk.gray(` Quality: ${options.quality}`));
|
|
104
|
+
}
|
|
103
105
|
console.log(chalk.gray(` Lossy: ${options.lossy ? 'Yes' : 'No'}`));
|
|
104
|
-
showPluginBranding('Image', '../../package.json');
|
|
105
106
|
continue;
|
|
106
107
|
}
|
|
107
|
-
if (options.explain) {
|
|
108
|
-
console.log(chalk.gray('Explain mode is not yet available.'));
|
|
109
|
-
console.log(chalk.cyan('Planned for v0.8.x.'));
|
|
110
|
-
}
|
|
111
108
|
const processSpinner = ora(`Compressing ${fileName}...`).start();
|
|
112
109
|
try {
|
|
113
110
|
const inputStat = await stat(inputPath);
|
|
@@ -118,42 +115,66 @@ export function compressCommand(imageCmd) {
|
|
|
118
115
|
// Apply compression based on format
|
|
119
116
|
let pipeline = sharp;
|
|
120
117
|
if (format === 'jpeg' || format === 'jpg') {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
if (typeof options.quality === 'number') {
|
|
119
|
+
pipeline = pipeline.jpeg({
|
|
120
|
+
quality: options.quality,
|
|
121
|
+
progressive: true,
|
|
122
|
+
mozjpeg: options.lossy || false,
|
|
123
|
+
force: true,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
pipeline = pipeline.jpeg({
|
|
128
|
+
progressive: true,
|
|
129
|
+
mozjpeg: options.lossy || false,
|
|
130
|
+
force: true,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
127
133
|
}
|
|
128
134
|
else if (format === 'png') {
|
|
135
|
+
let compressionLevel = 9;
|
|
136
|
+
if (typeof options.quality === 'number') {
|
|
137
|
+
compressionLevel = Math.round((100 - Math.max(1, Math.min(100, options.quality))) * 9 / 99);
|
|
138
|
+
}
|
|
129
139
|
pipeline = pipeline.png({
|
|
130
|
-
|
|
131
|
-
compressionLevel: 9,
|
|
140
|
+
compressionLevel,
|
|
132
141
|
palette: options.lossy || false,
|
|
133
142
|
force: true,
|
|
134
143
|
});
|
|
135
144
|
}
|
|
136
145
|
else if (format === 'webp') {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
if (typeof options.quality === 'number') {
|
|
147
|
+
pipeline = pipeline.webp({
|
|
148
|
+
quality: options.quality,
|
|
149
|
+
lossless: !options.lossy,
|
|
150
|
+
force: true,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
pipeline = pipeline.webp({
|
|
155
|
+
lossless: !options.lossy,
|
|
156
|
+
force: true,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
142
159
|
}
|
|
143
160
|
else if (format === 'avif') {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
161
|
+
if (typeof options.quality === 'number') {
|
|
162
|
+
pipeline = pipeline.avif({
|
|
163
|
+
quality: options.quality,
|
|
164
|
+
lossless: !options.lossy,
|
|
165
|
+
force: true,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
pipeline = pipeline.avif({
|
|
170
|
+
lossless: !options.lossy,
|
|
171
|
+
force: true,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
149
174
|
}
|
|
150
175
|
else {
|
|
151
|
-
// For other formats,
|
|
152
|
-
pipeline = pipeline
|
|
153
|
-
quality: options.quality || 75,
|
|
154
|
-
progressive: true,
|
|
155
|
-
mozjpeg: options.lossy || false,
|
|
156
|
-
});
|
|
176
|
+
// For other formats, ignore quality flag
|
|
177
|
+
pipeline = pipeline;
|
|
157
178
|
}
|
|
158
179
|
await pipeline.toFile(outputFile);
|
|
159
180
|
const outputStat = await stat(outputFile);
|
|
@@ -176,7 +197,6 @@ export function compressCommand(imageCmd) {
|
|
|
176
197
|
console.log();
|
|
177
198
|
console.log(chalk.green.bold('✓ Compression Complete!'));
|
|
178
199
|
console.log(chalk.gray(` Processed: ${inputFiles.length} image(s)`));
|
|
179
|
-
showPluginBranding('Image', '../../package.json');
|
|
180
200
|
}
|
|
181
201
|
catch (error) {
|
|
182
202
|
spinner.fail(chalk.red('Error during compression'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../../src/commands/compress.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../../src/commands/compress.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/commands/convert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/commands/convert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CA6MtD"}
|
package/dist/commands/convert.js
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { createSharpInstance } from '../utils/sharp.js';
|
|
4
|
-
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName,
|
|
4
|
+
import { validatePaths, resolveOutputPaths, IMAGE_EXTENSIONS, getFileName, createStandardHelp } from '@mediaproc/core';
|
|
5
5
|
export function convertCommand(imageCmd) {
|
|
6
6
|
imageCmd
|
|
7
7
|
.command('convert <input>')
|
|
8
8
|
.description('Convert image to different format')
|
|
9
9
|
.option('-f, --format <format>', 'Output format: jpg, png, webp, avif, tiff, gif, webp')
|
|
10
10
|
.option('-o, --output <path>', 'Output file path')
|
|
11
|
-
.option('-q, --quality <quality>', 'Quality (1-100)', parseInt
|
|
12
|
-
.option('--compression <level>', 'PNG compression level (0-9)', parseInt, 9)
|
|
11
|
+
.option('-q, --quality <quality>', 'Quality (1-100)', parseInt)
|
|
13
12
|
.option('--progressive', 'Use progressive/interlaced format')
|
|
14
13
|
.option('--dry-run', 'Show what would be done without executing')
|
|
15
14
|
.option('-v, --verbose', 'Verbose output')
|
|
16
|
-
.option('--explain', '
|
|
15
|
+
.option('--explain [mode]', 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.')
|
|
17
16
|
.option('--help', 'Display help for convert command')
|
|
18
17
|
.action(async (input, options) => {
|
|
19
|
-
if (options.help) {
|
|
18
|
+
if (options.help || !input) {
|
|
20
19
|
createStandardHelp({
|
|
21
20
|
commandName: 'convert',
|
|
22
21
|
emoji: '🔄',
|
|
@@ -25,11 +24,11 @@ export function convertCommand(imageCmd) {
|
|
|
25
24
|
options: [
|
|
26
25
|
{ flag: '-f, --format <format>', description: 'Output format: jpg, png, webp, avif, tiff, gif (default: webp)' },
|
|
27
26
|
{ flag: '-o, --output <path>', description: 'Output file path (default: <input>.<format>)' },
|
|
28
|
-
{ flag: '-q, --quality <quality>', description: 'Output quality 1-100 (
|
|
27
|
+
{ flag: '-q, --quality <quality>', description: 'Output quality 1-100 (optional, only applies to JPEG, WEBP, AVIF; for PNG, mapped to compression level)' },
|
|
29
28
|
{ flag: '--compression <level>', description: 'PNG compression level 0-9 (default: 9)' },
|
|
30
29
|
{ flag: '--progressive', description: 'Use progressive/interlaced format' },
|
|
31
30
|
{ flag: '--dry-run', description: 'Preview changes without executing' },
|
|
32
|
-
{ flag: '--explain', description: '
|
|
31
|
+
{ flag: '--explain [mode]', description: 'Show a detailed explanation of what this command will do, including technical and human-readable output. Modes: human, details, json. Adds context like timestamp, user, and platform.' },
|
|
33
32
|
{ flag: '-v, --verbose', description: 'Show detailed output' }
|
|
34
33
|
],
|
|
35
34
|
examples: [
|
|
@@ -90,7 +89,9 @@ export function convertCommand(imageCmd) {
|
|
|
90
89
|
if (options.verbose) {
|
|
91
90
|
console.log(chalk.blue('\nConfiguration:'));
|
|
92
91
|
console.log(chalk.dim(` Format: ${options.format.toUpperCase()}`));
|
|
93
|
-
|
|
92
|
+
if (typeof options.quality !== 'undefined') {
|
|
93
|
+
console.log(chalk.dim(` Quality: ${options.quality}`));
|
|
94
|
+
}
|
|
94
95
|
if (options.compression) {
|
|
95
96
|
console.log(chalk.dim(` Compression: ${options.compression}`));
|
|
96
97
|
}
|
|
@@ -106,13 +107,8 @@ export function convertCommand(imageCmd) {
|
|
|
106
107
|
const outputPath = outputPaths.get(inputFile);
|
|
107
108
|
console.log(chalk.dim(` ${index + 1}. ${getFileName(inputFile)} → ${getFileName(outputPath)}`));
|
|
108
109
|
});
|
|
109
|
-
showPluginBranding('Image', '../../package.json');
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
|
-
if (options.explain) {
|
|
113
|
-
console.log(chalk.gray('Explain mode is not yet available.'));
|
|
114
|
-
console.log(chalk.cyan('Planned for v0.8.x.'));
|
|
115
|
-
}
|
|
116
112
|
// Process each input file
|
|
117
113
|
let successCount = 0;
|
|
118
114
|
let failCount = 0;
|
|
@@ -125,23 +121,48 @@ export function convertCommand(imageCmd) {
|
|
|
125
121
|
let pipeline = createSharpInstance(inputFile);
|
|
126
122
|
// Apply format-specific options
|
|
127
123
|
if (options.format === 'jpg' || options.format === 'jpeg') {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
124
|
+
if (typeof options.quality === 'number') {
|
|
125
|
+
pipeline.jpeg({ quality: options.quality, progressive: options.progressive || false });
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
pipeline.jpeg({ progressive: options.progressive || false });
|
|
129
|
+
}
|
|
132
130
|
}
|
|
133
131
|
else if (options.format === 'webp') {
|
|
134
|
-
|
|
132
|
+
if (typeof options.quality === 'number') {
|
|
133
|
+
pipeline.webp({ quality: options.quality });
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
pipeline.webp();
|
|
137
|
+
}
|
|
135
138
|
}
|
|
136
139
|
else if (options.format === 'avif') {
|
|
137
|
-
|
|
140
|
+
if (typeof options.quality === 'number') {
|
|
141
|
+
pipeline.avif({ quality: options.quality });
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
pipeline.avif();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (options.format === 'png') {
|
|
148
|
+
let compressionLevel = 9;
|
|
149
|
+
if (typeof options.quality === 'number') {
|
|
150
|
+
compressionLevel = Math.round((100 - Math.max(1, Math.min(100, options.quality))) * 9 / 99);
|
|
151
|
+
}
|
|
152
|
+
pipeline.png({ compressionLevel, progressive: options.progressive || false });
|
|
138
153
|
}
|
|
139
154
|
else if (options.format === 'tiff') {
|
|
140
|
-
|
|
155
|
+
if (typeof options.quality === 'number') {
|
|
156
|
+
pipeline.tiff({ quality: options.quality });
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
pipeline.tiff();
|
|
160
|
+
}
|
|
141
161
|
}
|
|
142
162
|
else if (options.format === 'gif') {
|
|
143
163
|
pipeline.gif();
|
|
144
164
|
}
|
|
165
|
+
// For other formats, do not set quality
|
|
145
166
|
await pipeline.toFile(outputPath);
|
|
146
167
|
spinner.succeed(chalk.green(`✓ ${fileName} converted to ${options.format.toUpperCase()}`));
|
|
147
168
|
if (options.verbose) {
|
|
@@ -166,7 +187,6 @@ export function convertCommand(imageCmd) {
|
|
|
166
187
|
console.log(chalk.red(` ✗ Failed: ${failCount}`));
|
|
167
188
|
}
|
|
168
189
|
console.log(chalk.dim(` Target format: ${options.format.toUpperCase()}`));
|
|
169
|
-
showPluginBranding('Image', '../../package.json');
|
|
170
190
|
}
|
|
171
191
|
catch (error) {
|
|
172
192
|
spinner.fail(chalk.red('Failed to convert images'));
|