@openinary/core 1.1.0
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/LICENSE +661 -0
- package/dist/config/deps.d.ts +14 -0
- package/dist/config/deps.d.ts.map +1 -0
- package/dist/config/deps.js +2 -0
- package/dist/config/deps.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/routes/authenticated.d.ts +4 -0
- package/dist/routes/authenticated.d.ts.map +1 -0
- package/dist/routes/authenticated.js +130 -0
- package/dist/routes/authenticated.js.map +1 -0
- package/dist/routes/download-folder.d.ts +4 -0
- package/dist/routes/download-folder.d.ts.map +1 -0
- package/dist/routes/download-folder.js +101 -0
- package/dist/routes/download-folder.js.map +1 -0
- package/dist/routes/download-zip.d.ts +15 -0
- package/dist/routes/download-zip.d.ts.map +1 -0
- package/dist/routes/download-zip.js +147 -0
- package/dist/routes/download-zip.js.map +1 -0
- package/dist/routes/download.d.ts +4 -0
- package/dist/routes/download.d.ts.map +1 -0
- package/dist/routes/download.js +83 -0
- package/dist/routes/download.js.map +1 -0
- package/dist/routes/invalidate.d.ts +4 -0
- package/dist/routes/invalidate.d.ts.map +1 -0
- package/dist/routes/invalidate.js +114 -0
- package/dist/routes/invalidate.js.map +1 -0
- package/dist/routes/queue-events.d.ts +4 -0
- package/dist/routes/queue-events.d.ts.map +1 -0
- package/dist/routes/queue-events.js +125 -0
- package/dist/routes/queue-events.js.map +1 -0
- package/dist/routes/queue.d.ts +4 -0
- package/dist/routes/queue.d.ts.map +1 -0
- package/dist/routes/queue.js +130 -0
- package/dist/routes/queue.js.map +1 -0
- package/dist/routes/storage.d.ts +4 -0
- package/dist/routes/storage.d.ts.map +1 -0
- package/dist/routes/storage.js +694 -0
- package/dist/routes/storage.js.map +1 -0
- package/dist/routes/transform-helpers.d.ts +62 -0
- package/dist/routes/transform-helpers.d.ts.map +1 -0
- package/dist/routes/transform-helpers.js +372 -0
- package/dist/routes/transform-helpers.js.map +1 -0
- package/dist/routes/transform.d.ts +4 -0
- package/dist/routes/transform.d.ts.map +1 -0
- package/dist/routes/transform.js +65 -0
- package/dist/routes/transform.js.map +1 -0
- package/dist/routes/video-status.d.ts +4 -0
- package/dist/routes/video-status.d.ts.map +1 -0
- package/dist/routes/video-status.js +208 -0
- package/dist/routes/video-status.js.map +1 -0
- package/dist/services/transform.service.d.ts +71 -0
- package/dist/services/transform.service.d.ts.map +1 -0
- package/dist/services/transform.service.js +362 -0
- package/dist/services/transform.service.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/asset-deletion.d.ts +16 -0
- package/dist/utils/asset-deletion.d.ts.map +1 -0
- package/dist/utils/asset-deletion.js +131 -0
- package/dist/utils/asset-deletion.js.map +1 -0
- package/dist/utils/cache.d.ts +44 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +248 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/get-unique-file-path.d.ts +8 -0
- package/dist/utils/get-unique-file-path.d.ts.map +1 -0
- package/dist/utils/get-unique-file-path.js +26 -0
- package/dist/utils/get-unique-file-path.js.map +1 -0
- package/dist/utils/image/aspect-ratio.d.ts +7 -0
- package/dist/utils/image/aspect-ratio.d.ts.map +1 -0
- package/dist/utils/image/aspect-ratio.js +40 -0
- package/dist/utils/image/aspect-ratio.js.map +1 -0
- package/dist/utils/image/background.d.ts +6 -0
- package/dist/utils/image/background.d.ts.map +1 -0
- package/dist/utils/image/background.js +22 -0
- package/dist/utils/image/background.js.map +1 -0
- package/dist/utils/image/compression.d.ts +44 -0
- package/dist/utils/image/compression.d.ts.map +1 -0
- package/dist/utils/image/compression.js +345 -0
- package/dist/utils/image/compression.js.map +1 -0
- package/dist/utils/image/gravity.d.ts +6 -0
- package/dist/utils/image/gravity.d.ts.map +1 -0
- package/dist/utils/image/gravity.js +24 -0
- package/dist/utils/image/gravity.js.map +1 -0
- package/dist/utils/image/index.d.ts +8 -0
- package/dist/utils/image/index.d.ts.map +1 -0
- package/dist/utils/image/index.js +77 -0
- package/dist/utils/image/index.js.map +1 -0
- package/dist/utils/image/param-registry.d.ts +63 -0
- package/dist/utils/image/param-registry.d.ts.map +1 -0
- package/dist/utils/image/param-registry.js +196 -0
- package/dist/utils/image/param-registry.js.map +1 -0
- package/dist/utils/image/quality.d.ts +8 -0
- package/dist/utils/image/quality.d.ts.map +1 -0
- package/dist/utils/image/quality.js +9 -0
- package/dist/utils/image/quality.js.map +1 -0
- package/dist/utils/image/resize.d.ts +7 -0
- package/dist/utils/image/resize.d.ts.map +1 -0
- package/dist/utils/image/resize.js +62 -0
- package/dist/utils/image/resize.js.map +1 -0
- package/dist/utils/image/rotation.d.ts +6 -0
- package/dist/utils/image/rotation.d.ts.map +1 -0
- package/dist/utils/image/rotation.js +20 -0
- package/dist/utils/image/rotation.js.map +1 -0
- package/dist/utils/image/round-corners.d.ts +12 -0
- package/dist/utils/image/round-corners.d.ts.map +1 -0
- package/dist/utils/image/round-corners.js +102 -0
- package/dist/utils/image/round-corners.js.map +1 -0
- package/dist/utils/image/types.d.ts +2 -0
- package/dist/utils/image/types.d.ts.map +1 -0
- package/dist/utils/image/types.js +2 -0
- package/dist/utils/image/types.js.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +82 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/parser.d.ts +8 -0
- package/dist/utils/parser.d.ts.map +1 -0
- package/dist/utils/parser.js +226 -0
- package/dist/utils/parser.js.map +1 -0
- package/dist/utils/signature.d.ts +35 -0
- package/dist/utils/signature.d.ts.map +1 -0
- package/dist/utils/signature.js +100 -0
- package/dist/utils/signature.js.map +1 -0
- package/dist/utils/storage/cache.d.ts +41 -0
- package/dist/utils/storage/cache.d.ts.map +1 -0
- package/dist/utils/storage/cache.js +90 -0
- package/dist/utils/storage/cache.js.map +1 -0
- package/dist/utils/storage/cloud-storage.d.ts +188 -0
- package/dist/utils/storage/cloud-storage.d.ts.map +1 -0
- package/dist/utils/storage/cloud-storage.js +514 -0
- package/dist/utils/storage/cloud-storage.js.map +1 -0
- package/dist/utils/storage/factory.d.ts +10 -0
- package/dist/utils/storage/factory.d.ts.map +1 -0
- package/dist/utils/storage/factory.js +17 -0
- package/dist/utils/storage/factory.js.map +1 -0
- package/dist/utils/storage/index.d.ts +7 -0
- package/dist/utils/storage/index.d.ts.map +1 -0
- package/dist/utils/storage/index.js +8 -0
- package/dist/utils/storage/index.js.map +1 -0
- package/dist/utils/storage/key-generator.d.ts +11 -0
- package/dist/utils/storage/key-generator.d.ts.map +1 -0
- package/dist/utils/storage/key-generator.js +23 -0
- package/dist/utils/storage/key-generator.js.map +1 -0
- package/dist/utils/storage/listing-cache.d.ts +14 -0
- package/dist/utils/storage/listing-cache.d.ts.map +1 -0
- package/dist/utils/storage/listing-cache.js +29 -0
- package/dist/utils/storage/listing-cache.js.map +1 -0
- package/dist/utils/storage/s3-client.d.ts +97 -0
- package/dist/utils/storage/s3-client.d.ts.map +1 -0
- package/dist/utils/storage/s3-client.js +297 -0
- package/dist/utils/storage/s3-client.js.map +1 -0
- package/dist/utils/storage/stats-tracker.d.ts +45 -0
- package/dist/utils/storage/stats-tracker.d.ts.map +1 -0
- package/dist/utils/storage/stats-tracker.js +97 -0
- package/dist/utils/storage/stats-tracker.js.map +1 -0
- package/dist/utils/storage/types.d.ts +2 -0
- package/dist/utils/storage/types.d.ts.map +1 -0
- package/dist/utils/storage/types.js +2 -0
- package/dist/utils/storage/types.js.map +1 -0
- package/dist/utils/storage-level.d.ts +66 -0
- package/dist/utils/storage-level.d.ts.map +1 -0
- package/dist/utils/storage-level.js +106 -0
- package/dist/utils/storage-level.js.map +1 -0
- package/dist/utils/storage-tree.d.ts +30 -0
- package/dist/utils/storage-tree.d.ts.map +1 -0
- package/dist/utils/storage-tree.js +81 -0
- package/dist/utils/storage-tree.js.map +1 -0
- package/dist/utils/upload-signature.d.ts +25 -0
- package/dist/utils/upload-signature.d.ts.map +1 -0
- package/dist/utils/upload-signature.js +56 -0
- package/dist/utils/upload-signature.js.map +1 -0
- package/dist/utils/video/auto-downscale.d.ts +12 -0
- package/dist/utils/video/auto-downscale.d.ts.map +1 -0
- package/dist/utils/video/auto-downscale.js +29 -0
- package/dist/utils/video/auto-downscale.js.map +1 -0
- package/dist/utils/video/command-builder.d.ts +22 -0
- package/dist/utils/video/command-builder.d.ts.map +1 -0
- package/dist/utils/video/command-builder.js +79 -0
- package/dist/utils/video/command-builder.js.map +1 -0
- package/dist/utils/video/config.d.ts +51 -0
- package/dist/utils/video/config.d.ts.map +1 -0
- package/dist/utils/video/config.js +170 -0
- package/dist/utils/video/config.js.map +1 -0
- package/dist/utils/video/format.d.ts +22 -0
- package/dist/utils/video/format.d.ts.map +1 -0
- package/dist/utils/video/format.js +64 -0
- package/dist/utils/video/format.js.map +1 -0
- package/dist/utils/video/index.d.ts +25 -0
- package/dist/utils/video/index.d.ts.map +1 -0
- package/dist/utils/video/index.js +104 -0
- package/dist/utils/video/index.js.map +1 -0
- package/dist/utils/video/param-registry.d.ts +64 -0
- package/dist/utils/video/param-registry.d.ts.map +1 -0
- package/dist/utils/video/param-registry.js +201 -0
- package/dist/utils/video/param-registry.js.map +1 -0
- package/dist/utils/video/quality.d.ts +12 -0
- package/dist/utils/video/quality.d.ts.map +1 -0
- package/dist/utils/video/quality.js +45 -0
- package/dist/utils/video/quality.js.map +1 -0
- package/dist/utils/video/queue-store.d.ts +51 -0
- package/dist/utils/video/queue-store.d.ts.map +1 -0
- package/dist/utils/video/queue-store.js +2 -0
- package/dist/utils/video/queue-store.js.map +1 -0
- package/dist/utils/video/resize.d.ts +7 -0
- package/dist/utils/video/resize.d.ts.map +1 -0
- package/dist/utils/video/resize.js +40 -0
- package/dist/utils/video/resize.js.map +1 -0
- package/dist/utils/video/sqlite-video-job-store.d.ts +29 -0
- package/dist/utils/video/sqlite-video-job-store.d.ts.map +1 -0
- package/dist/utils/video/sqlite-video-job-store.js +320 -0
- package/dist/utils/video/sqlite-video-job-store.js.map +1 -0
- package/dist/utils/video/thumbnail.d.ts +7 -0
- package/dist/utils/video/thumbnail.d.ts.map +1 -0
- package/dist/utils/video/thumbnail.js +22 -0
- package/dist/utils/video/thumbnail.js.map +1 -0
- package/dist/utils/video/trim.d.ts +7 -0
- package/dist/utils/video/trim.d.ts.map +1 -0
- package/dist/utils/video/trim.js +36 -0
- package/dist/utils/video/trim.js.map +1 -0
- package/dist/utils/video/types.d.ts +19 -0
- package/dist/utils/video/types.d.ts.map +1 -0
- package/dist/utils/video/types.js +2 -0
- package/dist/utils/video/types.js.map +1 -0
- package/dist/utils/video/video-info.d.ts +25 -0
- package/dist/utils/video/video-info.d.ts.map +1 -0
- package/dist/utils/video/video-info.js +58 -0
- package/dist/utils/video/video-info.js.map +1 -0
- package/dist/utils/video/video-worker.d.ts +52 -0
- package/dist/utils/video/video-worker.d.ts.map +1 -0
- package/dist/utils/video/video-worker.js +192 -0
- package/dist/utils/video/video-worker.js.map +1 -0
- package/dist/utils/video-job-queue.d.ts +62 -0
- package/dist/utils/video-job-queue.d.ts.map +1 -0
- package/dist/utils/video-job-queue.js +122 -0
- package/dist/utils/video-job-queue.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aspect-ratio.d.ts","sourceRoot":"","sources":["../../../src/utils/image/aspect-ratio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC3B,OAAO,KAAK,CAAC,KAAK,EAClB,aAAa,MAAM,EACnB,UAAS,WAAsB,KAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAuCrB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getSharpPosition } from './gravity.js';
|
|
2
|
+
/**
|
|
3
|
+
* Apply aspect ratio transformation to an image
|
|
4
|
+
*/
|
|
5
|
+
export const applyAspectRatio = async (image, aspectParam, gravity = 'center') => {
|
|
6
|
+
const aspectRatio = aspectParam.split(':');
|
|
7
|
+
if (aspectRatio.length !== 2) {
|
|
8
|
+
return image;
|
|
9
|
+
}
|
|
10
|
+
const targetRatio = parseFloat(aspectRatio[0]) / parseFloat(aspectRatio[1]);
|
|
11
|
+
// Get current image metadata
|
|
12
|
+
const metadata = await image.metadata();
|
|
13
|
+
const currentWidth = metadata.width || 0;
|
|
14
|
+
const currentHeight = metadata.height || 0;
|
|
15
|
+
const currentRatio = currentWidth / currentHeight;
|
|
16
|
+
// Only transform if ratios differ significantly
|
|
17
|
+
if (Math.abs(currentRatio - targetRatio) <= 0.01) {
|
|
18
|
+
return image; // Image already has correct aspect ratio
|
|
19
|
+
}
|
|
20
|
+
let newWidth;
|
|
21
|
+
let newHeight;
|
|
22
|
+
if (currentRatio > targetRatio) {
|
|
23
|
+
// Current image is wider, crop width
|
|
24
|
+
newHeight = currentHeight;
|
|
25
|
+
newWidth = Math.round(newHeight * targetRatio);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// Current image is taller, crop height
|
|
29
|
+
newWidth = currentWidth;
|
|
30
|
+
newHeight = Math.round(newWidth / targetRatio);
|
|
31
|
+
}
|
|
32
|
+
// Apply aspect ratio crop with specified gravity
|
|
33
|
+
return image.resize({
|
|
34
|
+
width: newWidth,
|
|
35
|
+
height: newHeight,
|
|
36
|
+
fit: 'cover',
|
|
37
|
+
position: getSharpPosition(gravity)
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=aspect-ratio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aspect-ratio.js","sourceRoot":"","sources":["../../../src/utils/image/aspect-ratio.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,KAAkB,EAClB,WAAmB,EACnB,UAAuB,QAAQ,EACT,EAAE;IACxB,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5E,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;IACzC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,YAAY,GAAG,aAAa,CAAC;IAElD,gDAAgD;IAChD,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,WAAW,CAAC,IAAI,IAAI,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC,CAAC,yCAAyC;IACzD,CAAC;IAED,IAAI,QAAgB,CAAC;IACrB,IAAI,SAAiB,CAAC;IAEtB,IAAI,YAAY,GAAG,WAAW,EAAE,CAAC;QAC/B,qCAAqC;QACrC,SAAS,GAAG,aAAa,CAAC;QAC1B,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,WAAW,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,uCAAuC;QACvC,QAAQ,GAAG,YAAY,CAAC;QACxB,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAC;IACjD,CAAC;IAED,iDAAiD;IACjD,OAAO,KAAK,CAAC,MAAM,CAAC;QAClB,KAAK,EAAE,QAAQ;QACf,MAAM,EAAE,SAAS;QACjB,GAAG,EAAE,OAAO;QACZ,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC;KACpC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background.d.ts","sourceRoot":"","sources":["../../../src/utils/image/background.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,aAAa,MAAM,KAAG,eAoB1D,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse background color from hex format or "transparent" keyword
|
|
3
|
+
*/
|
|
4
|
+
export const parseBackgroundColor = (background) => {
|
|
5
|
+
if (!background) {
|
|
6
|
+
return { r: 255, g: 255, b: 255, alpha: 1 }; // Default white
|
|
7
|
+
}
|
|
8
|
+
if (background.toLowerCase() === 'transparent') {
|
|
9
|
+
return { r: 0, g: 0, b: 0, alpha: 0 }; // Transparent
|
|
10
|
+
}
|
|
11
|
+
const hex = background.replace('#', '');
|
|
12
|
+
if (hex.length === 6) {
|
|
13
|
+
return {
|
|
14
|
+
r: parseInt(hex.substr(0, 2), 16),
|
|
15
|
+
g: parseInt(hex.substr(2, 2), 16),
|
|
16
|
+
b: parseInt(hex.substr(4, 2), 16),
|
|
17
|
+
alpha: 1
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return { r: 255, g: 255, b: 255, alpha: 1 }; // Default white if invalid
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=background.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background.js","sourceRoot":"","sources":["../../../src/utils/image/background.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAmB,EAAmB,EAAE;IAC3E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,gBAAgB;IAC/D,CAAC;IAED,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,aAAa,EAAE,CAAC;QAC/C,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,cAAc;IACvD,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YACjC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YACjC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YACjC,KAAK,EAAE,CAAC;SACT,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,2BAA2B;AAC1E,CAAC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { TransformParams, OptimizationResult } from './types';
|
|
2
|
+
export declare class Compression {
|
|
3
|
+
private static readonly FORMAT_PRIORITIES;
|
|
4
|
+
/**
|
|
5
|
+
* Optimizes an image with intelligent compression
|
|
6
|
+
* If format is not explicitly specified, encodes in all supported formats and returns the smallest one
|
|
7
|
+
*/
|
|
8
|
+
optimizeForDelivery(inputPath: string, params: TransformParams, userAgent?: string, acceptHeader?: string): Promise<OptimizationResult>;
|
|
9
|
+
/**
|
|
10
|
+
* Prepares the base pipeline with preliminary optimizations
|
|
11
|
+
*/
|
|
12
|
+
private preparePipeline;
|
|
13
|
+
/**
|
|
14
|
+
* Applies format encoding to the pipeline
|
|
15
|
+
*/
|
|
16
|
+
private applyFormat;
|
|
17
|
+
/**
|
|
18
|
+
* Analyzes image content to optimize compression (simplified for speed)
|
|
19
|
+
*/
|
|
20
|
+
private analyzeImage;
|
|
21
|
+
/**
|
|
22
|
+
* Determines optimal format based on content and browser support
|
|
23
|
+
*/
|
|
24
|
+
private determineOptimalFormat;
|
|
25
|
+
/**
|
|
26
|
+
* Calculates optimal quality based on content (simplified for speed).
|
|
27
|
+
* If userQuality is provided, it takes precedence over automatic calculation.
|
|
28
|
+
*/
|
|
29
|
+
private calculateOptimalQuality;
|
|
30
|
+
/**
|
|
31
|
+
* Determines maximum dimension based on content type
|
|
32
|
+
*/
|
|
33
|
+
private getMaxDimension;
|
|
34
|
+
/**
|
|
35
|
+
* Determines the optimal format for a browser without doing full optimization
|
|
36
|
+
* This is used for cache key generation
|
|
37
|
+
*/
|
|
38
|
+
determineOptimalFormatForCache(userAgent?: string, acceptHeader?: string, originalFormat?: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Checks browser support for a format
|
|
41
|
+
*/
|
|
42
|
+
private supportsFormat;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=compression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../../../src/utils/image/compression.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA8B,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAG1F,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAKvC;IAEF;;;OAGG;IACG,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,kBAAkB,CAAC;IA4J9B;;OAEG;IACH,OAAO,CAAC,eAAe;IAyBvB;;OAEG;IACH,OAAO,CAAC,WAAW;IA4CnB;;OAEG;YACW,YAAY;IAmB1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgC9B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAkC/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;;OAGG;IACH,8BAA8B,CAC5B,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM;IAwBT;;OAEG;IACH,OAAO,CAAC,cAAc;CAwCvB"}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import sharp from 'sharp';
|
|
2
|
+
import logger, { serializeError } from '../logger.js';
|
|
3
|
+
export class Compression {
|
|
4
|
+
static FORMAT_PRIORITIES = {
|
|
5
|
+
avif: { quality: 0.9, savings: 0.7 }, // AVIF: Excellent compression, slightly lower quality acceptable
|
|
6
|
+
webp: { quality: 0.95, savings: 0.6 }, // WebP: Good compression, high quality
|
|
7
|
+
jpeg: { quality: 1.0, savings: 0.3 }, // JPEG: Standard compression, full quality
|
|
8
|
+
png: { quality: 1.0, savings: 0.1 } // PNG: Lossless, minimal compression
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Optimizes an image with intelligent compression
|
|
12
|
+
* If format is not explicitly specified, encodes in all supported formats and returns the smallest one
|
|
13
|
+
*/
|
|
14
|
+
async optimizeForDelivery(inputPath, params, userAgent, acceptHeader) {
|
|
15
|
+
const originalBuffer = await sharp(inputPath).toBuffer();
|
|
16
|
+
const originalSize = originalBuffer.length;
|
|
17
|
+
// CONTENT ANALYSIS
|
|
18
|
+
const analysis = await this.analyzeImage(inputPath);
|
|
19
|
+
const metadata = await sharp(inputPath).metadata();
|
|
20
|
+
// If format is explicitly specified, use it directly (no size comparison needed)
|
|
21
|
+
if (params.format) {
|
|
22
|
+
const explicitFormat = params.format === 'jpg' ? 'jpeg' : params.format;
|
|
23
|
+
const userQuality = params.quality ? parseInt(String(params.quality)) : undefined;
|
|
24
|
+
const optimalQuality = this.calculateOptimalQuality(analysis, originalSize, explicitFormat, userQuality);
|
|
25
|
+
let pipeline = this.preparePipeline(inputPath, analysis, metadata, originalSize);
|
|
26
|
+
// Apply the explicit format
|
|
27
|
+
pipeline = this.applyFormat(pipeline, explicitFormat, optimalQuality);
|
|
28
|
+
const optimizedBuffer = await pipeline.toBuffer();
|
|
29
|
+
const optimizedSize = optimizedBuffer.length;
|
|
30
|
+
const savings = ((originalSize - optimizedSize) / originalSize) * 100;
|
|
31
|
+
const compressionRatio = originalSize / optimizedSize;
|
|
32
|
+
return {
|
|
33
|
+
buffer: optimizedBuffer,
|
|
34
|
+
format: explicitFormat,
|
|
35
|
+
originalSize,
|
|
36
|
+
optimizedSize,
|
|
37
|
+
savings,
|
|
38
|
+
compressionRatio
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// FORMAT SIZE COMPARISON: Encode in all supported formats and compare sizes
|
|
42
|
+
const supportsAVIF = this.supportsFormat('avif', userAgent, acceptHeader);
|
|
43
|
+
const supportsWebP = this.supportsFormat('webp', userAgent, acceptHeader);
|
|
44
|
+
logger.debug({
|
|
45
|
+
userAgent,
|
|
46
|
+
acceptHeader,
|
|
47
|
+
supportsAVIF,
|
|
48
|
+
supportsWebP
|
|
49
|
+
}, 'Browser format support detection');
|
|
50
|
+
const formatsToTest = [];
|
|
51
|
+
const originalFormat = metadata.format;
|
|
52
|
+
const hasTransparency = metadata.hasAlpha;
|
|
53
|
+
// Modern browsers: Test AVIF, WebP, and JPEG (plus PNG if original is PNG)
|
|
54
|
+
if (supportsAVIF) {
|
|
55
|
+
formatsToTest.push('avif', 'webp', 'jpeg');
|
|
56
|
+
// If original is PNG, also test PNG to compare sizes (AVIF/WebP support transparency too)
|
|
57
|
+
if (originalFormat === 'png') {
|
|
58
|
+
formatsToTest.push('png');
|
|
59
|
+
logger.debug('Testing formats: AVIF, WebP, JPEG, PNG (original is PNG)');
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
logger.debug('Testing formats: AVIF, WebP, JPEG');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Browsers with WebP but not AVIF: Test WebP and JPEG (plus PNG if original is PNG)
|
|
66
|
+
else if (supportsWebP) {
|
|
67
|
+
formatsToTest.push('webp', 'jpeg');
|
|
68
|
+
// If original is PNG, also test PNG to compare sizes (WebP supports transparency)
|
|
69
|
+
if (originalFormat === 'png') {
|
|
70
|
+
formatsToTest.push('png');
|
|
71
|
+
logger.debug('Testing formats: WebP, JPEG, PNG (original is PNG)');
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
logger.debug('Testing formats: WebP, JPEG');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Older browsers: Use JPEG/PNG (keep original format if PNG for transparency)
|
|
78
|
+
else {
|
|
79
|
+
// Preserve PNG for transparency, otherwise use JPEG
|
|
80
|
+
if (originalFormat === 'png' && hasTransparency) {
|
|
81
|
+
formatsToTest.push('png');
|
|
82
|
+
logger.debug('Testing format: PNG (preserving transparency, legacy browser)');
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
formatsToTest.push('jpeg');
|
|
86
|
+
logger.debug('Testing format: JPEG (legacy browser)');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Encode in all formats and compare sizes
|
|
90
|
+
const results = [];
|
|
91
|
+
const userQuality = params.quality ? parseInt(String(params.quality)) : undefined;
|
|
92
|
+
for (const format of formatsToTest) {
|
|
93
|
+
try {
|
|
94
|
+
const quality = this.calculateOptimalQuality(analysis, originalSize, format, userQuality);
|
|
95
|
+
let pipeline = this.preparePipeline(inputPath, analysis, metadata, originalSize);
|
|
96
|
+
pipeline = this.applyFormat(pipeline, format, quality);
|
|
97
|
+
const buffer = await pipeline.toBuffer();
|
|
98
|
+
results.push({
|
|
99
|
+
format,
|
|
100
|
+
buffer,
|
|
101
|
+
size: buffer.length
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
// If encoding fails for a format, skip it
|
|
106
|
+
logger.debug({ error: serializeError(error), format }, `Failed to encode in ${format}, skipping`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Find the smallest format
|
|
110
|
+
if (results.length === 0) {
|
|
111
|
+
// Fallback: use JPEG
|
|
112
|
+
const quality = this.calculateOptimalQuality(analysis, originalSize, 'jpeg', userQuality);
|
|
113
|
+
let pipeline = this.preparePipeline(inputPath, analysis, metadata, originalSize);
|
|
114
|
+
pipeline = this.applyFormat(pipeline, 'jpeg', quality);
|
|
115
|
+
const buffer = await pipeline.toBuffer();
|
|
116
|
+
return {
|
|
117
|
+
buffer,
|
|
118
|
+
format: 'jpeg',
|
|
119
|
+
originalSize,
|
|
120
|
+
optimizedSize: buffer.length,
|
|
121
|
+
savings: ((originalSize - buffer.length) / originalSize) * 100,
|
|
122
|
+
compressionRatio: originalSize / buffer.length
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// Sort by size and pick the smallest
|
|
126
|
+
results.sort((a, b) => a.size - b.size);
|
|
127
|
+
const bestResult = results[0];
|
|
128
|
+
// Normalize format (jpg -> jpeg)
|
|
129
|
+
const normalizedFormat = bestResult.format === 'jpg' ? 'jpeg' : bestResult.format;
|
|
130
|
+
logger.debug({
|
|
131
|
+
testedFormats: results.map(r => ({ format: r.format, size: r.size })),
|
|
132
|
+
selectedFormat: normalizedFormat,
|
|
133
|
+
selectedSize: bestResult.size,
|
|
134
|
+
originalSize
|
|
135
|
+
}, 'Format size comparison results');
|
|
136
|
+
const savings = ((originalSize - bestResult.size) / originalSize) * 100;
|
|
137
|
+
const compressionRatio = originalSize / bestResult.size;
|
|
138
|
+
return {
|
|
139
|
+
buffer: bestResult.buffer,
|
|
140
|
+
format: normalizedFormat,
|
|
141
|
+
originalSize,
|
|
142
|
+
optimizedSize: bestResult.size,
|
|
143
|
+
savings,
|
|
144
|
+
compressionRatio
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Prepares the base pipeline with preliminary optimizations
|
|
149
|
+
*/
|
|
150
|
+
preparePipeline(inputPath, analysis, metadata, originalSize) {
|
|
151
|
+
let pipeline = sharp(inputPath);
|
|
152
|
+
// Resolution reduction only for extremely large files
|
|
153
|
+
if (originalSize > 5 * 1024 * 1024) { // > 5MB
|
|
154
|
+
const maxDimension = this.getMaxDimension(analysis);
|
|
155
|
+
if (metadata.width > maxDimension || metadata.height > maxDimension) {
|
|
156
|
+
pipeline = pipeline.resize(maxDimension, maxDimension, {
|
|
157
|
+
fit: 'inside',
|
|
158
|
+
withoutEnlargement: true
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Remove metadata to save space
|
|
163
|
+
pipeline = pipeline.withMetadata();
|
|
164
|
+
return pipeline;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Applies format encoding to the pipeline
|
|
168
|
+
*/
|
|
169
|
+
applyFormat(pipeline, format, quality) {
|
|
170
|
+
switch (format) {
|
|
171
|
+
case 'avif':
|
|
172
|
+
return pipeline.avif({
|
|
173
|
+
quality,
|
|
174
|
+
effort: 1,
|
|
175
|
+
chromaSubsampling: '4:2:0'
|
|
176
|
+
});
|
|
177
|
+
case 'webp':
|
|
178
|
+
return pipeline.webp({
|
|
179
|
+
quality,
|
|
180
|
+
effort: 1,
|
|
181
|
+
smartSubsample: false
|
|
182
|
+
});
|
|
183
|
+
case 'jpeg':
|
|
184
|
+
case 'jpg':
|
|
185
|
+
return pipeline.jpeg({
|
|
186
|
+
quality,
|
|
187
|
+
progressive: false,
|
|
188
|
+
mozjpeg: false,
|
|
189
|
+
chromaSubsampling: '4:2:0'
|
|
190
|
+
});
|
|
191
|
+
case 'png':
|
|
192
|
+
return pipeline.png({
|
|
193
|
+
compressionLevel: 3,
|
|
194
|
+
adaptiveFiltering: false
|
|
195
|
+
});
|
|
196
|
+
default:
|
|
197
|
+
// PNG fallback
|
|
198
|
+
return pipeline.png({
|
|
199
|
+
compressionLevel: 3,
|
|
200
|
+
adaptiveFiltering: false
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Analyzes image content to optimize compression (simplified for speed)
|
|
206
|
+
*/
|
|
207
|
+
async analyzeImage(inputPath) {
|
|
208
|
+
const image = sharp(inputPath);
|
|
209
|
+
const metadata = await image.metadata();
|
|
210
|
+
// Simplified analysis based only on metadata (no expensive stats calculation)
|
|
211
|
+
const isPhotographic = metadata.channels >= 3; // RGB or more channels
|
|
212
|
+
const hasText = false;
|
|
213
|
+
const hasSharpEdges = false; // Skip expensive edge detection
|
|
214
|
+
const complexity = 0.5; // Default medium complexity
|
|
215
|
+
return {
|
|
216
|
+
hasText,
|
|
217
|
+
hasSharpEdges,
|
|
218
|
+
isPhotographic,
|
|
219
|
+
dominantColors: metadata.channels || 3,
|
|
220
|
+
complexity
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Determines optimal format based on content and browser support
|
|
225
|
+
*/
|
|
226
|
+
determineOptimalFormat(analysis, fileSize, userAgent, acceptHeader, explicitFormat) {
|
|
227
|
+
// If format is explicitly specified, use it (TypeScript ensures it's valid)
|
|
228
|
+
if (explicitFormat) {
|
|
229
|
+
// Normalize jpg to jpeg
|
|
230
|
+
return explicitFormat === 'jpg' ? 'jpeg' : explicitFormat;
|
|
231
|
+
}
|
|
232
|
+
// Check support for modern formats
|
|
233
|
+
const supportsAVIF = this.supportsFormat('avif', userAgent, acceptHeader);
|
|
234
|
+
const supportsWebP = this.supportsFormat('webp', userAgent, acceptHeader);
|
|
235
|
+
// NEW DEFAULT: Prefer AVIF by default if supported
|
|
236
|
+
if (supportsAVIF) {
|
|
237
|
+
return 'avif';
|
|
238
|
+
}
|
|
239
|
+
// Fallback to WebP if supported
|
|
240
|
+
if (supportsWebP) {
|
|
241
|
+
return 'webp';
|
|
242
|
+
}
|
|
243
|
+
// JPEG fallback for compatibility
|
|
244
|
+
return 'jpeg';
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Calculates optimal quality based on content (simplified for speed).
|
|
248
|
+
* If userQuality is provided, it takes precedence over automatic calculation.
|
|
249
|
+
*/
|
|
250
|
+
calculateOptimalQuality(analysis, fileSize, format, userQuality) {
|
|
251
|
+
if (userQuality !== undefined && !isNaN(userQuality) && userQuality >= 1 && userQuality <= 100) {
|
|
252
|
+
return userQuality;
|
|
253
|
+
}
|
|
254
|
+
let baseQuality = 85;
|
|
255
|
+
// Simplified format-specific adjustments
|
|
256
|
+
switch (format) {
|
|
257
|
+
case 'avif':
|
|
258
|
+
baseQuality = 80; // AVIF can handle slightly lower quality
|
|
259
|
+
break;
|
|
260
|
+
case 'webp':
|
|
261
|
+
baseQuality = 85;
|
|
262
|
+
break;
|
|
263
|
+
case 'jpeg':
|
|
264
|
+
baseQuality = 90; // Higher quality for JPEG
|
|
265
|
+
break;
|
|
266
|
+
case 'png':
|
|
267
|
+
return 100; // PNG is lossless, no quality adjustment needed
|
|
268
|
+
}
|
|
269
|
+
// Simplified size-based adjustment (less aggressive)
|
|
270
|
+
if (fileSize > 5 * 1024 * 1024)
|
|
271
|
+
baseQuality -= 5; // Only for very large files
|
|
272
|
+
// Limits (higher minimum quality)
|
|
273
|
+
return Math.max(70, Math.min(95, baseQuality));
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Determines maximum dimension based on content type
|
|
277
|
+
*/
|
|
278
|
+
getMaxDimension(analysis) {
|
|
279
|
+
if (analysis.hasText)
|
|
280
|
+
return 2560; // Text requires higher resolution
|
|
281
|
+
if (analysis.isPhotographic)
|
|
282
|
+
return 1920; // Standard photos
|
|
283
|
+
return 1600; // Other content
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Determines the optimal format for a browser without doing full optimization
|
|
287
|
+
* This is used for cache key generation
|
|
288
|
+
*/
|
|
289
|
+
determineOptimalFormatForCache(userAgent, acceptHeader, originalFormat) {
|
|
290
|
+
// If format is explicitly specified, we wouldn't call this, but handle it anyway
|
|
291
|
+
const supportsAVIF = this.supportsFormat('avif', userAgent, acceptHeader);
|
|
292
|
+
const supportsWebP = this.supportsFormat('webp', userAgent, acceptHeader);
|
|
293
|
+
// Prefer AVIF if supported (best compression)
|
|
294
|
+
if (supportsAVIF) {
|
|
295
|
+
return 'avif';
|
|
296
|
+
}
|
|
297
|
+
// Fallback to WebP if supported
|
|
298
|
+
if (supportsWebP) {
|
|
299
|
+
return 'webp';
|
|
300
|
+
}
|
|
301
|
+
// For legacy browsers, preserve PNG if original is PNG (for transparency)
|
|
302
|
+
// Otherwise use JPEG
|
|
303
|
+
if (originalFormat === 'png') {
|
|
304
|
+
return 'png';
|
|
305
|
+
}
|
|
306
|
+
return 'jpeg';
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Checks browser support for a format
|
|
310
|
+
*/
|
|
311
|
+
supportsFormat(format, userAgent, acceptHeader) {
|
|
312
|
+
// First check Accept header - most reliable method
|
|
313
|
+
if (acceptHeader) {
|
|
314
|
+
const acceptLower = acceptHeader.toLowerCase();
|
|
315
|
+
if (format === 'avif' && acceptLower.includes('image/avif')) {
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
if (format === 'webp' && acceptLower.includes('image/webp')) {
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (!userAgent) {
|
|
323
|
+
// If no user agent, assume modern browser supports AVIF and WebP
|
|
324
|
+
// This handles cases where Accept header might not be sent
|
|
325
|
+
return format === 'avif' || format === 'webp';
|
|
326
|
+
}
|
|
327
|
+
const ua = userAgent.toLowerCase();
|
|
328
|
+
switch (format) {
|
|
329
|
+
case 'avif':
|
|
330
|
+
// Chrome 85+ (released Aug 2020), Firefox 93+ (released Oct 2021), Safari 16+ (released Sep 2022), Edge 122+
|
|
331
|
+
return ((ua.includes('chrome') && !ua.includes('edg') && parseInt(ua.match(/chrome\/(\d+)/)?.[1] || '0') >= 85) ||
|
|
332
|
+
(ua.includes('firefox') && parseInt(ua.match(/firefox\/(\d+)/)?.[1] || '0') >= 93) ||
|
|
333
|
+
(ua.includes('safari') && !ua.includes('chrome') && parseInt(ua.match(/version\/(\d+)/)?.[1] || '0') >= 16) ||
|
|
334
|
+
(ua.includes('edg') && parseInt(ua.match(/edg\/(\d+)/)?.[1] || '0') >= 122));
|
|
335
|
+
case 'webp':
|
|
336
|
+
// Very broad support now - almost all modern browsers
|
|
337
|
+
return !ua.includes('msie') &&
|
|
338
|
+
!ua.includes('trident') &&
|
|
339
|
+
!(ua.includes('edge') && parseInt(ua.match(/edge\/(\d+)/)?.[1] || '0') < 18);
|
|
340
|
+
default:
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=compression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../../../src/utils/image/compression.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gravity.d.ts","sourceRoot":"","sources":["../../../src/utils/image/gravity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,KAAG,MAmBvD,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map gravity to Sharp position values
|
|
3
|
+
*/
|
|
4
|
+
export const getSharpPosition = (gravity) => {
|
|
5
|
+
switch (gravity) {
|
|
6
|
+
case 'center':
|
|
7
|
+
return 'center';
|
|
8
|
+
case 'north':
|
|
9
|
+
return 'top';
|
|
10
|
+
case 'south':
|
|
11
|
+
return 'bottom';
|
|
12
|
+
case 'east':
|
|
13
|
+
return 'right';
|
|
14
|
+
case 'west':
|
|
15
|
+
return 'left';
|
|
16
|
+
case 'face':
|
|
17
|
+
return 'attention'; // Sharp's attention strategy focuses on interesting features
|
|
18
|
+
case 'auto':
|
|
19
|
+
return 'entropy'; // Sharp's entropy strategy focuses on high-contrast areas
|
|
20
|
+
default:
|
|
21
|
+
return 'center';
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=gravity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gravity.js","sourceRoot":"","sources":["../../../src/utils/image/gravity.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAoB,EAAU,EAAE;IAC/D,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QACf,KAAK,OAAO;YACV,OAAO,QAAQ,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC;QACjB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,WAAW,CAAC,CAAC,6DAA6D;QACnF,KAAK,MAAM;YACT,OAAO,SAAS,CAAC,CAAC,0DAA0D;QAC9E;YACE,OAAO,QAAQ,CAAC;IACpB,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TransformParams } from './types';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export * from './param-registry';
|
|
4
|
+
/**
|
|
5
|
+
* Transform an image with the specified parameters
|
|
6
|
+
*/
|
|
7
|
+
export declare const transformImage: (inputPath: string, params: TransformParams) => Promise<Buffer>;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/image/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA2B1C,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AAEjC;;GAEG;AACH,eAAO,MAAM,cAAc,GAAU,WAAW,MAAM,EAAE,QAAQ,eAAe,KAAG,OAAO,CAAC,MAAM,CAsD/F,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import sharp from 'sharp';
|
|
2
|
+
import { readFile } from 'fs/promises';
|
|
3
|
+
import Psd from '@webtoon/psd';
|
|
4
|
+
import { applyAspectRatio } from './aspect-ratio.js';
|
|
5
|
+
import { applyRotation } from './rotation.js';
|
|
6
|
+
import { applyQuality } from './quality.js';
|
|
7
|
+
import { applyResizeComposite } from './param-registry.js';
|
|
8
|
+
import { applyRoundCorners } from './round-corners.js';
|
|
9
|
+
/**
|
|
10
|
+
* Decode a PSD file into a Sharp instance via raw RGBA pixel data.
|
|
11
|
+
* Sharp cannot read PSD natively; @webtoon/psd composites all layers first.
|
|
12
|
+
* The output is encoded as PNG so the temp-file step in processImage can read it.
|
|
13
|
+
*/
|
|
14
|
+
async function decodePsd(inputPath) {
|
|
15
|
+
const fileBuffer = await readFile(inputPath);
|
|
16
|
+
const arrayBuffer = fileBuffer.buffer.slice(fileBuffer.byteOffset, fileBuffer.byteOffset + fileBuffer.byteLength);
|
|
17
|
+
const psd = Psd.parse(arrayBuffer);
|
|
18
|
+
const pixelData = await psd.composite();
|
|
19
|
+
return sharp(Buffer.from(pixelData), {
|
|
20
|
+
raw: { width: psd.width, height: psd.height, channels: 4 },
|
|
21
|
+
}).png();
|
|
22
|
+
}
|
|
23
|
+
// Re-export types for backward compatibility
|
|
24
|
+
export * from './types.js';
|
|
25
|
+
export * from './param-registry.js';
|
|
26
|
+
/**
|
|
27
|
+
* Transform an image with the specified parameters
|
|
28
|
+
*/
|
|
29
|
+
export const transformImage = async (inputPath, params) => {
|
|
30
|
+
let image = inputPath.toLowerCase().endsWith('.psd')
|
|
31
|
+
? await decodePsd(inputPath)
|
|
32
|
+
: sharp(inputPath);
|
|
33
|
+
// Convert TransformParams to a record for easier access
|
|
34
|
+
const paramsRecord = {
|
|
35
|
+
...(params.rotate && { rotate: String(params.rotate) }),
|
|
36
|
+
...(params.aspect && { aspect: params.aspect }),
|
|
37
|
+
...(params.width && { width: params.width }),
|
|
38
|
+
...(params.height && { height: params.height }),
|
|
39
|
+
...(params.resize && { resize: params.resize }),
|
|
40
|
+
...(params.crop && { crop: params.crop }),
|
|
41
|
+
...(params.gravity && { gravity: params.gravity }),
|
|
42
|
+
...(params.background && { background: params.background }),
|
|
43
|
+
...(params.quality && { quality: String(params.quality) }),
|
|
44
|
+
...(params.format && { format: params.format }),
|
|
45
|
+
...(params.radius && { radius: params.radius }),
|
|
46
|
+
};
|
|
47
|
+
// 1. Apply rotation (if specified)
|
|
48
|
+
if (params.rotate) {
|
|
49
|
+
image = applyRotation(image, params.rotate, params.background);
|
|
50
|
+
}
|
|
51
|
+
// 2. Apply aspect ratio (if specified)
|
|
52
|
+
if (params.aspect) {
|
|
53
|
+
image = await applyAspectRatio(image, params.aspect, params.gravity);
|
|
54
|
+
// Sharp only honors one resize() per pipeline, so a following resize would
|
|
55
|
+
// override the aspect-ratio crop. Materialize the crop into a buffer first.
|
|
56
|
+
if (params.resize || params.width || params.height) {
|
|
57
|
+
image = sharp(await image.toBuffer());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// 3. Apply resize (if width or height specified)
|
|
61
|
+
if (params.resize || params.width || params.height) {
|
|
62
|
+
image = await applyResizeComposite(image, '', paramsRecord);
|
|
63
|
+
}
|
|
64
|
+
// 4. Apply rounded corners (if specified)
|
|
65
|
+
if (params.radius) {
|
|
66
|
+
image = await applyRoundCorners(image, params.radius, params.background);
|
|
67
|
+
// applyRoundCorners always returns a pipeline backed by a PNG buffer
|
|
68
|
+
// (alpha-capable), so the intermediate toBuffer() in processImage will
|
|
69
|
+
// correctly preserve transparency or the filled background color.
|
|
70
|
+
}
|
|
71
|
+
// 5. Apply quality (if specified)
|
|
72
|
+
if (params.quality) {
|
|
73
|
+
image = applyQuality(image, params.quality);
|
|
74
|
+
}
|
|
75
|
+
return await image.toBuffer();
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/image/index.ts"],"names":[],"mappings":"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"}
|