Rajhuggingface4253 commited on
Commit
970f7c4
·
verified ·
1 Parent(s): 5b3dda2

Update image-processing-logic.js

Browse files
Files changed (1) hide show
  1. image-processing-logic.js +35 -10
image-processing-logic.js CHANGED
@@ -1,12 +1,24 @@
1
  const sharp = require('sharp');
2
  const stream = require('stream');
3
 
 
 
 
 
 
 
 
 
 
4
  class ImageProcessor {
5
  /**
6
  * Processes an image to CMYK TIFF format from a readable stream.
 
 
 
7
  * @param {stream.Readable} input - The incoming stream of image data.
8
- * @param {Object } options - Processing options including quality.
9
- * @returns {stream.Readable} - A readable stream of the processed CMYK TIFF image.
10
  */
11
  processImage(input, options = {}) {
12
  return new Promise((resolve, reject) => {
@@ -24,15 +36,28 @@ class ImageProcessor {
24
  sharpInstance.on('error', (error) => {
25
  reject(new Error(`Image processing failed: ${error.message}`));
26
  });
27
- const compressionLevel = Math.max(1, Math.min(9, Math.round(parseInt(quality) / 100 * 9)));
28
- // Apply CMYK conversion with TIFF compression
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  sharpInstance = sharpInstance
30
  .toColorspace('cmyk')
31
  .tiff({
32
- compression: 'deflate', // CHANGED: Use PNG-style lossless compression
33
- quality: 100, // This is now ignored, but we set to 100
34
- level: compressionLevel, // NEW: Use our mapped level
35
- predictor: 'horizontal'
36
  });
37
 
38
  // Create transform stream for error handling
@@ -70,7 +95,6 @@ const compressionLevel = Math.max(1, Math.min(9, Math.round(parseInt(quality) /
70
  validateOptions(options) {
71
  const { quality } = options;
72
 
73
- // Validate quality exists and is valid
74
  if (quality && isNaN(quality)) {
75
  throw new Error('Quality must be a number');
76
  }
@@ -85,7 +109,8 @@ const compressionLevel = Math.max(1, Math.min(9, Math.round(parseInt(quality) /
85
  }
86
 
87
  /**
88
- * Validates the input content type
 
89
  * @param {string} contentType - Request content type
90
  */
91
  validateContentType(contentType) {
 
1
  const sharp = require('sharp');
2
  const stream = require('stream');
3
 
4
+ /**
5
+ * PRODUCTION OPTIMIZATION:
6
+ * Force sharp to use 1 thread per image operation.
7
+ * This is the recommended setting for web servers handling many concurrent requests.
8
+ * It prevents thread starvation and memory fragmentation by letting Node's libuv
9
+ * thread pool (UV_THREADPOOL_SIZE) handle concurrency at the request level instead.
10
+ */
11
+ sharp.concurrency(1);
12
+
13
  class ImageProcessor {
14
  /**
15
  * Processes an image to CMYK TIFF format from a readable stream.
16
+ * Accepts PNG, JPEG, WebP, AVIF, and TIFF inputs.
17
+ * Outputs the highest-quality CMYK TIFF suitable for professional printing.
18
+ *
19
  * @param {stream.Readable} input - The incoming stream of image data.
20
+ * @param {Object} options - Processing options including quality.
21
+ * @returns {Promise<stream.Readable>} - A readable stream of the processed CMYK TIFF image.
22
  */
23
  processImage(input, options = {}) {
24
  return new Promise((resolve, reject) => {
 
36
  sharpInstance.on('error', (error) => {
37
  reject(new Error(`Image processing failed: ${error.message}`));
38
  });
39
+
40
+ const compressionLevel = Math.max(1, Math.min(9, Math.round(parseInt(quality) / 100 * 9)));
41
+
42
+ /**
43
+ * CMYK conversion pipeline:
44
+ * - toColorspace('cmyk'): Converts from any input colorspace to CMYK.
45
+ * - compression: 'deflate' provides lossless PNG-style compression.
46
+ * - quality: 100 ensures no lossy degradation.
47
+ * - predictor: 'horizontal' improves deflate compression ratios on photographic data.
48
+ *
49
+ * NOTE: The input can be WebP (lossy or lossless). Sharp's libvips will decode
50
+ * WebP to full uncompressed pixel data before conversion, so there is ZERO quality
51
+ * loss from the transport format — the TIFF output quality depends only on the
52
+ * original render resolution (600 DPI), not the transport encoding.
53
+ */
54
  sharpInstance = sharpInstance
55
  .toColorspace('cmyk')
56
  .tiff({
57
+ compression: 'deflate',
58
+ quality: 100,
59
+ level: compressionLevel,
60
+ predictor: 'horizontal'
61
  });
62
 
63
  // Create transform stream for error handling
 
95
  validateOptions(options) {
96
  const { quality } = options;
97
 
 
98
  if (quality && isNaN(quality)) {
99
  throw new Error('Quality must be a number');
100
  }
 
109
  }
110
 
111
  /**
112
+ * Validates the input content type.
113
+ * Now accepts image/webp for optimized frontend transfers.
114
  * @param {string} contentType - Request content type
115
  */
116
  validateContentType(contentType) {