Un mΓ³dulo ligero y potente en JavaScript puro para agregar, personalizar y eliminar marcas de agua en imΓ‘genes y videos. Construido con canvas y fluent-ffmpeg, maneja sin problemas archivos locales, buffers y URLs, y sube automΓ‘ticamente el contenido multimedia procesado a una CDN dual (Adoolab y Soymaycol).
β Β‘Se agradecerΓa muchΓsimo si le das una estrellita al repo! Tu apoyo ayuda a que el proyecto siga creciendo. π¦
β¨ It would mean a lot if you starred the repo! Your support helps keep the project alive. πΎ
Autores / Authors:
πͺπΈ Ver en EspaΓ±ol
- π¦ Soporte Multiformato: Agrega marcas de agua tanto a imΓ‘genes como a videos.
- π’ Marcas de Agua Animadas: Soporta GIFs y videos cortos (hasta 15 segundos) como marca de agua sobre otros videos.
- π Texto como Marca de Agua: No tienes una imagen? Usa texto puro con fuente, color y borde personalizable.
- π§© PatrΓ³n Repetido (Tile): Protege tus imΓ‘genes con marcas de agua en mosaico diagonales o cuadradas.
- π Timestamp AutomΓ‘tico: Agrega la fecha y hora actual dinΓ‘micamente como marca de agua.
- πΈ MΓΊltiples Watermarks: Superpon varias marcas de agua en una sola imagen con posiciones individuales.
- π€ Eliminador de Watermarks (ImΓ‘genes): Elimina marcas de agua de imΓ‘genes automΓ‘ticamente usando Inteligencia Artificial (no requiere coordenadas).
- π©Ή Eliminador de Watermarks (Videos): Borra marcas de agua de videos difuminando una regiΓ³n especΓfica usando
delogo. - π Entradas Flexibles: Acepta rutas de archivos locales, Buffers o URLs directas HTTP/HTTPS.
- πΎ Posicionamiento Personalizado: Coloca tu marca de agua exactamente donde la necesitas usando coordenadas o posiciones relativas.
- π Opacidad, Escalado y Formatos: Ajusta transparencia, escala, calidad y formato de salida (PNG, JPG, WEBP, MP4, WEBM).
- π« Modo Local (Skip CDN): Procesa y devuelve solo el Buffer sin subir a ninguna CDN.
- π¦ Auto-CDN Dual: Sube automΓ‘ticamente el resultado a dos CDNs al mismo tiempo y devuelve ambos enlaces.
Para instalar el mΓ³dulo directamente desde GitHub usando la terminal (CLI), ejecuta:
VΓa GitHub:
npm install github:thisAdo/watermarkVΓa NPM:
npm install @adomay/watermarkComo este mΓ³dulo utiliza la sintaxis moderna de mΓ³dulos de ECMAScript (import/export), debes asegurarte de que el proyecto donde lo vayas a usar tenga configurado "type": "module" en su archivo package.json.
Si instalas vΓa GitHub, tu package.json deberΓa verse asΓ:
{
"name": "mi-proyecto-increible",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@adomay/watermark": "github:thisAdo/watermark"
}
}Si instalas vΓa NPM, tu package.json deberΓa verse asΓ:
{
"name": "mi-proyecto-increible",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@adomay/watermark": "*"
}
}import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'https://cdn.adoolab.xyz/dl/watermark.png',
'image',
{ x: 'right', y: 'bottom', margin: 20, opacity: 0.8, width: 150 }
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/db6f3f3b.mp4',
'https://cdn.adoolab.xyz/dl/watermark.png',
'video',
{ x: 'left', y: 'top', opacity: 0.9, width: 120 }
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/db6f3f3b.mp4',
'https://cdn.adoolab.xyz/dl/e426a597.gif',
'video',
{ x: 'left', y: 'bottom', width: 100 }
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
null,
'image',
{
text: 'Β© Mi Empresa 2024',
fontSize: 30,
fontColor: '#ff0000',
strokeColor: '#000000',
strokeWidth: 3,
x: 'center',
y: 'center'
}
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'https://cdn.adoolab.xyz/dl/watermark.png',
'image',
{
x: 'tile',
y: 'tile',
opacity: 0.2,
margin: 50,
rotation: -30
}
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
null,
'image',
{
timestamp: true,
timestampFormat: 'YYYY-MM-DD HH:mm:ss',
fontSize: 20,
x: 'right',
y: 'bottom',
margin: 10
}
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
[
{ source: 'https://cdn.adoolab.xyz/dl/watermark.png', x: 'left', y: 'top', width: 80 },
{ source: 'https://cdn.adoolab.xyz/dl/watermark2.png', x: 'right', y: 'bottom', width: 100 }
],
'image'
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
import fs from 'fs';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'https://cdn.adoolab.xyz/dl/watermark.png',
'image',
{ skipCDN: true, outputFormat: 'webp', quality: 80 }
);
if (result.status) {
fs.writeFileSync('mi_foto_local.webp', result.data);
}import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
// Para imΓ‘genes, solo pasa la URL. El mΓ³dulo usa IA para detectar y borrar la marca automΓ‘ticamente.
const result = await watermarkService.remove(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'image'
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
// Para videos, debes indicar las coordenadas exactas de la marca de agua a difuminar.
const result = await watermarkService.remove(
'https://cdn.adoolab.xyz/dl/db6f3f3b.mp4',
'video',
{
x: 'left',
y: 'bottom',
margin: 20,
width: 100,
height: 100
}
);
console.log(result.status ? result.urls : result.msg);Inicia el proceso de superposiciΓ³n de la marca de agua y devuelve un objeto que contiene el Buffer resultante y los enlaces de las subidas a las CDN.
πΎ ParΓ‘metros:
| ParΓ‘metro | Tipo | DescripciΓ³n |
|---|---|---|
source |
`String | Buffer` |
watermark |
`String | Buffer |
type |
String |
El tipo de medio del archivo principal. Debe ser 'image' o 'video'. Por defecto: 'image'. |
options |
Object |
Objeto opcional de configuraciΓ³n para cambiar la apariencia y posiciΓ³n de la marca de agua. |
π Objeto options:
| Propiedad | Tipo | Por defecto | DescripciΓ³n |
|---|---|---|---|
x |
`String | Number` | 'right' |
y |
`String | Number` | 'bottom' |
margin |
Number |
20 |
Distancia en pΓxeles hacia los bordes (se aplica cuando usas posiciones relativas o en mosaico). |
width |
Number |
null |
Fuerza a la marca de agua a cambiar su tamaΓ±o a este ancho especΓfico en pΓxeles. |
opacity |
Number |
1.0 |
Nivel de transparencia. Va desde 0.0 (invisible) hasta 1.0 (opaco). |
rotation |
Number |
null |
Rota la marca de agua en grados (solo aplicable en modo mosaico 'tile'). |
text |
String |
null |
Texto a renderizar como marca de agua (ignora el parΓ‘metro watermark). |
fontSize |
Number |
24 |
TamaΓ±o de la fuente si se usa text. |
fontColor |
String |
'#ffffff' |
Color del texto (hexadecimal). |
strokeColor |
String |
'#000000' |
Color del borde del texto (hexadecimal). |
strokeWidth |
Number |
2 |
Grosor del borde del texto. |
timestamp |
Boolean |
false |
Si es true, genera un texto dinΓ‘mico con la fecha y hora actuales. |
timestampFormat |
String |
'DD/MM/YYYY HH:mm:ss' |
Formato de la fecha (variables: YYYY, MM, DD, HH, mm, ss). |
skipCDN |
Boolean |
false |
Si es true, no sube el archivo a ninguna CDN y devuelve solo el Buffer. |
outputFormat |
String |
'png'/'mp4' |
Formato de salida ('png', 'jpg', 'webp' para imΓ‘genes; 'mp4', 'webm' para videos). |
quality |
Number |
90 |
Calidad de compresiΓ³n para formatos como jpg o webp (0 a 100). |
Elimina una marca de agua existente. En imΓ‘genes utiliza una API de Inteligencia Artificial que detecta y borra la marca automΓ‘ticamente. En videos difumina una regiΓ³n especΓfica usando el filtro delogo de FFmpeg.
πΎ ParΓ‘metros:
| ParΓ‘metro | Tipo | DescripciΓ³n |
|---|---|---|
source |
String |
El archivo principal. Nota: Para imΓ‘genes, debe ser obligatoriamente una URL pΓΊblica accesible por internet (no Buffers ni rutas locales). |
type |
String |
'image' o 'video'. |
region |
Object |
Opcional en imΓ‘genes (la IA se encarga). Obligatorio en videos: Requiere coordenadas (x, y, width, height). Acepta posiciones relativas ('left', 'right', 'bottom', etc.) junto con margin, o nΓΊmeros exactos en pΓxeles. |
π’ Valor de Retorno:
Si el proceso tiene Γ©xito, devuelve un objeto con la siguiente estructura:
{
creator: 'Ado & Maycol',
status: true,
data: <Buffer>,
urls: {
ado: 'https://cdn.adoolab.xyz/dl/output.png',
maycol: 'https://cdn.soymaycol.icu/files/output.png'
},
cdnData: { ... }
}En caso de error, devuelve:
{
creator: 'Ado & Maycol',
status: false,
msg: 'DescripciΓ³n detallada del error'
}πΊπΈ View in English
- π¦ Multi-Format Support: Add watermarks to both images and videos.
- π’ Animated Watermarks: Supports GIFs and short videos (up to 15 seconds) as watermarks over other videos.
- π Text Watermark: Don't have an image? Use pure text with custom font, color, and stroke.
- π§© Tile Pattern: Protect your images with diagonal or square mosaic watermarks.
- π Automatic Timestamp: Dynamically add the current date and time as a watermark.
- πΈ Multiple Watermarks: Overlay several watermarks on a single image with individual positions.
- π€ Watermark Remover (Images): Removes watermarks from images automatically using Artificial Intelligence (no coordinates required).
- π©Ή Watermark Remover (Videos): Erases watermarks from videos by blurring a specific region using
delogo. - π Flexible Inputs: Accepts local file paths, raw Buffers, or direct HTTP/HTTPS URLs.
- πΎ Custom Positioning: Place your watermark exactly where you need it using coordinates or relative text positions.
- π Opacity, Scaling & Formats: Adjust transparency, scale, quality, and output format (PNG, JPG, WEBP, MP4, WEBM).
- π« Local Mode (Skip CDN): Process and return only the Buffer without uploading to any CDN.
- π¦ Dual Auto-CDN: Automatically uploads the resulting output to two external CDNs simultaneously and returns both ready-to-use URLs.
To install the module directly from GitHub using the CLI, run the following command:
By GitHub:
npm install github:thisAdo/watermarkBy NPM:
npm install @adomay/watermarkSince this module uses modern ECMAScript module syntax (import/export), you must ensure that the project where you are using it has "type": "module" set in its package.json.
If installing via GitHub, your package.json should look like this:
{
"name": "my-project",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@adomay/watermark": "github:thisAdo/watermark"
}
}If installing via NPM, your package.json should look like this:
{
"name": "my-project",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@adomay/watermark": "*"
}
}import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'https://cdn.adoolab.xyz/dl/watermark.png',
'image',
{ x: 'right', y: 'bottom', margin: 20, opacity: 0.8, width: 150 }
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/db6f3f3b.mp4',
'https://cdn.adoolab.xyz/dl/watermark.png',
'video',
{ x: 'left', y: 'top', opacity: 0.9, width: 120 }
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/db6f3f3b.mp4',
'https://cdn.adoolab.xyz/dl/e426a597.gif',
'video',
{ x: 'left', y: 'bottom', width: 100 }
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
null,
'image',
{
text: 'Β© My Company 2024',
fontSize: 30,
fontColor: '#ff0000',
strokeColor: '#000000',
strokeWidth: 3,
x: 'center',
y: 'center'
}
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'https://cdn.adoolab.xyz/dl/watermark.png',
'image',
{
x: 'tile',
y: 'tile',
opacity: 0.2,
margin: 50,
rotation: -30
}
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
null,
'image',
{
timestamp: true,
timestampFormat: 'YYYY-MM-DD HH:mm:ss',
fontSize: 20,
x: 'right',
y: 'bottom',
margin: 10
}
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
[
{ source: 'https://cdn.adoolab.xyz/dl/watermark.png', x: 'left', y: 'top', width: 80 },
{ source: 'https://cdn.adoolab.xyz/dl/watermark2.png', x: 'right', y: 'bottom', width: 100 }
],
'image'
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
import fs from 'fs';
const watermarkService = new Watermark();
const result = await watermarkService.execute(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'https://cdn.adoolab.xyz/dl/watermark.png',
'image',
{ skipCDN: true, outputFormat: 'webp', quality: 80 }
);
if (result.status) {
fs.writeFileSync('my_local_photo.webp', result.data);
}import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
// For images, just pass the URL. The module uses AI to detect and erase the watermark automatically.
const result = await watermarkService.remove(
'https://cdn.adoolab.xyz/dl/8932d34a.jpg',
'image'
);
console.log(result.status ? result.urls : result.msg);import { Watermark } from '@adomay/watermark';
const watermarkService = new Watermark();
// For videos, you must specify the exact coordinates of the watermark area to blur.
const result = await watermarkService.remove(
'https://cdn.adoolab.xyz/dl/db6f3f3b.mp4',
'video',
{
x: 'left',
y: 'bottom',
margin: 20,
width: 100,
height: 100
}
);
console.log(result.status ? result.urls : result.msg);Executes the watermark overlay process and returns an object containing the resulting Buffer and the dual CDN upload data.
πΎ Parameters:
| Parameter | Type | Description |
|---|---|---|
source |
`String | Buffer` |
watermark |
`String | Buffer |
type |
String |
Specifies the main media type. Must be either 'image' or 'video'. Defaults to 'image'. |
options |
Object |
Optional configuration object to change the watermark's appearance and position. |
π Options Object:
| Property | Type | Default | Description |
|---|---|---|---|
x |
`String | Number` | 'right' |
y |
`String | Number` | 'bottom' |
margin |
Number |
20 |
Margin in pixels applied when using relative string positions or tile mode. |
width |
Number |
null |
Forces the watermark to scale to a specific width in pixels. |
opacity |
Number |
1.0 |
Transparency level, from 0.0 (invisible) to 1.0 (fully opaque). |
rotation |
Number |
null |
Rotates the watermark in degrees (only applicable in 'tile' mode). |
text |
String |
null |
Text to render as a watermark (ignores the watermark parameter). |
fontSize |
Number |
24 |
Font size if using text. |
fontColor |
String |
'#ffffff' |
Text color (hexadecimal). |
strokeColor |
String |
'#000000' |
Text stroke color (hexadecimal). |
strokeWidth |
Number |
2 |
Text stroke thickness. |
timestamp |
Boolean |
false |
If true, generates dynamic text with the current date and time. |
timestampFormat |
String |
'DD/MM/YYYY HH:mm:ss' |
Date format (variables: YYYY, MM, DD, HH, mm, ss). |
skipCDN |
Boolean |
false |
If true, skips uploading to CDNs and returns only the Buffer. |
outputFormat |
String |
'png'/'mp4' |
Output format ('png', 'jpg', 'webp' for images; 'mp4', 'webm' for videos). |
quality |
Number |
90 |
Compression quality for formats like jpg or webp (0 to 100). |
Removes an existing watermark. For images, it uses an Artificial Intelligence API that detects and erases the mark automatically. For videos, it blurs a specific region using FFmpeg's delogo filter.
πΎ Parameters:
| Parameter | Type | Description |
|---|---|---|
source |
String |
The main media file. Note: For images, it must strictly be a public URL accessible via the internet (no Buffers or local paths). |
type |
String |
'image' or 'video'. |
region |
Object |
Optional for images (AI handles it). Mandatory for videos: Requires coordinates (x, y, width, height). Accepts relative positions ('left', 'right', 'bottom', etc.) along with margin, or exact pixel numbers. |
π’ Return Value:
If successful, returns a Promise that resolves to an object with the following structure:
{
creator: 'Ado & Maycol',
status: true,
data: <Buffer>,
urls: {
ado: 'https://cdn.adoolab.xyz/dl/output.png',
maycol: 'https://cdn.soymaycol.icu/files/output.png'
},
cdnData: { ... }
}If an error occurs, it returns:
{
creator: 'Ado & Maycol',
status: false,
msg: 'Detailed error description'
}