@zhaoshijun/compress 1.2.1 → 1.2.3
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/package.json +1 -1
- package/src/core/watermark.js +78 -74
package/package.json
CHANGED
package/src/core/watermark.js
CHANGED
|
@@ -204,77 +204,81 @@ export async function addImageWatermark(sharpInstance, options) {
|
|
|
204
204
|
throw new Error(`Watermark image not found: ${watermarkPath}`);
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (width || height) {
|
|
212
|
-
watermarkImage = watermarkImage.resize({
|
|
213
|
-
width: width || undefined,
|
|
214
|
-
height: height || undefined,
|
|
215
|
-
fit: 'inside'
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (opacity < 1) {
|
|
220
|
-
const watermarkBuffer = await watermarkImage.toBuffer();
|
|
221
|
-
watermarkImage = sharp(watermarkBuffer).ensureAlpha();
|
|
222
|
-
const { data } = await watermarkImage.raw().toBuffer({ resolveWithObject: true });
|
|
207
|
+
try {
|
|
208
|
+
const watermarkBuffer = await fs.readFile(watermarkPath);
|
|
209
|
+
let watermarkImage = sharp(watermarkBuffer);
|
|
210
|
+
const watermarkMeta = await watermarkImage.metadata();
|
|
223
211
|
|
|
224
|
-
|
|
225
|
-
|
|
212
|
+
if (width || height) {
|
|
213
|
+
watermarkImage = watermarkImage.resize({
|
|
214
|
+
width: width || undefined,
|
|
215
|
+
height: height || undefined,
|
|
216
|
+
fit: 'inside'
|
|
217
|
+
});
|
|
226
218
|
}
|
|
227
219
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
220
|
+
if (opacity < 1) {
|
|
221
|
+
const tempBuffer = await watermarkImage.toBuffer();
|
|
222
|
+
const tempSharp = sharp(tempBuffer);
|
|
223
|
+
const { data, info } = await tempSharp.ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
224
|
+
|
|
225
|
+
for (let i = 3; i < data.length; i += 4) {
|
|
226
|
+
data[i] = Math.floor(data[i] * opacity);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
watermarkImage = sharp(data, {
|
|
230
|
+
raw: {
|
|
231
|
+
width: info.width,
|
|
232
|
+
height: info.height,
|
|
233
|
+
channels: 4
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const finalWatermarkBuffer = await watermarkImage.toBuffer();
|
|
239
|
+
const finalWatermarkMeta = await sharp(finalWatermarkBuffer).metadata();
|
|
240
|
+
|
|
241
|
+
let compositeX = x;
|
|
242
|
+
let compositeY = y;
|
|
243
|
+
|
|
244
|
+
if (position !== 'custom') {
|
|
245
|
+
switch (position) {
|
|
246
|
+
case 'top-left':
|
|
247
|
+
compositeX = padding;
|
|
248
|
+
compositeY = padding;
|
|
249
|
+
break;
|
|
250
|
+
case 'top-right':
|
|
251
|
+
compositeX = targetMetadata.width - finalWatermarkMeta.width - padding;
|
|
252
|
+
compositeY = padding;
|
|
253
|
+
break;
|
|
254
|
+
case 'bottom-left':
|
|
255
|
+
compositeX = padding;
|
|
256
|
+
compositeY = targetMetadata.height - finalWatermarkMeta.height - padding;
|
|
257
|
+
break;
|
|
258
|
+
case 'bottom-right':
|
|
259
|
+
compositeX = targetMetadata.width - finalWatermarkMeta.width - padding;
|
|
260
|
+
compositeY = targetMetadata.height - finalWatermarkMeta.height - padding;
|
|
261
|
+
break;
|
|
262
|
+
case 'center':
|
|
263
|
+
compositeX = Math.floor((targetMetadata.width - finalWatermarkMeta.width) / 2);
|
|
264
|
+
compositeY = Math.floor((targetMetadata.height - finalWatermarkMeta.height) / 2);
|
|
265
|
+
break;
|
|
233
266
|
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const watermarkBuffer = await watermarkImage.toBuffer();
|
|
238
|
-
const finalWatermarkMeta = await sharp(watermarkBuffer).metadata();
|
|
239
|
-
|
|
240
|
-
let compositeX = x;
|
|
241
|
-
let compositeY = y;
|
|
242
|
-
|
|
243
|
-
if (position !== 'custom') {
|
|
244
|
-
switch (position) {
|
|
245
|
-
case 'top-left':
|
|
246
|
-
compositeX = padding;
|
|
247
|
-
compositeY = padding;
|
|
248
|
-
break;
|
|
249
|
-
case 'top-right':
|
|
250
|
-
compositeX = targetMetadata.width - finalWatermarkMeta.width - padding;
|
|
251
|
-
compositeY = padding;
|
|
252
|
-
break;
|
|
253
|
-
case 'bottom-left':
|
|
254
|
-
compositeX = padding;
|
|
255
|
-
compositeY = targetMetadata.height - finalWatermarkMeta.height - padding;
|
|
256
|
-
break;
|
|
257
|
-
case 'bottom-right':
|
|
258
|
-
compositeX = targetMetadata.width - finalWatermarkMeta.width - padding;
|
|
259
|
-
compositeY = targetMetadata.height - finalWatermarkMeta.height - padding;
|
|
260
|
-
break;
|
|
261
|
-
case 'center':
|
|
262
|
-
compositeX = Math.floor((targetMetadata.width - finalWatermarkMeta.width) / 2);
|
|
263
|
-
compositeY = Math.floor((targetMetadata.height - finalWatermarkMeta.height) / 2);
|
|
264
|
-
break;
|
|
265
267
|
}
|
|
268
|
+
|
|
269
|
+
const result = await sharpInstance
|
|
270
|
+
.composite([{
|
|
271
|
+
input: finalWatermarkBuffer,
|
|
272
|
+
left: compositeX,
|
|
273
|
+
top: compositeY,
|
|
274
|
+
blend: 'over'
|
|
275
|
+
}])
|
|
276
|
+
.toBuffer();
|
|
277
|
+
|
|
278
|
+
return result;
|
|
279
|
+
} catch (error) {
|
|
280
|
+
throw new Error(`Failed to load watermark image: ${error.message}`);
|
|
266
281
|
}
|
|
267
|
-
|
|
268
|
-
const result = await sharpInstance
|
|
269
|
-
.composite([{
|
|
270
|
-
input: watermarkBuffer,
|
|
271
|
-
left: compositeX,
|
|
272
|
-
top: compositeY,
|
|
273
|
-
blend: 'over'
|
|
274
|
-
}])
|
|
275
|
-
.toBuffer();
|
|
276
|
-
|
|
277
|
-
return result;
|
|
278
282
|
}
|
|
279
283
|
|
|
280
284
|
/**
|
|
@@ -335,9 +339,9 @@ export async function addTiledImageWatermark(sharpInstance, options, providedMet
|
|
|
335
339
|
}
|
|
336
340
|
|
|
337
341
|
if (opacity < 1) {
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
const { data, info } = await
|
|
342
|
+
const tempBuffer = await watermarkImage.toBuffer();
|
|
343
|
+
const tempSharp = sharp(tempBuffer);
|
|
344
|
+
const { data, info } = await tempSharp.ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
341
345
|
|
|
342
346
|
for (let i = 3; i < data.length; i += 4) {
|
|
343
347
|
data[i] = Math.floor(data[i] * opacity);
|
|
@@ -353,21 +357,21 @@ export async function addTiledImageWatermark(sharpInstance, options, providedMet
|
|
|
353
357
|
}
|
|
354
358
|
|
|
355
359
|
if (angle !== 0) {
|
|
356
|
-
const
|
|
357
|
-
const rotatedMeta = await sharp(
|
|
360
|
+
const rotatedBuffer = await watermarkImage.toBuffer();
|
|
361
|
+
const rotatedMeta = await sharp(rotatedBuffer).metadata();
|
|
358
362
|
const radians = angle * Math.PI / 180;
|
|
359
363
|
const cos = Math.abs(Math.cos(radians));
|
|
360
364
|
const sin = Math.abs(Math.sin(radians));
|
|
361
365
|
const newWidth = Math.ceil(rotatedMeta.width * cos + rotatedMeta.height * sin);
|
|
362
366
|
const newHeight = Math.ceil(rotatedMeta.width * sin + rotatedMeta.height * cos);
|
|
363
367
|
|
|
364
|
-
watermarkImage = sharp(
|
|
368
|
+
watermarkImage = sharp(rotatedBuffer).rotate(angle, {
|
|
365
369
|
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
|
366
370
|
}).resize(newWidth, newHeight);
|
|
367
371
|
}
|
|
368
372
|
|
|
369
|
-
const
|
|
370
|
-
const finalWatermarkMeta = await sharp(
|
|
373
|
+
const finalWatermarkBuffer = await watermarkImage.toBuffer();
|
|
374
|
+
const finalWatermarkMeta = await sharp(finalWatermarkBuffer).metadata();
|
|
371
375
|
|
|
372
376
|
const cols = Math.ceil(metadata.width / spacingX) + 1;
|
|
373
377
|
const rows = Math.ceil(metadata.height / spacingY) + 1;
|
|
@@ -376,7 +380,7 @@ export async function addTiledImageWatermark(sharpInstance, options, providedMet
|
|
|
376
380
|
for (let row = 0; row < rows; row++) {
|
|
377
381
|
for (let col = 0; col < cols; col++) {
|
|
378
382
|
composites.push({
|
|
379
|
-
input:
|
|
383
|
+
input: finalWatermarkBuffer,
|
|
380
384
|
left: col * spacingX,
|
|
381
385
|
top: row * spacingY
|
|
382
386
|
});
|