# Водяний знак локальної фотографії API

Безкоштовні локальні інструменти для фотографій: пакетний водяний знак, мітки з іменами файлів і позначки дати.

## Виберіть поверхню для виконання

Відкриття API є загальнодоступним, безкоштовним, доступним лише для читання та не потребує ключа API. Він описує інструменти та налаштування; він ніколи не приймає зображення. Немає POST/водяного знака, служби хмарної обробки чи розміщеної кінцевої точки MCP.

Використовуйте браузер SDK для явно вибраних файлів у цьому джерелі. Для помічника з доступом до локальної файлової системи явно підключіть сервер stdio MCP сховища та авторизуйте кореневий каталог. Модель, яка знайшла цю документацію, не отримує доступу до пристрою чи його файлів.



| Поверхня | призначення |
| --- | --- |
| ОТРИМАТИ JSON / Markdown | Відкрийте для себе можливості, рецепти, обмеження та сигнатури локальних інструментів. |
| Браузер ESM SDK | Декодувати та рендерити файли локально; вимагає Canvas, DOM, createImageBitmap і File/Blob. Не Node або віддалена обробка HTTP API. |
| Локальний CLI / stdio MCP | Явно підключена локальна автоматизація за допомогою встановленого Google Chrome і залежностей репозиторію. |


## Громадські ресурси

GET і HEAD повертають статичні ресурси. Без автентифікації, тіла запиту, параметрів запиту або даних користувача. Невідомі шляхи до ресурсів повертають 404. Вважати версію 1 контрактною версією; закладки канонічних шляхів, а не хешованих фрагментів збірки. Перехресний доступ до браузера не обіцяно; використовуйте імпорт SDK того самого походження.

- [Каталог можливостей](/api/v1/capabilities.json)
- [Повні рецепти за замовчуванням і підтримувані текстові змінні](/api/v1/templates.json)
- [Рецепт JSON Schema (2020-12)](/api/v1/recipe.schema.json)
- [Локальні схеми введення MCP](/api/v1/mcp-tools.json)
- [Специфікація відкриття OpenAPI 3.1](/openapi.json)
- [Додатковий каталог відкриття](/llms.txt)

```
curl https://watermark.noxxxx.com/api/v1/capabilities.json
curl https://watermark.noxxxx.com/api/v1/recipes/filename.json
```


## Браузер SDK

Імпортуйте /sdk/watermark.js на джерело цього сайту. Це стабільна URL-адреса входу ESM; фрагменти реалізації можуть змінюватися. Наступний приклад передбачає введення кількох файлів і виконується після того, як користувач вибере локальні файли. Він створює ZIP успішних копій; абоненти повинні перевірити failures і cancelled, а не розглядати частковий експорт як повний.



```
import { createRecipe, validateRecipe, inspectImage, processBatch, packageResults }
  from '/sdk/watermark.js';

// Run on this site's origin in a modern browser, after explicit file selection.
const files = [...document.querySelector('input[type="file"]').files];
const recipe = createRecipe('filename'); // watermark | filename | date | frame
const errors = validateRecipe(recipe);
if (errors.length) throw new Error(errors.join('; '));
const records = [];
try {
  for (const file of files) records.push(await inspectImage(file));
  const result = await processBatch(records, recipe);
  if (result.failures.length || result.cancelled) {
    console.warn('Check partial results before downloading', result);
  }
  if (result.entries.length) {
    const zip = await packageResults(result.entries);
    const url = URL.createObjectURL(zip);
    const link = document.createElement('a');
    link.href = url; link.download = 'labeled-photos.zip'; link.click();
    setTimeout(() => URL.revokeObjectURL(url), 30000);
  }
} finally {
  records.forEach(record => URL.revokeObjectURL(record.thumbnail));
}
```

