# Lokalny znak wodny zdjęcia API

Bezpłatne lokalne narzędzia fotograficzne: wsadowy znak wodny, etykiety nazw plików i datowniki.

## Wybierz powierzchnię wykonania

Wykrycie API jest publiczne, bezpłatne, tylko do odczytu i nie wymaga klucza API. Opisuje narzędzia i ustawienia; nigdy nie akceptuje obrazów. Nie ma POST/znaku wodnego, usługi przetwarzania w chmurze ani hostowanego punktu końcowego MCP.

Użyj przeglądarki SDK dla wyraźnie wybranych plików tego pochodzenia. Aby uzyskać asystenta z dostępem do lokalnego systemu plików, podłącz jawnie serwer stdio MCP repozytorium i autoryzuj katalog główny. Model znajdując tę ​​dokumentację nie uzyskuje dostępu do urządzenia ani jego plików.



| Powierzchnia | Cel |
| --- | --- |
| POBIERZ JSON / Przecena | Odkryj możliwości, receptury, ograniczenia i lokalne sygnatury narzędzi. |
| Przeglądarka ESM SDK | Dekoduj i renderuj pliki lokalnie; wymaga Canvas, DOM, createImageBitmap i File/Blob. Nie Node ani zdalne przetwarzanie HTTP API. |
| Lokalny CLI/stdio MCP | Jawnie połączona automatyzacja lokalna przy użyciu zainstalowanego Google Chrome i zależności repozytorium. |


## Zasoby publiczne

GET i HEAD zwracają zasoby statyczne. Brak uwierzytelniania, treści żądania, parametrów zapytania i danych użytkownika. Nieznane ścieżki zasobów zwracają 404. Traktuj wersję 1 jako wersję kontraktu; dodaj do zakładek ścieżki kanoniczne, a nie zaszyfrowane fragmenty kompilacji. Nie gwarantuje się dostępu do przeglądarek z różnych źródeł; użyj importu SDK tego samego pochodzenia.

- [Katalog możliwości](/api/v1/capabilities.json)
- [Kompletne receptury domyślne i obsługiwane zmienne tekstowe](/api/v1/templates.json)
- [Przepis JSON Schema (2020-12)](/api/v1/recipe.schema.json)
- [Lokalne schematy wejściowe MCP](/api/v1/mcp-tools.json)
- [Specyfikacja wykrywania OpenAPI 3.1](/openapi.json)
- [Opcjonalny katalog wykrywania](/llms.txt)

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


## Przeglądarka SDK

Zaimportuj /sdk/watermark.js do źródła tej witryny. To jest stabilny adres URL wpisu ESM; fragmenty implementacji mogą ulec zmianie. Poniższy przykład oczekuje wprowadzenia wielu plików i jest uruchamiany po wybraniu przez użytkownika plików lokalnych. Tworzy ZIP udanych kopii; osoby dzwoniące muszą sprawdzić failures i cancelled, zamiast traktować częściowy eksport jako ukończony.



```
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));
}
```

