Marca d’água de fotoGrátis · Suas fotos permanecem no seu dispositivo

Ferramentas de fotos locais para desenvolvedores e assistentes

Marcas d’água em lote, etiquetas de nome de arquivo e carimbos de data gratuitos. Descubra os recursos e processe fotos explicitamente selecionadas no dispositivo.

Ler como Markdown · OpenAPI 3.1 · Esquema de receita

Escolha uma superfície de execução

A descoberta API é pública, gratuita, somente leitura e não requer chave API. Descreve ferramentas e configurações; nunca aceita imagens. Não há POST/marca d'água, serviço de processamento em nuvem ou endpoint MCP hospedado.

Use o navegador SDK para arquivos explicitamente selecionados nesta origem. Para um assistente com acesso ao sistema de arquivos local, conecte explicitamente o servidor stdio MCP do repositório e autorize um diretório raiz. Um modelo que encontra esta documentação não obtém acesso a um dispositivo ou a seus arquivos.

SuperfícieObjetivo
OBTER JSON / RemarcaçãoDescubra capacidades, receitas, restrições e assinaturas de ferramentas locais.
Navegador ESM SDKDecodifique e renderize arquivos localmente; requer Canvas, DOM, createImageBitmap e File/Blob. Não é um Node ou processamento HTTP remoto API.
CLI local/estdio MCPAutomação local conectada explicitamente usando Google Chrome instalado e dependências de repositório.

Recursos públicos

GET e HEAD retornam recursos estáticos. Sem autenticação, corpo de solicitação, parâmetros de consulta ou dados do usuário. Caminhos de recursos desconhecidos retornam 404. Trate a versão 1 como a versão do contrato; marcar caminhos canônicos em vez de blocos de construção com hash. O acesso ao navegador de origem cruzada não é prometido; use importações SDK da mesma origem.

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

Navegador SDK

Importe /sdk/watermark.js na origem deste site. Este é um URL de entrada ESM estável; pedaços de implementação podem mudar. O exemplo a seguir espera uma entrada de vários arquivos e é executado depois que o usuário seleciona os arquivos locais. Cria um ZIP de cópias bem-sucedidas; os chamadores devem inspecionar failures e cancelled em vez de tratar a exportação parcial como completa.

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));
}
FunçãoEntrada → resultado
createRecipe(mode)watermark | filename | date | frame → receita v1 independente.
validateRecipe(recipe)Receita → erros de string[]; vazio significa que a configuração é válida. A validação semântica também verifica IDs exclusivos e limites de corte.
inspectImage(file)File → Promise<Record> com id, nome, arquivo, largura, altura, URL do objeto em miniatura, substituições, metadados, metadadosAviso. Revogar a miniatura quando terminar.{id,name,file,width,height,thumbnail,overrides,metadata,metadataWarning}
renderImage(record, recipe, options?)→ Promise<{blob, geometry}>; preview:true retorna {canvas, geometry}. opções: ativos:Map<assetId,ImageBitmap|Canvas>, índice:número, maxDimension:número, tela:Canvas. missingMetadataText?:string.{blob,geometry} | {canvas,geometry}
processBatch(records, recipe, options?)→ Promise<{entries,failures,cancelled}>. Entrada: {name,blob,width,height,sourceId}; falha: {id,name,longEdge,message}. opções: ativos, sinal:AbortSignal, onProgress({done,total,failed}), onResult(entrada). missingMetadataText?:string.{entries:[{name,blob,width,height,sourceId}],failures:[{id,name,longEdge,message}],cancelled}
packageResults(entries)→ Promise<Blob> ZIP; rejeita quando a saída combinada excede 450 MiB.
decodeImage(blob)→ Promise<ImageBitmap>; close() quando terminar. HEIC usa a primeira imagem decodificada.
parseLabelCsv(text)filename,text CSV → Map<string,string>; correspondências de nomes exatos, nomes duplicados rejeitados. Defina record.label você mesmo antes do processamento.
imageRecipe(recipe, record)Mescla record.overrides.image e record.overrides.layers[id] sem alterar a receita compartilhada.
renderStudioImage / cleanLogoAjudantes Canvas de baixo nível; consulte pacotes de repositório/watermark-core/src/studio.js para assinaturas. Prefira renderImage para saída codificada.

Regras e erros de receita

Baixe receitas completas de /api/v1/recipes/watermark.json, filename.json, date.json ou frame.json. Valide JSON Schema primeiro e depois validateRecipe para verificações semânticas. Os IDs de camada devem ser exclusivos. O corte x + largura e y + altura devem ficar dentro da imagem. Tamanhos, margens, bordas e rodapés usam porcentagens da borda curta da imagem cortada e girada. A saída longEdge:0 mantém o tamanho; redimensionar nunca aumenta. O campo opcional image.crop.aspectRatio define largura/altura do conteúdo após a rotação. O recorte fica centrado na seleção normalizada de cada imagem, mesmo com tamanhos diferentes. Bordas e rodapé são adicionados depois. Editar as percentagens remove a regra de proporção.