| функція | Введення → результат |
| --- | --- |
| createRecipe(mode) | watermark \| filename \| date \| frame → незалежний рецепт v1. |
| validateRecipe(recipe) | Рецепт → рядок [] помилки; порожній означає дійсну конфігурацію. Семантична перевірка також перевіряє унікальні ідентифікатори та межі обрізання. |
| inspectImage(file) | File → Promise<Record> з ідентифікатором, іменем, файлом, шириною, висотою, URL-адресою об’єкта мініатюри, перевизначеннями, метаданими, попередженням метаданих. Скасувати мініатюру після завершення. `{id,name,file,width,height,thumbnail,overrides,metadata,metadataWarning}` |
| renderImage(record, recipe, options?) | → Promise<{blob, geometry}>; preview:true повертає {canvas, geometry}. параметри: Assets:Map<assetId,ImageBitmap\|Canvas>, index:number, maxDimension:number, canvas:Canvas. missingMetadataText?:string. `{blob,geometry} \| {canvas,geometry}` |
| processBatch(records, recipe, options?) | → Promise<{entries,failures,cancelled}>. Запис: {name,blob,width,height,sourceId}; помилка: {id,name,longEdge,message}. параметри: активи, сигнал:AbortSignal, onProgress({done,total,failed}), onResult(запис). missingMetadataText?:string. `{entries:[{name,blob,width,height,sourceId}],failures:[{id,name,longEdge,message}],cancelled}` |
| packageResults(entries) | → Promise<Blob> ZIP; відхиляється, коли сукупний вихід перевищує 450 МіБ. |
| decodeImage(blob) | → Promise<ImageBitmap>; close() після завершення. HEIC використовує перше декодоване зображення. |
| parseLabelCsv(text) | filename,text CSV → Map<рядок,рядок>; точні збіги імен, повторювані імена відхиляються. Встановіть record.label самостійно перед обробкою. |
| imageRecipe(recipe, record) | Об’єднує record.overrides.image і record.overrides.layers[id], не змінюючи спільний рецепт. |
| renderStudioImage / cleanLogo | Низькорівневі хелпери Canvas; див. репозиторій packages/watermark-core/src/studio.js для підписів. Віддавайте перевагу renderImage для кодованого виведення. |


## Правила рецептури та помилки

Завантажте повні рецепти з /api/v1/recipes/watermark.json, filename.json, date.json або frame.json. Спочатку перевірте JSON Schema, а потім validateRecipe для семантичної перевірки. Ідентифікатори шарів мають бути унікальними. Обрізання x + ширина та y + висота мають залишатися всередині зображення. Розміри, поля, рамки та нижні колонтитули використовують відсотки короткого краю обрізаного та повернутого зображення. Вихід longEdge:0 зберігає розмір; зміна розміру ніколи не збільшується. Необов’язкове image.crop.aspectRatio задає ширину/висоту вмісту після повороту. Обрізання центрується в нормалізованій області кожного зображення, зокрема різного розміру. Рамки й нижній підпис додаються потім. Ручна зміна відсотків скасовує правило пропорцій.

Текстові змінні: {filename} виключає розширення; {fullname} включає його; {index} використовує sequence.start і доповнення; {label} використовує record.label. Змінні камери: {camera}, {lens}, {aperture}, {iso}, {shutter}, {focal}. CSV не заповнює записи SDK автоматично.

Попереднє налаштування дати використовує DateTimeOriginal або CreateDate кожного зображення. Дата зміни файлу не замінюється. Відсутня дата за умовчанням має порожню мітку дати; missing:error не відповідає цьому зображенню, missing:custom використовує date.custom, якщо його можна аналізувати. source:custom безпосередньо використовує надану дату. Спеціальні дати не є сертифікованими часовими мітками. Недійсні дати можуть спричинити порожню мітку або помилку відповідно до цієї політики.

Рецепт містить параметри, а не байти логотипу чи власні шрифти. Поставте логотипи через options.assets з ключем layer.assetId і закрийте декодовані растрові зображення логотипу після використання. Користувальницькі шрифти потрібно завантажити в document.fonts під їх сімейством LocalFont. Відсутні ресурси явно не вдаються.

