-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.ts
93 lines (81 loc) · 3.02 KB
/
index.ts
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import Sharp from "sharp";
import getValidatedOptions from "./helpers/getValidatedOptions";
import getWatermarkSize from "./helpers/getWatermarkSize";
import positions from "./helpers/positions";
import getTextAlignment from "./helpers/getTextAlignment";
import getAlpha from "./helpers/getAlpha";
import type { Options } from "./helpers/types";
/**
* Adds a watermark image to a main image.
* @async
* @param {string|Buffer} mainImage - The main image to which the watermark will be added.
* @param {string|Buffer} watermarkImage - The watermark image to be added to the main image.
* @param {Options} options - An object containing optional values for the watermark position, size, etc.
* @throws {Error} Invalid ratio value.
* @throws {Error} Invalid x-coordinate value.
* @throws {Error} Invalid y-coordinate value.
* @throws {Error} Invalid position value.
* @returns {Promise<Sharp.Sharp>} The main image object with the watermark applied.
*/
export const addImageWatermark = async (
mainImage: string | Buffer,
watermarkImage: string | Buffer,
options: Options = {}
): Promise<Sharp.Sharp> => {
const { ratio, position, x, y } = getValidatedOptions(options);
const mainImageSharp = Sharp(mainImage);
const { waterMarkWidth } = await getWatermarkSize(mainImageSharp, ratio);
const mainImageBuffer = await mainImageSharp.toBuffer();
const watermarkImageBuffer = await Sharp(watermarkImage).toBuffer();
const watermark = await Sharp(watermarkImageBuffer)
.resize(waterMarkWidth) // only passing width will maintain the aspect ratio
.toBuffer();
return Sharp(mainImageBuffer)
.composite([
{
input: watermark,
top: y,
left: x,
gravity: positions[position],
},
])
.withMetadata();
};
/**
* Adds a watermark text to a main image.
* @async
* @param {string|Buffer} mainImage - The main image to which the watermark will be added.
* @param {string} watermarkText - The watermark text to be added to the main image.
* @param {Options} options - An object containing optional values for the watermark position, size, opacity, etc.
* @throws {Error} Invalid x-coordinate value.
* @throws {Error} Invalid y-coordinate value.
* @throws {Error} Invalid position value.
* @returns {Promise<Sharp.Sharp>} The main image object with the watermark applied.
*/
export const addTextWatermark = async (
mainImage: string | Buffer,
watermarkText: string,
options: Options = {}
): Promise<Sharp.Sharp> => {
const { dpi, opacity, position, x, y } = getValidatedOptions(options);
const mainImageBuffer = await Sharp(mainImage).toBuffer();
const textColor = `#000000${getAlpha(opacity)}`;
const watermarkObj = {
text: {
text: `<span foreground="${textColor}">${watermarkText}</span>`,
align: getTextAlignment(position),
dpi: dpi,
rgba: true,
},
};
return Sharp(mainImageBuffer)
.composite([
{
input: watermarkObj,
top: y,
left: x,
gravity: positions[position],
},
])
.withMetadata();
};