| Funkcja | Wejście → wynik |
| --- | --- |
| createRecipe(mode) | watermark \| filename \| date \| frame → niezależny przepis v1. |
| validateRecipe(recipe) | Przepis → błędy string[]; pusty oznacza, że ​​konfiguracja jest prawidłowa. Walidacja semantyczna sprawdza również unikalne identyfikatory i granice upraw. |
| inspectImage(file) | File → Promise<Record> z identyfikatorem, nazwą, plikiem, szerokością, wysokością, adresem URL obiektu miniatury, nadpisaniami, metadanymi, metadanymiOstrzeżenie. Po zakończeniu cofnij miniaturę. `{id,name,file,width,height,thumbnail,overrides,metadata,metadataWarning}` |
| renderImage(record, recipe, options?) | → Promise<{blob, geometry}>; preview:true zwraca {canvas, geometry}. opcje: zasoby:Map<assetId,ImageBitmap\|Canvas>, indeks:liczba, maksymalny wymiar:liczba, płótno:Canvas. missingMetadataText?:string. `{blob,geometry} \| {canvas,geometry}` |
| processBatch(records, recipe, options?) | → Promise<{entries,failures,cancelled}>. Wpis: {name,blob,width,height,sourceId}; awaria: {id,name,longEdge,message}. opcje: aktywa, sygnał: AbortSignal, onProgress({done,total,failed}), onResult(wpis). missingMetadataText?:string. `{entries:[{name,blob,width,height,sourceId}],failures:[{id,name,longEdge,message}],cancelled}` |
| packageResults(entries) | → Promise<Blob> ZIP; odrzuca, gdy łączny rozmiar danych wyjściowych przekracza 450 MiB. |
| decodeImage(blob) | → Promise<ImageBitmap>; zamknij() po zakończeniu. HEIC wykorzystuje pierwszy zdekodowany obraz. |
| parseLabelCsv(text) | filename,text CSV → Map<ciąg,ciąg>; dopasowanie dokładnej nazwy, duplikaty nazw są odrzucane. Ustaw record.label samodzielnie przed obróbką. |
| imageRecipe(recipe, record) | Łączy record.overrides.image i record.overrides.layers[id] bez mutowania udostępnionej receptury. |
| renderStudioImage / cleanLogo | Pomocnicy niskiego poziomu Canvas; zobacz pakiety repozytorium/watermark-core/src/studio.js, aby uzyskać podpisy. Preferuj renderImage dla zakodowanego wyjścia. |


## Zasady przepisu i błędy

Pobierz pełne przepisy z /api/v1/recipes/watermark.json, nazwa pliku.json, data.json lub ramka.json. Najpierw sprawdź poprawność JSON Schema, a następnie validateRecipe w celu sprawdzenia semantyki. Identyfikatory warstw muszą być unikalne. Przytnij x + szerokość i y + wysokość muszą pozostać wewnątrz obrazu. Rozmiary, marginesy, obramowania i stopki wykorzystują wartości procentowe krótkiej krawędzi przyciętego i obróconego obrazu. Dane wyjściowe longEdge:0 zachowują rozmiar; zmiana rozmiaru nigdy nie zwiększa rozmiaru. Opcjonalne image.crop.aspectRatio określa szerokość/wysokość treści po obrocie. Kadrowanie jest wyśrodkowane w znormalizowanym zaznaczeniu każdego obrazu, także przy różnych rozmiarach. Ramki i stopki są dodawane później. Ręczna zmiana procentów usuwa regułę proporcji.

Zmienne tekstowe: {filename} wyklucza rozszerzenie; Zawiera go {fullname}; {index} wykorzystuje sequence.start i dopełnienie; {label} wykorzystuje record.label. Zmienne kamery to {camera}, {lens}, {aperture}, {iso}, {shutter}, {focal}. CSV nie wypełnia automatycznie rekordów SDK.

Wstępne ustawienie daty wykorzystuje DateTimeOriginal lub CreateDate każdego obrazu. Żadna data modyfikacji pliku nie jest zastępowana. Brakująca data domyślnie przyjmuje pustą etykietę daty; missing:error nie obsługuje tego obrazu, missing:custom używa date.custom, jeśli można go przeanalizować. source:custom wykorzystuje bezpośrednio dostarczoną datę. Daty niestandardowe nie są certyfikowanymi znacznikami czasu. Zgodnie z tymi zasadami nieprawidłowe daty mogą spowodować pustą etykietę lub błąd.

Przepis zawiera ustawienia, a nie bajty logo czy niestandardowe czcionki. Dostarczaj logo za pomocą options.assets z kluczem layer.assetId i zamykaj zdekodowane mapy bitowe logo po użyciu. Czcionki niestandardowe muszą zostać załadowane do document.fonts w ramach ich rodziny LocalFont. Brakujące zasoby kończą się jawnym niepowodzeniem.