SDK видає недійсні рецепти перед пакетним виконанням. У failures з’являються помилки декодування, візуалізації, метаданих або кодування кожного зображення, тоді як успішний entries залишається доступним. Помилки наразі містять читабельні повідомлення китайською мовою; споживачі не повинні розгалужуватися на їхньому тексті. Скасування перевіряється між виходами; поточний рендер не переривається. З onResult entries доставляються до зворотного виклику та не зберігаються у поверненому масиві entries.




## Обмеження та конфіденційність

Немає платної квоти на кількість фотографій, облікового запису, ключа API, підписки чи доданого бренду сайту. Кожен вхід обмежений 150 МіБ і 120 мільйонами пікселів; Вихід ZIP обмежено 450 МіБ. Максимум 30 шарів, 6 додаткових розмірів виводу, довгий край до 32768. Обмеження браузера Canvas, пам’яті, декодера та файлової системи можуть бути меншими; розділити великі партії.

Виходи: JPEG, PNG або WebP. JPEG і WebP із втратою кодуються повторно. Типовим режимом метаданих є strip. Для режимів safe і all необхідний вихід JPEG. Режим safe виключає GPS; режим all може зберігати метадані розташування. Профілі ICC, HDR і підписи не зберігаються. Оригінальні файли ніколи не змінюються.

У /studio/. додатково кешуються лише ресурси програми для використання в автономному режимі. Для початкового завантаження нових загальнодоступних сторінок потрібне підключення до мережі. Зображення та імена файлів користувачів не надсилаються в загальнодоступний API і не зберігаються в попередньо встановлених налаштуваннях. Зберігайте/діліться лише рецептами, які не містять приватного тексту.




## Місцевий MCP

Ця можливість надається репозиторієм, а не кінцевою точкою Інтернету. Необхідні умови: Node.js, pnpm встановити в репозиторій і встановити Google Chrome. Запустіть сервер зі сховища з явним дозволеним каталогом. Не виводьте шлях до приватної файлової системи з результатів веб-пошуку.



```
node scripts/watermark-mcp.mjs --root /absolute/authorized/photo-folder
```

| Інструмент | Вхід і результат |
| --- | --- |
| validate_recipe | {recipe} → {errors:string[]}. Не читає зображення. |
| inspect_images | {files:string[]} → {images:[{id,name,width,height,metadata,metadataWarning}],failures:[{id,name,index,stage,message}]}. |
| preview_watermark | {files,recipe,output?,logos?} → {files:[{path,width,height}],failures,cancelled}. Записує лише перше зображення, найдовший край ≤1400. |
| batch_watermark | {files,recipe,output?,logos?} → {files:[{path,width,height}],failures,cancelled}. Записує окремі зображення, а не ZIP. |
Шляхи введення в files вирішуються всередині --root. Карта logos пов'язує ідентифікатори активів із шляхами в одному корені. Типовим значенням output є watermark-output в корені; абсолютні шляхи також повинні залишатися всередині цього кореня. Екранування символічних посилань відхилено. Існуючі файли зберігаються шляхом вибору нових імен вихідних файлів. Схеми перегляду й пакета вимагають recipe; inspect_images приймає лише files. Непридатні зображення потрапляють до failures, решта обробляються далі. index починається з 0 у початковому масиві files; stage — inspect або render. Перегляд обробляє лише files[0], без заміни іншим файлом.  Недійсні запити повертають isError з текстовим повідомленням; окремі помилки обробки залишаються в failures. Дзвінки є запитом/відповіддю, і немає інструменту переривання.

MCP повертає JSON, серіалізований у content[0].text, а не structuredContent. Перевірка та перевірка доступні лише для читання; попередній перегляд і пакетне записування копій. Жоден інструмент не завантажує фотографії. Клієнт повинен явно налаштувати цю локальну команду stdio перед використанням інструментів.