Variáveis de texto: {filename} exclui extensão; {fullname} inclui; {index} usa sequence.start e preenchimento; {label} usa record.label. As variáveis ​​da câmera são {camera}, {lens}, {aperture}, {iso}, {shutter}, {focal}. Um CSV não preenche automaticamente os registros SDK.

A predefinição de data usa DateTimeOriginal ou CreateDate de cada imagem. Nenhuma data de modificação do arquivo é substituída. A data ausente é padronizada como um rótulo de data vazio; missing:error falha nessa imagem, missing:custom usa date.custom se for analisável. source:custom usa a data fornecida diretamente. Datas personalizadas não são carimbos de data/hora certificados. Datas inválidas podem gerar um rótulo vazio ou um erro de acordo com esta política.

Uma receita contém configurações, não bytes de logotipo ou fontes personalizadas. Forneça logotipos por meio de options.assets codificados por layer.assetId e feche os bitmaps de logotipo decodificados após o uso. As fontes personalizadas devem ser carregadas em document.fonts na família LocalFont. Os recursos ausentes falham explicitamente.

O SDK lança receitas inválidas antes da execução em lote. Erros de decodificação, renderização, metadados ou codificação por imagem aparecem em failures, enquanto entries bem-sucedido permanecem disponíveis. Os erros atualmente contêm mensagens em chinês legíveis por humanos; os consumidores não devem diversificar o seu texto. O cancelamento é verificado entre saídas; a renderização atual não é interrompida. Com onResult, entries são entregues ao retorno de chamada e não são retidos na matriz entries retornada.

Limites e privacidade

Nenhuma cota de contagem de fotos paga, conta, chave API, assinatura ou marca de site adicionada. Cada entrada é limitada a 150 MiB e 120 milhões de pixels; A saída ZIP é limitada a 450 MiB. Máximo de 30 camadas, 6 tamanhos de saída adicionais, borda longa até 32768. Navegador Canvas, limites de memória, decodificador e sistema de arquivos podem ser menores; dividir grandes lotes.

As saídas são JPEG, PNG ou WebP. JPEG e WebP com perdas são recodificados. O modo de metadados padrão é strip. Os modos safe e all requerem saída JPEG. O modo safe exclui GPS; o modo all pode reter metadados de localização. Perfis ICC, HDR e assinaturas não são preservados. Os arquivos originais nunca são alterados.

Apenas os recursos do programa são opcionalmente armazenados em cache para uso offline em /studio/.. As novas páginas públicas precisam de uma conexão de rede para serem carregadas inicialmente. Imagens de usuários e nomes de arquivos não são enviados ao API público ou armazenados em predefinições. Salve/compartilhe apenas receitas que não contenham texto privado.

Local MCP

Esse recurso é fornecido pelo repositório, não por um terminal da Internet. Pré-requisitos: Node.js, pnpm instalados no repositório e Google Chrome instalado. Execute o servidor a partir do repositório, com um diretório permitido explícito. Não infira um caminho de sistema de arquivos privado a partir dos resultados de pesquisa na web.

node scripts/watermark-mcp.mjs --root /absolute/authorized/photo-folder
FerramentaEntrada e resultado
validate_recipe{recipe} → {errors:string[]}. Não lê imagens.
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}. Grava apenas a primeira imagem, borda mais longa ≤1400.
batch_watermark{files,recipe,output?,logos?} → {files:[{path,width,height}],failures,cancelled}. Grava imagens individuais, não um ZIP.

Os caminhos de entrada em files são resolvidos dentro de --root. O mapa logos vincula IDs de ativos a caminhos dentro da mesma raiz. O padrão output é watermark-output dentro da raiz; caminhos absolutos também devem ficar dentro desta raiz. Os escapes de link simbólico são rejeitados. Os arquivos existentes são preservados escolhendo novos nomes de arquivos de saída. Os esquemas de pré-visualização e lote exigem recipe; inspect_images aceita apenas files. Imagens inválidas ficam em failures e as válidas continuam. index começa em 0 no array files original; stage é inspect ou render. A pré-visualização só processa files[0], sem substituição. Solicitações inválidas retornam isError com uma mensagem de texto; erros de processamento individuais permanecem em failures. As chamadas são de solicitação/resposta e não há ferramenta de anulação.

MCP retorna JSON serializado dentro de content[0].text, não structuredContent. Inspecionar e validar são somente leitura; visualizar e gravar cópias em lote. Nenhuma ferramenta carrega fotos. Um cliente deve configurar explicitamente este comando stdio local antes de usar as ferramentas.