-
Notifications
You must be signed in to change notification settings - Fork 27
/
index.js
55 lines (45 loc) · 1.42 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import fs from 'node:fs/promises';
import {randomUUID} from 'node:crypto';
import {tmpdir} from 'node:os';
import path from 'node:path';
import {execa} from 'execa';
import jpegtran from 'jpegtran-bin';
import {fileTypeFromBuffer} from 'file-type';
import {imageDimensionsFromData} from 'image-dimensions';
import {assertUint8Array} from 'uint8array-extras';
export default function imageminJpegtran(options = {}) {
return async function (data) {
assertUint8Array(data);
const fileType = await fileTypeFromBuffer(data);
if (!fileType || fileType.mime !== 'image/jpeg') {
return data;
}
const dimensions = imageDimensionsFromData(data);
if (dimensions?.width === 0 && dimensions?.height === 0) {
return data;
}
const arguments_ = ['-copy', 'none'];
if (options.progressive) {
arguments_.push('-progressive');
}
if (options.arithmetic) {
arguments_.push('-arithmetic');
} else {
arguments_.push('-optimize');
}
const inputPath = path.join(tmpdir(), `input-${randomUUID()}.jpg`);
const outputPath = path.join(tmpdir(), `output-${randomUUID()}.jpg`);
arguments_.push('-outfile', outputPath, inputPath);
await fs.writeFile(inputPath, data);
try {
await execa(jpegtran, arguments_);
return await fs.readFile(outputPath);
} finally {
// Clean up temporary files
await Promise.all([
fs.unlink(inputPath).catch(() => {}),
fs.unlink(outputPath).catch(() => {}),
]);
}
};
}