SDK zgłasza nieprawidłowe receptury przed wykonaniem wsadowym. W failures pojawiają się błędy dekodowania, renderowania, metadanych lub kodowania poszczególnych obrazów, natomiast udane entries pozostają dostępne. Błędy zawierają obecnie czytelne dla człowieka wiadomości w języku chińskim; konsumenci nie powinni rozgałęziać się na swoim tekście. Anulowanie sprawdzane jest pomiędzy wyjściami; bieżący rendering nie zostanie przerwany. W przypadku onResult, entries są dostarczane do wywołania zwrotnego i nie są zachowywane w zwróconej tablicy entries.




## Ograniczenia i prywatność

Brak płatnego limitu liczby zdjęć, konta, klucza API, subskrypcji lub dodanego brandingu witryny. Każde wejście jest ograniczone do 150 MiB i 120 milionów pikseli; Dane wyjściowe ZIP są ograniczone do 450 MiB. Maksymalnie 30 warstw, 6 dodatkowych rozmiarów wyjściowych, długa krawędź do 32768. Przeglądarka Canvas, limity pamięci, dekodera i systemu plików mogą być niższe; podzielić duże partie.

Dane wyjściowe to JPEG, PNG lub WebP. JPEG i stratny WebP są ponownie kodowane. Domyślny tryb metadanych to „strip”. Tryby safe i all wymagają wyjścia w formacie JPEG. Tryb „safe” wyklucza GPS; tryb „all” może zachować metadane lokalizacji. Profile ICC, HDR i podpisy nie są zachowywane. Oryginalne pliki nigdy nie są zmieniane.

Tylko zasoby programu są opcjonalnie buforowane do użytku w trybie offline w /studio/.. Nowe strony publiczne wymagają początkowo połączenia sieciowego, aby się załadować. Obrazy użytkowników i nazwy plików nie są wysyłane do publicznej wiadomości API ani przechowywane w ustawieniach wstępnych. Zapisuj/udostępniaj tylko przepisy, które nie zawierają prywatnego tekstu.




## Lokalny MCP

Tę możliwość zapewnia repozytorium, a nie internetowy punkt końcowy. Wymagania wstępne: Zainstaluj Node.js, pnpm w repozytorium i zainstaluj Google Chrome. Uruchom serwer z repozytorium z jawnie dozwolonym katalogiem. Nie wnioskuj ścieżki prywatnego systemu plików z wyników wyszukiwania w Internecie.



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

| Narzędzie | Wejście i wynik |
| --- | --- |
| validate_recipe | {recipe} → {errors:string[]}. Nie czyta obrazów. |
| 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}. Zapisuje tylko pierwszy obraz, najdłuższa krawędź ≤1400. |
| batch_watermark | {files,recipe,output?,logos?} → {files:[{path,width,height}],failures,cancelled}. Zapisuje pojedyncze obrazy, a nie ZIP. |
Ścieżki wejściowe w files są rozwiązywane wewnątrz --root. Mapa „logos” łączy identyfikatory zasobów ze ścieżkami w tym samym katalogu głównym. Domyślnym „output” jest „watermark-output” w katalogu głównym; ścieżki bezwzględne muszą również pozostać wewnątrz tego katalogu głównego. Ucieczki dowiązań symbolicznych są odrzucane. Istniejące pliki są zachowywane poprzez wybranie nowych nazw plików wyjściowych. Schematy podglądu i partii wymagają recipe; inspect_images przyjmuje tylko files. Nieprawidłowe obrazy trafiają do failures, poprawne są dalej przetwarzane. index liczy od 0 w pierwotnej tablicy files; stage to inspect lub render. Podgląd dotyczy tylko files[0], bez zamiany pliku.  Nieprawidłowe żądania zwracają isError wraz z wiadomością tekstową; indywidualne błędy przetwarzania pozostają w failures. Połączenia są żądaniem/odpowiedzią i nie ma narzędzia przerywania.

MCP zwraca JSON serializowany wewnątrz content[0].text, a nie structuredContent. Inspekcja i sprawdzanie poprawności są przeznaczone tylko do odczytu; podgląd i wsadowy zapis kopii. Żadne narzędzie nie przesyła zdjęć. Klient musi jawnie skonfigurować to lokalne polecenie stdio przed użyciem tych narzędzi.