--- url: https://docs.snapotter.com/guide/getting-started.md description: >- Install SnapOtter with Docker in one command. Includes Docker Compose setup, building from source, and a full feature overview. --- # Getting Started {#getting-started} ::: tip Try before installing Explore the full UI at [demo.snapotter.com](https://demo.snapotter.com) - no signup or install required. ::: ## Quick Start {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` This single container runs everything it needs: with no `DATABASE_URL` set, it starts its own PostgreSQL and Redis on the loopback interface (embedded mode) and keeps all data in the `SnapOtter-data` volume. It is the fastest way to try SnapOtter or self-host on a homelab. For production, use the [canonical Docker Compose stack](#docker-compose), which keeps PostgreSQL and Redis in their own containers. Embedded mode runs as root (the default) and turns off automatically as soon as you set `DATABASE_URL`. Installing on a Raspberry Pi, an old laptop, or a small VPS? See [Low-Resource Setups](/guide/low-resource) for a tuned walkthrough and what to expect from constrained hardware. You will be asked to change your password on first login. ::: tip Anonymous Product Analytics SnapOtter includes anonymous product analytics by default. To turn it off, open **Settings → System → Privacy** and switch off **Anonymous Product Analytics**. It stops immediately for the whole instance. You can also set the environment variable `SNAPOTTER_TELEMETRY=0` (`false` and `off` work too) to disable all telemetry for the instance without a rebuild. Error monitoring is powered by [Sentry](https://sentry.io), which sponsors SnapOtter through its open-source program. For details about what is collected, see [What SnapOtter collects](/guide/telemetry). ::: ::: tip NVIDIA CUDA acceleration Add `--gpus all` for NVIDIA CUDA-accelerated background removal, upscaling, face enhancement, and restoration. OCR remains CPU-based and works in the same image with or without GPU access: ```bash docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest ``` Requires the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). Falls back to CPU automatically when CUDA is unavailable. Intel/AMD iGPU acceleration through VA-API, Quick Sync, or OpenCL is not supported for AI inference today. See [Docker Tags](/guide/docker-tags) for benchmarks. If AI tools run on CPU despite `--gpus all`, see [Verify GPU acceleration](/guide/deployment#verify-gpu-acceleration). ::: ::: details Also on GHCR ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snapotter-hq/snapotter:latest ``` Both registries publish the same image on every release. ::: ## Docker Compose {#docker-compose} Use the production file maintained and tested with each release instead of copying an abbreviated Compose example from this page: ```bash install -d -m 700 snapotter && cd snapotter curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \ https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.2.0/docker/docker-compose.yml # Keep generated service credentials out of shell history and world-readable files. umask 077 POSTGRES_PASSWORD="$(openssl rand -hex 32)" REDIS_PASSWORD="$(openssl rand -hex 32)" printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \ "$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --no-build ``` The canonical [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.2.0/docker/docker-compose.yml) includes all four runtime volumes, health checks, resource limits, durable Redis configuration, pinned database/cache images, and the current container hardening. Change the default admin password immediately after first login. For a reproducible deployment, pin the SnapOtter application image to the release tag or digest you verified instead of following `latest`. See [Configuration](/guide/configuration) for all environment variables and [Security & Hardening](/guide/security) for secrets, network policy, and backup guidance. ## Build from Source {#build-from-source} **Prerequisites:** Node.js 22.22+, pnpm 9+, Docker (for Postgres + Redis), Python 3.11+ (for AI features), Git. ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` * Frontend: * Backend: ## What You Can Do {#what-you-can-do} ### File Processing (200+ Tools) {#file-processing-200-tools} | Modality | Count | Example Tools | |----------|-------|---------------| | **Image** | 107 | Resize, Crop, Compress, Convert, Remove Background, Upscale, OCR, Watermark, Collage, Colorize, GIF Tools, format presets | | **Video** | 57 | Trim, Crop, Compress, Convert, Merge, Extract Audio, Auto Subtitles, Video to GIF, Resize, Stabilize, format presets | | **Audio** | 27 | Trim, Merge, Convert, Normalize, Noise Reduction, Transcribe, Pitch Shift, Fade, Ringtone Maker, format presets | | **PDF / Document** | 29 | Merge, Split, Compress, OCR, Watermark, Redact, Word to PDF, Excel to PDF, Rotate, Protect, Repair | | **Files** | 23 | CSV to JSON, JSON to XML, Merge CSVs, Split CSV, Create ZIP, Extract ZIP, Chart Maker, YAML/JSON | ### Pipelines {#pipelines} Chain tools into multi-step workflows and apply them to one image or a whole batch: 1. Open **Pipelines** in the sidebar. 2. Add steps (any tool, any settings). 3. Run on a single file - or an entire batch at once. 4. Save the pipeline for later reuse. Pipelines allow 20 steps by default. Set `MAX_PIPELINE_STEPS=0` to make the limit unlimited. ### File Library {#file-library} Every file you process can be saved to your **Files** library. SnapOtter tracks the full version history so you can trace every processing step from the original upload to the final output. Saving is explicit: results you save to the library are kept until you delete them, while results you process and leave unsaved are cleared automatically after 72 hours (configurable via `FILE_MAX_AGE_HOURS`). ### REST API & API Keys {#rest-api-api-keys} Every tool is accessible via HTTP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800,"height":600,"fit":"cover"}' ``` Generate API keys under **Settings → API Keys**. See the [REST API reference](/api/rest) for all endpoints, or visit for the interactive reference. ### Multi-User & Teams {#multi-user-teams} Enable multiple users with role-based access control: * **Admin**: full access - manage users, teams, settings, all files/pipelines/API keys * **User**: use tools, manage own files/pipelines/API keys Create teams under **Settings → Teams** to group users. Set `AUTH_ENABLED=true` (or `false` for single-user/self-use without login). ## Use It From Your Phone {#use-it-from-your-phone} SnapOtter works in mobile browsers, and you can install it as an app. Open your instance on the phone, then: * **iPhone / iPad (Safari):** tap Share, then **Add to Home Screen**. * **Android (Chrome):** open the browser menu and tap **Install app**. The installed app opens in its own window, straight to your instance. One catch: browsers only offer the install prompt over HTTPS. A plain HTTP address on your LAN still works fine in a browser tab; for the real install, put the instance behind a reverse proxy with a certificate (see the [deployment guide](/guide/deployment)). On phones and tablets, image tools show a **Take photo** button next to the upload button. Shoot a receipt or a whiteboard and it lands straight in the tool. --- --- url: https://docs.snapotter.com/guide/architecture.md description: >- Monorepo structure, app and package architecture, request lifecycle, and resource footprint of SnapOtter. --- # Architecture {#architecture} SnapOtter is a monorepo managed with pnpm workspaces and Turborepo. It deploys as a 3-container Docker Compose stack: the SnapOtter app image, PostgreSQL 17, and Redis 8. ## Project structure {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Packages {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} The core image processing library built on [Sharp](https://sharp.pixelplumbing.com/). It handles all non-AI operations: resize, crop, rotate, flip, convert, compress, strip metadata, and color adjustments (brightness, contrast, saturation, grayscale, sepia, invert, color channels). This package has no network dependencies and runs entirely in-process. ### `@snapotter/ai` {#snapotter-ai} A bridge layer that calls native and Python ML runtimes. Most Python tools use a persistent dispatcher that pre-imports heavy libraries (PIL, NumPy, MediaPipe, rembg) so subsequent calls skip the import overhead. OCR is isolated from that mutable shared environment: `fast` invokes native Tesseract, while `balanced` and `best` use a dedicated persistent JSONL dispatcher pinned to the active immutable RapidOCR/ONNX generation. Each request holds a generation lease. Activation first runs a smoke test on a candidate, then atomically switches to its dispatcher. The prior dispatcher drains before its generation is garbage-collected. **Models are not pre-loaded.** Each tool script loads its model weights from disk at request time and discards them when the request finishes. See [Resource footprint](#resource-footprint) for the full memory profile. Supported operations: background removal (rembg/BiRefNet), upscaling (RealESRGAN), face blur (MediaPipe), face enhancement (GFPGAN/CodeFormer), object erasing (LaMa ONNX), OCR (Tesseract and RapidOCR with PP-OCR ONNX models), colorization (DDColor), noise removal, red eye removal, photo restoration, passport photo generation, transparency fixing (BiRefNet HR-matting), and content-aware resize (Go caire binary). Python scripts live in `packages/ai/python/`. Large optional model packs are installed on demand into the persistent `/data/ai` volume. Accurate OCR uses signed, platform-specific artifacts; the built-in Tesseract tier requires no model-pack download. ### `@snapotter/shared` {#snapotter-shared} Shared TypeScript types, constants (like `APP_VERSION` and tool definitions), and i18n translation strings used by both the frontend and backend. ## Applications {#applications} ### API (`apps/api`) {#api-apps-api} A Fastify v5 server exposing 243 tool routes across five modalities (image, video, audio, PDF, file) that handles: * File uploads, temporary workspace management, and persistent file storage * User file library (`user_files` table): a saved edit is stored as an independent new file by default, or as a parent-linked version when you overwrite the original. It records which tools were applied (`toolChain`) and gets an auto-generated thumbnail for the Files page * Tool execution (routes each tool request to the image engine or AI bridge) * Pipeline orchestration (chaining multiple tools sequentially) * Batch processing with concurrency control via BullMQ job queues (pools: image, media, ai, docs, system) * User authentication, RBAC (admin/user roles with a full permission set), API key management, and rate limiting * Teams management - admin-only CRUD; users are assigned to a team via the `team` field on their profile * Runtime settings - a key-value store in the `settings` table that controls `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit`, and other operational knobs without redeploying * Custom branding and runtime preferences through database-backed settings * Scalar/OpenAPI documentation at `/api/docs` * Serving the built frontend as a SPA in production Key dependencies: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod for validation. The server handles graceful shutdown on SIGTERM/SIGINT: it drains HTTP connections, stops BullMQ workers, shuts down the Python dispatcher, and closes the database connection. ### Web (`apps/web`) {#web-apps-web} A React 19 single-page app built with Vite. Uses Zustand for state management, Tailwind CSS v4 for styling, and Lucide for icons. Communicates with the API over REST and SSE (for progress tracking). Pages include a tool workspace, a Files page for managing persistent uploads and results, an automation/pipeline builder, and an admin settings panel. The built frontend gets served by the Fastify backend in production, so there is no separate web server in the Docker container. ### Docs (`apps/docs`) {#docs-apps-docs} This VitePress site. Deployed to Cloudflare Pages automatically on push to `main`. ## How a request flows {#how-a-request-flows} 1. The user picks a tool in the web UI and uploads a file. 2. The frontend sends a multipart POST to `/api/v1/tools/:section/:toolId` with the file and settings. 3. The API route validates the input with Zod, then dispatches processing. 4. For standard tools, the job is enqueued to the appropriate BullMQ pool (image, media, or docs based on modality). The in-process BullMQ worker auto-orients the image based on EXIF metadata, runs the tool's process function, and returns the result. 5. For most AI tools, the TypeScript bridge sends a request to the persistent Python dispatcher. Fast OCR instead invokes Tesseract, and accurate OCR starts the pinned executable from the active immutable OCR generation. The requested OCR tier is fixed at ingress and is never silently changed during execution. 6. Job progress is persisted to the `jobs` table in PostgreSQL so state survives container restarts. Real-time updates are delivered via SSE at `/api/v1/jobs/:jobId/progress`. 7. The API returns a `jobId` and `downloadUrl`. The user downloads the processed file from `/api/v1/download/:jobId/:filename`. For pipelines, the API feeds the output of each step as input to the next, running them sequentially. For batch processing, the API uses BullMQ flows with per-step child jobs and returns a ZIP file with all processed files. ## Resource footprint {#resource-footprint} SnapOtter is designed for low idle memory use. Nothing is preloaded or kept warm at startup. ### At idle {#at-idle} The Node.js/Fastify process, PostgreSQL, and Redis are running. Typical idle RAM is **~200-300 MB** across all three containers (Node.js process, Postgres, and Redis). No Python process, no model weights in memory. ### What starts, and when {#what-starts-and-when} | Component | Starts when | Memory while active | |-----------|-------------|---------------------| | Fastify server + Postgres + Redis | Container start | ~200-300 MB total | | BullMQ workers | Container start (in-process) | One worker per pool (image, media, ai, docs, system) | | Python dispatcher | First AI tool request | Python interpreter + pre-imported libraries (PIL, NumPy, MediaPipe, rembg) - no model weights | | AI model weights | During the specific tool's request | Loaded from disk, freed when the request finishes | ### Model loading {#model-loading} All model weight files (totalling several GB) sit on disk in `/opt/models/` at all times. Each AI tool script loads only its own model(s) into memory for the duration of a request, then releases them. Some scripts explicitly call `del model` and `torch.cuda.empty_cache()` after inference to ensure memory is returned immediately. There is no model cache between requests. Running the same AI tool back-to-back reloads the model each time. This keeps idle memory near zero at the cost of a model-load delay on every AI request. ### First AI request cold start {#first-ai-request-cold-start} The Python dispatcher is not running when the container starts. The first AI request triggers two things in parallel: the dispatcher starts warming up in the background, and the request itself falls back to a one-off Python subprocess spawn. Once the dispatcher signals ready, all subsequent AI requests use it directly and skip the subprocess spawn cost. --- --- url: https://docs.snapotter.com/guide/configuration.md description: >- All SnapOtter environment variables with defaults. Configure auth, storage, AI models, analytics, and more. --- # Configuration {#configuration} All configuration is done through environment variables. Every variable has a sensible default, so SnapOtter works out of the box without setting any of them. ## Environment variables {#environment-variables} ### Server {#server} | Variable | Default | Description | |---|---|---| | `PORT` | `1349` | Port the server listens on. | | `RATE_LIMIT_PER_MIN` | `1000` | Maximum requests per minute per IP. Set to 0 to disable rate limiting. | | `CORS_ORIGIN` | (empty) | Comma-separated allowed origins for CORS, or empty for same-origin only. | | `LOG_LEVEL` | `info` | Log verbosity. One of: `fatal`, `error`, `warn`, `info`, `debug`, `trace`. | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Which peers may set the client IP through `X-Forwarded-For`. The default believes only a private-network peer, so a reverse proxy on a Docker network or a LAN is trusted and a public client's forged header is not. Set `true` only when a proxy you control sits in front on a public address. | ### Authentication {#authentication} The two booleans below accept only `true` and `false`. Anything else, `1` or `yes` or `on`, fails validation and the server exits before it starts listening. | Variable | Default | Description | |---|---|---| | `AUTH_ENABLED` | `true` | Require a login. Set to `false` to run with no accounts at all, which grants every request admin rights, so keep that to a trusted network. | | `DEFAULT_USERNAME` | `admin` | Username for the initial admin account. Only used on first run. | | `DEFAULT_PASSWORD` | `admin` | Password for the initial admin account. Change this after first login. | | `MAX_USERS` | `0` (unlimited) | Maximum number of registered user accounts. Set to 0 for unlimited. | | `SESSION_DURATION_HOURS` | `168` | Login session lifetime in hours (default is 7 days). | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Set to `true` to skip the forced password-change prompt on first login. | ### Storage {#storage} | Variable | Default | Description | |---|---|---| | `STORAGE_MODE` | `local` | `local` or `s3`. S3 and MinIO need a license with the s3\_storage feature plus the `S3_*` variables below. | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | PostgreSQL connection string. The Compose stack points this at its `postgres` service; leave it unset (together with `REDIS_URL`) to get embedded mode. | | `REDIS_URL` | `redis://localhost:6379` | Redis connection string (used for BullMQ job queues). Compose points this at its `redis` service. | | `WORKSPACE_PATH` | `./tmp/workspace` | Directory for temporary files during processing. Cleaned up automatically. The image sets `/tmp/workspace`. | | `FILES_STORAGE_PATH` | `./data/files` | Directory for persistent user files (uploaded images, saved results). The image sets `/data/files`. | ### S3 object storage {#s3-object-storage} Only read when `STORAGE_MODE=s3`. Miss any of the three required ones and startup fails with the name of the variable you left out. | Variable | Default | Description | |---|---|---| | `S3_BUCKET` | (empty) | Bucket that holds uploads and outputs. Required. | | `S3_ACCESS_KEY_ID` | (empty) | Access key. Required. In the container you can mount it instead, via `S3_ACCESS_KEY_ID_FILE`. | | `S3_SECRET_ACCESS_KEY` | (empty) | Secret key. Required. Same file convention: `S3_SECRET_ACCESS_KEY_FILE`. | | `S3_REGION` | `us-east-1` | Bucket region. | | `S3_ENDPOINT` | (empty) | Custom endpoint for MinIO, R2, Backblaze, and other S3-compatible stores. Empty means AWS. | | `S3_FORCE_PATH_STYLE` | `false` | Set to `true` for MinIO and anything else that wants `endpoint/bucket/key` instead of virtual-host addressing. | | `S3_PREFIX` | (empty) | Key prefix, so one bucket can hold several instances. | ### Encryption at rest {#encryption-at-rest} | Variable | Default | Description | |---|---|---| | `DATA_ENCRYPTION_KEY` | (empty) | 64 hex characters (32 bytes). Encrypts sensitive settings stored in the database. Anything that is not 64 hex characters is rejected at startup. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (empty) | The key you are rotating away from, same format. Set both during a rotation so existing rows still decrypt, then drop this one. | ### Embedded mode {#embedded-mode} Run the image with no `DATABASE_URL` and no `REDIS_URL` and it starts its own PostgreSQL 17 and Redis inside the container, bound to loopback, with all data on the `/data` volume. This restores the single-command `docker run` experience for quick start, homelab, and upgrades from 1.x. It is a convenience path, not a production deployment: for production, run the 3-container Compose stack with separate PostgreSQL and Redis. Embedded mode requires running the container as root and is incompatible with arbitrary-UID runtimes (OpenShift, Kubernetes `runAsNonRoot`); use Compose there. | Variable | Default | Description | |---|---|---| | `EMBEDDED` | `auto` | Auto-enabled when both `DATABASE_URL` and `REDIS_URL` are unset. Set to `0` to disable it (the app then fails fast if no external `DATABASE_URL`/`REDIS_URL` is set, rather than silently starting an in-container database). | | `REDIS_MAXMEMORY` | `512mb` | Memory cap for the embedded Redis (embedded mode only). Lower it on memory-constrained hosts such as a Raspberry Pi. | Upgrading from 1.x: put your old `snapotter.db` at `/data/snapotter.db` in the volume and embedded mode imports it into the embedded PostgreSQL on first boot. The import runs once; later boots skip it. Telemetry note: embedded mode inherits the image's analytics default like any other configuration. The published image ships with analytics on; build with `--build-arg SNAPOTTER_ANALYTICS=off`, or use the in-app admin opt-out, to disable it. ### Processing limits {#processing-limits} | Variable | Default | Description | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (unlimited) | Maximum file size per upload in megabytes. Set to 0 for unlimited. The published image ships `0`; a source build starts at 100. | | `MAX_BATCH_SIZE` | `0` (unlimited) | Maximum number of files in a single batch request. Set to 0 for unlimited. The published image ships `0`; a source build starts at 100. | | `CONCURRENT_JOBS` | `0` (auto) | Number of batch jobs that run in parallel. Set to 0 to auto-detect based on available CPU cores. | | `MAX_MEGAPIXELS` | `0` (unlimited) | Maximum image resolution allowed in megapixels. Set to 0 for unlimited. | | `MAX_WORKER_THREADS` | `0` (auto) | Maximum worker threads for image processing. Set to 0 to auto-detect based on available CPU cores. | | `PROCESSING_TIMEOUT_S` | `0` (no limit) | Maximum processing time per request in seconds. Set to 0 for no timeout. | | `MAX_PIPELINE_STEPS` | `20` | Maximum number of steps in a pipeline. Set to 0 for no limit. | | `MAX_CANVAS_PIXELS` | `0` (no limit) | Maximum canvas size in pixels for output images. Set to 0 for no limit. | | `MAX_SVG_SIZE_MB` | `50` | Largest SVG accepted before sanitizing, in megabytes. `0` behaves differently here than in the rows around it. It removes the pre-parse size cap entirely rather than raising it, so leave this one set. | | `MAX_PDF_PAGES` | `0` (unlimited) | Maximum number of PDF pages for PDF-to-image conversion. Set to 0 for unlimited. | ### Cleanup {#cleanup} | Variable | Default | Description | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | How long unsaved processing results (raw uploads and tool outputs) are kept before automatic deletion. Files you explicitly save to the Files library are not affected and persist until you delete them. | | `CLEANUP_INTERVAL_MINUTES` | `60` | How often the cleanup job runs. | ### Appearance {#appearance} | Variable | Default | Description | |---|---|---| | `DEFAULT_THEME` | `light` | Default theme for new sessions. `light`, `dark`, or `system`. | | `DEFAULT_LOCALE` | `en` | Default interface language. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Default tool layout. `sidebar` or `fullscreen`. | ### Docker permissions {#docker-permissions} | Variable | Default | Description | |---|---|---| | `PUID` | `999` | Run the container process as this UID. Set to match your host user for bind mounts (`id -u`). | | `PGID` | `999` | Run the container process as this GID. Set to match your host group for bind mounts (`id -g`). | ## Docker example {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volumes {#volumes} The Docker Compose stack uses four volumes: * `/data` (app) - AI models, Python venv, and user files. Mount this to keep uploaded files and installed AI bundles across restarts. * `/tmp/workspace` (app) - Temporary storage for files being processed. This can be ephemeral, but mounting it avoids filling up the container's writable layer. * `SnapOtter-pgdata` (postgres) - PostgreSQL data directory. This holds all relational data (users, settings, pipelines, jobs, audit log). Back up via `pg_dump` or volume snapshot. * `SnapOtter-redisdata` (redis) - Redis append-only file for durable job queues. --- --- url: https://docs.snapotter.com/guide/oidc.md description: >- Set up Single Sign-On with OpenID Connect. Step-by-step guides for Keycloak, Authentik, Google, and other OIDC providers. --- # OIDC / Single Sign-On {#oidc-single-sign-on} SnapOtter supports OpenID Connect (OIDC) for single sign-on. Users can log in with an external identity provider such as Keycloak, Authentik, or Google instead of (or alongside) local username/password authentication. ::: tip See also [SAML SSO](/guide/saml) | [SCIM Provisioning](/guide/scim) | [Users, Roles & Permissions](/guide/users-roles) ::: ## Quick start {#quick-start} Add these environment variables to your `docker-compose.yml`: ```yaml services: SnapOtter: image: snapotter/snapotter:latest environment: EXTERNAL_URL: "https://photos.example.com" OIDC_ENABLED: "true" OIDC_ISSUER_URL: "https://auth.example.com/realms/myrealm" OIDC_CLIENT_ID: "snapotter" OIDC_CLIENT_SECRET: "your-secret-here" ``` The redirect URI for your provider is always: ``` ${EXTERNAL_URL}/api/auth/oidc/callback ``` For example, if `EXTERNAL_URL` is `https://photos.example.com`, configure your provider's redirect URI as `https://photos.example.com/api/auth/oidc/callback`. ## Configuration reference {#configuration-reference} | Variable | Default | Description | |---|---|---| | `OIDC_ENABLED` | `false` | Enable OIDC login. A "Sign in with SSO" button appears on the login page. | | `OIDC_ISSUER_URL` | | Provider's issuer URL. Must support OIDC Discovery (`/.well-known/openid-configuration`). | | `OIDC_CLIENT_ID` | | OAuth client ID registered with your provider. | | `OIDC_CLIENT_SECRET` | | OAuth client secret. | | `OIDC_SCOPES` | `openid profile email` | Space-separated list of scopes to request. | | `OIDC_AUTO_CREATE_USERS` | `true` | Automatically create a local user account on first OIDC login. | | `OIDC_DEFAULT_ROLE` | `user` | Role assigned to auto-created OIDC users. One of `admin`, `editor`, or `user`. | | `OIDC_AUTO_LINK_USERS` | `false` | Link an OIDC identity to an existing local user if the email address matches. | | `OIDC_PROVIDER_NAME` | | Display name shown on the login button (e.g. "Keycloak", "Google"). If empty, the button says "SSO". | | `OIDC_CLOCK_TOLERANCE` | `30` | Clock skew tolerance in seconds for token validation. | | `OIDC_USERNAME_CLAIM` | `preferred_username` | ID token claim used as the username for new accounts. | | `EXTERNAL_URL` | | The public URL where SnapOtter is reachable. Required for OIDC to build the correct redirect URI. | | `COOKIE_SECRET` | auto-generated | Secret for signing session cookies. Set this explicitly when running multiple replicas. | ## Provider guides {#provider-guides} ### Keycloak {#keycloak} 1. Create a new realm (or use an existing one). 2. Go to **Clients** and create a new client: * **Client ID**: `snapotter` * **Client authentication**: On (confidential) * **Authentication flow**: Standard flow (Authorization Code) 3. Under the client's **Settings** tab, set **Valid redirect URIs** to your callback URL (e.g. `https://photos.example.com/api/auth/oidc/callback`). 4. Copy the **Client secret** from the **Credentials** tab. 5. Set `OIDC_ISSUER_URL` to `https://keycloak.example.com/realms/your-realm`. ### Authentik {#authentik} 1. In the admin interface, go to **Applications > Providers** and create a new **OAuth2/OpenID Provider**. * **Client type**: Confidential * **Redirect URIs**: Your callback URL * **Signing key**: Select an existing key or create one 2. Create an **Application** and link it to the provider. 3. Copy the **Client ID** and **Client Secret** from the provider settings. 4. Set `OIDC_ISSUER_URL` to `https://authentik.example.com/application/o/snapotter/` (the trailing slash matters). ### Google {#google} 1. Go to the [Google Cloud Console](https://console.cloud.google.com/). 2. Create a project (or select an existing one). 3. Navigate to **APIs & Services > OAuth consent screen** and configure it. 4. Go to **APIs & Services > Credentials** and create an **OAuth 2.0 Client ID**: * **Application type**: Web application * **Authorized redirect URIs**: Your callback URL 5. Copy the **Client ID** and **Client secret**. 6. Set `OIDC_ISSUER_URL` to `https://accounts.google.com`. 7. Set `OIDC_USERNAME_CLAIM` to `email` (Google does not provide `preferred_username`). ## User provisioning {#user-provisioning} ### Auto-create {#auto-create} When `OIDC_AUTO_CREATE_USERS` is `true` (the default), a local user account is created the first time someone logs in via OIDC. The username is taken from the claim specified by `OIDC_USERNAME_CLAIM`, and the role is set to `OIDC_DEFAULT_ROLE`. If a username collision occurs, a numeric suffix is appended (e.g. `jane` becomes `jane_2`). ### Auto-link {#auto-link} When `OIDC_AUTO_LINK_USERS` is `true`, SnapOtter links an OIDC identity to an existing local account if the email addresses match. This is useful when you have pre-created user accounts and want them to start using SSO without losing their data. ::: warning Only enable auto-link if you trust your OIDC provider to verify email addresses. An unverified email could allow someone to take over another user's account. ::: ### Disabling local login {#disabling-local-login} OIDC does not disable local username/password login. Both methods remain available. Admins can still log in with local credentials if the OIDC provider is unreachable. ## Self-signed certificates {#self-signed-certificates} If your OIDC provider uses a self-signed or private CA certificate, mount the CA bundle into the container and point `NODE_EXTRA_CA_CERTS` to it: ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - ./my-ca.pem:/etc/ssl/certs/custom-ca.pem:ro environment: NODE_EXTRA_CA_CERTS: /etc/ssl/certs/custom-ca.pem OIDC_ENABLED: "true" OIDC_ISSUER_URL: "https://auth.internal.example.com/realms/myrealm" OIDC_CLIENT_ID: "snapotter" OIDC_CLIENT_SECRET: "your-secret-here" ``` ::: danger Do not set `NODE_TLS_REJECT_UNAUTHORIZED=0`. This disables all TLS verification and is a security risk. ::: ## Troubleshooting {#troubleshooting} ### Redirect URI mismatch {#redirect-uri-mismatch} The most common error. Check for these differences between what your provider expects and what SnapOtter sends: * `http` vs `https` - the scheme must match exactly * Trailing slash - some providers are strict about this * Port number - include the port if it is non-standard * Path - must be `/api/auth/oidc/callback` Double-check `EXTERNAL_URL`. It must match the URL users type in their browser. ### UNABLE\_TO\_VERIFY\_LEAF\_SIGNATURE {#unable-to-verify-leaf-signature} The OIDC provider is using a certificate that Node.js does not trust. See [Self-signed certificates](#self-signed-certificates) above. ### Clock skew errors {#clock-skew-errors} If your server clock and the OIDC provider clock are out of sync, token validation may fail. Increase `OIDC_CLOCK_TOLERANCE` (default is 30 seconds). A better fix is to run NTP on both machines. ### "OIDC provider unreachable" {#oidc-provider-unreachable} SnapOtter fetches the provider's discovery document at startup and during login. Check: * DNS resolution from inside the Docker container (`docker exec snapotter nslookup auth.example.com`) * Firewall rules between the container and the provider * The `OIDC_ISSUER_URL` value - it must be reachable from the server, not just from your browser ### Missing claims {#missing-claims} If usernames or emails are empty after login, your provider may not be returning the expected claims. Verify: * The scopes configured in `OIDC_SCOPES` include `profile` and `email` * The provider is configured to include the claim specified in `OIDC_USERNAME_CLAIM` in the ID token * Some providers require explicit mapper/scope configuration to release claims --- --- url: https://docs.snapotter.com/guide/saml.md description: >- Set up SAML 2.0 Single Sign-On for SnapOtter. Step-by-step guides for Okta, Azure AD / Entra ID, Google Workspace, and other SAML identity providers. --- # SAML SSO {#saml-sso} SnapOtter supports SAML 2.0 for single sign-on. Users can log in via an external identity provider (Okta, Azure AD / Entra ID, Google Workspace, or any standard SAML 2.0 IdP) instead of local username/password authentication. ::: tip Enterprise feature SAML SSO requires a **team** or **enterprise** license with the `saml_sso` feature. If `SAML_ENABLED=true` is set without a valid license, the SAML routes are silently skipped and a warning is logged. ::: ## Prerequisites {#prerequisites} * A running SnapOtter instance reachable at a public URL * `EXTERNAL_URL` set to that public URL (e.g. `https://photos.example.com`) * A team or enterprise license key with the `saml_sso` feature * Admin access to your SAML identity provider ## Quick start {#quick-start} Add these environment variables to your `docker-compose.yml`: ```yaml services: snapotter: image: snapotter/snapotter:latest environment: EXTERNAL_URL: "https://photos.example.com" SNAPOTTER_LICENSE_KEY: "your-license-key" SAML_ENABLED: "true" SAML_IDP_SSO_URL: "https://idp.example.com/sso/saml" SAML_IDP_CERTIFICATE: | MIICpDCCAYwCCQDU+pQ4pHgSpDANBgkqhkiG9w0BAQsFADAUMRIw ...your IdP's signing certificate in PEM format... EAYHKoZIzj0CAQYFK4EEACIDYgAE ``` Restart the container. A "Sign in with SAML" button (or the label set by `SAML_PROVIDER_NAME`) appears on the login page. ## Configuration reference {#configuration-reference} | Variable | Default | Description | |---|---|---| | `SAML_ENABLED` | `false` | Enable SAML login. | | `SAML_IDP_SSO_URL` | | IdP's SSO endpoint URL. **Required** when SAML is enabled. | | `SAML_IDP_CERTIFICATE` | | IdP's X.509 signing certificate in PEM format (the certificate text itself, not a file path). **Required** when SAML is enabled. | | `EXTERNAL_URL` | | The public URL where SnapOtter is reachable. **Required** when SAML is enabled. | | `SAML_ENTITY_ID` | `${EXTERNAL_URL}/api/auth/saml/metadata` | SP Entity ID / Audience URI sent to the IdP. | | `SAML_CALLBACK_URL` | `${EXTERNAL_URL}/api/auth/saml/callback` | Assertion Consumer Service (ACS) URL. | | `SAML_AUTO_CREATE_USERS` | `true` | Automatically create a local user account on first SAML login. | | `SAML_AUTO_LINK_USERS` | `false` | Link a SAML identity to an existing local user if the email address matches. | | `SAML_DEFAULT_ROLE` | `user` | Role assigned to auto-created SAML users. One of `admin`, `editor`, or `user`. | | `SAML_PROVIDER_NAME` | | Display label for the SAML login button on the frontend (e.g. "Okta", "Azure AD"). If empty, the button says "SAML". | | `SAML_USERNAME_ATTRIBUTE` | | SAML assertion attribute used as the username. If empty, falls back to the email local-part, then NameID. | | `SAML_EMAIL_ATTRIBUTE` | `email` | SAML assertion attribute used as the user's email address. | The server refuses to start if `SAML_ENABLED=true` and any of the three required variables (`SAML_IDP_SSO_URL`, `SAML_IDP_CERTIFICATE`, `EXTERNAL_URL`) are missing. ::: details Security notes Both `wantAuthnResponseSigned` and `wantAssertionsSigned` are hardcoded to `true`. SnapOtter rejects unsigned or improperly signed SAML responses. Assertions from a trusted IdP are treated as email-verified. Only SP-initiated login is supported. SnapOtter does not support IdP-initiated (unsolicited) login or Single Logout (SLO). Logging out of SnapOtter does not log the user out of the IdP. ::: ## SP metadata and URLs {#sp-metadata-and-urls} Your IdP needs three values from SnapOtter: | Field | Value | |---|---| | **ACS URL** (Assertion Consumer Service) | `${EXTERNAL_URL}/api/auth/saml/callback` | | **Entity ID** / **Audience URI** | `${EXTERNAL_URL}/api/auth/saml/metadata` | | **SP Metadata** (XML) | `GET ${EXTERNAL_URL}/api/auth/saml/metadata` | For example, if `EXTERNAL_URL` is `https://photos.example.com`: * ACS URL: `https://photos.example.com/api/auth/saml/callback` * Entity ID: `https://photos.example.com/api/auth/saml/metadata` * Metadata endpoint: `https://photos.example.com/api/auth/saml/metadata` (returns XML) Some IdPs can import the SP metadata URL directly, which auto-fills the ACS URL and Entity ID. ## Provider setup {#provider-setup} ### Okta {#okta} 1. In the Okta admin console, go to **Applications > Create App Integration**. 2. Select **SAML 2.0** and click **Next**. 3. Set a name (e.g. "SnapOtter") and click **Next**. 4. Configure the SAML settings: * **Single sign-on URL**: Your ACS URL (e.g. `https://photos.example.com/api/auth/saml/callback`) * **Audience URI (SP Entity ID)**: Your Entity ID (e.g. `https://photos.example.com/api/auth/saml/metadata`) * **Name ID format**: EmailAddress * **Application username**: Email 5. Under **Attribute Statements**, add `email` mapped to `user.email`. 6. Click **Next**, then **Finish**. 7. Go to the **Sign On** tab, click **View SAML setup instructions**, and copy: * **Identity Provider Single Sign-On URL** into `SAML_IDP_SSO_URL` * **X.509 Certificate** into `SAML_IDP_CERTIFICATE` ### Azure AD / Entra ID {#azure-ad-entra-id} 1. In the Azure portal, go to **Microsoft Entra ID > Enterprise applications > New application**. 2. Click **Create your own application**, name it "SnapOtter", and select **Integrate any other application you don't find in the gallery**. 3. Go to **Single sign-on > SAML** and click **Edit** on the **Basic SAML Configuration** section: * **Identifier (Entity ID)**: Your Entity ID (e.g. `https://photos.example.com/api/auth/saml/metadata`) * **Reply URL (ACS URL)**: Your ACS URL (e.g. `https://photos.example.com/api/auth/saml/callback`) 4. Under **SAML Certificates**, download the **Certificate (Base64)**. 5. Under **Set up SnapOtter**, copy the **Login URL**. 6. Set `SAML_IDP_SSO_URL` to the Login URL and `SAML_IDP_CERTIFICATE` to the downloaded certificate contents. 7. Assign users or groups to the application under **Users and groups**. ### Google Workspace {#google-workspace} 1. In the Google Admin console, go to **Apps > Web and mobile apps > Add app > Add custom SAML app**. 2. Name the app "SnapOtter" and click **Continue**. 3. On the **Google Identity Provider details** page, copy the **SSO URL** and download the **Certificate**. Click **Continue**. 4. Configure the Service Provider details: * **ACS URL**: Your ACS URL (e.g. `https://photos.example.com/api/auth/saml/callback`) * **Entity ID**: Your Entity ID (e.g. `https://photos.example.com/api/auth/saml/metadata`) * **Name ID format**: EMAIL * **Name ID**: Basic Information > Primary email 5. Click **Continue**, then **Finish**. 6. Turn the app **ON** for your organizational units. 7. Set `SAML_IDP_SSO_URL` to the SSO URL from step 3 and `SAML_IDP_CERTIFICATE` to the downloaded certificate contents. ### Generic SAML 2.0 IdP {#generic-saml-2-0-idp} For any SAML 2.0 compliant identity provider: 1. Create a new SAML application/service provider in your IdP. 2. Set the **ACS URL** to `${EXTERNAL_URL}/api/auth/saml/callback`. 3. Set the **Entity ID** / **Audience** to `${EXTERNAL_URL}/api/auth/saml/metadata`. 4. Configure the IdP to send the user's email in an attribute named `email` (or set `SAML_EMAIL_ATTRIBUTE` to match your IdP's attribute name). 5. Copy the **IdP SSO URL** and **signing certificate** into `SAML_IDP_SSO_URL` and `SAML_IDP_CERTIFICATE`. ## User provisioning {#user-provisioning} ### Auto-create {#auto-create} When `SAML_AUTO_CREATE_USERS` is `true` (the default), a local user account is created the first time someone logs in via SAML. The role is set to `SAML_DEFAULT_ROLE`. The username is derived in this order: 1. The value of the assertion attribute specified by `SAML_USERNAME_ATTRIBUTE` (if set and present) 2. The local-part of the email address (everything before `@`) 3. The SAML NameID If a username collision occurs, a numeric suffix is appended (e.g. `jane` becomes `jane_2`). ### Auto-link {#auto-link} When `SAML_AUTO_LINK_USERS` is `true`, SnapOtter links a SAML identity to an existing local account if the email addresses match. This is useful when you have pre-created user accounts and want them to start using SSO without losing their data. ::: warning Only enable auto-link if you trust your SAML IdP to verify email addresses. An unverified email from a misconfigured IdP could allow someone to take over another user's account. ::: ### Attribute mapping {#attribute-mapping} | SnapOtter field | Source | Configuration | |---|---|---| | Email | Assertion attribute | `SAML_EMAIL_ATTRIBUTE` (default: `email`) | | Username | Assertion attribute, email, or NameID | `SAML_USERNAME_ATTRIBUTE` (see derivation order above) | | External ID | NameID | Always the SAML NameID, not configurable | ## SSO enforcement {#sso-enforcement} If you want to require all users to log in via SAML (or OIDC) and block local password login, enable SSO enforcement: 1. Ensure the `sso_enforcement` enterprise feature is licensed (available on team and enterprise plans). 2. In **Admin Settings > Security**, toggle **SSO Enforcement** on. 3. Set a **break-glass username**: this is the one local account that can still log in with a password, for emergency access if the IdP is unreachable. When SSO enforcement is active, any local login attempt (except for the break-glass user) returns a 403 error with the message "Local password login is disabled. Please use SSO." ::: tip Always configure a break-glass username before enabling SSO enforcement. Without it, you could be locked out of SnapOtter if your IdP goes down. ::: ## Using SAML alongside OIDC {#using-saml-alongside-oidc} SAML and OIDC can be enabled simultaneously. When both are active, the login page shows separate buttons for each provider (labeled by `SAML_PROVIDER_NAME` and `OIDC_PROVIDER_NAME`). Users can log in with either method. Both providers share the same auto-create, auto-link, and SSO enforcement settings independently: each has its own `*_AUTO_CREATE_USERS`, `*_AUTO_LINK_USERS`, and `*_DEFAULT_ROLE` variables. ## Troubleshooting {#troubleshooting} ### Assertion validation failed {#assertion-validation-failed} The SAML response signature or assertion signature could not be verified. Check: * The certificate in `SAML_IDP_CERTIFICATE` matches the current signing certificate in your IdP (certificates rotate, so check for expiry) * The certificate is in PEM format (begins with `-----BEGIN CERTIFICATE-----`) * The certificate is the full text, not a file path * The ACS URL and Entity ID configured in your IdP match SnapOtter's values exactly (scheme, host, port, path) ### Missing attributes {#missing-attributes} If usernames or emails are empty after login, your IdP may not be sending the expected attributes. Check: * Your IdP is configured to release an `email` attribute (or whatever `SAML_EMAIL_ATTRIBUTE` is set to) * If using `SAML_USERNAME_ATTRIBUTE`, verify that attribute is included in the assertion * Some IdPs require explicit attribute mapping configuration before they release claims ### Clock skew {#clock-skew} SAML assertions include timestamp conditions (`NotBefore`, `NotOnOrAfter`). If your server clock and the IdP clock are out of sync, assertion validation fails. Run NTP on both machines to keep clocks aligned. ### "SAML is enabled via env but saml\_sso enterprise feature is not licensed" {#saml-is-enabled-via-env-but-saml-sso-enterprise-feature-is-not-licensed} This warning appears in the server logs when `SAML_ENABLED=true` but the license does not include the `saml_sso` feature. Verify your license key and plan. The `saml_sso` feature is available on team and enterprise plans. ### Login redirects back with error {#login-redirects-back-with-error} If clicking the SAML login button redirects back to the login page with an error, check the server logs for details. Common causes: * The IdP SSO URL is unreachable from the server * The IdP rejected the authentication request (check the IdP's audit logs) * The IdP returned an unsigned response (SnapOtter requires both the response and assertion to be signed) --- --- url: https://docs.snapotter.com/guide/scim.md description: >- Set up SCIM 2.0 provisioning to sync users and groups from your identity provider to SnapOtter. Covers Okta, Azure AD / Entra ID, and custom integrations. --- # SCIM Provisioning {#scim-provisioning} SnapOtter implements SCIM 2.0 (System for Cross-domain Identity Management) for automated user and group provisioning. Your identity provider can create, update, deactivate, and reactivate user accounts and sync group memberships automatically. ::: tip Enterprise feature SCIM provisioning requires an **enterprise** license with the `scim` feature. It is not available on the team plan. Without the feature, all SCIM endpoints (except discovery) return 403. ::: ## Prerequisites {#prerequisites} * A running SnapOtter instance reachable at a public URL * An enterprise license key with the `scim` feature * A built-in SnapOtter `admin` account with its full effective permission set. A delegated custom role or an admin API key missing any admin permission cannot generate or revoke the global SCIM token. * Admin access to your identity provider's provisioning settings ## Quick start {#quick-start} 1. Generate a SCIM bearer token: ```bash curl -X POST https://photos.example.com/api/v1/enterprise/scim/token \ -H "Cookie: snapotter-session=YOUR_SESSION" \ -H "Content-Type: application/json" ``` The response contains the token. Save it immediately; it cannot be retrieved again. ```json { "token": "so_scim_v2_a1b2c3d4e5f6...", "message": "Save this token - it cannot be retrieved again" } ``` 2. In your identity provider, configure SCIM provisioning with: * **Base URL**: `https://photos.example.com/api/v1/scim/v2` * **Authentication**: Bearer token (paste the token from step 1) ## Authentication {#authentication} SCIM endpoints use a dedicated Bearer token, separate from user sessions and API keys. ### Generating a token {#generating-a-token} `POST /api/v1/enterprise/scim/token` generates a new SCIM token. Because the token can provision and mutate users across the instance, this endpoint requires the built-in `admin` role with the complete effective admin permission set. Holding `users:manage` in a custom role is not sufficient. The token is returned in plaintext exactly once. SnapOtter stores only a scrypt hash. If you lose the token, revoke it and generate a new one. Only one SCIM token is active at a time. Generating a new token replaces the previous one. ::: warning Token reissue after upgrade Legacy unversioned SCIM tokens are rejected. After upgrading to a release that issues `so_scim_v2_...` tokens, generate a new token and update your identity provider before resuming provisioning. ::: ### Revoking a token {#revoking-a-token} `DELETE /api/v1/enterprise/scim/token` revokes the current SCIM token. It has the same full built-in admin requirement as token generation. ### Rate limiting {#rate-limiting} SCIM endpoints are rate-limited to 1000 requests per minute per token. Exceeding this limit returns HTTP 429. ## Supported resources {#supported-resources} | SCIM resource | SnapOtter concept | Create | Read | Update | Delete | |---|---|---|---|---|---| | User | User account | Yes | Yes | Yes | Soft delete | | Group | Team | Yes | Yes | Yes | Yes | ::: warning SCIM Groups map to SnapOtter **teams**, not roles. SCIM cannot set a user's role. All users created via SCIM are assigned the `user` role. To change a user's role, use the SnapOtter admin UI. ::: ## User operations {#user-operations} ### Create user {#create-user} `POST /api/v1/scim/v2/Users` Creates a new user account with `authProvider` set to `scim` and the `user` role. The user is assigned to the Default team. If `active` is `false`, the role is set to `disabled` instead. Required attributes: `userName`. Optional: `externalId`, `emails`, `active` (default `true`). ### List and filter users {#list-and-filter-users} `GET /api/v1/scim/v2/Users` Returns a paginated list of users. Supports `startIndex` and `count` query parameters (maximum 200 results per page). Filtering supports `eq` (equals) only, on these attributes: * `userName eq "jane"` * `externalId eq "ext-12345"` Other filter operators and attributes return HTTP 400. ### Get user {#get-user} `GET /api/v1/scim/v2/Users/:id` Returns a single user by their SnapOtter user ID. ### Replace user {#replace-user} `PUT /api/v1/scim/v2/Users/:id` Replaces the user's attributes. Supports `userName`, `externalId`, `emails`, and `active`. Username changes are checked for conflicts (409 if the new username is taken by another user). ### Patch user {#patch-user} `PATCH /api/v1/scim/v2/Users/:id` Partial update using SCIM PatchOp. Supported operations: | Operation | Paths | |---|---| | `replace` | `active`, `userName`, `externalId`, `emails`, `emails[type eq "work"].value`, `name.formatted`, `displayName` | | `add` | Same as `replace` | | `remove` | `externalId`, `emails` | The `name.formatted` and `displayName` paths are accepted for compatibility but have no persistent effect (SnapOtter does not store a separate display name). Valueless `replace` operations (where the value is an object without a `path`) are also supported, with keys `userName`, `externalId`, `emails`, and `active`. ### Deactivate user (soft delete) {#deactivate-user-soft-delete} `DELETE /api/v1/scim/v2/Users/:id` SnapOtter does not hard-delete users via SCIM. Instead, DELETE performs a soft deactivation: 1. The user's role is changed from its current value (e.g. `editor`) to `disabled:editor`, preserving the original role. 2. The user's password is cleared. 3. All active sessions are revoked. 4. All API keys are revoked. The user can no longer log in or use any API keys. Their data (files, history) is retained. ### Reactivate user {#reactivate-user} To reactivate a previously deactivated user, send a `PUT` or `PATCH` request with `active: true`. SnapOtter restores the original role from before deactivation (e.g. `disabled:editor` becomes `editor` again). If the original role cannot be determined, it falls back to `user`. ::: details Example: deactivate and reactivate via PATCH ```json // Deactivate { "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": false } ] } // Reactivate { "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": true } ] } ``` ::: ## Group operations {#group-operations} SCIM Groups map to SnapOtter teams. Creating a group creates a team. Group membership controls which team a user belongs to. ### Create group {#create-group} `POST /api/v1/scim/v2/Groups` Required: `displayName`. Optional: `members` (array of `{ value: userId }`). ### List and filter groups {#list-and-filter-groups} `GET /api/v1/scim/v2/Groups` Filtering supports `displayName eq "..."` only. Paginated with `startIndex` and `count` (maximum 200 results per page). ### Get group {#get-group} `GET /api/v1/scim/v2/Groups/:id` ### Replace group {#replace-group} `PUT /api/v1/scim/v2/Groups/:id` Replaces the group name and full membership list. Existing members not in the new list are moved to the Default team. ### Patch group {#patch-group} `PATCH /api/v1/scim/v2/Groups/:id` Supports these operations: | Operation | Path | Effect | |---|---|---| | `add` | `members` | Adds users to the team | | `remove` | `members[value eq "userId"]` | Moves the user to the Default team | | `replace` | `displayName` | Renames the team | | `replace` | `members` | Replaces all members (removed members move to the Default team) | ### Delete group {#delete-group} `DELETE /api/v1/scim/v2/Groups/:id` Deletes the team. All members of the deleted team are moved to the Default team. Users are not deactivated or deleted. ## IdP setup {#idp-setup} ### Okta {#okta} 1. In the Okta admin console, open your SnapOtter application (or create one). 2. Go to the **Provisioning** tab and click **Configure API Integration**. 3. Check **Enable API Integration** and enter: * **Base URL**: `https://photos.example.com/api/v1/scim/v2` * **API Token**: The SCIM bearer token generated above 4. Click **Test API Credentials**, then **Save**. 5. Under **Provisioning > To App**, enable: * **Create Users** * **Update User Attributes** * **Deactivate Users** 6. Under **Push Groups**, configure which Okta groups to sync as SnapOtter teams. ### Azure AD / Entra ID {#azure-ad-entra-id} 1. In the Azure portal, go to your SnapOtter enterprise application. 2. Go to **Provisioning** and set **Provisioning Mode** to **Automatic**. 3. Under **Admin Credentials**, enter: * **Tenant URL**: `https://photos.example.com/api/v1/scim/v2` * **Secret Token**: The SCIM bearer token generated above 4. Click **Test Connection**, then **Save**. 5. Under **Mappings**, configure the user and group attribute mappings. The defaults typically work, but verify that `userName` maps to `userPrincipalName` or `mail` as desired. 6. Set **Provisioning Status** to **On** and save. Azure provisions users and groups on a fixed sync cycle (typically every 40 minutes). ## Discovery endpoints {#discovery-endpoints} These three endpoints are available without authentication and describe the SCIM server's capabilities: | Endpoint | Description | |---|---| | `GET /api/v1/scim/v2/ServiceProviderConfig` | Server capabilities and supported features | | `GET /api/v1/scim/v2/Schemas` | User and Group schema definitions | | `GET /api/v1/scim/v2/ResourceTypes` | Available resource types (User, Group) | The `ServiceProviderConfig` advertises these capabilities: | Feature | Supported | |---|---| | Patch | Yes | | Bulk | No | | Filter | Yes (max 200 results, `eq` operator only) | | Change password | No | | Sort | No | | ETag | No | ## Limitations {#limitations} * **Filtering**: Only the `eq` operator is supported. Complex filters, `and`/`or` operators, `co` (contains), and `sw` (starts with) are not implemented. * **Bulk operations**: Not supported. * **Sort and ETag**: Not supported. * **Roles**: SCIM cannot assign SnapOtter roles. All provisioned users get the `user` role. * **MAX\_USERS**: The `MAX_USERS` environment variable limit is not enforced on SCIM user creation. If you need to cap user counts, manage assignments in your IdP. * **One token**: Only one SCIM token can be active at a time. If multiple IdPs need SCIM access, they must share the token. * **Groups are teams**: SCIM Groups correspond to teams, not roles or permission groups. ## Troubleshooting {#troubleshooting} ### 403 "SCIM provisioning requires an enterprise license with the scim feature" {#\_403-scim-provisioning-requires-an-enterprise-license-with-the-scim-feature} Your license does not include the `scim` feature, or no license is configured. SCIM requires an enterprise plan license. Verify `SNAPOTTER_LICENSE_KEY` is set and the license includes the `scim` feature. ### 401 "Bearer token required" {#\_401-bearer-token-required} The SCIM request did not include an `Authorization: Bearer ` header. Check your IdP's provisioning configuration. ### 401 "Invalid token" {#\_401-invalid-token} The token is malformed, uses the retired unversioned format, or does not match the stored hash. Generate a current `so_scim_v2_...` token and update the token in your IdP's provisioning settings. ### 401 "SCIM not configured" {#\_401-scim-not-configured} No SCIM token has been generated yet. Use the `POST /api/v1/enterprise/scim/token` endpoint to create one. ### 409 "User already exists" / "userName already taken" {#\_409-user-already-exists-username-already-taken} A user with the same username already exists. This can happen when an IdP retries a failed create. Check for duplicate usernames in the SnapOtter admin panel. ### 429 "SCIM rate limit exceeded" {#\_429-scim-rate-limit-exceeded} The IdP is sending more than 1000 requests per minute. This typically happens during a large initial sync. Most IdPs automatically retry after the rate limit window resets. If the problem persists, check your IdP's provisioning sync interval. ### Users deprovisioned but not removed from the UI {#users-deprovisioned-but-not-removed-from-the-ui} SCIM DELETE is a soft deactivation. Deactivated users still appear in the admin user list with a disabled status. This is by design so their data is preserved. Their role shows as `disabled:`. --- --- url: https://docs.snapotter.com/guide/users-roles.md description: >- Manage users, built-in and custom roles, permissions, API keys, teams, sessions, and the audit log in SnapOtter. --- # Users, Roles & Permissions {#users-roles-permissions} SnapOtter ships three built-in roles, 17 granular permissions, and support for custom roles with optional per-tool access control. This page covers the full authorization model, API key scoping, team management, and audit logging. ::: tip Related pages [OIDC / SSO](/guide/oidc) | [SAML SSO](/guide/saml) | [SCIM Provisioning](/guide/scim) | [Security & Hardening](/guide/security) ::: ## Users {#users} ### Creating users {#creating-users} Admins can create users through the admin panel or the `POST /api/auth/register` endpoint. Each user has a username, role, team assignment, and an optional email address. ### Default admin {#default-admin} On first startup SnapOtter creates a default admin account. The credentials come from environment variables: | Variable | Default | Description | |---|---|---| | `DEFAULT_USERNAME` | `admin` | Username for the initial admin account | | `DEFAULT_PASSWORD` | `admin` | Password for the initial admin account | The default admin is required to change their password on first login. ### Authentication providers {#authentication-providers} Users can authenticate through several methods: * **Local** - username and password stored in the SnapOtter database * **OIDC** - any OpenID Connect provider (see [OIDC / SSO](/guide/oidc)) * **SAML** - SAML 2.0 identity providers (see [SAML SSO](/guide/saml)) * **SCIM** - automated provisioning from an identity provider (see [SCIM Provisioning](/guide/scim)) ### Disabling authentication {#disabling-authentication} Set `AUTH_ENABLED=false` to disable authentication entirely. In this mode a synthetic anonymous user with the `admin` role is used for all requests. No login is required. ::: warning Disabling authentication grants full admin access to anyone who can reach the instance. Only use this in trusted environments. ::: ## Built-in roles {#built-in-roles} SnapOtter includes three built-in roles. They cannot be modified or deleted. ### Admin {#admin} All 17 permissions. Full control over the instance. `tools:use` `files:own` `files:all` `apikeys:own` `apikeys:all` `pipelines:own` `pipelines:all` `settings:read` `settings:write` `users:manage` `teams:manage` `features:manage` `system:health` `audit:read` `compliance:manage` `webhooks:manage` `security:manage` ### Editor {#editor} 7 permissions. Can use all tools and manage all files and pipelines, but cannot access admin functions. `tools:use` `files:own` `files:all` `apikeys:own` `pipelines:own` `pipelines:all` `settings:read` ### User {#user} 5 permissions. Can use tools and manage their own resources. `tools:use` `files:own` `apikeys:own` `pipelines:own` `settings:read` ## Permissions reference {#permissions-reference} | Permission | Description | |---|---| | `tools:use` | Use any processing tool | | `files:own` | View and manage own files | | `files:all` | View and manage all users' files | | `apikeys:own` | Create and manage own API keys | | `apikeys:all` | View all users' API keys | | `pipelines:own` | Create and manage own pipelines | | `pipelines:all` | View and manage all users' pipelines | | `settings:read` | View instance settings | | `settings:write` | Modify instance settings | | `users:manage` | Create and manage user accounts within the actor's authority boundary | | `teams:manage` | Create, update, and delete teams | | `features:manage` | Install and manage AI feature bundles | | `system:health` | Access health and readiness endpoints | | `audit:read` | View the audit log and list roles | | `compliance:manage` | Manage GDPR lifecycle and compliance features; destructive user operations remain authority-bounded | | `webhooks:manage` | Configure outbound webhooks | | `security:manage` | Manage security settings (IP allowlist, SSO enforcement) | ## Custom roles {#custom-roles} Admins with the `security:manage` permission can create custom roles through the admin panel or the roles API. Listing roles requires `audit:read`. ### Creating a custom role {#creating-a-custom-role} ```bash curl -X POST http://localhost:1349/api/v1/roles \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "reviewer", "description": "Can use tools and view all files", "permissions": ["tools:use", "files:own", "files:all", "settings:read"] }' ``` Role names must be 2-30 characters, lowercase alphanumeric with hyphens and underscores. ### Delegated administration boundaries {#delegated-administration-boundaries} All 17 permissions can be delegated through custom roles, but an administrative permission does not make that role equivalent to the built-in `admin` role. User mutations authorized by `users:manage`, destructive operations authorized by `compliance:manage`, and custom-role management authorized by `security:manage` are bounded by the actor's current authority: * Built-in roles follow `admin` > `editor` > `user`; custom roles are below built-in roles. * The target's permissions must be contained by the actor's **effective** permissions. A scoped API key therefore cannot exercise permissions omitted from its scope. * A target role's tool access must be contained by the actor's own tool access. * A disabled account is checked against its original role when that role is recorded as `disabled:`. * Deleting a custom role also requires authority to assign the built-in `user` fallback; disabled members remain disabled as `disabled:user`. Global credentials and configuration are stricter: issuing or revoking the SCIM token and importing instance configuration require the built-in `admin` role with complete effective admin authority. ### Tool-level permissions {#tool-level-permissions} Custom roles can optionally restrict which tools users may access. Two modes are available: | Mode | Behavior | License requirement | |---|---|---| | `category` | Restrict by modality (image, video, audio, document, file) | None (free) | | `tool` | Restrict by individual tool ID | Requires the `per_tool_permissions` enterprise feature | When `tool` mode is set but the enterprise feature is not available, SnapOtter degrades gracefully and allows access to all tools. ```json { "name": "image-only", "permissions": ["tools:use", "files:own"], "toolPermissions": { "mode": "category", "allowed": ["image"] } } ``` ### Deleting a custom role {#deleting-a-custom-role} When a custom role is deleted, all users assigned to it are automatically reassigned to the `user` role. ## Teams {#teams} Teams group users for storage and retention management. A `Default` team is created on first startup. | Field | Type | Description | |---|---|---| | `name` | string | Unique team name (1-50 characters) | | `storageQuota` | number | Per-team storage limit in bytes (works without enterprise) | | `retentionHours` | number | Auto-delete outputs after this many hours (requires `team_retention_overrides`, enterprise) | | `legalHold` | boolean | Prevent automatic deletion of team members' files (requires `legal_hold`, enterprise) | ::: info The `Default` team cannot be deleted. Teams that still have members cannot be deleted. Reassign members first. ::: ## API keys {#api-keys} Users can generate API keys for programmatic access. Each key uses the `si_` prefix and is shown only once at creation time. ### Scoped permissions {#scoped-permissions} API keys can optionally carry a `permissions` array. When set, the effective permissions for a request are the **intersection** of the user's role permissions and the key's scoped permissions. This means an API key can never escalate beyond the user's own permissions. ```bash curl -X POST http://localhost:1349/api/v1/api-keys \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "CI pipeline key", "permissions": ["tools:use", "files:own"], "expiresAt": "2027-01-01T00:00:00Z" }' ``` ### Expiration {#expiration} Keys accept an optional `expiresAt` timestamp. Expired keys are rejected at authentication time. ## Audit log {#audit-log} SnapOtter records security-relevant events in a structured audit log stored in the `audit_log` database table. ### Viewing the audit log {#viewing-the-audit-log} ``` GET /api/v1/audit-log?page=1&limit=50&action=LOGIN_FAILED&from=2026-01-01T00:00:00Z&to=2026-12-31T23:59:59Z ``` Requires the `audit:read` permission. Supports pagination (`page`, `limit`) and filters (`action`, `ip`, `from`, `to`). ### Tool operation auditing {#tool-operation-auditing} ::: warning `TOOL_EXECUTED` events are **not** logged by default. They are opt-in through either of two paths: 1. Set the `auditToolOperations` admin setting to `true`. 2. Hold an active license with the `audit_export` feature (available on both team and enterprise plans). Without one of these, individual tool executions are not recorded in the audit log. ::: ### Exporting {#exporting} ``` GET /api/v1/enterprise/audit/export?format=csv&from=2026-01-01T00:00:00Z ``` Requires the `audit:read` permission and the `audit_export` enterprise feature (available on both team and enterprise plans). Supports CSV and JSON formats, filtered by `action`, `actorId`, `targetType`, `targetId`, `from`, and `to`. ### Tamper-resistant signing {#tamper-resistant-signing} When enabled, each audit log entry is signed with an HMAC derived from `DATA_ENCRYPTION_KEY`. This requires: 1. Setting `DATA_ENCRYPTION_KEY` in your environment. 2. Enabling the `tamperResistantAudit` admin setting. 3. An enterprise license with the `tamper_resistant_audit` feature. ### Retention {#retention} Set `AUDIT_RETENTION_DAYS` to automatically purge old entries. The default is `0`, which means entries are kept indefinitely. ### Event reference {#event-reference} | Event | Category | |---|---| | `LOGIN_SUCCESS`, `LOGIN_FAILED` | Authentication | | `OIDC_LOGIN_SUCCESS`, `OIDC_LOGIN_FAILED` | Authentication | | `SAML_LOGIN_SUCCESS`, `SAML_LOGIN_FAILED` | Authentication | | `LOGOUT` | Authentication | | `USER_CREATED`, `USER_UPDATED`, `USER_DELETED` | User management | | `PASSWORD_CHANGED`, `PASSWORD_RESET` | User management | | `MFA_ENROLLED`, `MFA_DISABLED`, `MFA_VERIFIED`, `MFA_VERIFY_FAILED` | MFA | | `MFA_CHALLENGE_ISSUED`, `MFA_RECOVERY_USED`, `MFA_RESET` | MFA | | `ROLE_CREATED`, `ROLE_UPDATED`, `ROLE_DELETED` | Roles | | `API_KEY_CREATED`, `API_KEY_DELETED` | API keys | | `SETTINGS_UPDATED`, `IP_ALLOWLIST_UPDATED` | Settings | | `FILE_UPLOADED`, `FILE_DELETED` | Files | | `TOOL_EXECUTED` | Tools (opt-in) | | `SCIM_USER_PROVISIONED`, `SCIM_USER_UPDATED`, `SCIM_USER_DEPROVISIONED` | SCIM | | `SCIM_GROUP_SYNCED` | SCIM | | `LEGAL_HOLD_APPLIED`, `LEGAL_HOLD_RELEASED` | Compliance | | `GDPR_EXPORT_INITIATED`, `GDPR_USER_PURGED`, `GDPR_TEAM_PURGED` | Compliance | | `CONFIG_EXPORTED`, `CONFIG_IMPORTED` | Configuration | ## Session management {#session-management} Sessions are cookie-based, controlled by `SESSION_DURATION_HOURS` (default: 168 hours / 7 days). ### Role changes invalidate sessions {#role-changes-invalidate-sessions} When an admin changes a user's role, all of that user's active sessions are deleted. The user must log in again to pick up their new permissions. ### Safety guards {#safety-guards} * **Last-admin protection**: the last remaining admin cannot be demoted to a lower role. The API returns an error if you try. * **Self-delete prevention**: admins cannot delete their own account through the API. --- --- url: https://docs.snapotter.com/guide/database.md description: >- PostgreSQL database schema, tables, migrations, and backup procedures for SnapOtter. --- # Database {#database} SnapOtter uses PostgreSQL 17 with [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) for data persistence. The schema is defined in `apps/api/src/db/schema.ts`. The connection is configured via the `DATABASE_URL` environment variable (default `postgres://snapotter:snapotter@postgres:5432/snapotter`). In Docker Compose, the Postgres container stores its data in the `SnapOtter-pgdata` named volume. ## Tables {#tables} ### users {#users} Stores user accounts. Created automatically on first run from `DEFAULT_USERNAME` and `DEFAULT_PASSWORD`. | Column | Type | Notes | |---|---|---| | `id` | uuid | Primary key | | `username` | varchar | Unique, required | | `passwordHash` | varchar | scrypt hash | | `role` | varchar | `admin`, `editor`, or `user` | | `mustChangePassword` | boolean | Forced password reset flag | | `createdAt` | timestamp | Creation time | | `updatedAt` | timestamp | Last update time | ### sessions {#sessions} Active login sessions. Each row ties a session token to a user. | Column | Type | Notes | |---|---|---| | `id` | varchar | Primary key (session token) | | `userId` | uuid | Foreign key to `users.id` | | `expiresAt` | timestamp | Expiry time | | `createdAt` | timestamp | Creation time | ### teams {#teams} Groups for organizing users. Admins can assign users to teams. | Column | Type | Description | |--------|------|-------------| | `id` | uuid | Primary key | | `name` | varchar (unique, max 50 chars) | Team name | | `createdAt` | timestamp | Creation time | ### api\_keys {#api-keys} API keys for programmatic access. The raw key is shown once on creation; only the hash is stored. | Column | Type | Notes | |---|---|---| | `id` | uuid | Primary key | | `userId` | uuid | Foreign key to `users.id` | | `keyHash` | varchar | scrypt hash of the key | | `name` | varchar | User-provided label | | `createdAt` | timestamp | Creation time | | `lastUsedAt` | timestamp | Updated on each authenticated request | Keys are prefixed with `si_` followed by 96 hex characters (48 random bytes). ### pipelines {#pipelines} Saved tool chains that users create in the UI. | Column | Type | Notes | |---|---|---| | `id` | uuid | Primary key | | `name` | varchar | Pipeline name | | `description` | varchar | Optional description | | `steps` | jsonb | Array of `{ toolId, settings }` objects | | `createdAt` | timestamp | Creation time | ### user\_files {#user-files} Persistent file library. A saved edit is inserted as an independent root row by default ("save as new": `version` 1, `parentId` null, so the original stays listed), or as a parent-linked version when you overwrite the original (`parentId` set, `version` incremented, superseding it). The `toolChain` column records the tools applied. | Column | Type | Description | |--------|------|-------------| | `id` | uuid | Primary key | | `userId` | uuid | FK to users (CASCADE DELETE) | | `originalName` | varchar | Original upload filename | | `storedName` | varchar | Filename on disk | | `mimeType` | varchar | MIME type | | `size` | integer | File size in bytes | | `width` | integer | Image width in px | | `height` | integer | Image height in px | | `version` | integer | Version number (1 = original) | | `parentId` | uuid or null | FK to user\_files (parent version) | | `toolChain` | jsonb | Tool IDs applied in order to produce this version | | `createdAt` | timestamp | Creation time | ### jobs {#jobs} Tracks processing jobs for progress reporting and cleanup. | Column | Type | Notes | |---|---|---| | `id` | uuid | Primary key | | `type` | varchar | Tool or pipeline identifier | | `status` | varchar | `queued`, `processing`, `completed`, or `failed` | | `progress` | real | 0.0-1.0 fraction | | `inputFiles` | jsonb | Array of input file paths | | `outputPath` | varchar | Path to the result file | | `settings` | jsonb | Tool settings used | | `error` | varchar | Error message if failed | | `createdAt` | timestamp | Creation time | | `completedAt` | timestamp | Completion time | ### settings {#settings} Key-value store for server-wide settings that admins can change from the UI. | Column | Type | Notes | |---|---|---| | `key` | varchar | Primary key | | `value` | varchar | Setting value | | `updatedAt` | timestamp | Last update time | ### roles {#roles} Custom roles with granular permissions. | Column | Type | Notes | |---|---|---| | `id` | uuid | Primary key | | `name` | varchar | Unique role name | | `description` | varchar | Optional description | | `permissions` | jsonb | Array of permission strings | | `createdAt` | timestamp | Creation time | ### audit\_log {#audit-log} Security-relevant action log. | Column | Type | Notes | |---|---|---| | `id` | uuid | Primary key | | `userId` | uuid | FK to users | | `action` | varchar | Action type | | `details` | jsonb | Action-specific data | | `createdAt` | timestamp | Action time | ### user\_preferences {#user-preferences} Per-user UI state, keyed by preference name. Backs the dashboard's pinned tools through `PUT /api/v1/preferences`. | Column | Type | Notes | |---|---|---| | `userId` | text | FK to users, cascades on delete. Primary key with `key` | | `key` | text | Preference name. Primary key with `userId` | | `value` | jsonb | Preference payload | | `updatedAt` | timestamp | Last write | ## Migrations {#migrations} Drizzle handles schema migrations. Migration files live in `apps/api/drizzle/`. During development: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` In production, pending migrations are applied automatically on startup. ## Backup and restore {#backup-and-restore} The relational database lives in the Postgres container's `SnapOtter-pgdata` volume, not the app's `/data` volume. **Logical backup with validation (recommended)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` This database dump does not contain saved library objects in `/data/files` or durable BullMQ state in Redis. Back up and restore those with the coordinated procedure in [Security & Hardening](/guide/security#backup-and-recovery). **Cold volume snapshot** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Do not copy a live PostgreSQL data directory with `tar`. Compose prefixes volume names by project, so resolve the mounted volume IDs from `docker inspect` or your storage platform rather than assuming the literal label `SnapOtter-pgdata`. ### Migrating from 1.x (SQLite) {#migrating-from-1-x-sqlite} Upgrading from SnapOtter 1.x has its own guide: see [Upgrading from 1.x to 2.0](./upgrading). In short, reuse your existing `/data` volume and 2.0 auto-detects and imports `/data/snapotter.db` on first boot (or set `SQLITE_MIGRATE_PATH` to point at it explicitly). Back up the whole `/data` volume first, not just `snapotter.db`: 1.x uses SQLite WAL mode, so a stopped container often leaves most of its data in `snapotter.db-wal` beside an almost-empty `snapotter.db`. --- --- url: https://docs.snapotter.com/guide/upgrading.md --- # Upgrading from 1.x to 2.0 {#upgrading-from-1-x-to-2-0} SnapOtter 1.x stored everything in a single SQLite file and ran as one container. SnapOtter 2.0 uses PostgreSQL and Redis. This guide walks through moving a 1.x install to 2.0 without losing data. The short version: reuse your existing `/data` volume, and 2.0 imports your 1.x database automatically on first boot. Your users, saved files, settings, API keys, and pipelines come across. The old database is never modified, so you can always roll back. ::: tip A note for our 1.x users Many of you have trusted SnapOtter since day one, and your feedback shaped this release. 2.0 changes a lot under the hood, and this guide exists so the move doesn't cost you anything you care about. Your accounts, files, settings, API keys, and pipelines carry over, and your old database is never touched. Thank you for upgrading with us. ::: ## Before you start: back up the whole `/data` volume {#before-you-start-back-up-the-whole-data-volume} Do this first, every time. Back up the **entire** `/data` volume, not just the `snapotter.db` file. Here is why it matters. 1.x runs SQLite in WAL mode, so a stopped 1.x container routinely leaves most of its committed data in `snapotter.db-wal` beside an almost-empty `snapotter.db`. Copying only `snapotter.db` captures an empty database and silently loses everything. The volume carries `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm`, and your `files/` directory together, and they must travel as a set. ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## Upgrade to 1.17.2 first {#upgrade-to-1-17-2-first} Upgrade your 1.x install to the latest 1.x release (1.17.2) before moving to 2.0. That lets 1.x run its own final schema migrations, so 2.0 imports from a known, complete schema. Upgrading from an older 1.x straight to 2.0 is not supported. ## Check your volume name {#check-your-volume-name} The importer only sees your data if the 2.0 stack mounts the same volume your 1.x install used. Docker volume names are case sensitive, and older README snippets used a lowercase `snapotter-data` while the Compose files use `SnapOtter-data`. Confirm which one you have: ```bash docker volume ls | grep -i snapotter ``` Use that exact name in your 2.0 configuration. ## Path A: single container (quickest) {#path-a-single-container-quickest} If you run SnapOtter with a single `docker run`, keep doing that. 2.0 boots an embedded PostgreSQL and Redis inside the container when you do not set `DATABASE_URL` or `REDIS_URL`, and it auto-detects and imports `/data/snapotter.db` on first boot. ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` Watch the logs for a line like: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` That is it. Log in with your existing credentials. ## Path B: Compose (recommended for production) {#path-b-compose-recommended-for-production} The 2.0 Compose stack runs three services (app, Postgres, Redis). Reuse your 1.x `/data` volume for the app service. The app auto-detects `/data/snapotter.db` and imports it into Postgres on first boot. ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` If you would rather point at the old database explicitly, set `SQLITE_MIGRATE_PATH=/data/snapotter.db`. An explicit path always wins over auto-detect. ## Preview the import first (optional) {#preview-the-import-first-optional} To see exactly what would be imported without writing anything, run a dry run against your database file: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` It prints the row counts per table, how many saved-library files it found on disk, and any job statuses it will normalize. It needs no running Postgres. ## What carries over, and what does not {#what-carries-over-and-what-does-not} Carried over: * Users, and the ability to log in. Password hashes are unchanged, so the same username and password work. * Teams, settings (including your instance identity), roles, API keys (they keep working), and saved pipelines. * Job history records. * Your saved-file library, both the records and the actual files, because `/data/files` is preserved on the volume. Not carried over: * Login sessions. Everyone signs in once after the upgrade. Credentials are unchanged, so it is a single re-login, nothing more. * The input and output files of old processing jobs. Those lived in a temporary workspace and are gone by design. The job history records remain. * Per-user analytics-consent flags from 1.x, which have no 2.0 equivalent (2.0 analytics is an instance-level setting). ## Turning the import off {#turning-the-import-off} If you deliberately want a fresh database even though a `snapotter.db` is present on the volume, set `SQLITE_MIGRATE_PATH=off`. ## If you already have data in the 2.0 instance {#if-you-already-have-data-in-the-2-0-instance} The importer only runs into an empty database. If you started 2.0 fresh (creating data), then later mounted an old `snapotter.db`, 2.0 will detect it but will not import, because merging two datasets can collide on IDs. You will see a warning in the logs. To import the 1.x data you need an empty instance: * If the 2.0 instance only holds the default admin (you have not really used it), stop the stack, remove the Postgres volume (`SnapOtter-pgdata`), and boot again with the old `/data` present. It will import cleanly. This wipes only the throwaway Postgres data, not your 1.x database. * If the 2.0 instance holds real data you want to keep, the two datasets cannot be auto-merged. Export what you need and import the 1.x data into a separate fresh deployment. ## Rolling back {#rolling-back} The upgrade never modifies or deletes your 1.x `snapotter.db`. If you need to go back to 1.x, redeploy the 1.x image against the same volume. Anything you created in 2.0 after the upgrade lives in Postgres and would not be in the 1.x database, so roll back promptly if you are going to. --- --- url: https://docs.snapotter.com/guide/deployment.md description: >- Deploy SnapOtter to production with Docker. Hardware requirements, GPU setup, and reverse proxy configs for Nginx, Traefik, and Cloudflare. --- # Deployment {#deployment} SnapOtter deploys as a 3-container Docker Compose stack: the SnapOtter app image, PostgreSQL 17, and Redis 8. The app image supports **linux/amd64** (with NVIDIA CUDA for AI acceleration) and **linux/arm64** (CPU), so it runs natively on Intel/AMD servers, Apple Silicon Macs, and ARM devices like the Raspberry Pi 4/5. Intel/AMD iGPU acceleration through VA-API, Quick Sync, or OpenCL is not supported for AI inference today. See [Docker Image](./docker-tags) for GPU setup, Docker Compose examples, and version pinning. ## Quick Start (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` The app is then available at `http://localhost:1349`. > **Docker Hub rate limits?** Replace `snapotter/snapotter:latest` with `ghcr.io/snapotter-hq/snapotter:latest` to pull from GitHub Container Registry instead. Both registries receive the same image on every release. ## Quick Start (NVIDIA CUDA) {#quick-start-nvidia-cuda} For NVIDIA CUDA acceleration on supported AI tools (background removal, upscaling, face enhancement): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### Verify GPU acceleration {#verify-gpu-acceleration} Check CUDA detection in the logs: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` If AI tools run on CPU even though `--gpus all` and the NVIDIA Container Toolkit are set up correctly, reinstall the affected bundle (for example Background Removal) from **Settings → AI Features**. The installer restores the GPU build of ONNX Runtime, which a CPU-only build pulled in by another bundle (such as transcription) can otherwise shadow in the shared AI environment. If reinstalling from the UI doesn't restore GPU on an older image, see the manual repair in [issue #490](https://github.com/snapotter-hq/SnapOtter/issues/490). ## Hardware Requirements {#hardware-requirements} These numbers come from benchmarks across a range of systems, from a modern amd64 workstation with an NVIDIA RTX 4070 down to a Raspberry Pi, running the whole tool catalog on each and sweeping Docker resource limits to find the real floor. Running at the small end of these tiers (a Pi, an old laptop, a 2 GB VPS)? [Low-Resource Setups](/guide/low-resource) turns these numbers into a concrete walkthrough with tuned caps. ### Quick Reference {#quick-reference} | Tier | Use Case | CPU | RAM | GPU | Storage | |------|----------|-----|-----|-----|---------| | Minimum | Image, files, and light PDF tools; single user; small batches | 2 cores | 2 GB | None | ~7 GB | | Recommended | All five modalities incl. video, PDF, and AI on CPU; batches; a few users | 4 cores | 4 GB | None | ~25 GB | | Full | Everything at speed incl. GPU AI; large batches; many users | 6-8 cores | 8 GB | NVIDIA 8 GB+ VRAM (12 GB comfortable) | ~35 GB | **Architecture: 64-bit only** (`linux/amd64` or `linux/arm64`). SnapOtter runs natively on Intel/AMD servers, Apple Silicon Macs, and 64-bit ARM boards including the **Raspberry Pi 4 and 5** (4-8 GB). It does **not** run on 32-bit ARM (`armv7`/`armhf`) — no image is built for it — nor on 512 MB-class boards such as the Pi Zero, which are below the memory floor (see below). ### Minimum (image, files, and light PDF tools; no AI) {#minimum-image-files-and-light-pdf-tools-no-ai} | Resource | Requirement | |---|---| | CPU | 2 cores | | RAM | 2 GB | | Disk | ~5.5 GB (image) + data volume | | GPU | Not required | All 222 non-AI catalog tools - image (resize, crop, convert, compress, adjust, watermark), video (trim, mute, remux), audio (convert, normalize, trim), PDF (merge, split, compress, rotate, protect), file conversions, and dedicated conversion presets - run on modest hardware. Most operations finish in well under a second even on a large file: a 2.7 MB image resizes in ~0.05 s and re-encodes to WebP in ~2 s. The memory floor is real, from a Docker resource-limit sweep: **512 MB cannot start the stack** (even a single image resize is killed), **1 GB** handles single-file operations but a multi-file batch runs out of memory, and **2 GB / 2 cores** is the smallest configuration that handles batches comfortably. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **The one CPU-heavy exception is video re-encoding.** Stream-copy operations (trim, mute, container remux) are instant, but transcoding to a different codec is CPU-bound. A 1080p / 45-second clip re-encoded to VP9 (WebM) takes roughly **~40 s** on a fast modern CPU, ~45 s on Apple Silicon, ~80 s on an older mobile 4-core, and **~130 s** on an older 4-core server. If your workload is video-heavy, prioritize CPU cores and clock speed, or raise the container's `cpus:` limit — the shipped compose caps the app at 4 cores by default (8 on the GPU compose). ### Recommended (AI tools on CPU) {#recommended-ai-tools-on-cpu} | Resource | Requirement | |---|---| | CPU | 4 cores | | RAM | 4 GB | | Disk | 3 GB (image) + about 20 GB (all optional AI packs) + workspace | | GPU | Not required (CPU fallback) | **Installing and running the larger AI bundles is what pushes the recommendation to 4 GB of RAM.** With no optional packs installed the app idles around 360 MB. Legacy Python tools share a sidecar, while accurate OCR uses a dedicated long-lived dispatcher pinned to the active immutable generation. Before activation, the installer runs a smoke test on the candidate. It then atomically switches to the new dispatcher and drains the prior dispatcher before garbage collection. Every official accurate-OCR artifact must pass its worst-case release suite inside a 4 GiB cgroup, while the 4 GB host recommendation leaves headroom for the Node.js application, Postgres, Redis, queues, and concurrent work. Most AI tools are perfectly usable on CPU; a couple really want a GPU. Measured on a modern 4-core CPU: | AI Tool | CPU Time | Usable on CPU? | |---|---|---| | Face detection (blur-faces, smart-crop, red-eye), noise-removal | under 1 s | Yes | | OCR, transcription, subtitles | 1-3 s | Yes | | Colorize, face enhancement | ~10 s | Yes | | Background removal / replace / blur | ~29 s | Yes (you'll wait) | | AI upscale (RealESRGAN) | ~33 s small; minutes on large images | Marginal — GPU strongly recommended | | Photo restoration (full pipeline) | several minutes | No — needs a GPU or a fast many-core CPU | SnapOtter intentionally does not bake these model downloads into the Docker image. AI bundles are pulled only when an admin enables the related tool, stored in the persistent `/data/ai` volume, and shared by every tool that depends on the same model stack. This keeps the final container image small while still letting a full AI installation reach the larger storage numbers below. Some tools depend on more than one shared bundle. For example, Passport Photo needs both `background-removal` and `face-detection`; if `background-removal` is already installed, enabling Passport Photo only downloads the missing `face-detection` bundle. The same reuse applies across all AI tools. Optional AI pack storage estimates: | Bundle | Disk Size | |---|---| | Background removal | 4-5 GB | | Upscale + Face enhance + Noise removal | 5-6 GB | | Face detection | 200-300 MB | | Object eraser + Colorize | 1-2 GB | | Accurate OCR (`balanced`/`best`) | ~208-234 MiB download / ~409-488 MiB installed | | Photo restoration | 4-5 GB | | Transcription | ~600 MB | | **All bundles** | **~20 GB installed** | Fast OCR is built into the image through Tesseract, adds about 25 MiB, and does not require the optional OCR pack or its 4 GiB memory requirement. Fast supports `auto`, `en`, `de`, `es`, `fr`, `zh`, and `ja`, but not Korean (`ko`). Korean uses `balanced` or `best` and therefore requires the accurate pack. The accurate pack is available in the official Linux amd64 and arm64 containers and runs ONNX Runtime on CPU. NVIDIA hosts use that same CPU OCR runtime, so OCR does not depend on the CUDA version or GPU architecture. The accurate runtime requires at least 4 GiB of effective memory: the configured container cgroup limit, otherwise host memory. SnapOtter rejects systems below that signed compatibility minimum before downloading the pack. Accurate-pack installation is also rejected on bare-metal/prebuilt archives whose libc and Python ABI cannot be guaranteed. On those unsupported hosts, Korean OCR returns an explicit incompatibility error and never silently falls back to Fast. Replicas that share the same `DATA_DIR` must use the same CPU architecture; pin multi-replica deployments with node affinity. Mixed amd64/arm64 replicas need separate data volumes and independent SnapOtter deployments. The accurate runtime keeps one active generation and purges its download cache after activation. For this release, a first install temporarily needs roughly 620-720 MiB for the archive plus staging, and an upgrade can peak near 1.2 GiB while the old generation remains active. The installer computes the exact requirement from the signed index and current generations before downloading or extracting, and fails early if the data volume is too small. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Full (AI tools on NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | Resource | Requirement | |---|---| | CPU | 6-8 cores (video prep + concurrency run on CPU even with GPU AI) | | RAM | 8 GB | | GPU | NVIDIA with 8+ GB VRAM (12 GB recommended) | | Disk | ~35 GB total | An NVIDIA GPU (CUDA) dramatically speeds up the heavy AI models. Measured on an RTX 4070 vs a modern CPU: | AI Tool | Speedup with GPU | Notes | |---|---|---| | AI upscale (RealESRGAN 2×) | **~47×** | The biggest win — under a second vs ~33 s (minutes on large images) | | Face enhancement (CodeFormer) | **~12×** | ~0.9 s vs ~11 s | | Transcription (Whisper) | ~4.5× | | | Background removal / replace / blur | ~4× | ~7 s on GPU vs ~29 s on CPU | | Colorize | ~1.8× | | | OCR, face detection, red-eye, noise-removal | ~1× | Already fast on CPU — a GPU doesn't help | | Photo restoration | none | CPU-bound even on a GPU (0% GPU utilisation); a fast CPU matters more than a GPU here | The tools worth a GPU are **upscale, face enhancement, transcription, and background removal**. Face detection, OCR, and red-eye are CPU-bound and already fast, so a GPU adds nothing. Peak VRAM usage reaches 7.5 GB during upscale with face enhancement. A 6 GB NVIDIA GPU works for most AI tools individually but will fail on upscale. 8-12 GB VRAM handles everything. Intel/AMD iGPU acceleration through VA-API, Quick Sync, or OpenCL is not supported for AI inference today. Mapping `/dev/dri` into the container does not enable AI GPU acceleration; SnapOtter will run AI tools on CPU unless NVIDIA CUDA is available. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Concurrent Users {#concurrent-users} Parallel image-resize requests against the default 4-core-capped app container: | Concurrent Requests | Avg Response Time | Errors | |---|---|---| | 1 | 0.4s | 0 | | 5 | 1.2s | 0 | | 10 | 2.1s | 0 | Response time degrades sub-linearly with no errors as the worker pool saturates. Raising the app container's `cpus:` limit (or using a host with more cores) lifts the ceiling. Note that heavy jobs (video transcode, CPU AI) hold a worker for their full duration, so size CPU to your expected number of concurrent heavy jobs, not just request count. ### Supported Image Formats {#supported-image-formats} SnapOtter supports **55+ input formats** and **14 output formats**, including RAW files from 20+ camera brands, professional formats (PSD, EPS, OpenEXR, HDR), modern codecs (JPEG XL, AVIF, HEIC, QOI), and scientific/gaming formats (FITS, DDS). See the [complete format list](/guide/supported-formats) for details on every supported format, decoder used, and available quality controls. ### Known Limitations {#known-limitations} * **Content-aware resize** crashes on large images (>5 MP) due to a limitation in the caire binary. Works fine with smaller images. * **HEIF decode** takes 13-23 seconds. HEIC (Apple's variant) is much faster at 0.3-0.9 seconds. * **Upscale** times out on CPU for anything beyond small images. GPU required for practical use. * **CodeFormer** face enhancement is significantly slower than GFPGAN (53s vs 2s on GPU). GFPGAN is recommended for most use cases. ## Volumes {#volumes} | Mount / Volume | Purpose | Required? | |---|---|---| | `/data` (app) | AI models, Python venv, user files | **Yes** - file loss without it | | `/tmp/workspace` (app) | Temporary processing files (auto-cleaned) | Recommended | | `SnapOtter-pgdata` (postgres) | PostgreSQL data directory (users, settings, pipelines, jobs) | **Yes** - data loss without it | | `SnapOtter-redisdata` (redis) | Redis append-only file for durable job queues | Recommended | ### Bind mounts vs. named volumes {#bind-mounts-vs-named-volumes} **Named volumes** (recommended) — Docker manages permissions automatically: ```yaml volumes: - SnapOtter-data:/data ``` **Bind mounts** — You manage permissions. Set `PUID`/`PGID` to match your host user: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Storage permissions {#storage-permissions} SnapOtter writes to two locations at runtime: `/data` (user files, logs, AI models and the Python venv) and `/tmp/workspace` (temporary processing scratch). Both must be writable by the user the container runs as. If either is not, the container **fails fast at startup** with a message naming the directory, the running UID/GID, and how to fix it — instead of booting "healthy" and then failing on the first upload with a cryptic error. How permissions are handled depends on how the container is launched: **Default (starts as root, drops to `snapotter`)** — the entrypoint starts as root, fixes ownership of the mounted volumes, then drops to the unprivileged `snapotter` user via `gosu`. Named volumes work with no configuration. For bind mounts, set `PUID`/`PGID` to your host user (above) so the files it writes are owned by you. **Kubernetes / OpenShift (non-root via `runAsUser`)** — launched directly as a non-root user, the container cannot chown the volumes itself, so the orchestrator must make them writable. Set `fsGroup`: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` The image's writable directories are group-owned by GID 0 and group-writable, so a pod running with an **arbitrary UID** plus the root supplementary group (the OpenShift default) can write with no `chown`. **TrueNAS Scale (and other "foreign UID" setups)** — TrueNAS runs apps as a non-root user (often `568:568`) and mounts host datasets owned by a different user, so neither the entrypoint nor `fsGroup` makes them writable on its own. Choose one: * **Run the app as root** (recommended) — leave the app's user unset or set it to `0`, and let the default entrypoint fix permissions and drop to `snapotter`. * **Run as UID `999`** — set the app's user/group to `999:999` (SnapOtter's built-in `snapotter` user) so it matches the image's ownership. * **`chown` the host dataset** to the UID the container runs as, from the TrueNAS shell: ```bash # Use the UID from the startup error (or run `id` inside the container) chown -R 568:568 /mnt// ``` The startup error names the exact UID to use, so the quickest path is to start the app once, read the message, then `chown` (or adjust the user) accordingly. ## Environment Variables {#environment-variables} | Variable | Default | Description | |---|---|---| | `AUTH_ENABLED` | `true` | Enable/disable login requirement | | `DEFAULT_USERNAME` | `admin` | Initial admin username | | `DEFAULT_PASSWORD` | `admin` | Initial admin password (forced change on first login) | | `MAX_UPLOAD_SIZE_MB` | `0` (unlimited) | Per-file upload limit in MB. The image ships `0`; a source build starts at 100 | | `MAX_BATCH_SIZE` | `0` (unlimited) | Max files per batch request. The image ships `0`; a source build starts at 100 | | `RATE_LIMIT_PER_MIN` | `1000` | API requests per minute per IP (set 0 to disable) | | `MAX_USERS` | `0` (unlimited) | Maximum user accounts | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Which peers may set the client IP through `X-Forwarded-For`. Private networks only by default | | `PUID` | `999` | Run as this UID (for bind mount permissions) | | `PGID` | `999` | Run as this GID (for bind mount permissions) | | `LOG_LEVEL` | `info` | Log verbosity: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (auto) | Max parallel AI processing jobs | | `SESSION_DURATION_HOURS` | `168` | Login session lifetime (7 days) | | `CORS_ORIGIN` | (empty) | Comma-separated allowed origins, or empty for same-origin | ### Outbound proxy and private CA {#outbound-proxy-and-private-ca} The official container enables Node's environment-proxy support. If SnapOtter must reach the OCR runtime repository or other HTTPS services through a corporate proxy, set `HTTPS_PROXY` (and `HTTP_PROXY` when needed). Set `NO_PROXY` to a comma-separated list of hosts that must be reached directly, such as Postgres, Redis, and internal object storage. If the proxy or an internal service is signed by a private certificate authority, mount the CA certificate read-only and point `NODE_EXTRA_CA_CERTS` to it. The file must exist when the Node process starts: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Keep the proxy credentials outside the Compose file (for example in a protected `.env` file or secret). Do not disable TLS verification: the signed OCR index authenticates release metadata, while normal TLS validation still protects transport and every other outbound request. ## Health Check {#health-check} The container includes a built-in health check: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Reverse Proxy {#reverse-proxy} `TRUST_PROXY` defaults to `loopback,linklocal,uniquelocal`, so SnapOtter believes `X-Forwarded-For` only from a peer on a private network. A reverse proxy on the same host, on a Docker network, or on your LAN is trusted out of the box, which means rate limiting, the login brute-force limiter, the audit log, and the enterprise IP allowlist all see the real client IP with no configuration. Set `TRUST_PROXY=true` only when the proxy in front reaches SnapOtter from a **public** address, a cloud load balancer on a different network for instance. On a directly exposed instance that value makes `request.ip` attacker-controlled, because a caller who rotates the header gets a fresh rate-limit bucket per request. Two things to know before you go measuring client IPs. Docker Desktop on macOS and Windows serves a published port through a userland proxy that rewrites every source address to the VM gateway `192.168.65.1`, so no value of `TRUST_PROXY` recovers the real client there; deploy on Linux for anything internet-facing. And on any platform, reaching a published port over `localhost` is observed as the bridge gateway rather than as your client, so a localhost test tells you nothing about how a real client is attributed. The full table of `TRUST_PROXY` values and the Docker Desktop caveat are in [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy). Two things matter for every proxy below: allow large request bodies (uploads), and do not buffer responses. A response-buffering proxy breaks SSE progress and, more visibly, makes a large file download "start but never finish", because the proxy holds the whole file before passing it on. SnapOtter sends `X-Accel-Buffering: no` on downloads so nginx streams them even if buffering is left on elsewhere, but proxies other than nginx need response buffering disabled explicitly (shown in each config below). If a download stalls partway, a buffering proxy in front is the first thing to check. A note on HSTS: the API sends `Strict-Transport-Security` on every response itself, so a proxy that passes response headers through (all of the configs below do) needs no HSTS setup of its own. Only if your proxy is configured to strip or override upstream response headers do you need to preserve the header or re-add it at the edge. ### Nginx {#nginx} ```nginx server { # Plain HTTP shown for brevity. Terminate TLS in your own `listen 443 ssl` # server block; the Strict-Transport-Security header the API sends passes # through with every proxied response, so no add_header is needed there. listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Stream responses instead of buffering: needed for SSE progress # (batch, AI, feature installs) and for large file downloads. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Add a new Proxy Host 2. Set Domain Name to your domain 3. Set Scheme to `http`, Forward Hostname to `SnapOtter` (or your container IP), Forward Port to `1349` 4. Enable WebSocket support 5. Under Advanced, add: `client_max_body_size 500M;` and `proxy_buffering off;` The API's `Strict-Transport-Security` header passes through NPM as-is; the HSTS toggle on the SSL tab is optional on top of it. ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` Traefik forwards upstream response headers unchanged, so the API's `Strict-Transport-Security` header reaches browsers without a `headers` middleware. If you already run one that rewrites response headers, make sure it leaves that header intact. ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` disables response buffering, which is required for SSE progress events (batch processing, AI tools, feature installs) and for large file downloads to stream through instead of stalling. The extended timeouts allow large file uploads to complete without Caddy closing the connection early. Caddy also passes the API's `Strict-Transport-Security` header through untouched, so no `header` directive is needed for HSTS. ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Note: Cloudflare has a 100 MB upload limit on free plans. Set `MAX_UPLOAD_SIZE_MB=100` to match. The tunnel forwards the API's response headers, `Strict-Transport-Security` included, so no dashboard HSTS configuration is required (Cloudflare's own edge HSTS setting is optional on top). ## Troubleshooting {#troubleshooting} ### "Postgres not reachable: EAI\_AGAIN" right after a failed first start {#eai-again-after-failed-first-start} If the very first `docker compose up -d` fails partway (a port already in use is the usual reason), a plain `up -d` retry can start the app container without attaching it to the compose network. The app then crash-loops with: ``` Postgres not reachable: EAI_AGAIN ``` while `docker ps` shows postgres healthy. The error is real but points at the wrong container: without the network, DNS for the `postgres` hostname cannot resolve at all, and the restart policy replays the same failure forever. Fix whatever broke the first start (usually: free the port), then force the app container to be recreated so it reattaches to the network: ```bash docker compose up -d --force-recreate SnapOtter ``` ### Windows: reachable from other devices, not from the PC itself {#windows-wsl2-loopback} With Docker running inside WSL2 (the usual Windows setup), the stack can be reachable from every other machine on your network while `http://localhost:1349` times out on the Windows host itself, even with WSL's mirrored networking mode enabled. The port never shows up in Windows `netstat`, and nothing is wrong with the containers. Open the app from another device, or from inside the distro using its own address (`hostname -I` in the WSL shell). If localhost forwarding happens to work on your WSL version, treat it as a bonus rather than something to depend on. ## CI/CD {#ci-cd} The GitHub repository has three workflows: * **ci.yml** - Runs automatically on every push and PR. Lints, typechecks, tests, builds, and validates the Docker image (without pushing). * **release.yml** - Triggered manually via `workflow_dispatch`. Runs semantic-release to create a version tag and GitHub release, then builds a multi-arch Docker image (amd64 + arm64) and pushes to Docker Hub (`snapotter/snapotter`) and GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`). * **deploy-docs.yml** - Builds this documentation site and deploys it to Cloudflare Pages on push to `main`. To create a release, go to **Actions > Release > Run workflow** in the GitHub UI, or run: ```bash gh workflow run release.yml ``` Semantic-release determines the version from commit history. The `latest` Docker tag always points to the most recent release. ## Analytics {#analytics} SnapOtter includes anonymous product analytics (tool usage patterns, error reports) to help catch bugs and improve features. It is on by default. Your files, file names, and personal data are never part of this. SnapOtter works normally with analytics disabled. ### Disabling analytics {#disabling-analytics} The runtime opt-out is a one-click admin toggle. Open Settings > System > Privacy and turn off Anonymous Product Analytics. It stops immediately for the whole instance, no rebuild required. For an image that can never emit analytics, set the build-time hard-off by cloning the repository and rebuilding: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` Or add the build arg to your existing `docker-compose.yml`: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/guide/security.md description: >- Security hardening guide for SnapOtter. Container security, network isolation, Docker secrets, Kubernetes deployment, and compliance artifacts. --- # Security & Hardening {#security-hardening} SnapOtter processes files entirely on your infrastructure. It sends anonymous, content-free product analytics and crash reports by default to help improve the project. It never sends your files, file names, file contents, OCR output, image metadata, or document text. Optional feedback is sent only after a user submits it, only when analytics is enabled, and contact fields are included only with explicit contact consent. An administrator can turn analytics and feedback capture off in one click under Settings > System > Privacy, no rebuild required. File processing always stays inside your container. The container runs as a dedicated non-root user (`snapotter`) with all Linux capabilities dropped except the minimum required set. For the full vulnerability disclosure policy and security architecture, see [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) on GitHub. ## Container Hardening {#container-hardening} The canonical [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) and [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml) Compose files are the source of truth. Do not copy an abbreviated example into production; deploy the file from the release tag you verified. Both stacks apply the following controls: * Memory, swap, CPU, and PID limits contain runaway native processing. * Every service drops all Linux capabilities. The application adds back only `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` for volume ownership, the one-way `gosu` identity drop, and graceful signal forwarding. PostgreSQL and Redis receive only the subset their official entrypoints need. * `security_opt: [no-new-privileges:true]` prevents processes in the application, PostgreSQL, and Redis containers from gaining additional privileges. This remains compatible with `gosu`: the entrypoint begins as root, prepares the volumes, and only drops to the dedicated `snapotter` user. * PostgreSQL and Redis image inputs are pinned by digest. The application should likewise be pinned to a verified release tag or digest rather than `latest`. * Health checks, bounded JSON log rotation, durable Redis AOF, and restart policy are defined centrally in the canonical files. For an internet-facing deployment, bind port 1349 to loopback and terminate TLS at a maintained reverse proxy. Generate unique PostgreSQL and Redis credentials, store secrets in protected files or a secret manager, and change the initial administrator password immediately. ### Why `read_only` Is Not Set {#why-read-only-is-not-set} `read_only: true` is not set because PUID/PGID remapping writes to `/etc/passwd` and `/etc/group` at startup. If you use Docker's `--user` flag or Kubernetes `runAsUser` instead of PUID/PGID, you can safely enable a read-only root filesystem. ## Network Isolation {#network-isolation} File processing is local, but a default installation is **not an egress-free system**. Anonymous product analytics use PostHog and crash reporting uses Sentry when telemetry is enabled. Set `SNAPOTTER_TELEMETRY=0` (or disable analytics under Settings > System > Privacy) to turn off both. SnapOtter never includes uploaded files, file names, OCR output, document text, or other file contents in those events. Other outbound traffic is feature-driven: AI bundle/model installation downloads signed release inputs; URL import fetches a user-requested public URL; and explicitly configured OIDC, SAML, OpenTelemetry, webhooks, S3-compatible storage, or similar integrations contact the destinations chosen by the administrator. Runtime model downloads are disabled by default. Set `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` only to explicitly opt into automatic fallback downloads. An [offline bundle import](/guide/deployment) can provision AI features without runtime model egress. **Firewall recommendations:** | Scenario | Outbound rule | |---|---| | Air-gapped | Set `SNAPOTTER_TELEMETRY=0` and `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0`, use offline AI bundle import, disable URL import and external integrations, then block egress | | Default telemetry | Allow the PostHog and Sentry endpoints listed by your browser/network logs; disable telemetry if policy does not permit them | | AI bundles needed | During installation, allow HTTPS to `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org`; then block those hosts | | External integrations | Allow only the exact administrator-configured OIDC/SAML/OTLP/webhook/object-storage destinations | Bundle archives are served from Hugging Face's Xet storage, which transfers over the `*.xethub.hf.co` endpoints in parallel and is what makes multi-GB bundle downloads fast. If your firewall allows `huggingface.co` but blocks `*.xethub.hf.co`, installs still succeed but fall back to a slower single-stream download, so allowlist the Xet hosts to stay on the fast path. Fully offline installs can skip all of this and use [Offline Bundle Import](/guide/deployment) instead. For reverse proxy configuration (Nginx, Traefik, Caddy, Cloudflare Tunnels), see the [Deployment guide](/guide/deployment#reverse-proxy). ## Docker Secrets {#docker-secrets} For production deployments, avoid passing secrets as plain-text environment variables. The entrypoint supports Docker's `_FILE` convention: mount a secret as a file and set the corresponding `_FILE` variable to its path. **Supported secrets:** | Variable | `_FILE` equivalent | |---|---| | `DEFAULT_PASSWORD` | `DEFAULT_PASSWORD_FILE` | | `COOKIE_SECRET` | `COOKIE_SECRET_FILE` | | `OIDC_CLIENT_SECRET` | `OIDC_CLIENT_SECRET_FILE` | | `S3_ACCESS_KEY_ID` | `S3_ACCESS_KEY_ID_FILE` | | `S3_SECRET_ACCESS_KEY` | `S3_SECRET_ACCESS_KEY_FILE` | | `SNAPOTTER_LICENSE_KEY` | `SNAPOTTER_LICENSE_KEY_FILE` | **Example with Docker Compose secrets:** ```yaml services: SnapOtter: image: snapotter/snapotter:latest environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD_FILE=/run/secrets/snapotter_password - COOKIE_SECRET_FILE=/run/secrets/cookie_secret secrets: - snapotter_password - cookie_secret secrets: snapotter_password: file: ./secrets/snapotter_password.txt cookie_secret: file: ./secrets/cookie_secret.txt ``` ::: tip Docker Compose secrets (without Swarm) require Compose v2.23 or later. ::: ## Kubernetes Deployment {#kubernetes-deployment} The entrypoint detects when the container is already running as non-root (e.g., via Kubernetes `runAsUser`) and skips the gosu privilege drop automatically. In that case it cannot chown the mounted volumes itself, so it verifies they are writable and exits early with actionable guidance if they are not — see [Storage permissions](/guide/deployment#storage-permissions) for `fsGroup` and foreign-UID setups (TrueNAS, OpenShift). **Recommended Pod SecurityContext:** ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: snapotter spec: replicas: 1 selector: matchLabels: app: snapotter template: metadata: labels: app: snapotter spec: securityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 fsGroup: 999 containers: - name: snapotter image: snapotter/snapotter:latest ports: - containerPort: 1349 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] resources: requests: cpu: "1" memory: 2Gi limits: cpu: "4" memory: 6Gi livenessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readinessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - name: data mountPath: /data - name: workspace mountPath: /tmp/workspace volumes: - name: data persistentVolumeClaim: claimName: snapotter-data - name: workspace emptyDir: medium: Memory sizeLimit: 2Gi ``` Since `runAsUser: 999` is set at the pod level, the entrypoint skips gosu entirely. This allows `allowPrivilegeEscalation: false` and `drop: [ALL]` capabilities without conflict. For resource sizing, see [Hardware Requirements](/guide/deployment#hardware-requirements). ## Backup and Recovery {#backup-and-recovery} The production Compose stack defines four volumes. Stop ingress and let active jobs finish before taking a coordinated backup so PostgreSQL, Redis, and file state describe the same point in time. | Volume | Contents | Recovery treatment | |---|---|---| | `SnapOtter-pgdata` | PostgreSQL users, settings, pipelines, jobs, file metadata, and audit log | Critical; use a fail-fast logical dump for portable recovery | | `SnapOtter-data` | Saved library objects, logs, and AI state (`/data/files, /data/logs, /data/ai, /data/ai/venv`) | Back up the whole volume; to save space, deliberately omit all AI state and reinstall its bundles | | `SnapOtter-redisdata` | Redis AOF for durable BullMQ queue state | Back up after pausing the app and forcing `SAVE`; required to resume queued work exactly | | `SnapOtter-workspace` | Temporary object-storage keys (`/tmp/workspace/uploads, /tmp/workspace/outputs`) | Do not back up after all jobs are drained or cancelled; never discard it while jobs are active | Compose normally prefixes volume names with the project name. Resolve the real source volume from the mounted container instead of assuming that a display name such as `SnapOtter-data` is the Docker volume name. ### Database backup {#database-backup} Use PostgreSQL's custom archive format and verify the archive before treating the backup as complete: ```bash docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore only into a fresh/disposable target first; any SQL error fails the command. docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Test every backup by restoring it into an isolated stack, checking database records and file checksums, and starting the application. The repository's `tests/qa/backup-restore-drill.sh` automates that release gate against an explicit `QA_IMAGE`. If your platform takes crash-consistent volume snapshots instead, stop the entire stack first and snapshot all critical volumes as one set. A raw PostgreSQL data-directory copy from a running container is not a supported logical backup. ### File and queue backup {#file-and-queue-backup} Pause the application before capturing file and queue volumes. Use `docker inspect` to resolve the actual volume name, force Redis to persist its current state, and archive with ownership and permissions preserved: ```bash docker stop SnapOtter docker exec SnapOtter-redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning SAVE docker stop SnapOtter-redis DATA_VOLUME="$(docker inspect SnapOtter --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" REDIS_VOLUME="$(docker inspect SnapOtter-redis --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" install -d -m 700 backup docker run --rm -v "$DATA_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-data.tar.gz -C /source . docker run --rm -v "$REDIS_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-redis.tar.gz -C /source . sha256sum backup/snapotter-*.tar.gz > backup/SHA256SUMS ``` Restart Redis before the application. If you intentionally exclude `/data/ai`, remove the whole AI subtree rather than preserving an `installed.json` record without its models or virtual environment. Keep backup files encrypted, access-controlled, and separate from the host running SnapOtter. ## Compliance Artifacts {#compliance-artifacts} Each SnapOtter release includes the following security artifacts: | Artifact | Format | Where to find it | |---|---|---| | Release subject binding | Canonical JSON + GitHub attestation | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases) asset: `snapotter-v{version}-release-subjects.json` | | Archive SBOM | CycloneDX and SPDX JSON | Release assets: `snapotter-v{version}-archive-linux-{arch}-sbom.{cdx,spdx}.json` | | Image SBOM | CycloneDX and SPDX JSON | Release assets: `snapotter-v{version}-image-linux-{arch}-sbom.{cdx,spdx}.json` | | Vulnerability scans | Trivy JSON | Release assets with matching `archive-linux-{arch}` or `image-linux-{arch}` prefixes | | Vulnerability scan | SARIF | [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security) tab | | Static analysis | CodeQL (JS/TS + Python) | [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security) tab, runs weekly + per PR | | Dependency review | GitHub native | Per-PR check, fails on high-severity additions | | Python dependency audit | pip-audit | CI run log on every push | | Security policy | Markdown | [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) in the repository | | Dependency updates | Dependabot | Automated weekly PRs for npm, pip, Docker, Actions | **Running your own scan:** Download the release-subject manifest and verify that it was attested by the release workflow: ```bash gh attestation verify snapotter-v2.2.0-release-subjects.json \ --repo snapotter-hq/SnapOtter \ --signer-workflow snapotter-hq/SnapOtter/.github/workflows/release.yml ``` The manifest records `releaseTag`, `releaseCommit`, and `workflowTriggerCommit` separately. Verify that `releaseCommit` is the commit peeled from the immutable tag, then verify the SHA-256 digest of the archive, image, SBOM, or scan you consume against its entry in `subjects`. This distinction is intentional: checking out a newly created release commit does not change the commit identity in the workflow's OIDC credential. You can also scan a downloaded SBOM or the image directly: ```bash # Scan with Grype using the CycloneDX SBOM grype sbom:snapotter-v2.2.0-image-linux-amd64-sbom.cdx.json # Scan with Trivy using the SPDX SBOM trivy sbom snapotter-v2.2.0-image-linux-amd64-sbom.spdx.json # Scan the Docker image directly trivy image snapotter/snapotter:2.2.0 ``` ::: info Image SBOMs and scans reflect the exact architecture-specific image published for that release. Archive SBOMs and scans describe the prebuilt archive separately. AI model bundles installed after deployment are not included in these SBOMs because they are downloaded at runtime. ::: --- --- url: https://docs.snapotter.com/guide/account-recovery.md --- # Account Recovery If you get locked out of SnapOtter (most often by an MFA policy you can no longer satisfy), you can recover from inside the container without a database client. Recovery commands are offline and require shell access to the container, which already means full control of the instance. ## Which wall am I hitting? SnapOtter's login applies two independent MFA gates. Diagnose first: ```bash docker exec -it snapotter snapotter-admin status ``` This prints the current MFA policy and which users have TOTP enrolled. * **"MFA enrollment is required before login" (and you never set up an app):** the policy requires MFA but you have no enrollment. Relax the policy. * **You are prompted for a code you cannot produce** (lost your phone and your recovery codes): your account is enrolled. Clear that enrollment. ## Relax the MFA policy ```bash docker exec -it snapotter snapotter-admin reset-mfa-policy ``` This sets the policy back to `optional`. It applies on your next login with no restart. It only ever sets `optional`, so it cannot turn enforcement back on. ## Clear one user's TOTP enrollment ```bash docker exec -it snapotter snapotter-admin disable-mfa ``` If the policy still requires MFA for that user, they will hit the enrollment wall next, so also run `reset-mfa-policy`, log in, and re-enroll from Settings. ## Older images and fallbacks On an image built before the `snapotter-admin` wrapper existed, call the script directly: ```bash docker exec -w /app/apps/api snapotter ./node_modules/.bin/tsx \ src/scripts/mfa-recover.ts reset-mfa-policy ``` As a last resort on any version, set the policy in the database. On the all-in-one image Postgres runs inside the container: ```bash docker exec -it snapotter psql -h 127.0.0.1 -U snapotter -d snapotter \ -c "UPDATE settings SET value = 'optional' WHERE key = 'mfaPolicy';" ``` On the multi-container setup, point `psql` at your own `DATABASE_URL` instead. ## Locked out of SSO, not MFA? If an enforced SSO login is failing, use the break-glass local account instead: set `ssoBreakGlassUsername` to a local admin under Settings > Security before you enforce SSO, and log in with that account's password. --- --- url: https://docs.snapotter.com/guide/telemetry.md description: >- What anonymous usage data SnapOtter collects, when it is sent, and how to turn instance-wide product analytics off. --- # What SnapOtter collects {#what-snapotter-collects} Anonymous Product Analytics is on by default and set for the whole instance by an administrator. Turn it off under Settings > System > Privacy. ## Events we send (when enabled) {#events-we-send-when-enabled} * tool\_used: tool id, status, duration, category, whether it is an AI tool, an error code on failure. * pipeline\_executed: step count, tool ids, batch flag, file count, duration, status. * ai\_bundle\_action: bundle id, action, duration. * Frontend usage: which tool pages open, files added (counts only), tool started, downloads, saves, search (result count only), batch processed. * Crash reports: error type, a redacted error message (file names, paths, emails, and quoted values removed), a source stack with file basenames, and for AI tools a Python traceback with file basenames only. ## What we never collect {#what-we-never-collect} * File names or paths * File contents * OCR output text * Image metadata (EXIF) * Extracted document text * Your IP address or account identity ## Turning it off {#turning-it-off} Admins: Settings > System > Privacy, flip "Anonymous Product Analytics" off. It stops immediately, instance-wide. To build an image that can never emit, set the `SNAPOTTER_ANALYTICS=off` build arg. --- --- url: https://docs.snapotter.com/guide/supported-formats.md description: >- Supported file formats across all modalities - 55+ image input formats, video, audio, PDF, and file formats. --- # Supported Formats {#supported-formats} SnapOtter processes files across five modalities: image, video, audio, PDF, and files. This page lists all supported formats. ## Image Formats {#image-formats} SnapOtter supports 55+ image formats for input and 17 formats for output. ## Input Formats {#input-formats} ### Web Standards (9) {#web-standards-9} | Format | Extensions | Decoder | Notes | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (native) | | | PNG | .png | Sharp (native) | APNG first-frame extracted | | WebP | .webp | Sharp (native) | | | GIF | .gif | Sharp (native) | Animated supported | | AVIF | .avif | Sharp (native) | | | SVG | .svg | Sharp (librsvg) | Sanitized for XXE/SSRF | | SVGZ | .svgz | gunzip + Sharp | Gzip bomb protection | | APNG | .apng | Sharp (native) | First frame only | | JPEG XL | .jxl | djxl / ImageMagick | Two-tier fallback | ### Professional (7) {#professional-7} | Format | Extensions | Decoder | Notes | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (native) | Multi-page supported | | PSD | .psd | ImageMagick | Flattened composite | | EPS | .eps, .epsf | ImageMagick + Ghostscript | 300dpi rasterization, security hardened | | OpenEXR | .exr | ImageMagick | Linear-to-sRGB conversion | | Radiance HDR | .hdr | ImageMagick | Linear-to-sRGB conversion | | DPX | .dpx | ImageMagick | Log-to-sRGB conversion | | Cineon | .cin | ImageMagick | Film/VFX format | ### Camera RAW (23) {#camera-raw-23} | Format | Extensions | Camera Brand | Decoder | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (universal) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (pre-2018) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (legacy) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (compact) | exiftool / ImageMagick + LibRaw | ### Modern Formats (3) {#modern-formats-3} | Format | Extensions | Decoder | Notes | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Digital cinema, medical imaging | | QOI | .qoi | Inline TypeScript codec | Game dev, embedded systems | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | iPhone photos | ### Legacy/System (4) {#legacy-system-4} | Format | Extensions | Decoder | Notes | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | Largest layer extracted | | CUR | .cur | ImageMagick | Windows cursor (ICO variant) | | TGA | .tga | ImageMagick | Extension-only detection | ### Scientific and Gaming (2) {#scientific-and-gaming-2} | Format | Extensions | Decoder | Notes | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Astronomy (NASA standard) | | DDS | .dds | ImageMagick | Game textures (DirectX) | ### Interchange (6) {#interchange-6} | Format | Extensions | Decoder | Notes | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (native) | Color pixmap | | PGM | .pgm | Sharp (native) | Grayscale | | PBM | .pbm | Sharp (native) | 1-bit bitmap | | PNM | .pnm | Sharp (native) | Umbrella format | | PAM | .pam | Sharp (native) | Arbitrary map | | PFM | .pfm | Sharp (native) | Float map | ## Output Formats (17) {#output-formats-13} | Format | Encoder | Quality Control | Available In | |--------|---------|----------------|-------------| | JPEG | Sharp native | 1-100 | All tools | | PNG | Sharp native | Compression 0-9 | All tools | | WebP | Sharp native | 1-100 | All tools | | AVIF | Sharp native | 1-100 | All tools | | TIFF | Sharp native | 1-100 | Full conversion tools | | GIF | Sharp native | 1-100 | Full conversion tools | | JXL | Sharp native | 1-100 | All tools | | HEIC | heif-enc CLI | 1-100 | Full conversion tools | | HEIF | heif-enc CLI | 1-100 | Full conversion tools | | BMP | ImageMagick CLI | Lossless | Convert tool | | ICO | ImageMagick CLI | Lossless | Convert tool | | JP2 | opj\_compress CLI | Compression ratio | Convert tool | | QOI | Inline codec | Lossless | Convert tool | | PSD | ImageMagick CLI | Lossless | Convert tool | | PPM | ImageMagick CLI | Lossless | Convert tool | | EPS | ImageMagick CLI | Lossless | Convert tool | | TGA | ImageMagick CLI | Lossless | Convert tool | ## Video Formats {#video-formats} Video decoding and encoding are handled by FFmpeg (static build), so every common container and codec is supported on input. ### Input Containers (15) {#input-containers-15} | Format | Extensions | Typical codecs | Notes | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | Most widely used container | | QuickTime | .mov | H.264, ProRes | Apple capture/editing | | WebM | .webm | VP8, VP9, AV1 | Royalty-free web format | | Matroska | .mkv | Any | Flexible open container | | AVI | .avi | Various | Legacy Microsoft container | | M4V | .m4v | H.264 | Apple MP4 variant | | AVCHD | .mts | H.264 | Camcorder recordings | | BDAV | .m2ts | H.264 | Blu-ray / AVCHD transport stream | | 3GP | .3gp | H.264, MPEG-4 | Mobile capture | | Flash Video | .flv | H.264, VP6 | Legacy streaming | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | DVD-era video | | MPEG-TS | .ts | MPEG-2, H.264 | Broadcast transport stream | | Ogg | .ogv | Theora | Open Ogg video | ### Output Formats {#output-formats} | Format | Extension | Video codec | Produced by | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Convert, compress, and most video tools | | QuickTime | .mov | H.264 | Convert Video | | WebM | .webm | VP9 | Convert Video | | GIF | .gif | - | Video to GIF | | WebP | .webp | - | Video to WebP (animated) | ### Subtitles {#subtitles} | Format | Extension | Operations | |--------|-----------|-----------| | SubRip | .srt | Embed, burn-in, extract, auto-generate | | WebVTT | .vtt | Embed, burn-in, extract, auto-generate | | ASS / SSA | .ass | Embed, burn-in (supports styling) | ## Audio Formats {#audio-formats} Audio is also processed by FFmpeg. ### Input Formats (11) {#input-formats-11} | Format | Extensions | Compression | Notes | |--------|-----------|-------------|-------| | MP3 | .mp3 | Lossy | Universal compatibility | | WAV | .wav | Uncompressed (PCM) | Studio / editing | | FLAC | .flac | Lossless | Open lossless codec | | AAC | .aac | Lossy | Raw AAC stream | | M4A | .m4a | Lossy (AAC) / Lossless (ALAC) | MPEG-4 audio | | Ogg Vorbis | .ogg | Lossy | Open format | | Opus | .opus | Lossy | Modern, low-latency | | WMA | .wma | Lossy | Windows Media Audio | | AIFF | .aiff | Uncompressed (PCM) | Apple uncompressed | | AMR | .amr | Lossy | Speech / mobile | | AC-3 | .ac3 | Lossy | Dolby Digital | ### Output Formats {#output-formats-1} | Format | Extension | Codec | Produced by | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Convert Audio, Extract Audio | | WAV | .wav | PCM | Convert Audio, Extract Audio | | FLAC | .flac | FLAC (lossless) | Convert Audio | | Ogg | .ogg | Vorbis | Convert Audio | | M4A | .m4a | AAC | Convert Audio, Extract Audio | ## Document Formats {#document-formats} Document processing uses qpdf, LibreOffice, Ghostscript, Pandoc, and WeasyPrint. ### Input Formats (15) {#input-formats-15} | Format | Extensions | Engine | Notes | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Core document format | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Text, sheet, presentation | | Rich Text | .rtf | LibreOffice | Cross-app rich text | | Plain Text | .txt | LibreOffice, Pandoc | UTF-8 text | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | Rendered to PDF | | EPUB | .epub | Pandoc, LibreOffice | E-book format | ### Output Formats {#output-formats-2} | Format | Extensions | Produced by | |--------|-----------|-------------| | PDF | .pdf | Word/Excel/PowerPoint to PDF, Markdown to PDF, HTML to PDF | | PDF/A | .pdf | PDF/A Convert (archival) | | Word | .docx, .odt, .rtf, .txt | Convert Document, PDF to Word, Markdown to Word | | Presentation | .pptx, .odp | Convert Presentation | | Spreadsheet | .xlsx, .ods, .csv | Convert Spreadsheet | | HTML | .html | Markdown to HTML | | EPUB | .epub | Convert to EPUB | | Images | .png, .jpg | PDF to Image | ## File Formats {#file-formats} Data and archive tools convert between structured formats and bundle files. | Format | Extensions | Conversions | |--------|-----------|-------------| | CSV | .csv | To/from JSON and Excel; split and merge; from XML | | JSON | .json | To/from CSV, XML, and YAML | | XML | .xml | To/from JSON; to CSV | | YAML | .yaml, .yml | To/from JSON | | Excel | .xlsx | To/from CSV | | ZIP | .zip | Create archives, extract contents | --- --- url: https://docs.snapotter.com/guide/low-resource.md --- # Low-Resource Setups {#low-resource-setups} SnapOtter runs well on small hardware: a Raspberry Pi 4 or 5, an old laptop, or a 2 GB VPS. This page is the practical guide for those machines: what to expect, a copy-paste setup with sensible caps, and which features to skip. The full benchmark data behind these numbers lives in [Hardware Requirements](/guide/deployment#hardware-requirements). Two hard constraints up front: * **64-bit only.** The image is built for `linux/amd64` and `linux/arm64`. 32-bit ARM (`armv7`/`armhf`) is not supported, so first-generation Pis and the Pi Zero family are out. * **2 GB memory floor.** 512 MB cannot start the stack, and 1 GB fails on multi-file batches. 2 GB with 2 cores is the smallest configuration that works comfortably. ## What runs well on small hardware {#what-runs-well} Every non-AI tool works on a 2 GB / 2-core machine: the whole Image and Files sections, PDF tools, and the stream-copy video and audio operations (trim, mute, container remux). Most finish in under a second. Two workloads are the exceptions: * **Video re-encoding** (converting between codecs) is CPU-bound. A 1080p clip that takes ~40 s on a fast desktop CPU can take several minutes on a Pi-class CPU. Stream-copy operations stay instant. * **AI tools** need RAM (4 GB recommended) and disk (the larger bundles are 4-5 GB each), and the heavy ones (upscaling, photo restoration, background removal) are not practical on Pi-class CPUs. Light AI such as face detection and OCR is usable if you have the memory for it. Neither is installed or running unless you use it: with no AI bundles installed the app idles around 360 MB, and AI bundles only download when an admin enables them. ## Raspberry Pi / old laptop walkthrough {#walkthrough} This is the standard Compose install from [Getting Started](/guide/getting-started), plus resource limits and conservative caps. It assumes a 64-bit OS (on a Pi: Raspberry Pi OS 64-bit or Ubuntu Server arm64). ```yaml services: snapotter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - ./snapotter-data:/data environment: - DATABASE_URL=postgres://snapotter:snapotter@db:5432/snapotter - REDIS_URL=redis://redis:6379 # Small-box profile: see the table below for what each cap does. - CONCURRENT_JOBS=1 - MAX_WORKER_THREADS=2 - MAX_BATCH_SIZE=5 - MAX_UPLOAD_SIZE_MB=100 - MAX_MEGAPIXELS=50 - MAX_VIDEO_DURATION_S=300 deploy: resources: limits: cpus: "2" memory: 2G depends_on: - db - redis restart: unless-stopped db: image: postgres:17-alpine environment: - POSTGRES_USER=snapotter - POSTGRES_PASSWORD=snapotter # Change this for non-local deployments - POSTGRES_DB=snapotter volumes: - ./postgres-data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:8-alpine command: redis-server --maxmemory 256mb --maxmemory-policy noeviction restart: unless-stopped ``` Notes for Pi-class machines: * **Prefer a USB SSD over an SD card** for the data volume and Postgres. Job workspaces do real disk IO, and SD cards are both slow and quick to wear out. * **The all-in-one single container also works here** (embedded Postgres and Redis when `DATABASE_URL`/`REDIS_URL` are unset), and on a memory-constrained host you should lower its embedded Redis cap with `REDIS_MAXMEMORY` (see [Configuration](/guide/configuration)). Compose gives you finer per-service control, which is why this walkthrough uses it. * **Add swap on 2 GB devices.** It keeps the occasional spike (a large PDF, a batch you forgot to cap) from ending in an out-of-memory kill. zram is the SD-card-friendly option. * The arm64 image is CPU-only; there is no CUDA on ARM boards. ## The tuning knobs {#tuning-knobs} All caps are environment variables, documented fully in [Configuration](/guide/configuration). `0` means unlimited or auto. The ones that matter on small hardware: | Variable | Small-box suggestion | What it protects | |---|---|---| | `CONCURRENT_JOBS` | `1` | How many jobs run in parallel. Auto-detect uses CPU cores minus one, which is fine on big machines and too eager on a 2-core box under memory pressure. | | `MAX_WORKER_THREADS` | `2` | Image-processing thread pool. | | `MAX_BATCH_SIZE` | `5` | Batches are where 1-2 GB machines run out of memory first. | | `MAX_UPLOAD_SIZE_MB` | `100` | Keeps a single huge file from occupying the whole workspace. | | `MAX_MEGAPIXELS` | `50` | Decoding a 100+ MP image costs RAM regardless of file size. | | `MAX_VIDEO_DURATION_S` | `300` | Long transcodes monopolize a small CPU for minutes to hours. | | `PROCESSING_TIMEOUT_S` | `600` | Hard ceiling so a runaway job frees the box eventually. | These caps apply to what the server accepts, so set them to match what you actually use rather than as small as possible. If you never touch video, a `MAX_VIDEO_DURATION_S` cap costs nothing; if you scan documents daily, do not cap `MAX_PDF_PAGES`. ## What to skip {#what-to-skip} * **Heavy AI bundles.** Upscaling, photo restoration, and background removal want a GPU or a fast many-core CPU, and each bundle costs 4-5 GB of disk. On a small box, simply do not install them; tools whose bundle is missing show an install prompt instead of running. * **Video re-encoding as a routine workload.** Occasional transcodes are fine (they are just slow); a steady transcode queue wants CPU cores, not a Pi. * **Unused tools generally.** An admin can turn off individual tools in Settings, which removes them from the UI and stops registering their API routes. That does not save memory by itself, but it keeps a shared small instance from being used for the one workload the hardware cannot take. If you later move the instance to bigger hardware, remove the caps (set them back to `0`) and the same data volume carries over. --- --- url: https://docs.snapotter.com/guide/docker-tags.md description: >- SnapOtter Docker image tags, GPU benchmarks, version pinning, and multi-platform support for AMD64 and ARM64. --- # Docker Image {#docker-image} SnapOtter ships as a single Docker image. Run it on its own and it starts an embedded PostgreSQL 17 and Redis on the loopback interface (embedded mode); for production, run it alongside separate PostgreSQL 17 and Redis 8 containers with Compose. The app image works on all platforms. ## Quick start {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` With no `DATABASE_URL` set, this runs in embedded mode: PostgreSQL and Redis start inside the container on loopback, with all data under the `SnapOtter-data` volume. Set `DATABASE_URL` and `REDIS_URL` (as the [Compose](#docker-compose) stack does) to use external services instead. See [Configuration](/guide/configuration#embedded-mode). ## NVIDIA CUDA acceleration {#nvidia-cuda-acceleration} The image includes NVIDIA CUDA support on amd64. If you have an NVIDIA GPU with the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) installed, add `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` The image auto-detects CUDA at runtime. Without `--gpus all`, or when CUDA is unavailable, AI tools run on CPU. Same image either way. Intel/AMD iGPU acceleration through VA-API, Quick Sync, or OpenCL is not supported for SnapOtter AI inference today. Mapping `/dev/dri` into the container can expose the render device, but the AI runtime will still use CPU unless CUDA is available. ### Benchmarks {#benchmarks} Tested on an NVIDIA RTX 4070 (12 GB VRAM) with a 572x1024 JPEG portrait. #### Warm performance {#warm-performance} | Tool | CPU | GPU | Speedup | |------|-----|-----|---------| | Background removal (u2net) | 2,415ms | 879ms | 2.7x | | Background removal (isnet) | 2,457ms | 1,137ms | 2.2x | | Upscale 2x | 350ms | 309ms | 1.1x | | Upscale 4x | 910ms | 310ms | 2.9x | | Face blur | 139ms | 122ms | 1.1x | #### Cold start (first request after container start) {#cold-start-first-request-after-container-start} | Tool | CPU | GPU | Speedup | |------|-----|-----|---------| | Background removal | 22,286ms | 4,792ms | 4.7x | | Upscale 2x | 3,957ms | 2,318ms | 1.7x | OCR is not included in the CUDA comparison. Both the built-in Tesseract tier and the optional RapidOCR/ONNX tiers use CPU, including when the container has NVIDIA GPU access. ### CUDA health check {#cuda-health-check} After the first AI request, the admin health endpoint reports CUDA GPU status: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} The full Compose stack includes the app, PostgreSQL 17, and Redis 8. See [Deployment](/guide/deployment) for the complete `docker-compose.yml`. A minimal example: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` For NVIDIA CUDA acceleration via Docker Compose, add the deploy section to the SnapOtter service: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Version pinning {#version-pinning} | Tag | Description | |-----|------------| | `latest` | Latest release | | `2.2.0` | Exact version | | `2.2` | Latest patch in 2.2.x | | `2` | Latest minor in 2.x | ## Platforms {#platforms} | Architecture | GPU support | Notes | |---|---|---| | linux/amd64 | NVIDIA CUDA | Full CUDA acceleration for AI tools | | linux/arm64 | CPU only | Raspberry Pi 4/5, Apple Silicon via Docker Desktop | ## Migration from previous tags {#migration-from-previous-tags} If you were using the `:cuda` tag, switch to `:latest` and keep `--gpus all`. Same GPU support, unified image. Your data and settings are preserved in the volumes. --- --- url: https://docs.snapotter.com/guide/developer.md description: >- Local development setup, commands, code conventions, and how to add a new tool to SnapOtter. --- # Developer guide {#developer-guide} How to set up a local development environment and contribute code to SnapOtter. ## Prerequisites {#prerequisites} * [Node.js](https://nodejs.org/) 22.22+ * [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`) * [Docker](https://www.docker.com/) (required for local Postgres + Redis, container builds, and AI features) * Git Python 3.11+ is only needed if you are working on the AI/ML sidecar (background removal, upscaling, OCR). ## Setup {#setup} ```bash git clone https://github.com/snapotter-hq/snapotter.git cd snapotter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` This starts two dev servers: | Service | URL | Notes | |----------|--------------------------|------------------------------------| | Frontend | http://localhost:1351 | Vite dev server, proxies /api | | Backend | http://localhost:13490 | Fastify API (accessed via proxy) | Open http://localhost:1351 in your browser. Login with `admin` / `admin`. You will be prompted to change the password on first login. ## Project structure {#project-structure} ``` apps/ api/ Fastify backend web/ Vite + React frontend docs/ VitePress documentation (this site) packages/ shared/ Constants, types, i18n strings image-engine/ Sharp-based image operations media-engine/ FFmpeg spawn + progress parsing doc-engine/ qpdf, LibreOffice, ghostscript wrappers ai/ Python sidecar bridge for ML models tests/ unit/ Vitest unit tests integration/ Vitest integration tests (full API) e2e/ Playwright end-to-end specs fixtures/ Small test images ``` ## Commands {#commands} ```bash pnpm dev # start frontend + backend pnpm build # build all workspaces pnpm typecheck # TypeScript check across monorepo pnpm lint # Biome lint + format check pnpm lint:fix # auto-fix lint + format pnpm test # unit + integration tests pnpm test:unit # unit tests only pnpm test:integration # integration tests only pnpm test:e2e # Playwright e2e tests pnpm test:coverage # tests with coverage report ``` ## Code conventions {#code-conventions} * Double quotes, semicolons, 2-space indentation (enforced by Biome) * ES modules in all workspaces * [Conventional commits](https://www.conventionalcommits.org/) for semantic-release * Zod for all API input validation * No modifications to Biome, TypeScript, or editor config files. Fix the code, not the linter. ## Database {#database} PostgreSQL 17 via Drizzle ORM (pg-core). Local dev requires Postgres and Redis running - start them with: ```bash docker compose -f docker-compose.dev.yml up -d ``` This gives you Postgres on port 5432 and Redis on port 6379. Then generate and apply migrations: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Schema is defined in `apps/api/src/db/schema.ts`. Tables: users, sessions, settings, jobs, apiKeys, pipelines, teams, userFiles, roles, auditLog. ## Adding a new tool {#adding-a-new-tool} Every tool follows the same pattern. Here is a minimal example. ### 1. Backend route {#\_1-backend-route} Create `apps/api/src/routes/tools/my-tool.ts`: ```ts import { z } from "zod"; import type { FastifyInstance } from "fastify"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ intensity: z.number().min(0).max(100).default(50), }); export function registerMyTool(app: FastifyInstance) { createToolRoute(app, { toolId: "my-tool", settingsSchema, async process(inputBuffer, settings, filename) { // Use sharp or other libraries to process the image const sharp = (await import("sharp")).default; const result = await sharp(inputBuffer) // ... your processing logic .toBuffer(); return { buffer: result, filename: filename.replace(/\.[^.]+$/, ".png"), contentType: "image/png", }; }, }); } ``` Then register it in `apps/api/src/routes/tools/index.ts`. ### 2. Frontend settings component {#\_2-frontend-settings-component} Create `apps/web/src/components/tools/my-tool-settings.tsx`: ```tsx import { useState } from "react"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; export function MyToolSettings() { const { files } = useFileStore(); const { processFiles, processing, error, downloadUrl } = useToolProcessor("my-tool"); const [intensity, setIntensity] = useState(50); const handleProcess = () => { processFiles(files, { intensity }); }; return (
{/* your controls here */}
); } ``` Then register it in the frontend tool registry at `apps/web/src/lib/tool-registry.tsx`: ```tsx // Add the lazy import const MyToolSettings = lazy(() => import("@/components/tools/my-tool-settings").then((m) => ({ default: m.MyToolSettings, })), ); // Add to the toolRegistry Map ["my-tool", { displayMode: "before-after", Settings: MyToolSettings }], ``` Display modes: `"side-by-side"`, `"before-after"`, `"live-preview"`, `"no-comparison"`, `"interactive-crop"`, `"interactive-eraser"`, `"no-dropzone"`. ### 3. i18n entry {#\_3-i18n-entry} Add to `packages/shared/src/i18n/en.ts`: ```ts "my-tool": { name: "My Tool", description: "Short description of what this tool does", }, ``` ### 4. Tests {#\_4-tests} Add a `data-testid` attribute to your action button (as shown above) so e2e tests can target it reliably. ## Docker builds {#docker-builds} Build the full production image locally: ```bash docker build -f docker/Dockerfile -t snapotter:latest . ``` Use BuildKit cache mounts for faster rebuilds: ```bash DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest . ``` ## Release version domains {#release-version-domains} SnapOtter intentionally has three version domains. Do not copy one domain into another during a release: * The application release version covers the root manifest, all private workspace packages and `APP_VERSION`. Semantic-release supplies this value, and `pnpm version:sync ` updates every workspace before an application release. * OpenAPI `info.version` is the stable public API-major contract. All localized specifications stay on `.0.0` for compatible application releases and change only when the API contract moves to a new major version. * `docker/feature-manifest.json` keeps `imageVersion: 2.0.0` as the immutable legacy feature-bundle storage epoch. Those v2 archive paths are not application package versions. Accurate OCR uses runtime format v3 and records its application release provenance separately. `tests/unit/infra/release-version-policy.test.ts` enforces these boundaries. A new version domain or migration must update that contract and the relevant artifact migration design together. The independent API and legacy-bundle values live in `config/release-version-policy.json`; application version synchronization must never rewrite that policy file implicitly. ## Environment variables {#environment-variables} See the [Configuration guide](/guide/configuration) for the full list. Key ones for development: | Variable | Default | Description | |-----------------------------|-----------|------------------------------------------------| | `AUTH_ENABLED` | `true` | Enable/disable authentication | | `DEFAULT_USERNAME` | `admin` | Default admin username | | `DEFAULT_PASSWORD` | `admin` | Default admin password | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Skip forced password change (CI/dev only) | | `RATE_LIMIT_PER_MIN` | `1000` | API rate limit per minute (0 = disabled) | | `MAX_UPLOAD_SIZE_MB` | `100` | Maximum upload size in MB (0 = unlimited) | --- --- url: https://docs.snapotter.com/guide/translations.md description: >- 21 supported languages and how to create or improve translations for SnapOtter using the TypeScript-enforced i18n system. --- # Translation guide {#translation-guide} SnapOtter ships with 21 languages out of the box. The i18n system uses a lightweight custom runtime with TypeScript-enforced locale completeness and dynamic code-splitting. ## Supported languages {#supported-languages} | Code | Language | Native Name | Direction | |------|----------|-------------|-----------| | `en` | English | English | LTR | | `zh-CN` | Chinese (Simplified) | 简体中文 | LTR | | `zh-TW` | Chinese (Traditional) | 繁體中文 | LTR | | `ja` | Japanese | 日本語 | LTR | | `ko` | Korean | 한국어 | LTR | | `es` | Spanish | Español | LTR | | `fr` | French | Français | LTR | | `it` | Italian | Italiano | LTR | | `pt-BR` | Portuguese (Brazil) | Português (Brasil) | LTR | | `de` | German | Deutsch | LTR | | `nl` | Dutch | Nederlands | LTR | | `sv` | Swedish | Svenska | LTR | | `ru` | Russian | Русский | LTR | | `pl` | Polish | Polski | LTR | | `uk` | Ukrainian | Українська | LTR | | `ar` | Arabic | العربية | RTL | | `tr` | Turkish | Türkçe | LTR | | `hi` | Hindi | हिन्दी | LTR | | `vi` | Vietnamese | Tiếng Việt | LTR | | `id` | Indonesian | Bahasa Indonesia | LTR | | `th` | Thai | ไทย | LTR | ## How language detection works {#how-language-detection-works} SnapOtter uses a three-tier resolution order: 1. **User preference** - stored in `localStorage("snapotter-locale")` and synced to user settings when authenticated 2. **Browser auto-detect** - walks the `navigator.languages` array with BCP 47 prefix matching 3. **Instance default** - the admin's `DEFAULT_LOCALE` env var (fetched from `GET /api/v1/config/locale`) 4. **English fallback** - always available Users can change language from: * The **footer Globe selector** (desktop, always visible) * The **login page** language selector (pre-auth) * The **Settings > General** section (per-user preference) * The **mobile sidebar** language dropdown * The **Settings > System** section sets the instance-wide default (admin only) ## How translations work {#how-translations-work} All UI strings live in `packages/shared/src/i18n/`. The reference file is `en.ts`, which exports a typed object with every string the app uses (~1500 keys). Other languages are separate files (e.g., `de.ts`, `fr.ts`) that export the same shape. The `TranslationKeys` type uses `DeepStringRecord` to accept any string value while enforcing the key structure. TypeScript catches missing keys in any translation file at compile time. Only the active locale is loaded at runtime via dynamic `import()`, keeping the main bundle small. ## Using translations in components {#using-translations-in-components} ```tsx import { useTranslation } from "@/contexts/i18n-context"; import { format, plural } from "@/lib/format"; function MyComponent() { const { t, locale, setLocale } = useTranslation(); return (

{t.common.settings}

{format(t.settings.people.deleteConfirm, { username: "admin" })}

{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}

); } ``` ## Contributing a translation {#contributing-a-translation} We welcome translation PRs directly. You can improve an existing locale or add a new one. To report a mistranslation without submitting code, open a [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) with the language, the incorrect string, and the suggested fix. ::: tip Translation PRs do not require prior approval. Fork the repo, make your changes, and open a PR. See the [Contributing Guide](/guide/contributing) for the full PR process and CLA requirement. ::: ## How to create or update a translation {#how-to-create-or-update-a-translation} ### 1. Fork and clone {#\_1-fork-and-clone} ```bash git clone https://github.com//snapotter.git cd snapotter pnpm install ``` ### 2. Copy the reference file (new language only) {#\_2-copy-the-reference-file-new-language-only} Skip this step if you are improving an existing translation. ```bash cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts ``` ### 3. Translate the strings {#\_3-translate-the-strings} Open your new file and translate every string value. Keep the object structure and keys exactly the same. ```ts import type { TranslationKeys } from "./en.js"; export const xx: TranslationKeys = { common: { upload: "Your translation here", // ... translate all entries }, // ... translate all sections } as const; ``` Rules: * Do not translate object keys, only string values * Keep `as const` at the end * Import `TranslationKeys` from `./en.js` and type your export * Keep `{variable}` placeholders exactly as-is * Arrays (`rotatingPhrases`, `progressMessages`) must have the same number of entries * Do not translate: SnapOtter, JPEG, PNG, WebP, EXIF, API, and other technical terms ### 4. Register the locale (new language only) {#\_4-register-the-locale-new-language-only} Add your locale to `SUPPORTED_LOCALES` in `packages/shared/src/i18n/index.ts`: ```ts { code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" }, ``` ### 5. Verify {#\_5-verify} ```bash pnpm typecheck # catches missing or mistyped keys pnpm lint # formatting check pnpm dev # manually verify strings appear correctly ``` ### 6. Submit {#\_6-submit} Open a PR against `main` with a title like `feat(i18n): add Swedish translation` or `fix(i18n): correct German typos`. The CLA bot will ask you to sign on your first contribution. ## Adding new translation keys {#adding-new-translation-keys} When adding a new feature that needs new UI strings: 1. Add the new keys to `en.ts` first (the reference file) 2. Run `pnpm typecheck` - every locale file will fail if missing the new key 3. Add the new key to all locale files (use English as a temporary fallback) ## Configuration {#configuration} Set the instance default language via environment variable: ```yaml DEFAULT_LOCALE: "de" # German as the default for all new users ``` ## File reference {#file-reference} | File | Purpose | |------|---------| | `packages/shared/src/i18n/en.ts` | English strings (reference locale, ~1500 keys) | | `packages/shared/src/i18n/index.ts` | `SUPPORTED_LOCALES`, `loadTranslations()`, type exports | | `packages/shared/src/i18n/.ts` | Per-language translation files | | `apps/web/src/contexts/i18n-context.tsx` | `I18nProvider`, `useTranslation()` hook | | `apps/web/src/lib/format.ts` | `format()`, `plural()`, `formatFileSize()` helpers | | `apps/api/src/routes/config.ts` | `GET /api/v1/config/locale` public endpoint | ## Translating the website, docs, and API reference {#translating-the-web-surfaces} The 21-language support above covers the **app**. The public website (snapotter.com), this documentation site, and the REST API reference are also translated into all 21 languages, by a separate hash-gated pipeline that reuses the same tool names and descriptions from `packages/shared/src/i18n`, so terminology stays consistent everywhere. ### Machine-translated by default {#machine-translated-by-default} Every non-English page on the website and docs is **machine-translated** on the first pass (by a Claude Code session, not a third-party service) and carries a small, dismissible banner saying so, with a link back here. That is deliberate: it ships all 21 languages quickly and honestly, then invites the community to refine the pages that matter most. Machine translation gets the meaning across; human review makes it read naturally. ### How the pipeline decides what to translate {#how-the-web-pipeline-decides} Each translatable unit of English source is hashed, and the hash is stored next to its translation. On each run the pipeline: * translates any unit that has no translation yet, * skips any unit whose stored hash still matches the English source, * re-translates a **machine** unit when its English source changes, * and flags a **human**-refined unit as `stale` (needs review) when its English source changes, instead of overwriting your work. ### Refining a web translation by PR {#refining-a-web-translation-by-pr} You improve a website, docs, or API-reference translation the same way you improve an app locale: by editing the generated file and opening a PR. 1. Find the generated translation for your language: * website UI strings: `apps/landing/src/i18n/.json` * a docs page: `apps/docs//**.md` * the API reference: `apps/api/src/openapi..yaml` 2. Edit the text. Keep code, links, `{placeholders}`, and any `⸤I18N…⸥` markers exactly as they are; the pipeline's validator rejects a translation that drops or reorders them. 3. Open a PR. Editing a unit flips its provenance from `machine` to `human`, so the pipeline will **never overwrite it** on a later run. If the English source changes afterwards, your unit is flagged `stale` for review rather than silently replaced. To report a mistranslation without submitting code, open a [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) with the page URL, the language, the incorrect text, and your suggested fix. ::: tip Maintainers run the translation pipeline; you do not need an API key to contribute. Just edit the generated file and open a PR. See [`scripts/i18n/README.md`](https://github.com/snapotter-hq/SnapOtter/blob/main/scripts/i18n/README.md) for how the pipeline runs. ::: --- --- url: https://docs.snapotter.com/guide/contributing.md description: >- How to contribute to SnapOtter. Bug reports, feature requests, pull requests, and CLA requirements. --- # Contributing {#contributing} Thanks for your interest in contributing. This guide covers how to participate, what we accept, and how to get started. ## Ways to contribute {#ways-to-contribute} ### Issues (no setup required) {#issues-no-setup-required} * **Bug reports** - Something broken? Open a [bug report](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) with reproduction steps. * **Feature requests** - Have an idea? Start a [discussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) so the community can weigh in and upvote it. * **Translation issues** - Spot a wrong or missing translation? Open a [translation issue](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Documentation issues** - Something off in the docs? Open a [documentation issue](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Code (requires CLA) {#code-requires-cla} We accept pull requests for: | Type | Process | |------|---------| | Bug fixes | Open a PR directly (link the issue if one exists) | | New translations | Open a PR directly (see [Translation Guide](/guide/translations)) | | Documentation improvements | Open a PR directly | | Test coverage improvements | Open a PR directly | | New tools or features | Start a [discussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) first; a maintainer converts approved ideas into a tracked issue before you write code | | Refactors or architecture changes | Start a [discussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) first and wait for maintainer sign-off before writing code | ### What we will not accept {#what-we-will-not-accept} * Changes to CI/CD workflows, release config, or linter/compiler config * PRs without a signed [Contributor License Agreement](#contributor-license-agreement) * PRs over 400 lines of change (break large work into smaller PRs) * Features that were not discussed and approved first * Changes to `packages/ai/` without prior discussion ## Contributor License Agreement {#contributor-license-agreement} Before we can merge your first PR, you must sign our [Individual CLA](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md). This is a one-time requirement. **Why:** SnapOtter is dual-licensed (AGPLv3 + commercial). The CLA grants us the right to distribute your contributions under both licenses. You retain full copyright ownership of your work. **How:** When you open your first PR, the CLA Assistant bot will comment with a link. Click it, review the agreement, and sign with your GitHub account. Takes 30 seconds. If you are contributing on behalf of your employer and your employer retains IP rights over your work, contact contact@snapotter.com to arrange a Corporate CLA before submitting. ## Getting started {#getting-started} ### Prerequisites {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (only for AI tools) * Docker (optional, for full integration testing) ### Setup {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Running checks {#running-checks} Before submitting a PR, ensure all checks pass locally: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Pull request process {#pull-request-process} 1. Fork the repo and create a branch from `main` (`feat/my-feature` or `fix/issue-123`) 2. Make your changes in focused, reviewable commits using [conventional commits](https://www.conventionalcommits.org/) 3. Add or update tests for your changes 4. Run `pnpm lint && pnpm typecheck && pnpm test` locally 5. Open a PR against `main` and fill out the template 6. Sign the CLA if prompted 7. Wait for CI to pass and a maintainer to review ### Review expectations {#review-expectations} * We aim to respond to PRs within 7 days * Small, focused PRs get reviewed faster * If you have not heard back in 7 days, leave a comment pinging the thread * We may request changes, suggest a different approach, or close the PR if it does not align with project direction ### After your PR is merged {#after-your-pr-is-merged} Your contribution will be included in the next release and credited in the changelog. ## Good first issues {#good-first-issues} Looking for something to work on? Check our [good first issues](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) for beginner-friendly tasks, or [help wanted](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) for larger items where we'd appreciate community help. ## Code style {#code-style} * Biome handles formatting and linting (double quotes, semicolons, 2-space indent) * Pre-commit hook runs `biome check --write` on staged files automatically * If the linter complains, fix the code (do not modify Biome config) * ES modules everywhere (`import`/`export`) * Conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` For full architecture details, see the [Developer Guide](/guide/developer). ## Security {#security} **Do not open a public PR or issue for security vulnerabilities.** Report them privately through [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) or email contact@snapotter.com. See [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) for full details. ## Questions? {#questions} * [Documentation](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/tools/conversion-presets.md description: >- Dedicated conversion preset endpoints generated from the SnapOtter tool catalog. --- # Conversion Presets {#conversion-presets} SnapOtter exposes 83 dedicated conversion preset endpoints in addition to the base converter tools. Each preset locks the output format and delegates to its base processing pipeline, so the behavior, validation, and output contract match the base tool listed below. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Send `multipart/form-data` with a `file` part and optional `settings` JSON string. Presets follow the response contract of the base tool. Fast presets usually return `200` with a `downloadUrl`, but can return `202` if they exceed the synchronous wait window. Video presets and long file/document presets return `202` and progress streams from `/api/v1/jobs//progress`. PDF-to-image presets return page download URLs plus a ZIP URL. ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG to PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG to JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG to WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG to WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP to JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP to PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG to AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG to AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP to AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC to JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC to PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC to AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG to GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG to GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF to JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF to PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP to GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG to TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG to TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF to JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF to PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD to JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD to PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG to EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG to EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS to PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS to JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG to SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG to SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF to SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD to SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS to SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG to PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG to JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG to PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG to PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC to PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF to PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP to PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF to PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS to PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV to MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM to MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV to MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI to MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 to MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 to WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM to MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV to MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI to MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 to AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV to AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV to AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI to MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 to GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV to GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV to GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI to GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF to MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF to WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF to MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 to MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV to MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV to MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM to MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI to MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 to WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV to WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 to OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A to MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A to WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC to MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC to WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC to FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG to MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG to WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV to MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 to WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC to MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF to JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF to PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF to TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel to CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * Presets are first-class API endpoints and are also valid in batch requests where their base route supports batch processing. * Presets that use video conversion can return `202 Accepted`; connect to the job progress SSE endpoint before downloading the result. * For advanced options not exposed by a preset, call the base converter tool directly and set the output format in `settings`. --- --- url: https://docs.snapotter.com/tools/image/resize.md description: Resize images by pixels, percentage, or with fit modes. --- # Resize Image {#resize} Resize images by specifying exact pixel dimensions, a percentage scale factor, or a fit mode that controls how the image adapts to the target dimensions. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/resize` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | - | Target width in pixels (max 16383) | | height | integer | No | - | Target height in pixels (max 16383) | | fit | string | No | `"contain"` | How the image fits the dimensions: `contain`, `cover`, `fill`, `inside`, `outside` | | withoutEnlargement | boolean | No | `false` | Prevent upscaling if image is smaller than target | | percentage | number | No | - | Scale by percentage (e.g. 50 for half size) | At least one of `width`, `height`, or `percentage` must be provided. ### Fit Modes {#fit-modes} * **contain** - Resize to fit within the dimensions, preserving aspect ratio (may leave empty space) * **cover** - Resize to cover the dimensions, preserving aspect ratio (may crop) * **fill** - Stretch to exactly match dimensions (ignores aspect ratio) * **inside** - Like `contain`, but only downscales, never upscales * **outside** - Like `cover`, but only downscales, never upscales ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"width": 800, "height": 600, "fit": "contain"}' ``` Resize by percentage: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"percentage": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 980000 } ``` ## Notes {#notes} * Maximum dimension is 16383 pixels on either axis (Sharp/libvips limit). * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. * EXIF orientation is auto-applied before resizing. * The `withoutEnlargement` flag is useful for batch processing where some images may already be smaller than the target. --- --- url: https://docs.snapotter.com/tools/image/crop.md description: Crop images by specifying a region with position and dimensions. --- # Crop Image {#crop} Crop images by defining a rectangular region using position and size. Supports both pixel and percentage units. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/crop` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | left | number | Yes | - | X offset of the crop region (from left edge) | | top | number | Yes | - | Y offset of the crop region (from top edge) | | width | number | Yes | - | Width of the crop region | | height | number | Yes | - | Height of the crop region | | unit | string | No | `"px"` | Unit for the values: `px` or `percent` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 100, "top": 50, "width": 800, "height": 600}' ``` Crop using percentage values: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 10, "top": 10, "width": 80, "height": 80, "unit": "percent"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1200000 } ``` ## Notes {#notes} * The crop region must fit within the image boundaries. If the region extends beyond the image, the request will fail. * When using `percent` unit, values represent percentages of the image dimensions (e.g. `left: 10` means 10% from the left edge). * Output format matches the input format. * EXIF orientation is auto-applied before cropping, so coordinates correspond to the visually correct orientation. --- --- url: https://docs.snapotter.com/tools/image/rotate.md description: Rotate images by any angle and flip horizontally or vertically. --- # Rotate & Flip Image {#rotate-flip} Rotate images by an arbitrary angle and/or flip them horizontally or vertically. Rotation and flip operations can be combined in a single request. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/rotate` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | angle | number | No | `0` | Rotation angle in degrees (clockwise). Accepts any numeric value. | | horizontal | boolean | No | `false` | Flip the image horizontally (mirror) | | vertical | boolean | No | `false` | Flip the image vertically | ## Example Request {#example-request} Rotate 90 degrees clockwise: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 90}' ``` Flip horizontally: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"horizontal": true}' ``` Rotate and flip together: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 45, "vertical": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Notes {#notes} * Rotation is applied first, then flip operations. * Non-90-degree rotations (e.g. 45 degrees) will enlarge the canvas to fit the rotated image, with transparent or black fill depending on the output format. * Common values: 90, 180, 270 for quarter-turn rotations. * EXIF orientation is auto-applied before processing, so the rotation is relative to the visual orientation. --- --- url: https://docs.snapotter.com/tools/image/convert.md description: >- Convert images between formats including modern formats like AVIF, JXL, and HEIC. --- # Convert Image {#convert} Convert images between formats. Supports common web formats as well as specialized formats like HEIC, JXL, BMP, ICO, JP2, QOI, and PSD. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/convert` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Target format: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | No | - | Output quality (1-100). Applies to lossy formats like jpg, webp, avif, heic. | ## Supported Output Formats {#supported-output-formats} | Format | Type | Notes | |--------|------|-------| | jpg | Lossy | JPEG, best compatibility | | png | Lossless | Supports transparency | | webp | Both | Modern web format, good compression | | avif | Lossy | Next-gen format, excellent compression | | tiff | Both | Print/publishing workflows | | gif | Lossless | Limited to 256 colors | | heic / heif | Lossy | Apple ecosystem format | | jxl | Both | JPEG XL, next-gen format | | bmp | Lossless | Uncompressed bitmap | | ico | Lossless | Windows icon format | | jp2 | Lossy | JPEG 2000 | | qoi | Lossless | Quite OK Image format | | psd | Layered | Adobe Photoshop (requires ImageMagick) | | ppm | Lossless | Portable Pixmap (PPM/PGM/PBM) | | eps | Vector | Encapsulated PostScript | | tga | Lossless | Targa image format | ## Example Request {#example-request} Convert to WebP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` Convert to PNG (lossless): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Notes {#notes} * The output filename extension is automatically updated to match the target format. * SVG inputs are rasterized at 300 DPI before conversion. * PSD conversion requires ImageMagick to be installed on the server. * BMP, EPS, ICO, JP2, JXL, PPM, QOI, and TGA use specialized CLI encoders and bypass Sharp processing. * HEIC/HEIF encoding uses the system HEIC encoder library. * Input formats are broad: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, etc.), PSD, SVG, BMP, and more. --- --- url: https://docs.snapotter.com/tools/image/compress.md description: Reduce image file size by quality level or to a target file size. --- # Compress Image {#compress} Reduce image file size by specifying a quality level or a target file size in kilobytes. The tool uses iterative binary search to hit size targets accurately. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compress` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Compression mode: `quality` or `targetSize` | | quality | number | No | `80` | Quality level (1-100). Used when mode is `quality`. | | targetSizeKb | number | No | - | Target file size in kilobytes. Used when mode is `targetSize`. | ## Example Request {#example-request} Compress to quality 60: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Compress to target size of 200 KB: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Notes {#notes} * In `quality` mode, lower values produce smaller files with more compression artifacts. A value of 80 is a good default for web use. * In `targetSize` mode, the engine performs iterative compression to get as close to the target as possible without exceeding it. * Output format matches the input format. The compression applies to the format's native encoding (e.g. JPEG quality for JPEG files, WebP quality for WebP files). * If the default quality (80) is acceptable, you can omit the `quality` parameter entirely. --- --- url: https://docs.snapotter.com/tools/image/optimize-for-web.md description: >- Optimize images for web delivery with format conversion, quality control, resizing, and metadata stripping. --- # Optimize for Web {#optimize-for-web} Optimize images for web delivery in a single step. Combines format conversion, quality adjustment, optional resizing, progressive encoding, and metadata stripping. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/optimize-for-web` Accepts multipart form data with an image file and a JSON `settings` field. A live preview endpoint is also available at `POST /api/v1/tools/image/optimize-for-web/preview`, which returns the processed image directly as binary (no workspace creation) for real-time parameter tuning. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"webp"` | Output format: `webp`, `jpeg`, `avif`, `png`, `jxl` | | quality | number | No | `80` | Output quality (1-100) | | maxWidth | number | No | - | Maximum width in pixels. Image is downscaled if wider. | | maxHeight | number | No | - | Maximum height in pixels. Image is downscaled if taller. | | progressive | boolean | No | `true` | Enable progressive/interlaced encoding | | stripMetadata | boolean | No | `true` | Remove EXIF, GPS, ICC, and XMP metadata | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/optimize-for-web \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 75, "maxWidth": 1920}' ``` Optimize for AVIF with aggressive compression: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/optimize-for-web \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "avif", "quality": 50, "maxWidth": 1200, "maxHeight": 800}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 4500000, "processedSize": 320000 } ``` ### Preview Endpoint Response {#preview-endpoint-response} The preview endpoint (`/api/v1/tools/image/optimize-for-web/preview`) returns the binary image directly with informational headers: * `X-Original-Size` - Original file size in bytes * `X-Processed-Size` - Processed file size in bytes * `X-Output-Filename` - URL-encoded output filename ## Notes {#notes} * This tool is designed as a one-stop optimization pipeline for web assets. It handles format conversion, quality tuning, max dimension capping, and metadata removal in a single pass. * The output filename extension is updated to match the chosen format. * JXL (JPEG XL) encoding uses a specialized CLI encoder. The image is first processed as PNG, then encoded to JXL. * Progressive encoding improves perceived load time for JPEG and PNG by allowing browsers to render a low-quality preview before the full image loads. * The preview endpoint is lighter weight (no workspace/job creation) and is intended for the frontend's live parameter tuning UI. --- --- url: https://docs.snapotter.com/tools/image/strip-metadata.md description: >- Remove EXIF, GPS, ICC, and XMP metadata from images for privacy and smaller file sizes. --- # Remove Image Metadata {#remove-metadata} Remove EXIF, GPS, ICC color profiles, and XMP metadata from images. Useful for privacy (removing GPS coordinates, camera info) and reducing file size. ## API Endpoints {#api-endpoints} ### Strip Metadata {#strip-metadata} `POST /api/v1/tools/image/strip-metadata` Processes the image and returns a cleaned version with selected metadata removed. ### Inspect Metadata {#inspect-metadata} `POST /api/v1/tools/image/strip-metadata/inspect` Returns the parsed metadata as JSON without modifying the image. Useful for previewing what metadata exists before stripping. ## Parameters (Strip) {#parameters-strip} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | stripExif | boolean | No | `false` | Remove EXIF data (camera settings, dates, etc.) | | stripGps | boolean | No | `false` | Remove GPS/location data only | | stripIcc | boolean | No | `false` | Remove ICC color profile | | stripXmp | boolean | No | `false` | Remove XMP metadata (Adobe, IPTC) | | stripAll | boolean | No | `true` | Remove all metadata at once | When `stripAll` is `true`, it overrides the individual flags and removes everything. ## Example Request {#example-request} Strip all metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": true}' ``` Strip only GPS data (keep camera info and color profile): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": false, "stripGps": true}' ``` Inspect metadata without modifying: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Example Response (Strip) {#example-response-strip} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Example Response (Inspect) {#example-response-inspect} ```json { "filename": "photo.jpg", "fileSize": 2450000, "exif": { "Make": "Canon", "Model": "EOS R5", "DateTimeOriginal": "2024:03:15 14:30:00", "ExposureTime": "1/250", "FNumber": 2.8, "ISO": 400 }, "gps": { "GPSLatitudeRef": "N", "GPSLatitude": [37, 46, 30], "_latitude": 37.775, "_longitude": -122.4183 }, "icc": { "Profile Size": "3144 bytes", "Color Space": "RGB", "Description": "sRGB IEC61966-2.1" }, "xmp": { "CreatorTool": "Adobe Photoshop 25.0" } } ``` ## Notes {#notes} * The image is re-encoded in its original format after stripping. JPEG uses mozjpeg at quality 90, PNG uses compression level 9, WebP uses quality 85. * Stripping ICC profiles may cause subtle color shifts if the image was tagged with a non-sRGB profile. Use `stripIcc: false` if color accuracy matters. * The inspect endpoint parses GPS coordinates into decimal latitude/longitude values (prefixed with underscore) for convenience. * Supported input formats: JPEG, PNG, WebP, AVIF, TIFF, GIF. --- --- url: https://docs.snapotter.com/tools/image/edit-metadata.md description: >- Edit EXIF, IPTC, GPS, and XMP metadata fields in images without re-encoding pixels. --- # Edit Image Metadata {#edit-metadata} Edit image metadata fields including EXIF, IPTC, GPS coordinates, dates, and keywords. Uses ExifTool under the hood, so metadata is written in-place without re-encoding pixels, preserving full image quality. ## API Endpoints {#api-endpoints} ### Edit Metadata {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Writes metadata fields to the image and returns the modified file. ### Inspect Metadata {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Returns the full metadata from the image via ExifTool as JSON. Does not modify the image. ## Parameters (Edit) {#parameters-edit} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | title | string | No | - | Image title (XMP/EXIF) | | author | string | No | - | Author name | | artist | string | No | - | Artist name (EXIF Artist tag) | | copyright | string | No | - | Copyright notice | | imageDescription | string | No | - | Image description (EXIF) | | software | string | No | - | Software tag | | dateTime | string | No | - | EXIF DateTime value | | dateTimeOriginal | string | No | - | EXIF DateTimeOriginal value | | setAllDates | string | No | - | Set all date fields at once | | dateShift | string | No | - | Shift all dates by offset (format: `+HH:MM` or `-HH:MM`) | | clearGps | boolean | No | `false` | Remove all GPS data | | gpsLatitude | number | No | - | Set GPS latitude (-90 to 90) | | gpsLongitude | number | No | - | Set GPS longitude (-180 to 180) | | gpsAltitude | number | No | - | Set GPS altitude in meters | | keywords | string\[] | No | - | Keywords/tags to add or set | | keywordsMode | string | No | `"add"` | How to handle keywords: `add` (append) or `set` (replace) | | fieldsToRemove | string\[] | No | `[]` | List of specific metadata field names to remove | | iptcTitle | string | No | - | IPTC Object Name | | iptcHeadline | string | No | - | IPTC Headline | | iptcCity | string | No | - | IPTC City | | iptcState | string | No | - | IPTC Province/State | | iptcCountry | string | No | - | IPTC Country | ## Example Request {#example-request} Set author and copyright: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` Set GPS coordinates: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` Remove GPS and add keywords: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Inspect metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Example Response (Edit) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Notes {#notes} * This tool requires ExifTool to be installed on the server. It is included in the Docker image. * Metadata is written in-place, so no pixel re-encoding occurs. The file size change is minimal (just the metadata bytes). * The `dateShift` parameter shifts all date fields by the specified offset, useful for correcting timezone errors (e.g. `+02:00` or `-05:30`). * If no changes are requested (all parameters omitted or empty), the original file is returned unchanged. * Supported formats: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * For non-browser-previewable formats (HEIF, TIFF), the response includes a `previewUrl` field with a WebP preview. --- --- url: https://docs.snapotter.com/tools/image/bulk-rename.md description: Rename multiple files using a pattern template and download as ZIP. --- # Bulk Rename {#bulk-rename} Rename multiple files using a pattern template with placeholders for index, padded index, and original filename. Returns a ZIP archive containing all renamed files. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` Accepts multipart form data with multiple files and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pattern | string | No | `"image-{{index}}"` | Naming pattern with placeholders (max 1000 characters) | | startIndex | number | No | `1` | Starting index number | ### Pattern Placeholders {#pattern-placeholders} | Placeholder | Description | Example | |-------------|-------------|---------| | `{{index}}` | Sequential number starting from `startIndex` | `1`, `2`, `3` | | `{{padded}}` | Zero-padded sequential number | `01`, `02`, `03` | | `{{original}}` | Original filename without extension | `photo`, `IMG_001` | The original file extension is always preserved. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` This produces: `vacation-1.jpg`, `vacation-2.jpg`, `vacation-3.jpg` Using original filename: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` This produces: `2024-trip-IMG_001-1.jpg`, `2024-trip-IMG_002-2.jpg` ## Example Response {#example-response} The response is a ZIP file streamed directly (not a JSON response). The response headers are: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Notes {#notes} * This tool does not process images. It only renames files and packages them into a ZIP archive. * The zero-padding width for `{{padded}}` is determined automatically based on the total number of files (e.g. 100 files would use 3-digit padding: `001`, `002`, etc.). * File extensions are preserved from the original filenames. * Filenames are sanitized to remove unsafe characters. * At least one file must be provided. --- --- url: https://docs.snapotter.com/tools/image/image-to-pdf.md description: >- Combine one or more images into a PDF document with page size, orientation, and target file size options. --- # Image to PDF {#image-to-pdf} Combine one or more images into a PDF document. Supports multiple page sizes, orientations, margins, and optional file size targeting via quality adjustment. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-to-pdf` Accepts multipart form data with one or more image files and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pageSize | string | No | `"A4"` | Page size: `A4`, `Letter`, `A3`, `A5` | | orientation | string | No | `"portrait"` | Page orientation: `portrait` or `landscape` | | margin | number | No | `20` | Page margin in points (0-500) | | targetSize | object | No | - | Target file size constraint (see below) | | collate | boolean | No | `true` | Combine all images into one PDF. If `false`, creates one PDF per image. | ### Target Size Object {#target-size-object} | Field | Type | Required | Description | |-------|------|----------|-------------| | value | number | Yes | Target size value | | unit | string | Yes | Unit: `KB` or `MB` | Minimum target size is 50 KB. ## Example Request {#example-request} Basic multi-image PDF: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page1.jpg" \ -F "file=@page2.jpg" \ -F "file=@page3.jpg" \ -F 'settings={"pageSize": "A4", "orientation": "portrait", "margin": 20}' ``` With file size target: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@scan1.jpg" \ -F "file=@scan2.jpg" \ -F 'settings={"pageSize": "Letter", "targetSize": {"value": 2, "unit": "MB"}}' ``` One PDF per image: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F 'settings={"collate": false}' ``` ## Example Response (Collated) {#example-response-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 5000000, "processedSize": 1200000, "pages": 3 } ``` ## Example Response (Non-Collated) {#example-response-non-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.zip", "originalSize": 5000000, "processedSize": 2400000, "pages": 2, "collated": false } ``` ## Example Response (With Target Size) {#example-response-with-target-size} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 10000000, "processedSize": 2000000, "pages": 5, "compression": { "targetRequested": 2097152, "targetMet": true, "jpegQuality": 72 } } ``` ## Notes {#notes} * Images are centered on the page and scaled to fit within the margins while preserving aspect ratio. Images are never upscaled. * When `collate` is `false`, each image becomes a separate PDF file, and the download is a ZIP archive containing all PDFs. * The target size feature uses iterative binary search over JPEG quality levels (10-95) to find the best quality that fits within the budget. * Transparent images are flattened to white before embedding in the PDF. * Supported input formats: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW, PSD, SVG, and more. * EXIF orientation is auto-applied before embedding. --- --- url: https://docs.snapotter.com/tools/image/favicon.md description: Generate all standard favicon and app icon sizes from a source image. --- # Favicon Generator {#favicon-generator} Generate a complete set of favicon and app icon files from a source image. Produces all standard sizes needed for browsers, Apple devices, and Android, along with a web manifest and an HTML snippet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/favicon` Accepts multipart form data with one or more image files and an optional JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | background | string | No | - | Background hex color (e.g. `"#ffffff"`). When set, the icon is flattened onto this color. | | padding | integer | No | `0` | Padding percentage around the icon content (0 to 40) | | radius | integer | No | `0` | Corner radius percentage for rounded icons (0 to 50) | | sizes | integer\[] | No | - | Restrict output to specific pixel sizes (e.g. `[16, 32, 180]`). Omit to generate all standard sizes. | | themeColor | string | No | `"#ffffff"` | Theme color hex for the web manifest | ## Generated Files {#generated-files} For each input image, the following files are produced: | File | Size | Purpose | |------|------|---------| | `favicon-16x16.png` | 16x16 | Browser tab icon | | `favicon-32x32.png` | 32x32 | Browser tab icon (HiDPI) | | `favicon-48x48.png` | 48x48 | Desktop shortcut | | `apple-touch-icon.png` | 180x180 | iOS home screen | | `android-chrome-192x192.png` | 192x192 | Android home screen | | `android-chrome-512x512.png` | 512x512 | Android splash screen | | `favicon.ico` | 32x32 | Legacy ICO format | | `manifest.json` | - | Web app manifest with icon references | | `favicon-snippet.html` | - | Ready-to-use HTML link tags | ## Example Request {#example-request} Single source image with rounded corners and padding: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Multiple source images (each gets its own set in a subfolder): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Example Response {#example-response} The response is a ZIP file streamed directly. The response headers are: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## HTML Snippet Included {#html-snippet-included} The ZIP includes a `favicon-snippet.html` file you can paste into your HTML ``: ```html ``` ## Notes {#notes} * Source images are resized using `cover` fit mode, meaning they are cropped to fill each square size. For best results, use a square source image. * When multiple files are uploaded, each gets its own subfolder in the ZIP (named after the source file). * For a single file upload, all outputs are at the root of the ZIP with no subfolder. * Files that fail validation or decoding are skipped, and a `skipped-files.txt` is included in the ZIP explaining the issues. * Supported input formats: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD, and more. * EXIF orientation is auto-applied before resizing. --- --- url: https://docs.snapotter.com/tools/image/adjust-colors.md description: >- Adjust brightness, contrast, saturation, temperature, hue, channels, and apply color effects. --- # Adjust Colors {#adjust-colors} Comprehensive color adjustment tool combining brightness, contrast, exposure, saturation, temperature, tint, hue rotation, per-channel levels, and one-click effects (grayscale, sepia, invert) in a single endpoint. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | Brightness adjustment (-100 to 100) | | contrast | number | No | `0` | Contrast adjustment (-100 to 100) | | exposure | number | No | `0` | Exposure / midtone gamma (-100 to 100) | | saturation | number | No | `0` | Color saturation (-100 to 100) | | temperature | number | No | `0` | White balance: cool/blue to warm/orange (-100 to 100) | | tint | number | No | `0` | Tint shift: green to magenta (-100 to 100) | | hue | number | No | `0` | Hue rotation in degrees (-180 to 180) | | sharpness | number | No | `0` | Sharpening strength (0 to 100) | | red | number | No | `100` | Red channel level (0 to 200, 100 = unchanged) | | green | number | No | `100` | Green channel level (0 to 200, 100 = unchanged) | | blue | number | No | `100` | Blue channel level (0 to 200, 100 = unchanged) | | effect | string | No | `"none"` | Color effect: `none`, `grayscale`, `sepia`, `invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` Apply a warm vintage look: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * All parameters default to neutral values so you can adjust only what you need. * Adjustments are applied in this order: brightness, contrast, exposure, saturation/hue, temperature/tint, sharpness, channels, effects. * Temperature uses a 3x3 color recombination matrix on the blue-orange and green-magenta axes. * Exposure maps to Sharp's gamma function (positive brightens midtones, negative darkens them). * This endpoint also responds at the legacy paths `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels`, and `/api/v1/tools/image/color-effects`. All use the same schema. * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/sharpening.md description: >- Sharpen images using adaptive, unsharp mask, or high-pass methods with optional noise reduction. --- # Sharpen Image {#sharpening} Advanced sharpening tool with three methods: adaptive (smart edge-aware), unsharp mask (classic radius/amount), and high-pass (texture emphasis). Includes built-in noise reduction to prevent sharpening artifacts. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/sharpening` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | method | string | No | `"adaptive"` | Sharpening algorithm: `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | No | `1.0` | Adaptive: Gaussian sigma (0.5 to 10) | | m1 | number | No | `1.0` | Adaptive: flat area sharpening (0 to 10) | | m2 | number | No | `3.0` | Adaptive: jagged area sharpening (0 to 20) | | x1 | number | No | `2.0` | Adaptive: flat/jagged threshold (0 to 10) | | y2 | number | No | `12` | Adaptive: maximum flat sharpening (0 to 50) | | y3 | number | No | `20` | Adaptive: maximum jagged sharpening (0 to 50) | | amount | number | No | `100` | Unsharp mask: sharpening amount (0 to 1000) | | radius | number | No | `1.0` | Unsharp mask: blur radius in pixels (0.1 to 5) | | threshold | number | No | `0` | Unsharp mask: minimum brightness difference to sharpen (0 to 255) | | strength | number | No | `50` | High-pass: filter strength (0 to 100) | | kernelSize | number | No | `3` | High-pass: convolution kernel size (3 or 5) | | denoise | string | No | `"off"` | Pre-sharpening noise reduction: `off`, `light`, `medium`, `strong` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Unsharp mask with threshold to protect smooth areas: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Notes {#notes} * Only parameters relevant to the chosen method are used. For example, `amount`, `radius`, and `threshold` are ignored when `method` is `adaptive`. * The adaptive method uses Sharp's built-in adaptive sharpening with configurable flat/jagged region behavior. * The `denoise` option applies noise reduction before sharpening to prevent amplification of noise/grain. * High-pass sharpening extracts fine detail by subtracting a blurred version from the original, then blending back. * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/replace-color.md description: >- Replace a specific color in an image with another color or make it transparent. --- # Replace & Invert Color {#replace-invert-color} Replace pixels matching a source color with a target color, or make them transparent. Uses Euclidean distance in RGB space with configurable tolerance for smooth blending at color boundaries. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/replace-color` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sourceColor | string | No | `"#FF0000"` | Hex color to find (format: `#RRGGBB`) | | targetColor | string | No | `"#00FF00"` | Hex color to replace with (format: `#RRGGBB`) | | makeTransparent | boolean | No | `false` | Make matching pixels transparent instead of replacing with target color | | tolerance | number | No | `30` | Color matching tolerance (0 to 255). Higher values match a wider range of similar colors | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/replace-color \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"sourceColor": "#FF0000", "targetColor": "#0000FF", "tolerance": 40}' ``` Make a green background transparent: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/replace-color \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@greenscreen.png" \ -F 'settings={"sourceColor": "#00FF00", "makeTransparent": true, "tolerance": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 2100000 } ``` ## Notes {#notes} * Color matching uses Euclidean distance in RGB space, scaled by `tolerance * sqrt(3)`. * Replacement blending is proportional to color distance: pixels closer to the source color receive more of the target color, creating smooth transitions. * When `makeTransparent` is `true`, the output is forced to PNG (or WebP/AVIF) if the input format does not support alpha channels (e.g., JPEG). * A tolerance of 0 matches only the exact source color. Higher values (50+) will match a broader range of similar hues. * Output format matches the input format unless transparency is needed and the input format lacks alpha support. --- --- url: https://docs.snapotter.com/tools/image/color-blindness.md description: >- Simulate how images appear to people with different types of color vision deficiency. --- # Color Blindness Simulation {#color-blindness-simulation} Simulate color vision deficiency (CVD) to preview how images appear to people with various types of color blindness. Useful for accessibility testing of designs, charts, and UI. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-blindness` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | simulationType | string | No | `"deuteranomaly"` | Type of color vision deficiency to simulate | ### Simulation Types {#simulation-types} | Value | Condition | Description | |-------|-----------|-------------| | `protanopia` | Red-blind | Complete absence of red cone cells | | `deuteranopia` | Green-blind | Complete absence of green cone cells | | `tritanopia` | Blue-blind | Complete absence of blue cone cells | | `protanomaly` | Red-weak | Reduced red cone sensitivity | | `deuteranomaly` | Green-weak | Reduced green cone sensitivity (most common) | | `tritanomaly` | Blue-weak | Reduced blue cone sensitivity | | `achromatopsia` | Total color blind | Complete absence of color vision | | `blueConeMonochromacy` | Blue-cone only | Only blue cones functional | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-blindness \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@design.png" \ -F 'settings={"simulationType": "deuteranopia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/design.png", "originalSize": 1850000, "processedSize": 1820000 } ``` ## Notes {#notes} * Deuteranomaly (green-weak) is the default because it is the most common form of color vision deficiency, affecting approximately 6% of males. * The simulation uses color transformation matrices that model how reduced or absent cone photoreceptors alter perceived colors. * This tool is non-destructive and produces a preview only. It does not modify the original image for accessibility. * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/duotone.md description: Apply a two-color duotone effect with custom shadow and highlight colors. --- # Duotone {#duotone} Apply a two-color duotone effect to an image. The image is converted to grayscale, then mapped to a gradient between the shadow color (dark tones) and the highlight color (bright tones). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | shadow | string | No | `"#1e3a8a"` | Shadow hex color (applied to dark tones) | | highlight | string | No | `"#fbbf24"` | Highlight hex color (applied to bright tones) | | intensity | integer | No | `100` | Effect intensity (0-100); 0 returns the original, 100 applies the full duotone | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notes {#notes} * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. * An `intensity` of less than 100 blends the duotone result with the original image, allowing for subtler effects. * Popular duotone combinations include navy/gold, teal/coral, and purple/pink. --- --- url: https://docs.snapotter.com/tools/image/pixelate.md description: Apply a pixelation effect to the full image or a specific region. --- # Pixelate {#pixelate} Apply a pixelation effect to an entire image or a specific rectangular region. Useful for obscuring sensitive content like faces, license plates, or personal information. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/pixelate` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | blockSize | integer | No | `12` | Pixel block size (2-128); larger values produce coarser pixelation | | region | object | No | - | Restrict pixelation to a rectangle (see below) | ### Region Object {#region-object} | Field | Type | Required | Description | |-------|------|----------|-------------| | left | integer | Yes | Left offset in pixels (>= 0) | | top | integer | Yes | Top offset in pixels (>= 0) | | width | integer | Yes | Region width in pixels (>= 1) | | height | integer | Yes | Region height in pixels (>= 1) | ## Example Request {#example-request} Pixelate the full image: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/pixelate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"blockSize": 20}' ``` Pixelate a specific region: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/pixelate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"blockSize": 16, "region": {"left": 100, "top": 50, "width": 200, "height": 150}}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * When `region` is omitted, the entire image is pixelated. * The region coordinates are in pixels relative to the top-left corner of the image. The region must fall within the image bounds. * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/vignette.md description: Add a vignette effect with adjustable strength, color, and position. --- # Vignette {#vignette} Add a vignette effect that darkens or tints the edges of an image. Supports adjustable strength, color, radius, softness, roundness, and center position. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/vignette` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | strength | number | No | `0.5` | Vignette opacity (0.1-1) | | color | string | No | `"#000000"` | Vignette hex color | | radius | integer | No | `70` | Outer radius as percentage of half-diagonal (0-100) | | softness | integer | No | `50` | Feather softness (0-100); higher values produce a more gradual fade | | roundness | integer | No | `100` | Shape: 100 = circle, 0 = ellipse matching image aspect ratio | | centerX | integer | No | `50` | Horizontal center position as percentage (0-100) | | centerY | integer | No | `50` | Vertical center position as percentage (0-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vignette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"strength": 0.7, "radius": 60, "softness": 70}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2410000 } ``` ## Notes {#notes} * A smaller `radius` darkens more of the image; a larger radius confines the vignette to the extreme edges. * Use a non-black `color` (e.g., white or sepia tones) for creative vignette effects. * Adjusting `centerX` and `centerY` lets you position the clear area off-center, useful for drawing focus to a subject that is not in the middle of the frame. * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/watermark-text.md description: Add text watermarks with configurable position, opacity, rotation, and tiling. --- # Text Watermark {#text-watermark} Add a text watermark overlay to images. Supports single placement at corners/center or tiled repetition across the entire image, with configurable font size, color, opacity, and rotation. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/watermark-text` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Watermark text (1 to 500 characters) | | fontSize | number | No | `48` | Font size in pixels (8 to 1000) | | color | string | No | `"#000000"` | Text color in hex format (`#RRGGBB`) | | opacity | number | No | `50` | Text opacity percentage (0 to 100) | | position | string | No | `"center"` | Placement: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right`, `tiled` | | rotation | number | No | `0` | Text rotation angle in degrees (-360 to 360) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-text \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "SAMPLE", "fontSize": 64, "opacity": 30, "position": "center", "rotation": -30}' ``` Tiled watermark across the entire image: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-text \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "DRAFT", "fontSize": 36, "opacity": 20, "position": "tiled", "rotation": -45}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Notes {#notes} * The watermark is rendered as SVG text and composited onto the image, preserving output quality. * Tiled mode spaces text elements based on font size (6x horizontal, 4x vertical spacing), capped at 500 elements maximum. * For corner positions, padding from the edge equals the font size. * The font used is the system's default sans-serif font. * XML-special characters in the text (`&`, `<`, `>`, `"`, `'`) are safely escaped. * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/watermark-image.md description: >- Overlay a logo or image as a watermark with configurable position, opacity, and scale. --- # Image Watermark {#image-watermark} Overlay a logo or secondary image as a watermark on a base image. The watermark is scaled relative to the base image width and positioned at a corner or center. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/watermark-image` Accepts multipart form data with **two** image files and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | position | string | No | `"bottom-right"` | Watermark placement: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` | | opacity | number | No | `50` | Watermark opacity percentage (0 to 100) | | scale | number | No | `25` | Watermark width as percentage of main image width (1 to 100) | ### File Fields {#file-fields} | Field Name | Required | Description | |------------|----------|-------------| | file | Yes | The main/base image | | watermark | Yes | The watermark/logo image | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "watermark=@logo.png" \ -F 'settings={"position": "bottom-right", "opacity": 60, "scale": 20}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2520000 } ``` ## Notes {#notes} * Both images are validated and decoded (HEIC, RAW, PSD, SVG supported). * The watermark is resized proportionally so its width equals `scale`% of the main image width. * Opacity is applied via an alpha mask composited with `dest-in` blending. * Corner positions use a 20px padding from the image edge. * If the watermark image has transparency (e.g., a PNG logo), it is preserved during compositing. * EXIF orientation is auto-applied on both images before processing. --- --- url: https://docs.snapotter.com/tools/image/text-overlay.md description: Add styled text overlays with drop shadows and background boxes. --- # Text Overlay {#text-overlay} Add styled text to images with optional drop shadow and semi-transparent background box. Suitable for titles, captions, or annotations on photos. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/text-overlay` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Text to overlay (1 to 500 characters) | | fontSize | number | No | `48` | Font size in pixels (8 to 200) | | color | string | No | `"#FFFFFF"` | Text color in hex format (`#RRGGBB`) | | position | string | No | `"bottom"` | Vertical placement: `top`, `center`, `bottom` | | backgroundBox | boolean | No | `false` | Show a semi-transparent background rectangle behind the text | | backgroundColor | string | No | `"#000000"` | Background box color in hex format (`#RRGGBB`) | | shadow | boolean | No | `true` | Apply a drop shadow behind the text | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/text-overlay \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "Hello World", "fontSize": 64, "color": "#FFFFFF", "position": "bottom", "shadow": true}' ``` With a background box: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/text-overlay \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "Caption", "fontSize": 36, "position": "bottom", "backgroundBox": true, "backgroundColor": "#000000"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2470000 } ``` ## Notes {#notes} * Text is always centered horizontally within the image. * The drop shadow uses a 2px offset with 3px blur at 70% black opacity. * The background box spans the full image width at 70% opacity, with height proportional to the font size (1.8x). * Text is rendered via SVG composite, so the system's default sans-serif font is used. * XML-special characters in the text are safely escaped. * Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/compose.md description: Layer images with position, opacity, and blend modes for compositing. --- # Image Composition {#image-composition} Layer an overlay image on top of a base image with configurable position, opacity, and blend mode. Useful for compositing logos, graphics, or combining multiple images. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compose` Accepts multipart form data with **two** image files and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | x | number | No | `0` | Horizontal offset of the overlay from the top-left corner in pixels (min 0) | | y | number | No | `0` | Vertical offset of the overlay from the top-left corner in pixels (min 0) | | opacity | number | No | `100` | Overlay opacity percentage (0 to 100) | | blendMode | string | No | `"over"` | Compositing blend mode | ### Blend Modes {#blend-modes} | Value | Description | |-------|-------------| | `over` | Normal overlay (default) | | `multiply` | Darken by multiplying pixel values | | `screen` | Lighten by inverting, multiplying, and inverting again | | `overlay` | Combines multiply and screen based on base brightness | | `darken` | Keep the darker pixel from each layer | | `lighten` | Keep the lighter pixel from each layer | | `hard-light` | Strong contrast overlay | | `soft-light` | Subtle contrast overlay | | `difference` | Absolute difference between layers | | `exclusion` | Similar to difference but lower contrast | ### File Fields {#file-fields} | Field Name | Required | Description | |------------|----------|-------------| | file | Yes | The base/background image | | overlay | Yes | The overlay/foreground image | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Using multiply blend mode: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Notes {#notes} * Both images are validated and decoded (HEIC, RAW, PSD, SVG supported) before compositing. * The overlay is placed at the exact pixel coordinates specified by `x` and `y`. It is not resized to fit. * If opacity is less than 100, an alpha mask is applied to the overlay before blending. * The overlay can extend beyond the base image boundaries (it will be clipped). * EXIF orientation is auto-applied on both images before processing. * Output dimensions match the base image dimensions. --- --- url: https://docs.snapotter.com/tools/image/meme-generator.md description: >- Create memes with templates or custom images, styled text boxes, and font options. --- # Meme Generator {#meme-generator} Create memes using built-in templates or custom images. Add text with classic meme styling (bold, outlined text), multiple layout presets, and font choices. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/meme-generator` Accepts either: * **Multipart form data** with an image file and a JSON `settings` field (custom image mode) * **JSON body** with a `templateId` (template mode, no file upload needed) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | templateId | string | No | - | Built-in meme template ID. If provided, no image upload is needed | | textLayout | string | No | `"top-bottom"` | Text box layout: `top-bottom`, `top-only`, `bottom-only`, `center`, `side-by-side` | | textBoxes | array | No | `[]` | Array of text box objects with `id` and `text` fields | | fontFamily | string | No | `"anton"` | Font: `anton`, `arial-black`, `comic-sans`, `montserrat`, `bebas-neue`, `permanent-marker`, `roboto` | | fontSize | number | No | auto | Font size in pixels (8 to 200). Auto-calculated if omitted | | textColor | string | No | `"#ffffff"` | Text fill color | | strokeColor | string | No | `"#000000"` | Text stroke/outline color | | textAlign | string | No | `"center"` | Text alignment: `left`, `center`, `right` | | allCaps | boolean | No | `true` | Convert text to uppercase | ### Text Boxes {#text-boxes} Each entry in the `textBoxes` array should have: | Field | Type | Description | |-------|------|-------------| | id | string | Box identifier matching the layout (e.g., `"top"`, `"bottom"`, `"left"`, `"right"`, `"center"`) | | text | string | The meme text to display | ### Text Layout Box IDs {#text-layout-box-ids} | Layout | Available Box IDs | |--------|-------------------| | `top-bottom` | `top`, `bottom` | | `top-only` | `top` | | `bottom-only` | `bottom` | | `center` | `center` | | `side-by-side` | `left`, `right` | ## Example Request {#example-request} Custom image with top and bottom text: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"textLayout": "top-bottom", "textBoxes": [{"id": "top", "text": "When the code works"}, {"id": "bottom", "text": "On the first try"}], "fontFamily": "anton", "allCaps": true}' ``` Using a built-in template (JSON body, no file upload): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"templateId": "drake", "textBoxes": [{"id": "top", "text": "Manual testing"}, {"id": "bottom", "text": "Automated tests"}]}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/meme-drake.png", "originalSize": 450000, "processedSize": 520000 } ``` ## Notes {#notes} * Either `templateId` or an uploaded image file is required. Providing both uses the template. * Templates define their own text box positions; the `textLayout` parameter is ignored when using templates. * Text is rendered as SVG with stroke outlines for the classic meme look. * Font size is auto-calculated to fit the text box if not explicitly set. * Empty text boxes are skipped (no rendering occurs if all boxes are empty). * The output filename includes the template ID when using templates (e.g., `meme-drake.png`). * HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/info.md description: >- View detailed image metadata, properties, and per-channel histogram statistics. --- # Image Info {#image-info} Read-only analysis tool that returns comprehensive image metadata including dimensions, format, color space, EXIF/ICC/XMP presence, and per-channel histogram statistics. Does not produce a processed output file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/info` Accepts multipart form data with an image file. No settings field is needed. ## Parameters {#parameters} This tool has no configurable parameters. Simply upload the image file. | Field | Type | Required | Description | |-------|------|----------|-------------| | file | file | Yes | The image to analyze | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/info \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "orientation": 1, "hasProfile": true, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | Sanitized filename | | fileSize | number | File size in bytes | | width | number | Image width in pixels | | height | number | Image height in pixels | | format | string | Detected format (jpeg, png, webp, etc.) | | channels | number | Number of color channels | | hasAlpha | boolean | Whether the image has an alpha channel | | colorSpace | string | Color space (srgb, cmyk, etc.) | | density | number or null | DPI/PPI resolution | | isProgressive | boolean | Whether JPEG uses progressive encoding | | orientation | number or null | EXIF orientation value (1-8) | | hasProfile | boolean | Whether an ICC profile is embedded | | hasExif | boolean | Whether EXIF metadata is present | | hasIcc | boolean | Whether an ICC color profile is present | | hasXmp | boolean | Whether XMP metadata is present | | bitDepth | string or null | Bits per sample | | pages | number | Number of pages (for multi-page formats like TIFF, GIF) | | histogram | array | Per-channel statistics (min, max, mean, standard deviation) | ## Notes {#notes} * This is a read-only endpoint. It does not produce a downloadable output file or a `jobId`. * For RAW format images (DNG, CR2, NEF, ARW, etc.), ExifTool is used to extract true sensor dimensions and metadata flags that Sharp cannot read directly. * HEIC/HEIF files are decoded to PNG internally to extract pixel statistics, since Sharp cannot decode HEVC pixels. * The histogram provides min/max/mean/stdev per channel, not a full 256-bin distribution. * The `density` field reflects the embedded DPI metadata, if present. --- --- url: https://docs.snapotter.com/tools/image/compare.md description: >- Compare two images side by side with pixel-level diff visualization and similarity score. --- # Image Compare {#image-compare} Upload two images to compute a pixel-level difference map and a numerical similarity percentage. The output is a diff image highlighting changed regions in red. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compare` Accepts multipart form data with **two** image files. No settings field is needed. ## Parameters {#parameters} This tool has no configurable parameters. Upload exactly two image files. | Field | Type | Required | Description | |-------|------|----------|-------------| | file (first) | file | Yes | The first image | | file (second) | file | Yes | The second image | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | jobId | string | Job identifier for downloading the diff image | | similarity | number | Percentage similarity between the two images (0 to 100) | | dimensions | object | Width and height used for comparison | | downloadUrl | string | URL to download the generated diff image | | originalSize | number | Combined size of both input images in bytes | | processedSize | number | Size of the diff output image in bytes | ## Notes {#notes} * Both images are resized to the same dimensions (the maximum of each axis) before comparison. * The diff image highlights differences in red with opacity proportional to the magnitude of change. Identical or near-identical pixels (difference < 10) are shown as semi-transparent versions of the original. * Similarity is calculated as the inverse of the average pixel difference across all pixels, expressed as a percentage. * A similarity of 100% means the images are pixel-identical (at the comparison resolution). * The diff output is always PNG format regardless of input formats. * Both images are validated and decoded (HEIC, RAW, PSD, SVG supported) before comparison. * EXIF orientation is auto-applied on both images before processing. --- --- url: https://docs.snapotter.com/tools/image/find-duplicates.md description: Detect duplicate and near-duplicate images using perceptual hashing. --- # Find Duplicates {#find-duplicates} Upload multiple images to detect duplicates and near-duplicates using perceptual hashing (dHash). Groups similar images together, identifies the best quality version in each group, and calculates potential space savings. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` Accepts multipart form data with multiple image files and an optional JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | threshold | number | No | `8` | Maximum Hamming distance to consider images as duplicates (0 to 20). Lower = stricter matching | ### File Fields {#file-fields} Upload at least 2 image files in the multipart request (all using the `file` field name or any field name for file parts). ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Example Response {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | totalImages | number | Number of images successfully analyzed | | duplicateGroups | array | Groups of duplicate images | | uniqueImages | number | Number of images not part of any duplicate group | | spaceSaveable | number | Total bytes that could be saved by removing non-best duplicates | | skippedFiles | array | Files that could not be processed (with filename and reason) | ### Duplicate Group Object {#duplicate-group-object} | Field | Type | Description | |-------|------|-------------| | groupId | number | Group identifier | | files | array | Images in this duplicate group | ### File Object (within a group) {#file-object-within-a-group} | Field | Type | Description | |-------|------|-------------| | filename | string | Original filename | | similarity | number | Similarity percentage to the reference image (first in group) | | width | number | Image width in pixels | | height | number | Image height in pixels | | fileSize | number | File size in bytes | | format | string | Image format | | isBest | boolean | Whether this is the highest quality version (most pixels, largest file) | | thumbnail | string or null | Base64 JPEG thumbnail (200px wide) for preview | ## Notes {#notes} * Uses a 128-bit dHash (64-bit row + 64-bit column) for perceptual similarity detection. This catches duplicates even across resizes, recompression, and minor edits. * The threshold represents maximum Hamming distance between hashes. Default of 8 catches near-duplicates while avoiding false positives. Use 0 for pixel-identical only, or 15-20 for very loose matching. * The "best" image in each group is the one with the most pixels (width x height), with file size as a tiebreaker. * At least 2 images are required. Files that fail validation or decoding are reported in `skippedFiles` rather than causing the entire request to fail. * Thumbnails are 200px-wide JPEG previews encoded as data URIs. * All common formats are supported (HEIC, RAW, PSD, SVG decoded automatically). --- --- url: https://docs.snapotter.com/tools/image/color-palette.md description: Extract dominant colors from an image as a color palette. --- # Color Palette {#color-palette} Extract the dominant colors from an image and return them as hex color values. Uses quantized frequency analysis to identify the most prominent and visually distinct colors. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-palette` Accepts multipart form data with an image file and an optional JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | count | integer | No | `8` | Number of colors to extract (2-16) | | format | string | No | `"hex"` | Color format: `hex`, `rgb`, `hsl` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Example Response {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | Sanitized filename | | colors | array | Array of color strings in the requested format, ordered by dominance (most frequent first) | | hex | array | Array of hex color strings (always hex, regardless of the `format` setting) | | count | number | Number of colors extracted | ## Notes {#notes} * Returns up to `count` dominant colors (default 8, range 2-16), sorted by frequency (most common first). * The image is internally resized to 100x100 pixels for analysis, so the palette represents overall color distribution rather than small details. * Colors are extracted using median-cut quantization, which recursively splits pixel populations along the channel with the widest range. * The alpha channel is removed before analysis, so transparent areas are not considered. * This is a read-only endpoint. It does not produce a downloadable output file or a `jobId`. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before analysis. --- --- url: https://docs.snapotter.com/tools/image/qr-generate.md description: Generate QR codes with custom colors and error correction levels. --- # QR Code Generator {#qr-code-generator} Generate QR code images from text or URLs with configurable size, error correction level, and custom foreground/background colors. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/qr-generate` Accepts a **JSON body** (not multipart). No file upload is needed. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Content to encode in the QR code (1 to 2000 characters) | | size | number | No | `400` | Output image width/height in pixels (100 to 10000) | | errorCorrection | string | No | `"M"` | Error correction level: `L` (7%), `M` (15%), `Q` (25%), `H` (30%) | | foreground | string | No | `"#000000"` | QR code foreground/module color in hex (`#RRGGBB`) | | background | string | No | `"#FFFFFF"` | QR code background color in hex (`#RRGGBB`) | | logoDataUri | string | No | - | Logo image as a data URI (`data:image/png;base64,...` or `data:image/jpeg;base64,...`, max 700 KB). Centered on the QR code at 22% of the QR size. Forces error correction to `H` | ### Error Correction Levels {#error-correction-levels} | Level | Recovery | Use Case | |-------|----------|----------| | `L` | ~7% | Maximum data density | | `M` | ~15% | Balanced (default) | | `Q` | ~25% | Good for printed codes | | `H` | ~30% | Best for codes with logos overlay | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "https://snapotter.com", "size": 500, "errorCorrection": "H"}' ``` Branded QR code with custom colors: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "Hello World", "size": 300, "foreground": "#1a365d", "background": "#f7fafc"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/qrcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * This endpoint accepts JSON, not multipart form data, since no image upload is needed. * The output is always a PNG image. * The output filename is always `qrcode.png`. * `originalSize` is always 0 since this tool generates images from scratch. * A 2-module quiet zone (margin) is included around the QR code. * Maximum text length is 2000 characters. Actual capacity depends on error correction level and character encoding. * Higher error correction levels allow the QR code to remain scannable even if partially obscured but reduce data capacity. * When a `logoDataUri` is provided, error correction is automatically forced to `H` (30%) so the QR code remains scannable despite the logo occluding the center. --- --- url: https://docs.snapotter.com/tools/image/html-to-image.md description: >- Capture webpages or HTML snippets as high-quality images with device emulation. --- # HTML to Image {#html-to-image} Capture a webpage URL or raw HTML content as a screenshot image. Supports device emulation (desktop, tablet, mobile), full-page capture, and multiple output formats. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/html-to-image` Accepts a **JSON body** (not multipart). No file upload is needed. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | Conditional | - | URL to capture (must be a valid URL) | | html | string | Conditional | - | Raw HTML content to render (1 to 5,000,000 characters) | | format | string | No | `"png"` | Output format: `jpg`, `png`, `webp` | | quality | number | No | `90` | Output quality for lossy formats (1 to 100) | | fullPage | boolean | No | `false` | Capture the full scrollable page, not just the viewport | | devicePreset | string | No | `"desktop"` | Device emulation: `desktop`, `tablet`, `mobile`, `custom` | | viewportWidth | number | No | `1280` | Custom viewport width in pixels (320 to 3840, used when devicePreset is `custom`) | | viewportHeight | number | No | `720` | Custom viewport height in pixels (320 to 2160, used when devicePreset is `custom`) | Either `url` or `html` must be provided, but not both. ### Device Presets {#device-presets} | Preset | Width | Height | Mobile UA | |--------|-------|--------|-----------| | `desktop` | 1280 | 720 | No | | `tablet` | 768 | 1024 | No | | `mobile` | 375 | 812 | Yes | | `custom` | (user-specified) | (user-specified) | No | ## Example Request {#example-request} Capture a webpage: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com", "format": "png", "fullPage": true, "devicePreset": "desktop"}' ``` Render HTML content: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"html": "

Hello

", "format": "png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 0, "processedSize": 145000 } ``` ## Notes {#notes} * Requires Chromium to be installed on the server. Returns HTTP 503 if the browser service is not available. * URLs are validated against SSRF attacks (private/internal network addresses are blocked). * This endpoint is rate-limited to 120 requests per hour. * `originalSize` is always 0 since this tool generates images from URLs/HTML. * The output filename is `screenshot.`. * If the page takes too long to load, the request returns HTTP 504 (gateway timeout). * If the browser service crashes repeatedly, it is temporarily disabled and returns HTTP 503 with code `BROWSER_CRASHED`. --- --- url: https://docs.snapotter.com/tools/image/barcode-read.md description: Scan images for QR codes, barcodes, and 2D codes with annotated output. --- # Barcode Reader {#barcode-reader} Scan uploaded images for all types of barcodes and QR codes. Returns decoded text, barcode type, and position data for each detected code. Also generates an annotated image with colored bounding boxes around detected codes. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` Accepts multipart form data with an image file and an optional JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tryHarder | boolean | No | `true` | Enable aggressive scanning mode for harder-to-read barcodes (slower but more thorough) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Example Response {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | Original filename | | barcodes | array | Array of detected barcode objects | | annotatedUrl | string or null | URL to download the annotated image (null if no barcodes found) | | previewUrl | string or null | Same as annotatedUrl (for frontend preview compatibility) | ### Barcode Object {#barcode-object} | Field | Type | Description | |-------|------|-------------| | type | string | Barcode format (QRCode, EAN-13, Code128, DataMatrix, PDF417, etc.) | | text | string | Decoded content of the barcode | | position | object | Bounding box with topLeft, topRight, bottomLeft, bottomRight coordinates | ## Supported Barcode Types {#supported-barcode-types} 1D barcodes: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E 2D barcodes: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Notes {#notes} * Uses the zxing-wasm library for barcode detection. * The annotated image overlays colored polygon bounding boxes and numbered labels on each detected barcode. * Up to 255 barcodes can be detected in a single image. * If no barcodes are found, `barcodes` is an empty array and `annotatedUrl` is null. * The `tryHarder` mode performs more thorough scanning at the cost of processing time. Disable it for faster processing of clean, well-aligned barcodes. * The annotated output is always PNG format. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before scanning. * EXIF orientation is auto-applied before processing. --- --- url: https://docs.snapotter.com/tools/image/image-to-base64.md description: Convert images to base64 data URIs for embedding in HTML, CSS, and more. --- # Image to Base64 {#image-to-base64} Convert one or more images to base64-encoded strings and data URIs. Supports optional format conversion, quality control, and resizing. Useful for embedding images directly in HTML, CSS, JSON, or email templates. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-to-base64` Accepts multipart form data with one or more image files and an optional JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | outputFormat | string | No | `"original"` | Convert before encoding: `original`, `jpeg`, `png`, `webp`, `avif`, `jxl` | | quality | number | No | `80` | Output quality for lossy formats (1 to 100) | | maxWidth | number | No | `0` | Maximum width in pixels (0 = no resize, will not enlarge) | | maxHeight | number | No | `0` | Maximum height in pixels (0 = no resize, will not enlarge) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon.png" \ -F 'settings={"outputFormat": "webp", "quality": 80, "maxWidth": 200}' ``` Multiple files: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon1.png" \ -F "file=@icon2.png" \ -F "file=@icon3.png" \ -F 'settings={"outputFormat": "original"}' ``` ## Example Response {#example-response} ```json { "results": [ { "filename": "icon.png", "mimeType": "image/webp", "width": 200, "height": 200, "originalSize": 45000, "encodedSize": 28800, "overheadPercent": -36.0, "base64": "UklGRlYAAABXRUJQ...", "dataUri": "data:image/webp;base64,UklGRlYAAABXRUJQ..." } ], "errors": [] } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | results | array | Successfully converted images | | errors | array | Images that failed to process (with filename and error message) | ### Result Object {#result-object} | Field | Type | Description | |-------|------|-------------| | filename | string | Original filename | | mimeType | string | MIME type of the encoded output | | width | number | Final width in pixels (after any resizing) | | height | number | Final height in pixels (after any resizing) | | originalSize | number | Original file size in bytes | | encodedSize | number | Size of the base64 string in bytes | | overheadPercent | number | Percentage size difference vs original (positive = larger, negative = smaller) | | base64 | string | Raw base64-encoded image data | | dataUri | string | Complete data URI ready for use in `src` attributes | ## Notes {#notes} * Base64 encoding typically increases size by approximately 33% compared to the binary file. The `overheadPercent` field shows the actual difference. * When `outputFormat` is `"original"`, HEIC/HEIF files are converted to JPEG (since browsers cannot display HEIC in data URIs). * The `maxWidth` and `maxHeight` options resize using `fit: inside` with `withoutEnlargement`, so images smaller than the specified dimensions are not upscaled. * Multiple files can be processed in a single request. Each file is processed independently, and failures do not prevent other files from succeeding. * SVG files are passed through as `image/svg+xml` without re-encoding (unless a format conversion is requested). * This is a read-only endpoint. It does not produce a downloadable file or a `jobId`. The base64 data is returned directly in the response body. --- --- url: https://docs.snapotter.com/tools/image/histogram.md description: Generate an RGB histogram chart with per-channel statistics from an image. --- # Histogram {#histogram} Generate an RGB histogram chart from an image. Returns a PNG histogram image along with per-channel statistics and raw 256-bin histogram data in the response JSON. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/histogram` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | scale | string | No | `"linear"` | Y-axis scale: `linear` or `log` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Notes {#notes} * The `downloadUrl` points to a rendered PNG histogram chart showing the R, G, B, and luminance distributions. * `bins` contains raw 256-value arrays for each channel (red, green, blue, luminance), suitable for rendering custom visualizations. * `stats` provides mean, median, and standard deviation per channel. * `mean` and `max` are backward-compatible shorthand fields. * Use `log` scale when the histogram is dominated by a few peaks and you want to see detail in the lower bins. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before analysis. --- --- url: https://docs.snapotter.com/tools/image/lqip-placeholder.md description: Generate a tiny low-quality image placeholder with base64 data URI. --- # LQIP Placeholder {#lqip-placeholder} Generate a tiny low-quality image placeholder (LQIP) from a source image. Returns a small placeholder file along with a base64 data URI, ready-to-use HTML `` tag, and CSS `background-image` snippet for immediate embedding. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/lqip-placeholder` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | `16` | Target width in pixels (4-64) | | blur | number | No | `2` | Blur radius for the blur strategy (0-20) | | strategy | string | No | `"blur"` | Placeholder strategy: `blur`, `pixelate`, or `solid` | | format | string | No | `"webp"` | Output format: `webp`, `png`, or `jpeg` | | quality | integer | No | `50` | Output quality (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/lqip-placeholder \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"width": 20, "strategy": "blur", "format": "webp"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 280, "dataUri": "data:image/webp;base64,UklGR...", "width": 20, "height": 13, "bytes": 280, "strategy": "blur", "html": "", "css": "background-image:url('data:image/webp;base64,UklGR...');background-size:cover;background-position:center;" } ``` ## Notes {#notes} * The `dataUri` field contains the complete data URI, ready for use in `src` attributes or CSS without any additional requests. * The `html` and `css` fields provide copy-paste snippets for common use cases. * The `blur` strategy produces a soft, blurred thumbnail. The `pixelate` strategy creates a blocky mosaic. The `solid` strategy returns a single averaged color. * Typical placeholder sizes are 200-500 bytes, making them suitable for inlining directly in HTML. * Height is calculated automatically to preserve the source image's aspect ratio. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/barcode-generate.md description: >- Generate barcodes in Code 128, EAN-13, UPC-A, Code 39, ITF-14, and Data Matrix formats. --- # Barcode Generator {#barcode-generator} Generate barcode images from text input. Supports Code 128, EAN-13, UPC-A, Code 39, ITF-14, and Data Matrix formats. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Accepts an `application/json` body (not multipart). The barcode is generated from the provided text, not from an uploaded file. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Text to encode in the barcode (1-256 characters) | | type | string | No | `"code128"` | Barcode format: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | No | `3` | Image scale factor (1-8) | | includeText | boolean | No | `true` | Whether to render the text below the barcode | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * Unlike most tools, this endpoint accepts a JSON body, not multipart form data, since barcodes are generated from text rather than an uploaded file. * EAN-13 requires exactly 12 or 13 digits. UPC-A requires exactly 11 or 12 digits. If a check digit is omitted, it is calculated automatically. * Code 128 is the most flexible format and supports the full ASCII character set. * Data Matrix produces a 2D barcode suitable for encoding longer strings in a compact square. --- --- url: https://docs.snapotter.com/tools/image/collage.md description: >- Combine multiple images into grid collages with 25+ templates, adjustable gaps and corners, and per-cell pan and zoom. --- # Collage & Grid {#collage-grid} Combine multiple images into beautiful grid collages with 25+ templates. Supports 2-9 image layouts with customizable gap, corner radius, background color, and per-cell pan/zoom controls. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | templateId | string | Yes | - | Template layout ID (e.g. `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | No | - | Per-cell settings array with `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Yes | - | Index of the image to place in this cell (0-based) | | cells\[].panX | number | No | 0 | Horizontal pan offset (-100 to 100) | | cells\[].panY | number | No | 0 | Vertical pan offset (-100 to 100) | | cells\[].zoom | number | No | 1 | Zoom level (1 to 10) | | cells\[].objectFit | string | No | `"cover"` | How image fills cell: `cover` or `contain` | | gap | number | No | 8 | Gap between cells in pixels (0 to 500) | | cornerRadius | number | No | 0 | Corner radius for each cell in pixels (0 to 500) | | backgroundColor | string | No | `"#FFFFFF"` | Background color as hex or `"transparent"` | | aspectRatio | string | No | `"free"` | Canvas aspect ratio: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | No | `"png"` | Output format: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Output quality (1 to 100) | ## Available Templates {#available-templates} | Template ID | Images | Layout | |-------------|--------|--------| | `2-h-equal` | 2 | Two equal columns | | `2-v-equal` | 2 | Two equal rows | | `2-h-left-large` | 2 | Left 2/3, right 1/3 | | `2-h-right-large` | 2 | Left 1/3, right 2/3 | | `3-left-large` | 3 | Large left, two stacked right | | `3-right-large` | 3 | Two stacked left, large right | | `3-top-large` | 3 | Large top, two columns bottom | | `3-h-equal` | 3 | Three equal columns | | `3-v-equal` | 3 | Three equal rows | | `4-grid` | 4 | 2x2 grid | | `4-left-large` | 4 | Large left, three stacked right | | `4-top-large` | 4 | Large top, three columns bottom | | `4-bottom-large` | 4 | Three columns top, large bottom | | `5-top2-bottom3` | 5 | Two top, three bottom | | `5-top3-bottom2` | 5 | Three top, two bottom | | `5-left-large` | 5 | Large left, four stacked right | | `5-center-large` | 5 | Large center, four corners | | `6-grid-2x3` | 6 | 2 columns x 3 rows | | `6-grid-3x2` | 6 | 3 columns x 2 rows | | `6-top-large` | 6 | Large top, five columns bottom | | `7-mosaic` | 7 | Mosaic layout | | `8-mosaic` | 8 | Mosaic layout | | `9-grid` | 9 | 3x3 grid | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Notes {#notes} * Upload multiple image files in the multipart request. The images are assigned to template cells in upload order. * If more images are uploaded than the template supports, extra images are ignored. * Supports HEIC, RAW, PSD, and SVG input formats (automatically decoded). * The canvas base size is 2400px on the longest side, scaled by the chosen aspect ratio. * When `aspectRatio` is `"free"`, the canvas defaults to 4:3 (2400x1800). * Per-cell `panX`/`panY` values shift the crop window within the cell. A value of 100 moves fully to one edge, -100 to the other. * The `"transparent"` background color is only preserved with `png`, `webp`, or `avif` output formats. --- --- url: https://docs.snapotter.com/tools/image/stitch.md description: >- Join images side by side, stacked, or in a grid with control over alignment, gaps, borders, and resize mode. --- # Stitch Images {#stitch-combine} Join multiple images side by side, stacked vertically, or arranged in a grid. Supports alignment, gap, border, corner radius, and multiple resize modes. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/stitch` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | direction | string | No | `"horizontal"` | Layout direction: `horizontal`, `vertical`, `grid` | | gridColumns | integer | No | 2 | Number of columns when direction is `grid` (2 to 100) | | resizeMode | string | No | `"fit"` | How images are resized: `fit`, `original`, `stretch`, `crop` | | alignment | string | No | `"center"` | Cross-axis alignment: `start`, `center`, `end` | | gap | number | No | 0 | Gap between images in pixels (0 to 1000) | | border | number | No | 0 | Outer border width in pixels (0 to 500) | | cornerRadius | number | No | 0 | Corner radius applied to final output (0 to 500) | | backgroundColor | string | No | `"#FFFFFF"` | Background/border color as hex (e.g. `#FF0000`) | | format | string | No | `"png"` | Output format: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Output quality (1 to 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/stitch \ -F "file=@image1.png" \ -F "file=@image2.png" \ -F "file=@image3.png" \ -F 'settings={"direction":"horizontal","resizeMode":"fit","gap":10,"backgroundColor":"#FFFFFF","format":"png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stitch.png", "originalSize": 1234567, "processedSize": 987654 } ``` ## Notes {#notes} * Requires at least 2 images. Upload multiple image files in the multipart request. * Supports HEIC, RAW, PSD, and SVG input formats (automatically decoded). * Resize modes: * `fit` - Scale images to match the smallest dimension along the joining axis. * `original` - Keep original sizes (may produce uneven edges). * `stretch` - Force images to match the smallest dimension without preserving aspect ratio. * `crop` - Cover-crop images to match the smallest dimension. * In `grid` mode, cells are sized to the median dimensions of all images. * The `cornerRadius` is applied to the entire final output, not individual images. * Canvas size is limited by the `MAX_CANVAS_PIXELS` server configuration to prevent memory exhaustion. --- --- url: https://docs.snapotter.com/tools/image/split.md description: >- Split one image into grid tiles by rows and columns or by pixel size, returned as a ZIP archive. --- # Split Image {#image-splitting} Split a single image into grid tiles by column/row count or by specific pixel dimensions. Returns a ZIP archive containing all tiles. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/split` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | columns | integer | No | 3 | Number of columns to split into (1 to 100) | | rows | integer | No | 3 | Number of rows to split into (1 to 100) | | tileWidth | integer | No | - | Tile width in pixels (min 10). Overrides `columns` when both `tileWidth` and `tileHeight` are set. | | tileHeight | integer | No | - | Tile height in pixels (min 10). Overrides `rows` when both `tileWidth` and `tileHeight` are set. | | outputFormat | string | No | `"original"` | Output format for tiles: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Output quality for lossy formats (1 to 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Example Response {#example-response} The response is streamed directly as a ZIP file with `Content-Type: application/zip`. The filename follows the pattern `split-.zip`. Each tile inside the ZIP is named `_r_c.` (e.g. `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Notes {#notes} * Accepts a single image file. * Supports HEIC, RAW, PSD, and SVG input formats (automatically decoded). * When both `tileWidth` and `tileHeight` are provided, they take priority over `columns`/`rows`. The grid dimensions are calculated as `ceil(imageWidth / tileWidth)` and `ceil(imageHeight / tileHeight)`. * Edge tiles (rightmost column, bottom row) may be smaller than the specified tile size if the image dimensions are not evenly divisible. * Maximum grid size is capped at 100x100 (10,000 tiles). * The response streams the ZIP directly, so there is no JSON response body. Use `--output` with curl to save the file. --- --- url: https://docs.snapotter.com/tools/image/border.md description: >- Add borders, padding, rounded corners, and drop shadows to images in a predictable, controllable order. --- # Border & Frame {#border-frame} Add borders, padding, rounded corners, and drop shadows to images. The tool applies effects in order: padding, border, corner radius, then shadow. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | Border thickness in pixels (0 to 2000) | | borderColor | string | No | `"#000000"` | Border color as hex (e.g. `#FF0000`) | | padding | number | No | 0 | Inner padding between image and border in pixels (0 to 200) | | paddingColor | string | No | `"#FFFFFF"` | Padding fill color as hex | | cornerRadius | number | No | 0 | Corner radius in pixels (0 to 2000) | | shadow | boolean | No | `false` | Whether to add a drop shadow | | shadowBlur | number | No | 15 | Shadow blur radius (1 to 200) | | shadowOffsetX | number | No | 0 | Shadow horizontal offset (-50 to 50) | | shadowOffsetY | number | No | 5 | Shadow vertical offset (-50 to 50) | | shadowColor | string | No | `"#000000"` | Shadow color as hex | | shadowOpacity | number | No | 40 | Shadow opacity percentage (0 to 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * Uses the standard `createToolRoute` factory. Accepts a single image file via multipart upload. * Supports HEIC, RAW, PSD, and SVG input formats (automatically decoded). * Processing order: padding is added first, then the border wraps around, then corner radius is applied, then the shadow is composited. * When `cornerRadius` or `shadow` is enabled, the output is forced to PNG (regardless of input format) to preserve transparency. Formats that support alpha (PNG, WebP, AVIF) keep their original format. * The shadow is shape-aware: it follows the rounded corners rather than creating a rectangular shadow. * Setting `borderWidth` to 0 and using only `cornerRadius` + `shadow` creates a frameless rounded shadow effect. --- --- url: https://docs.snapotter.com/tools/image/beautify.md description: >- Turn plain screenshots into polished images with gradient backgrounds, device frames, shadows, and social media sizing. --- # Beautify Screenshot {#beautify-screenshot} Add gradient backgrounds, device frames, shadows, watermarks, and social media sizing to screenshots. Ideal for creating polished images for product marketing, social media, and documentation. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"linear-gradient"` | Background type: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | string | No | `"#667eea"` | Solid background color (used when `backgroundType` is `solid`) | | gradientStops | array | No | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | Gradient color stops (min 2). Each stop has `color` (hex) and `position` (0-100). | | gradientAngle | number | No | 135 | Gradient angle in degrees (0 to 360) | | padding | number | No | 64 | Padding around the image in pixels (0 to 256) | | borderRadius | number | No | 12 | Corner radius on the screenshot (0 to 64) | | shadowPreset | string | No | `"subtle"` | Shadow preset: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | number | No | 20 | Custom shadow blur radius (0 to 100, used when `shadowPreset` is `custom`) | | shadowOffsetX | number | No | 0 | Custom shadow horizontal offset (-50 to 50) | | shadowOffsetY | number | No | 10 | Custom shadow vertical offset (-50 to 50) | | shadowColor | string | No | `"#000000"` | Custom shadow color as hex | | shadowOpacity | number | No | 30 | Custom shadow opacity (0 to 100) | | frame | string | No | `"none"` | Device or window frame: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | string | No | - | Title text displayed in window frame title bars | | socialPreset | string | No | `"none"` | Resize to social media dimensions: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | string | No | - | Optional watermark text overlay | | watermarkPosition | string | No | `"bottom-right"` | Watermark position: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | number | No | 50 | Watermark opacity (0 to 100) | | outputFormat | string | No | `"png"` | Output format: `png`, `jpeg`, `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * Accepts two file fields: `file` (required, the main screenshot) and `backgroundImage` (optional, used when `backgroundType` is `image`). * Supports HEIC, RAW, PSD, and SVG input formats (automatically decoded). * Shadow presets map to specific values: * `subtle`: blur 20, offsetY 4, opacity 20% * `medium`: blur 40, offsetY 10, opacity 35% * `dramatic`: blur 80, offsetY 20, opacity 50% * Social media presets resize the final output to fit the target dimensions using `contain` mode: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * Device frames (`iphone`, `macbook`, `ipad`) apply a hardware bezel around the image and skip the `borderRadius` setting. * When transparency is required (shadow, border radius, device frames, or transparent background), the output is forced to PNG even if `jpeg` is selected. * Image backgrounds are not supported in pipeline/batch mode. --- --- url: https://docs.snapotter.com/tools/image/circle-crop.md description: Crop an image to a centered circle with transparent corners. --- # Circle Crop {#circle-crop} Crop an image to a centered circle with transparent corners. Supports adjustable zoom, offset, border, and output size. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | zoom | number | No | `1` | Zoom factor (1-5); higher values crop tighter | | offsetX | number | No | `0.5` | Horizontal center position (0-1) | | offsetY | number | No | `0.5` | Vertical center position (0-1) | | borderWidth | integer | No | `0` | Border width in pixels (0-200) | | borderColor | string | No | `"#ffffff"` | Border hex color | | background | string | No | `"transparent"` | Corner fill: `"transparent"` or a hex color | | outputSize | integer | No | - | Final square dimension in pixels (16-4096) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notes {#notes} * Output is always PNG to preserve the transparent corners (unless `background` is set to a solid color). * The circle is inscribed within the shorter dimension of the image. Use `zoom` to crop tighter and `offsetX`/`offsetY` to shift the visible area. * When `outputSize` is provided, the result is resized to that square dimension after cropping. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/image-pad.md description: >- Pad an image to a target aspect ratio with a solid color, transparent, or blurred background. --- # Image Pad {#image-pad} Pad an image to a target aspect ratio by adding a solid color, transparent, or blurred background around it. Useful for fitting images into fixed aspect ratios for social media or print without cropping. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-pad` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"1:1"` | Target aspect ratio: `16:9`, `9:16`, `1:1`, `4:3`, `3:4`, or `custom` | | ratioW | integer | No | `1` | Custom ratio width (1-100, used when target is `custom`) | | ratioH | integer | No | `1` | Custom ratio height (1-100, used when target is `custom`) | | background | string | No | `"color"` | Background mode: `color`, `transparent`, or `blur` | | color | string | No | `"#ffffff"` | Background hex color (when background is `color`) | | padding | integer | No | `0` | Extra padding as percentage of canvas (0-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 3100000 } ``` ## Notes {#notes} * The `blur` background mode creates a blurred copy of the original image as the pad fill, producing a visually cohesive result. * When using `transparent` background, the output is converted to PNG to preserve alpha. * Output format matches the input format unless transparency is involved. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. * Set `target` to `custom` and provide `ratioW` and `ratioH` for arbitrary aspect ratios (e.g., `ratioW: 3, ratioH: 2` for 3:2). --- --- url: https://docs.snapotter.com/tools/image/sprite-sheet.md description: Combine multiple images into a single sprite sheet grid with frame metadata. --- # Sprite Sheet {#sprite-sheet} Combine multiple images into a single sprite sheet grid. Each image is resized to match the first image's dimensions and placed into the grid. Returns the sprite sheet image along with per-frame coordinate metadata. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/sprite-sheet` Accepts multipart form data with two or more image files and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | columns | integer | No | `4` | Number of columns in the grid (1-16) | | padding | integer | No | `0` | Padding between cells in pixels (0-64) | | background | string | No | `"#ffffff"` | Background hex color | | format | string | No | `"png"` | Output format: `png`, `webp`, or `jpeg` | | quality | integer | No | `90` | Output quality (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sprite-sheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@frame1.png" \ -F "file=@frame2.png" \ -F "file=@frame3.png" \ -F "file=@frame4.png" \ -F 'settings={"columns": 2, "padding": 4, "format": "png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sprite-sheet.png", "originalSize": 120000, "processedSize": 95000, "frames": [ { "index": 0, "left": 0, "top": 0, "width": 128, "height": 128 }, { "index": 1, "left": 132, "top": 0, "width": 128, "height": 128 }, { "index": 2, "left": 0, "top": 132, "width": 128, "height": 128 }, { "index": 3, "left": 132, "top": 132, "width": 128, "height": 128 } ], "cols": 2, "rows": 2, "cellWidth": 128, "cellHeight": 128, "canvasWidth": 260, "canvasHeight": 260 } ``` ## Notes {#notes} * Accepts 2 to 64 images. All images are resized to match the dimensions of the first uploaded image. * The `frames` array provides the exact pixel coordinates of each frame in the output, suitable for CSS sprite definitions or game engine frame maps. * The number of rows is calculated automatically from the image count and `columns` value. * Use the `padding` parameter to add spacing between cells. The `background` color is visible in padding areas and any empty trailing cells. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/image/svg-to-raster.md description: >- Convert SVG files to PNG, JPEG, WebP, AVIF, TIFF, GIF, HEIF, or JXL at custom resolution and DPI, with batch support. --- # SVG to Raster {#svg-to-raster} Convert SVG files to raster image formats (PNG, JPEG, WebP, AVIF, TIFF, GIF, HEIF, or JXL) at custom resolution and DPI. Also supports batch conversion of multiple SVGs. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/svg-to-raster` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | - | Target width in pixels (1 to 65536). Maintains aspect ratio if only one dimension set. | | height | integer | No | - | Target height in pixels (1 to 65536). Maintains aspect ratio if only one dimension set. | | dpi | integer | No | 300 | Render DPI, controls the base rasterization density (36 to 2400) | | quality | number | No | 90 | Output quality for lossy formats (1 to 100) | | backgroundColor | string | No | `"#00000000"` | Background color as hex (6 or 8 characters, 8-char includes alpha) | | outputFormat | string | No | `"png"` | Output format: `png`, `jpg`, `webp`, `avif`, `tiff`, `gif`, `heif`, `jxl` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/svg-to-raster \ -F "file=@logo.svg" \ -F 'settings={"width":1024,"dpi":300,"outputFormat":"png","backgroundColor":"#FFFFFF"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logo.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/preview.webp", "originalSize": 12345, "processedSize": 67890 } ``` ## Batch Endpoint {#batch-endpoint} `POST /api/v1/tools/image/svg-to-raster/batch` Convert multiple SVG files in one request. Returns a ZIP archive. ### Additional Batch Parameters {#additional-batch-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | clientJobId | string | No | - | Optional client-provided job ID for progress tracking (max 128 chars) | ### Batch Example Request {#batch-example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/svg-to-raster/batch \ -F "file=@icon1.svg" \ -F "file=@icon2.svg" \ -F "file=@icon3.svg" \ -F 'settings={"width":512,"outputFormat":"png","dpi":150}' ``` ### Batch Response {#batch-response} The batch endpoint streams a ZIP file directly with headers: * `Content-Type: application/zip` * `X-Job-Id: ` * `X-File-Results: ` ## Notes {#notes} * Only accepts SVG and SVGZ files (validates content, not just extension). SVGZ is automatically decompressed. * SVG content is sanitized before rendering to prevent XSS and external resource loading. * The `dpi` setting controls the density at which the SVG is rasterized. Higher DPI produces larger pixel dimensions from the same SVG viewport. * When both `width` and `height` are provided, the image is resized using `fit: inside` (maintains aspect ratio within the bounds). * A `previewUrl` is included in the response for formats that browsers cannot display natively (TIFF, HEIF). The preview is a 1200px WebP thumbnail. * The default background `#00000000` is fully transparent. Set to `#FFFFFF` for a white background (useful with JPEG output which does not support transparency). * Batch processing respects the `MAX_BATCH_SIZE` server configuration and uses concurrent workers for performance. * Progress for batch operations can be tracked via SSE at `/api/v1/jobs/:jobId/progress`. --- --- url: https://docs.snapotter.com/tools/image/vectorize.md description: >- Convert raster images to SVG with black-and-white (potrace) and full-color multi-layer vectorization. --- # Image to SVG {#image-to-svg} Vectorize raster images into SVG using tracing algorithms. Supports black-and-white tracing (potrace) and full-color multi-layer vectorization. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/vectorize` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | colorMode | string | No | `"bw"` | Tracing mode: `bw` (black and white) or `color` (multi-color layers) | | threshold | number | No | 128 | Brightness threshold for B\&W mode (0 to 255). Pixels below become black. | | colorPrecision | number | No | 6 | Color quantization precision for color mode (1 to 16). Higher values produce more distinct color layers. | | layerDifference | number | No | 6 | Minimum color difference between layers in color mode (1 to 128) | | filterSpeckle | number | No | 4 | Minimum area for traced shapes in pixels (1 to 256). Removes noise/speckles. | | pathMode | string | No | `"spline"` | Path smoothing: `none` (jagged), `polygon` (straight segments), `spline` (smooth curves) | | cornerThreshold | number | No | 60 | Angle threshold for corner detection in color mode (0 to 180 degrees) | | invert | boolean | No | `false` | Invert the image before tracing (swap black/white) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@logo.png" \ -F 'settings={"colorMode":"bw","threshold":128,"filterSpeckle":4,"pathMode":"spline"}' ``` ### Color Vectorization {#color-vectorization} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@illustration.png" \ -F 'settings={"colorMode":"color","colorPrecision":8,"layerDifference":6,"filterSpeckle":4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logo.svg", "originalSize": 45678, "processedSize": 12345 } ``` ## Notes {#notes} * Output is always an SVG file regardless of input format. * Supports HEIC, RAW, PSD, and SVG input formats (automatically decoded to raster before tracing). * B\&W mode uses the potrace algorithm. The image is converted to grayscale first, then thresholded to pure black/white before tracing. * Color mode uses a multi-layer approach: the image is quantized into color layers, each traced separately and stacked in the SVG output. * Lower `filterSpeckle` values preserve more detail but produce larger SVG files with more paths. * The `pathMode` setting significantly affects file size: `none` produces the most paths, `spline` produces the smoothest (and usually smallest) output. * For best results with logos and icons, use B\&W mode with a clean high-contrast input. For photographs or illustrations, use color mode with higher `colorPrecision`. --- --- url: https://docs.snapotter.com/tools/image/gif-tools.md description: >- Resize, optimize, speed-change, reverse, rotate, and extract frames from animated GIFs in a single tool. --- # GIF Tools {#gif-tools} Resize, optimize, change speed, reverse, extract frames, and rotate animated GIFs. Provides multiple operation modes in a single tool. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parameters {#parameters} ### Common Parameters {#common-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"resize"` | Operation mode: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | No | 0 | Loop count for output GIF (0 = infinite, 1-100 = finite loops) | ### Resize Mode Parameters {#resize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | - | Target width in pixels (1 to 16384) | | height | integer | No | - | Target height in pixels (1 to 16384) | | percentage | number | No | - | Scale by percentage (1 to 500). Overrides width/height if set. | ### Optimize Mode Parameters {#optimize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | colors | number | No | 256 | Maximum number of colors in palette (2 to 256) | | dither | number | No | 1.0 | Dithering strength (0 to 1, where 0 disables dithering) | | effort | number | No | 7 | Optimization effort level (1 to 10, higher = slower but smaller) | ### Speed Mode Parameters {#speed-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | speedFactor | number | No | 1.0 | Speed multiplier (0.1 to 10). Values > 1 speed up, < 1 slow down. | ### Extract Mode Parameters {#extract-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | extractMode | string | No | `"single"` | Extraction mode: `single`, `range`, `all` | | frameNumber | number | No | 0 | Frame index to extract in `single` mode (0-based) | | frameStart | number | No | 0 | Start frame index for `range` mode (0-based) | | frameEnd | number | No | - | End frame index for `range` mode (0-based, inclusive) | | extractFormat | string | No | `"png"` | Format for extracted frames: `png`, `webp` | ### Rotate Mode Parameters {#rotate-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | angle | number | No | - | Rotation angle: `90`, `180`, or `270` degrees | | flipH | boolean | No | `false` | Flip horizontally | | flipV | boolean | No | `false` | Flip vertically | ## Example Requests {#example-requests} ### Resize {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimize {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Speed Up {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Extract Single Frame {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info Sub-Route {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Returns metadata about an animated GIF without processing it. ### Info Request {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info Response {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Notes {#notes} * Uses the standard `createToolRoute` factory for the main processing endpoint. * The info endpoint only requires a file upload (no settings needed). * In `resize` mode, if `percentage` is provided it takes priority over `width`/`height`. The resize uses `fit: inside` to maintain aspect ratio. * In `speed` mode, frame delays are divided by the speed factor. Minimum delay per frame is 20ms (GIF spec limitation). * In `reverse` mode, the `speedFactor` parameter is also available to simultaneously adjust speed while reversing. * In `extract` mode with `range` or `all`, the output is a ZIP file containing individual frames. * In `rotate` mode, each frame is processed individually and reassembled into an animation. * The `loop` parameter controls how many times the output GIF loops. Use 0 for infinite looping. * The `duration` field in the info response is the total animation duration in milliseconds. --- --- url: https://docs.snapotter.com/tools/image/gif-webp.md description: Convert animated GIF to WebP and vice versa, preserving all frames. --- # GIF/WebP Converter {#gif-webp-converter} Convert animated GIF files to WebP and vice versa, preserving all frames and animation timing. WebP animations are typically 25-35% smaller than equivalent GIFs. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Accepts multipart form data with a GIF or WebP file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | integer | No | `80` | Output quality for WebP encoding (1-100) | | lossless | boolean | No | `false` | Use lossless WebP compression | | resizePercent | integer | No | `100` | Scale the output by percentage (10-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Notes {#notes} * Only `.gif` and `.webp` files are accepted. Other image formats are not supported by this tool. * The conversion direction is automatic: GIF input produces WebP output, and WebP input produces GIF output. * The `quality` and `lossless` options only apply when encoding to WebP. When converting to GIF, the output uses the standard GIF palette. * Use `resizePercent` to reduce the dimensions (and file size) of large animations. --- --- url: https://docs.snapotter.com/tools/image/remove-background.md description: >- AI-powered background removal with optional effects (blur, shadow, gradient, custom background). --- # Remove Background {#remove-background} AI-powered background removal with optional effects (blur, shadow, gradient, custom background). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/remove-background` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `background-removal` (4-5 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | model | string | No | - | AI model variant to use | | backgroundType | string | No | `"transparent"` | One of: `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | No | - | Hex color for solid background | | gradientColor1 | string | No | - | First gradient color | | gradientColor2 | string | No | - | Second gradient color | | gradientAngle | number | No | - | Gradient angle in degrees | | blurEnabled | boolean | No | - | Enable background blur effect | | blurIntensity | number | No | - | Blur intensity (0-100) | | shadowEnabled | boolean | No | - | Enable drop shadow on subject | | shadowOpacity | number | No | - | Shadow opacity (0-100) | | outputFormat | string | No | - | Output format: `png`, `webp`, or `avif` | | edgeRefine | integer | No | - | Edge refinement level (0-3) | | decontaminate | boolean | No | - | Remove color bleed from edges | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType":"transparent","edgeRefine":2,"outputFormat":"png"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing background...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_mask.png", "maskUrl": "/api/v1/download/{jobId}/photo_mask.png", "originalUrl": "/api/v1/download/{jobId}/photo_original.png", "originalSize": 245000, "processedSize": 180000, "filename": "photo.jpg", "model": "rembg" } } ``` ## Effects Endpoint (Phase 2) {#effects-endpoint-phase-2} `POST /api/v1/tools/image/remove-background/effects` Re-applies background effects without re-running the AI model. Uses cached mask and original from Phase 1. ### Parameters {#parameters-1} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | settings | JSON | Yes | - | JSON with effect settings (see below) | | backgroundImage | file | No | - | Custom background image (when backgroundType is `image`) | #### Settings JSON fields {#settings-json-fields} | Field | Type | Required | Description | |-------|------|----------|-------------| | jobId | string | Yes | Job ID from Phase 1 | | filename | string | Yes | Original filename from Phase 1 | | backgroundType | string | No | `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | No | Hex color for solid background | | gradientColor1 | string | No | First gradient color | | gradientColor2 | string | No | Second gradient color | | gradientAngle | number | No | Gradient angle in degrees | | blurEnabled | boolean | No | Enable background blur | | blurIntensity | number | No | Blur intensity (0-100) | | shadowEnabled | boolean | No | Enable drop shadow | | shadowOpacity | number | No | Shadow opacity (0-100) | | outputFormat | string | No | `png`, `webp`, or `avif` | ### Example Request {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background/effects \ -F 'settings={"jobId":"a1b2c3d4-...","filename":"photo.jpg","backgroundType":"color","backgroundColor":"#FF5500","outputFormat":"png"}' ``` ### Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_nobg.png", "processedSize": 195000 } ``` ## Notes {#notes} * Requires the `background-removal` model bundle to be installed (4-5 GB). * Phase 1 caches the transparent mask and original image so that Phase 2 (effects) can re-apply different backgrounds instantly without re-running the AI model. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. * EXIF rotation is auto-corrected before processing. --- --- url: https://docs.snapotter.com/tools/image/upscale.md description: >- Upscale images 2x to 4x with Real-ESRGAN AI super-resolution while preserving fine detail. --- # Image Upscaling {#image-upscaling} AI super-resolution enhancement using Real-ESRGAN. Upscales images 2x-4x while preserving detail. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/upscale` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `upscale-enhance` (5-6 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | scale | number | No | `2` | Upscale factor (e.g., 2, 3, 4) | | model | string | No | `"auto"` | Model to use (e.g., `auto`, specific model names) | | faceEnhance | boolean | No | `false` | Apply face enhancement during upscaling | | denoise | number | No | `0` | Denoising strength (0 = off) | | format | string | No | `"auto"` | Output format: `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | No | `95` | Output quality (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Notes {#notes} * Requires the `upscale-enhance` model bundle to be installed (5-6 GB). * Uses Real-ESRGAN when available; falls back to Lanczos interpolation if the AI model is unavailable. * The `faceEnhance` option applies GFPGAN face restoration during upscaling for better face quality. * For non-browser-previewable output formats (HEIC, JXL, TIFF), a WebP preview is generated alongside the main output. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/erase-object.md description: >- Remove unwanted objects from images with AI inpainting (LaMa), guided by a mask of the region to erase. --- # Object Eraser {#object-eraser} Remove unwanted objects from images using AI inpainting (LaMa model). Accepts an image and a mask indicating the region to erase. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/erase-object` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Source image file (multipart) | | mask | file | Yes | - | Mask image (white = area to erase, black = keep). Must be uploaded with fieldname `mask` | | format | string | No | `"auto"` | Output format: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | Output quality (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/erase-object \ -F "file=@photo.jpg" \ -F "mask=@mask.png" \ -F "format=png" \ -F "quality=95" ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Inpainting...","percent":70} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_erased.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 245000, "processedSize": 230000 } } ``` ## Notes {#notes} * Requires the `object-eraser-colorize` model bundle to be installed (1-2 GB). * The mask must be the same dimensions as the source image. White pixels indicate areas to erase; the AI fills them with plausible content. * Uses LaMa (Large Mask Inpainting) for high-quality object removal. * For non-browser-previewable output formats, a WebP preview is generated alongside the main output. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/ocr.md description: >- Extract text from images locally with built-in Tesseract or the optional high-accuracy RapidOCR runtime. --- # Extract Text from Image (OCR) {#ocr-text-extraction} Extract text from images without sending the image to an external service. The built-in `fast` tier uses Tesseract. The optional `balanced` and `best` tiers use RapidOCR with pinned PP-OCR ONNX models. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ocr` **Processing:** OCR is always asynchronous. After validation and enqueueing, the endpoint immediately returns `202 Accepted` with a `jobId`. Follow the job's SSE progress stream to its terminal `complete` or `failed` event; a successful event's `result` contains the OCR fields. **Accurate OCR pack:** Optional `ocr` runtime (about 208-234 MiB to download and 409-488 MiB installed, depending on the target). `fast` does not require this pack; the installer verifies the exact sizes bound by the signed index. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart), up to 512 MiB encoded and 40 megapixels decoded; a lower operator upload limit still applies | | quality | string | No | Dynamic | Quality tier: `fast` (Tesseract), `balanced` (RapidOCR with the small PP-OCRv6 models), or `best` (the higher-accuracy medium PP-OCRv6 models with calibrated variant scoring) | | language | string | No | `"auto"` | Language hint: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`. Fast does not support `ko` | | enhance | boolean | No | Tier-dependent | Improve local contrast before recognition. Fast applies it directly; Balanced and Best retain the variant only when calibrated scoring improves the result. Defaults to `true` for `best` and `false` for `fast`/`balanced` | | engine | string | No | - | Deprecated compatibility alias. Use `quality` instead. `tesseract` maps to `fast`; the legacy `paddleocr` value maps to `balanced` but does not load PaddlePaddle | If `quality` and the deprecated `engine` field are both omitted, SnapOtter selects the highest available tier in this order: `best`, `balanced`, `fast`. Korean never selects `fast`; it uses `best`, then `balanced`, or returns the accurate-runtime install or compatibility error. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ocr \ -F "file=@document.png" \ -F 'settings={"quality":"best","language":"en","enhance":true}' ``` ## Accepted response (202) {#accepted-response-202} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress and result (SSE) {#progress-sse-optional} Connect to `GET /api/v1/jobs/{jobId}/progress` with the `jobId` returned by the `202` response (or the supplied `clientJobId`). Keep the stream open until the terminal `complete` or `failed` event. A successful terminal frame contains the OCR output in `result`: ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "type": "single", "phase": "complete", "stage": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document_ocr.txt", "originalSize": 12345, "processedSize": 47, "text": "Extracted text content from the image...", "engine": "rapidocr-onnx", "requestedQuality": "best", "actualQuality": "best", "device": "cpu", "provider": "CPUExecutionProvider", "degraded": false, "warnings": [], "runtimeVersion": "2.2.0", "modelVersion": "PP-OCRv6-best-v1-medium" } } ``` Processing failures arrive in the terminal `failed` event's `error` field; they are not returned as an HTTP `422` after enqueueing. ## Notes {#notes} * `fast` is available in supported SnapOtter images for `auto`, `en`, `de`, `es`, `fr`, `zh`, and `ja`. It does not support Korean (`ko`); Korean requires the optional accurate OCR pack and `balanced` or `best`. * Built-in Tesseract adds about 25 MiB to the official image. The accurate pack is stored in `/data/ai`, not baked into the image. * The accurate pack is published for the official Linux amd64 and arm64 containers. It deliberately uses ONNX Runtime's CPU provider, including on NVIDIA hosts, so it does not depend on CUDA libraries or GPU compatibility. Unsupported hosts receive an explicit incompatibility error for Korean instead of silently falling back to Fast. * The successful terminal `result` includes both the extracted text in `text` and a downloadable `.txt` artifact in `downloadUrl`. * SnapOtter honors an explicitly requested tier. If `balanced` or `best` is unavailable, the API returns `501` with `FEATURE_NOT_INSTALLED` or `FEATURE_INCOMPATIBLE`; it never silently downgrades the request to another tier. Explicit Fast or legacy `tesseract` with Korean returns `FEATURE_INCOMPATIBLE` and `fast-korean-unsupported` before queueing. * A successful empty result remains an empty result. Runtime failures return an error instead of retrying with a lower-quality engine. * The successful terminal `result` reports both `requestedQuality` and `actualQuality`, plus the engine, device, provider, runtime and model versions, and any warnings. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. * Oversized encoded inputs return `413`. Images over 40 megapixels and OCR responses over their bounded output limits are rejected instead of being partially processed. --- --- url: https://docs.snapotter.com/tools/image/blur-faces.md description: >- Auto-detect and blur faces in images with AI face detection for privacy and GDPR-compliant anonymization. --- # Blur Faces & PII {#face-pii-blur} Auto-detect and blur faces in images using AI-powered face detection (MediaPipe). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | blurRadius | number | No | `30` | Blur radius applied to detected faces (1-100) | | sensitivity | number | No | `0.5` | Face detection sensitivity (0-1). Lower values detect fewer faces with higher confidence | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### No Faces Detected {#no-faces-detected} If no faces are found, the result includes a warning: ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Notes {#notes} * Requires the `face-detection` model bundle to be installed (200-300 MB). * Output format matches the input format automatically. * The `faces` array contains bounding box coordinates (x, y, width, height) for each detected face. * Increase `sensitivity` (closer to 1.0) to detect more faces, including partially occluded ones. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/smart-crop.md description: >- Subject-, face-, and entropy-aware cropping that frames images intelligently using Sharp and AI face detection. --- # Smart Crop {#smart-crop} Smart subject-aware, face-aware, or trim-based cropping. Uses Sharp's attention/entropy strategies and AI face detection for intelligent framing. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/smart-crop` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `face-detection` (200-300 MB) - required only for `face` mode ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | mode | string | No | `"subject"` | Crop mode: `subject`, `face`, `trim`. (Legacy values `attention` and `content` map to `subject` and `trim`) | | strategy | string | No | `"attention"` | Strategy for subject mode: `attention` or `entropy` | | width | integer | No | - | Target width in pixels | | height | integer | No | - | Target height in pixels | | padding | integer | No | `0` | Padding percentage around subject (0-50) | | facePreset | string | No | `"head-shoulders"` | Face framing preset: `closeup`, `head-shoulders`, `upper-body`, `half-body` | | sensitivity | number | No | `0.5` | Face detection sensitivity (0-1) | | threshold | integer | No | `30` | Trim mode threshold for background detection (0-255) | | padToSquare | boolean | No | `false` | Pad trimmed result to a square | | padColor | string | No | `"#ffffff"` | Background color for padding | | targetSize | integer | No | - | Target size for padded output (pixels) | | quality | integer | No | - | Output quality (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/smart-crop \ -F "file=@portrait.jpg" \ -F 'settings={"mode":"face","width":1080,"height":1080,"facePreset":"head-shoulders"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_smartcrop.jpg", "originalSize": 500000, "processedSize": 320000 } } ``` ## Modes {#modes} ### Subject Mode {#subject-mode} Uses Sharp's attention or entropy strategy to find the most visually interesting region and crops around it. ### Face Mode {#face-mode} Detects faces using AI, then frames the crop around detected faces using the specified `facePreset`. Falls back to subject mode (attention strategy) if no faces are detected. ### Trim Mode {#trim-mode} Removes uniform borders/background from the image. Optionally pads the result to a square with a specified background color and target size. ## Notes {#notes} * This tool uses the `createToolRoute` factory with `executionHint: "long"`, so it returns 202 with SSE progress. * Face mode requires the `face-detection` model bundle (200-300 MB). * Subject and trim modes work without any AI model bundle. * The `facePreset` determines how tightly the crop frames detected faces: `closeup` is the tightest, `half-body` is the widest. * If no width/height are specified, defaults to 1080x1080. --- --- url: https://docs.snapotter.com/tools/image/image-enhancement.md description: >- One-click auto-enhance that analyzes an image and corrects exposure, contrast, white balance, saturation, and sharpness. --- # Image Enhancement {#image-enhancement} One-click auto-improve with smart analysis. Analyzes the image and applies exposure, contrast, white balance, saturation, sharpness, and denoising corrections. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **Processing:** Synchronous (uses `createToolRoute` factory, returns result directly) **Model bundle:** None required for basic enhancement. The `upscale-enhance` bundle (5-6 GB) is used only when `deepEnhance` is enabled (for AI noise removal via SCUNet). ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | mode | string | No | `"auto"` | Enhancement mode: `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | No | `50` | Overall enhancement intensity (0-100) | | corrections | object | No | all `true` | Selective corrections to apply (see below) | | deepEnhance | boolean | No | `false` | Enable AI-powered noise removal (requires `noise-removal` tool installed) | ### Corrections Object {#corrections-object} | Field | Type | Default | Description | |-------|------|---------|-------------| | exposure | boolean | `true` | Auto-correct exposure | | contrast | boolean | `true` | Auto-correct contrast | | whiteBalance | boolean | `true` | Auto-correct white balance | | saturation | boolean | `true` | Auto-correct saturation | | sharpness | boolean | `true` | Auto-sharpen | | denoise | boolean | `true` | Light denoising | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Analyze Endpoint {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Analyzes an image and returns correction recommendations without applying them. ### Parameters {#parameters-1} | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | file | file | Yes | Image file (multipart) | ### Example Request {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Response (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Notes {#notes} * This tool uses the synchronous `createToolRoute` factory, so it returns a standard response (not 202 async). * The `mode` parameter adjusts how corrections are weighted (e.g., portrait mode is gentler on skin tones, landscape mode boosts saturation). * When `deepEnhance` is enabled and the `noise-removal` tool (SCUNet) is installed, an additional AI denoising pass is applied after the standard corrections. * The analyze endpoint is useful for previewing what corrections would be applied before committing. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/enhance-faces.md description: >- Restore and sharpen blurry or low-quality faces in images with GFPGAN and CodeFormer AI models. --- # Face Enhancement {#face-enhancement} Restore and enhance faces in images using AI models (GFPGAN/CodeFormer). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundles:** `upscale-enhance` (5-6 GB) and `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | model | string | No | `"auto"` | Model to use: `auto`, `gfpgan`, `codeformer` | | strength | number | No | `0.8` | Enhancement strength (0-1). Higher values produce stronger enhancement | | onlyCenterFace | boolean | No | `false` | Only enhance the most central/prominent face | | sensitivity | number | No | `0.5` | Face detection sensitivity (0-1) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Notes {#notes} * Requires both the `upscale-enhance` model bundle (5-6 GB) and the `face-detection` model bundle (200-300 MB). * GFPGAN produces more aggressive enhancement; CodeFormer better preserves identity. `auto` selects the best model for the input. * Output is always PNG format for maximum quality. * A WebP preview is generated alongside the full-resolution output for faster frontend display. * The `strength` parameter blends the enhanced face with the original. Use lower values (0.3-0.5) for subtle improvements, higher values (0.7-1.0) for stronger restoration. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/colorize.md description: >- Colorize black-and-white or grayscale photos automatically with the DDColor AI model. --- # AI Colorization {#ai-colorization} Convert black-and-white or grayscale photos to full color using AI (DDColor model with OpenCV DNN fallback). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/colorize` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | intensity | number | No | `1.0` | Color intensity (0-1). Lower values produce more subtle colorization | | model | string | No | `"auto"` | Model to use: `auto`, `ddcolor`, `opencv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notes {#notes} * Requires the `object-eraser-colorize` model bundle to be installed (1-2 GB). * DDColor produces higher quality results but is slower; OpenCV DNN is faster with slightly lower quality. `auto` uses DDColor when available with OpenCV fallback. * The `intensity` parameter blends between the original grayscale and the AI-colorized result. Use 1.0 for full color, lower values for a partially desaturated vintage look. * Output format matches the input format automatically. * For non-browser-previewable output formats, a WebP preview is generated alongside the main output. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/noise-removal.md description: AI-powered noise and grain removal with multi-tier quality options. --- # Noise Removal {#noise-removal} AI-powered noise and grain removal with multi-tier quality options, using the Python sidecar (SCUNet model). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/noise-removal` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `upscale-enhance` (5-6 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | tier | string | No | `"balanced"` | Quality tier: `quick`, `balanced`, `quality`, `maximum` | | strength | number | No | `50` | Denoising strength (0-100) | | detailPreservation | number | No | `50` | How much detail to preserve (0-100). Higher values keep more texture | | colorNoise | number | No | `30` | Color noise reduction strength (0-100) | | format | string | No | `"original"` | Output format: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | No | `90` | Output encoding quality (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/noise-removal \ -F "file=@noisy-photo.jpg" \ -F 'settings={"tier":"quality","strength":60,"detailPreservation":70,"colorNoise":40}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Denoising...","percent":65} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/noisy-photo_denoised.jpg", "originalSize": 500000, "processedSize": 380000 } } ``` ## Notes {#notes} * Requires the `upscale-enhance` model bundle to be installed (5-6 GB). * Quality tiers trade speed for quality: `quick` is fastest with basic denoising, `maximum` uses the most thorough multi-pass approach. * The `detailPreservation` parameter is critical for textured subjects (fabric, hair, foliage). Higher values prevent the denoiser from smoothing away fine detail. * When `format` is set to `"original"`, the output format matches the input file format. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/red-eye-removal.md description: AI-powered detection and correction of red eye caused by camera flash. --- # Red Eye Removal {#red-eye-removal} AI-powered detection and correction of red eye caused by camera flash. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/red-eye-removal` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | sensitivity | number | No | `50` | Red eye detection sensitivity (0-100). Higher values detect more subtle red-eye | | strength | number | No | `70` | Correction strength (0-100). How aggressively to neutralize red | | format | string | No | - | Output format (optional override) | | quality | number | No | `90` | Output quality (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/red-eye-removal \ -F "file=@flash-photo.jpg" \ -F 'settings={"sensitivity":60,"strength":80}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting red eyes...","percent":40} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/flash-photo_redeye_fixed.png", "originalSize": 280000, "processedSize": 290000, "facesDetected": 2, "eyesCorrected": 4 } } ``` ## Notes {#notes} * Requires the `face-detection` model bundle to be installed (200-300 MB). * First detects faces, then locates eye regions within each face, and finally identifies and corrects red-eye pixels. * The `facesDetected` count indicates how many faces were found; `eyesCorrected` is the total number of individual eyes that had red-eye corrected. * Output is always PNG for maximum quality preservation. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/restore-photo.md description: >- Repair scratches, tears, and damage on old photos with an AI pipeline for restoration, face enhancement, and color. --- # Photo Restoration {#photo-restoration} Fix scratches, tears, and damage on old photos using a multi-step AI pipeline. Combines scratch repair, face enhancement, denoising, and optional colorization. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/restore-photo` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `photo-restoration` (4-5 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | scratchRemoval | boolean | No | `true` | Remove scratches and surface damage | | faceEnhancement | boolean | No | `true` | Enhance faces in the restored photo | | fidelity | number | No | `0.7` | Face enhancement fidelity (0-1). Higher values preserve original features more | | denoise | boolean | No | `true` | Apply denoising to the restored result | | denoiseStrength | number | No | `25` | Denoising strength (0-100) | | colorize | boolean | No | `false` | Colorize the restored photo (for grayscale images) | | colorizeStrength | number | No | `85` | Colorization intensity (0-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/restore-photo \ -F "file=@damaged-old-photo.jpg" \ -F 'settings={"scratchRemoval":true,"faceEnhancement":true,"fidelity":0.6,"colorize":true}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing scratches...","percent":30} ``` ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/damaged-old-photo_restored.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 200000, "processedSize": 350000, "width": 1200, "height": 900, "steps": ["scratch_removal", "face_enhancement", "denoise", "colorize"], "scratchCoverage": 12.5, "facesEnhanced": 2, "isGrayscale": true, "colorized": true } } ``` ## Notes {#notes} * Requires the `photo-restoration` model bundle to be installed (4-5 GB). * The pipeline runs multiple AI steps sequentially: scratch repair, face enhancement (GFPGAN), denoising, and optionally colorization. * The `steps` array in the result shows which processing steps were actually executed. * `scratchCoverage` is an estimated percentage of the image area that had scratch damage. * `fidelity` controls how strongly faces are enhanced vs. preserving the original appearance. Lower values produce more aggressive enhancement; higher values are more conservative. * The `colorize` option automatically detects if the image is grayscale. The `isGrayscale` flag in the result confirms this detection. * Output format matches the input format automatically. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, HDR, and AVIF input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/passport-photo.md description: >- AI-powered passport and ID photo generator with face detection, background removal, and print sheet tiling. --- # Passport Photo {#passport-photo} AI-powered passport and ID photo generator. Two-phase workflow: analyze (face detection + background removal) then generate (crop, resize, and tile for printing). ## API Endpoints {#api-endpoints} This tool uses a two-phase flow with separate endpoints for analysis and generation. **Model bundles:** `background-removal` and `face-detection` *** ### Phase 1: Analyze {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` Detects face landmarks and removes the background. Returns landmark data and a preview for the frontend to display a crop preview. #### Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | clientJobId | string | No | - | Optional job ID for progress tracking via SSE | #### Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/passport-photo/analyze \ -F "file=@headshot.jpg" ``` #### Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "filename": "headshot.jpg", "preview": "", "previewWidth": 800, "previewHeight": 1067, "landmarks": { "leftEye": { "x": 0.42, "y": 0.35 }, "rightEye": { "x": 0.58, "y": 0.35 }, "eyeCenter": { "x": 0.50, "y": 0.35 }, "chin": { "x": 0.50, "y": 0.65 }, "forehead": { "x": 0.50, "y": 0.22 }, "crown": { "x": 0.50, "y": 0.18 }, "nose": { "x": 0.50, "y": 0.48 }, "faceCenterX": 0.50 }, "imageWidth": 2400, "imageHeight": 3200 } ``` #### Progress (SSE, optional) {#progress-sse-optional} If `clientJobId` is provided, progress is streamed (0-30% for face detection, 30-95% for background removal). #### Error: No Face Detected (422) {#error-no-face-detected-422} ```json { "error": "No face detected", "details": "Could not detect a face in the uploaded image. Please upload a clear, front-facing photo with good lighting." } ``` *** ### Phase 2: Generate {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` Crops, resizes, and optionally tiles the photo onto a print sheet. Uses cached images from Phase 1 (no AI re-run). #### Parameters (JSON body) {#parameters-json-body} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | jobId | string | Yes | - | Job ID from Phase 1 | | filename | string | Yes | - | Original filename from Phase 1 | | countryCode | string | Yes | - | Country code for passport spec (e.g., `US`, `GB`, `IN`) | | documentType | string | No | `"passport"` | Document type (from country spec) | | bgColor | string | No | `"#FFFFFF"` | Background color hex | | printLayout | string | No | `"none"` | Print paper layout: `none`, `4x6`, `a4` | | maxFileSizeKb | number | No | `0` | Max file size constraint in KB (0 = no limit) | | dpi | number | No | `300` | Output DPI (72-1200) | | customWidthMm | number | No | - | Custom photo width in mm (overrides country spec) | | customHeightMm | number | No | - | Custom photo height in mm (overrides country spec) | | zoom | number | No | `1` | Zoom factor (0.5-3). Values > 1 crop tighter | | adjustX | number | No | `0` | Horizontal position adjustment | | adjustY | number | No | `0` | Vertical position adjustment | | landmarks | object | Yes | - | Landmarks object from Phase 1 response | | imageWidth | number | Yes | - | Image width from Phase 1 response | | imageHeight | number | Yes | - | Image height from Phase 1 response | #### Example Request {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/passport-photo/generate \ -H "Content-Type: application/json" \ -d '{ "jobId": "a1b2c3d4-...", "filename": "headshot.jpg", "countryCode": "US", "documentType": "passport", "bgColor": "#FFFFFF", "printLayout": "4x6", "dpi": 300, "zoom": 1, "adjustX": 0, "adjustY": 0, "landmarks": { "leftEye": {"x":0.42,"y":0.35}, "rightEye": {"x":0.58,"y":0.35}, "eyeCenter": {"x":0.50,"y":0.35}, "chin": {"x":0.50,"y":0.65}, "forehead": {"x":0.50,"y":0.22}, "crown": {"x":0.50,"y":0.18}, "nose": {"x":0.50,"y":0.48}, "faceCenterX": 0.50 }, "imageWidth": 2400, "imageHeight": 3200 }' ``` #### Response (200 OK) {#response-200-ok-1} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/headshot_passport.jpg", "dimensions": { "widthMm": 51, "heightMm": 51, "widthPx": 602, "heightPx": 602, "dpi": 300 }, "spec": { "country": "United States", "countryCode": "US", "documentType": "passport", "documentLabel": "Passport" }, "printDownloadUrl": "/api/v1/download/{jobId}/headshot_passport_print_4x6.jpg" } ``` *** ### Base Route {#base-route} `POST /api/v1/tools/image/passport-photo` Returns guidance to use the correct sub-endpoint. ```json { "error": "Use /api/v1/tools/image/passport-photo/analyze or /generate" } ``` ## Notes {#notes} * Requires the `background-removal` and `face-detection` model bundles to be installed. * Phase 1 runs AI (face landmarks + background removal) and caches results. Phase 2 is pure Sharp image manipulation (fast, no AI needed). * Landmarks are returned as normalized coordinates (0-1 range relative to image dimensions). * The `preview` field in the analyze response is a base64-encoded PNG (max 800px wide) for fast display. * Country specs include document dimensions, head height ratios, and eye-line positioning based on official passport photo requirements. * The `printLayout` option generates a tiled sheet on 4x6" or A4 paper with 2mm gutters between photos. * When `maxFileSizeKb` is set, the output is iteratively compressed to fit within the size limit. --- --- url: https://docs.snapotter.com/tools/image/content-aware-resize.md description: >- Seam-carving resize that adds or removes pixels along low-importance paths to preserve key content and faces. --- # Content-Aware Resize {#content-aware-resize} Seam carving resize that intelligently removes or adds pixels along paths of least visual importance, preserving important content and optionally protecting faces. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/content-aware-resize` **Processing:** Synchronous (returns result directly) **Model bundle:** None required for basic operation. Face protection uses the `face-detection` bundle (200-300 MB) if enabled. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | width | number | No | - | Target width in pixels | | height | number | No | - | Target height in pixels | | protectFaces | boolean | No | `false` | Detect and protect faces from seam removal | | blurRadius | number | No | `4` | Pre-processing blur radius for energy calculation (0-20) | | sobelThreshold | number | No | `2` | Sobel edge detection threshold (1-20). Higher values make the algorithm more aggressive | | square | boolean | No | `false` | Resize to a square (uses the smaller dimension) | At least one of `width`, `height`, or `square` must be specified. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/content-aware-resize \ -F "file=@landscape.jpg" \ -F 'settings={"width":800,"protectFaces":true}' ``` ## Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/landscape_seam.png", "originalSize": 450000, "processedSize": 380000, "width": 800, "height": 600 } ``` ## Notes {#notes} * This custom route currently returns a synchronous 200 response. * Uses the `caire` seam carving library for content-aware resizing. * Only reduces dimensions (removes seams). Cannot expand an image beyond its original size. * The `protectFaces` option uses AI face detection to mark face regions as high-energy, preventing seams from passing through faces. * `blurRadius` controls smoothing before energy map calculation. Higher values make the energy map more uniform, which can help with noisy images. * `sobelThreshold` affects how aggressively edges are detected. Lower values preserve more subtle edges. * Output is always PNG format. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/ai-canvas-expand.md description: >- Expand an image canvas with AI outpainting, extending it in any direction and filling new areas to match the original. --- # AI Canvas Expand {#ai-canvas-expand} Expand the canvas of an image with AI-powered fill (outpainting). Extends the image in any direction and fills the new areas with AI-generated content that matches the existing image. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | extendTop | integer | No | `0` | Pixels to extend at the top | | extendRight | integer | No | `0` | Pixels to extend at the right | | extendBottom | integer | No | `0` | Pixels to extend at the bottom | | extendLeft | integer | No | `0` | Pixels to extend at the left | | tier | string | No | `"balanced"` | Quality tier: `fast`, `balanced`, `high` | | format | string | No | `"auto"` | Output format: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | Output quality (1-100) | At least one extend direction must be greater than 0. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * Requires the `object-eraser-colorize` model bundle to be installed (1-2 GB). * Uses LaMa-based outpainting to generate content for the expanded regions. * The `tier` parameter trades speed for quality: `fast` produces results quickly with potential artifacts, `high` takes longer but produces smoother, more coherent fills. * Extend values are in pixels. The final image dimensions will be: original width + extendLeft + extendRight by original height + extendTop + extendBottom. * For non-browser-previewable output formats (HEIC, JXL, TIFF), a WebP preview is generated alongside the main output. * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/transparency-fixer.md description: >- Fix fake transparent PNGs with AI matting (BiRefNet) to produce true alpha, plus defringe edge cleanup. --- # PNG Transparency Fixer {#png-transparency-fixer} Fix fake transparent PNGs in one click. Uses AI matting (BiRefNet HR Matting model) to produce true alpha transparency, with defringe post-processing to clean up edges. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/transparency-fixer` **Processing:** Asynchronous (returns 202, poll `/api/v1/jobs/{jobId}/progress` for status via SSE) **Model bundle:** `background-removal` (4-5 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Image file (multipart) | | defringe | number | No | `30` | Defringe intensity (0-100). Removes semi-transparent fringe pixels around edges | | outputFormat | string | No | `"png"` | Output format: `png` or `webp` | | removeWatermark | boolean | No | `false` | Apply watermark removal pre-processing (median filter) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":40,"outputFormat":"png"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Processing transparency...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/fake-transparent_fixed.png", "originalSize": 180000, "processedSize": 150000, "filename": "fake-transparent.png" } } ``` ## Notes {#notes} * Requires the `background-removal` model bundle to be installed (4-5 GB). * Uses `birefnet-hr-matting` as the primary model for high-quality alpha matting. Falls back to `birefnet-general` if the HR model runs out of memory. * The `defringe` option removes semi-transparent fringe pixels that AI matting sometimes leaves around hair, fur, and fine edges. It works by blurring the alpha channel and zeroing out low-confidence pixels. * The `removeWatermark` option applies a median filter pre-processing step. It is a basic watermark reduction, not a dedicated watermark removal tool. * Only outputs PNG or lossless WebP (both support alpha transparency). * Supports HEIC/HEIF, RAW, TGA, PSD, EXR, and HDR input formats via automatic decoding. --- --- url: https://docs.snapotter.com/tools/image/background-replace.md description: Replace image background with a solid color or gradient using AI. --- # Background Replace {#background-replace} Replace the background of an image with a solid color or gradient. The AI model detects the subject, removes the original background, and composites the subject onto your chosen background. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"color"` | Background mode: `color` or `gradient` | | color | string | No | `"#ffffff"` | Background hex color (when backgroundType is `color`) | | gradientColor1 | string | No | - | First gradient hex color | | gradientColor2 | string | No | - | Second gradient hex color | | gradientAngle | integer | No | `180` | Gradient angle in degrees (0-360) | | feather | integer | No | `0` | Edge feathering radius (0-20) | | format | string | No | `"png"` | Output format: `png` or `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Track progress via SSE at `GET /api/v1/jobs/{jobId}/progress`. When the job completes, the SSE stream emits a `completed` event with the download URL. ## Notes {#notes} * This is an AI-powered tool that returns `202 Accepted` and processes asynchronously. Connect to the SSE endpoint to receive progress updates and the final result. * Requires the **background-removal** feature bundle to be installed. Returns `501` if the bundle is not available. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. * Output defaults to PNG to preserve transparency around the subject. --- --- url: https://docs.snapotter.com/tools/image/blur-background.md description: Blur the background while keeping the subject sharp using AI. --- # Blur Background {#blur-background} Blur the background of an image while keeping the subject sharp. The AI model isolates the subject, applies a blur to the original background, and composites the sharp subject on top. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` Accepts multipart form data with an image file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | No | `50` | Blur intensity (1-100) | | feather | integer | No | `0` | Edge feathering radius (0-20) | | format | string | No | `"png"` | Output format: `png` or `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Track progress via SSE at `GET /api/v1/jobs/{jobId}/progress`. When the job completes, the SSE stream emits a `completed` event with the download URL. ## Notes {#notes} * This is an AI-powered tool that returns `202 Accepted` and processes asynchronously. Connect to the SSE endpoint to receive progress updates and the final result. * Requires the **background-removal** feature bundle to be installed. Returns `501` if the bundle is not available. * Higher intensity values produce a stronger blur effect. Values above 80 create a pronounced bokeh-like separation. * HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. --- --- url: https://docs.snapotter.com/tools/video/convert-video.md description: Convert videos between MP4, MOV, WebM, AVI, and MKV. --- # Convert Video {#convert-video} Convert videos between MP4, MOV, WebM, AVI, and MKV formats with configurable quality presets. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Output format: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Quality preset: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * The `high` quality preset produces the best visual fidelity but larger files. The `small` preset aggressively compresses for minimum file size. * WebM output uses VP9 encoding. MP4 and MOV use H.264. AVI and MKV are available for legacy or archival workflows. * Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. --- --- url: https://docs.snapotter.com/tools/video/compress-video.md description: Shrink video file size with quality control. --- # Compress Video {#compress-video} Shrink video file size using configurable compression strength and optional resolution downscaling. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Compression strength: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Output resolution: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * The `light` preset preserves near-original quality. The `strong` preset reduces file size aggressively at the cost of visual fidelity. * Downscaling resolution (e.g. from 4K to 720p) compounds with compression for significant size reduction. * Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. --- --- url: https://docs.snapotter.com/tools/video/trim-video.md description: Cut a clip out of a video by specifying start and end times. --- # Trim Video {#trim-video} Cut a clip out of a video by specifying start and end times in seconds, with an option for frame-accurate cuts. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/trim-video` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | startS | number | No | `0` | Start time in seconds (must be >= 0) | | endS | number | Yes | - | End time in seconds (must be after startS) | | precise | boolean | No | `false` | Re-encode for frame-accurate cuts instead of keyframe seek | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/trim-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"startS": 5, "endS": 30, "precise": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 4200000 } ``` ## Notes {#notes} * When `precise` is `false` (the default), the tool uses keyframe seeking, which is fast but may start a few frames before the requested time. * Setting `precise` to `true` re-encodes the segment for exact frame boundaries, but takes longer. * The `endS` value must be greater than `startS`. --- --- url: https://docs.snapotter.com/tools/video/mute-video.md description: Remove the audio track from a video. --- # Mute Video {#mute-video} Remove the audio track from a video, leaving only the visual stream. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/mute-video` Accepts multipart form data with a video file. This tool has no configurable settings. ## Parameters {#parameters} This tool has no parameters. It strips the audio track from the uploaded video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/mute-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 8900000 } ``` ## Notes {#notes} * The video stream is copied without re-encoding, so there is no quality loss. * If the input video has no audio track, the file is returned unchanged. --- --- url: https://docs.snapotter.com/tools/video/video-to-gif.md description: Turn a video clip into an animated GIF. --- # Video to GIF {#video-to-gif} Turn a video clip into an animated GIF with configurable frame rate, width, start time, and duration. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-to-gif` Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | integer | No | `12` | Output frame rate (1-30) | | width | integer | No | `480` | Output width in pixels (64-1280). Height scales proportionally | | startS | number | No | `0` | Start time in seconds (must be >= 0) | | durationS | number | No | `5` | Duration in seconds (above 0, max 60) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-to-gif \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 15, "width": 320, "startS": 2, "durationS": 8}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Lower `fps` and `width` values produce smaller GIF files. A 480px-wide GIF at 12 fps is usually a good balance. * Maximum duration is 60 seconds. Longer clips produce very large files. * Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. --- --- url: https://docs.snapotter.com/tools/video/resize-video.md description: Scale a video to a new resolution or preset size. --- # Resize Video {#resize-video} Scale a video to a new resolution using custom pixel dimensions or a standard preset. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/resize-video` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | - | Target width in pixels (16-7680) | | height | integer | No | - | Target height in pixels (16-4320) | | preset | string | No | `"custom"` | Resolution preset: `custom`, `2160p`, `1440p`, `1080p`, `720p`, `480p`, `360p` | When `preset` is `"custom"`, at least one of `width` or `height` must be provided. The other dimension scales proportionally. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/resize-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"preset": "720p"}' ``` Resize to custom dimensions: ```bash curl -X POST http://localhost:1349/api/v1/tools/video/resize-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 1280, "height": 720}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 25000000, "processedSize": 8500000 } ``` ## Notes {#notes} * Preset values map to standard heights (e.g. `720p` = 1280x720, `1080p` = 1920x1080). Width scales proportionally from the source aspect ratio. * Dimensions are rounded to even numbers as required by most video codecs. * Maximum supported resolution is 7680x4320 (8K UHD). --- --- url: https://docs.snapotter.com/tools/video/crop-video.md description: Crop a region out of a video. --- # Crop Video {#crop-video} Crop a rectangular region out of a video by specifying the region's size and position. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Crop region width in pixels (minimum 16) | | height | integer | Yes | - | Crop region height in pixels (minimum 16) | | x | integer | No | `0` | Horizontal offset from the top-left corner | | y | integer | No | `0` | Vertical offset from the top-left corner | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * The crop region must fit within the video dimensions. If `x + width` or `y + height` exceeds the source size, the request returns a 400 error. * Minimum crop size is 16x16 pixels. * Dimensions are rounded to even numbers as required by most video codecs. --- --- url: https://docs.snapotter.com/tools/video/rotate-video.md description: Rotate or flip a video. --- # Rotate Video {#rotate-video} Rotate a video by 90, 180, or 270 degrees, or flip it horizontally or vertically. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/rotate-video` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | transform | string | Yes | - | Transformation to apply: `cw90`, `ccw90`, `180`, `hflip`, `vflip` | ### Transform Values {#transform-values} * **cw90** - Rotate 90 degrees clockwise * **ccw90** - Rotate 90 degrees counter-clockwise * **180** - Rotate 180 degrees * **hflip** - Flip horizontally (mirror) * **vflip** - Flip vertically ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/rotate-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"transform": "cw90"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12400000 } ``` ## Notes {#notes} * Rotations by 90 or 270 degrees swap the video's width and height. * Flip operations (hflip, vflip) do not change the video dimensions. --- --- url: https://docs.snapotter.com/tools/video/change-fps.md description: Change the frame rate of a video. --- # Change FPS {#change-fps} Change the frame rate of a video to a target value between 1 and 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Target frame rate (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Lowering the frame rate drops frames and reduces file size. Increasing it duplicates frames to fill the gap but does not add real motion detail. * Common target values: 24 (cinema), 30 (web/broadcast), 60 (smooth playback). * The audio track is preserved at its original sample rate. --- --- url: https://docs.snapotter.com/tools/video/video-color.md description: Adjust brightness, contrast, saturation, and gamma of a video. --- # Video Color {#video-color} Adjust brightness, contrast, saturation, and gamma correction on a video. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-color` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | Brightness adjustment (-1 to 1) | | contrast | number | No | `1` | Contrast multiplier (0-4) | | saturation | number | No | `1` | Saturation multiplier (0-3). Set to 0 for grayscale | | gamma | number | No | `1` | Gamma correction (0.1-10) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-color \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"brightness": 0.1, "contrast": 1.2, "saturation": 1.5}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12300000 } ``` ## Notes {#notes} * All values at their defaults (brightness 0, contrast 1, saturation 1, gamma 1) produce no change. * Setting saturation to `0` converts the video to grayscale. * Gamma values below 1 brighten shadows, while values above 1 darken them. --- --- url: https://docs.snapotter.com/tools/video/video-speed.md description: Speed up or slow down a video. --- # Video Speed {#video-speed} Speed up or slow down a video with an option to preserve audio pitch. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-speed` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | factor | number | No | `2` | Speed multiplier (0.25-4). Values above 1 speed up, below 1 slow down | | keepPitch | boolean | No | `true` | Preserve audio pitch when changing speed | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"factor": 0.5, "keepPitch": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 24800000 } ``` ## Notes {#notes} * A factor of `2` doubles playback speed (halves duration). A factor of `0.5` halves playback speed (doubles duration). * When `keepPitch` is `true`, the audio is time-stretched so voices sound natural. When `false`, pitch shifts proportionally with speed. * The valid range is 0.25x to 4x. --- --- url: https://docs.snapotter.com/tools/video/reverse-video.md description: Play a video clip backwards. --- # Reverse Video {#reverse-video} Play a video clip backwards. The audio track is also reversed. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/reverse-video` Accepts multipart form data with a video file. This tool has no configurable settings. ## Parameters {#parameters} This tool has no parameters. It reverses the entire video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/reverse-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12600000 } ``` ## Notes {#notes} * Limited to clips up to 5 minutes in length. Longer videos are rejected with a 400 error. * Both video and audio tracks are reversed. To reverse video without audio, mute it first. --- --- url: https://docs.snapotter.com/tools/video/video-loudnorm.md description: Normalize video audio volume to broadcast standard. --- # Normalize Video Audio {#normalize-audio} Normalize video audio volume to the EBU R128 broadcast loudness standard. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-loudnorm` Accepts multipart form data with a video file. This tool has no configurable settings. ## Parameters {#parameters} This tool has no parameters. It applies EBU R128 loudness normalization to the audio track. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-loudnorm \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12500000 } ``` ## Notes {#notes} * Uses FFmpeg's `loudnorm` filter targeting -16 LUFS integrated loudness with -1.5 dBTP true peak and 11 LU loudness range (EBU R128 broadcast standard). * The source audio sample rate is preserved in the output. * If the video has no audio track, the request returns a 400 error. --- --- url: https://docs.snapotter.com/tools/video/aspect-pad.md description: Add solid-color bars to fit a target aspect ratio. --- # Aspect Pad {#aspect-pad} Add solid-color letterbox or pillarbox bars to fit a video into a target aspect ratio without cropping. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | Target aspect ratio: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | No | `"#000000"` | Hex color for the padding bars (e.g. `"#000000"` for black) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * If the video already matches the target aspect ratio, the file is returned unchanged. * Use `9:16` for vertical/portrait social media formats (TikTok, Reels, Shorts). * For blurred padding instead of solid color, use the Blur Pad tool. --- --- url: https://docs.snapotter.com/tools/video/blur-pad.md description: Fill bars with a blurred copy of the video. --- # Blur Pad {#blur-pad} Fit a video into a target aspect ratio by filling the padding area with a blurred, scaled copy of the video instead of solid-color bars. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | Target aspect ratio: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | No | `20` | Gaussian blur sigma for the background (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Higher blur values produce a softer, more abstract background. Lower values keep more detail visible. * If the video already matches the target aspect ratio, the file is returned unchanged. * For solid-color padding, use the Aspect Pad tool instead. --- --- url: https://docs.snapotter.com/tools/video/watermark-video.md description: Burn a text watermark onto video frames. --- # Watermark Video {#watermark-video} Burn a text watermark onto every frame of a video with configurable position, size, opacity, and color. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/watermark-video` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Watermark text (1-200 characters) | | position | string | No | `"br"` | Position on the frame: `tl`, `tc`, `tr`, `l`, `c`, `r`, `bl`, `bc`, `br` | | fontSize | integer | No | `36` | Font size in pixels (8-120) | | opacity | number | No | `0.5` | Watermark opacity (0.05-1) | | color | string | No | `"#ffffff"` | Hex color for the text (e.g. `"#ffffff"`) | ### Position Values {#position-values} * **tl** - Top left, **tc** - Top center, **tr** - Top right * **l** - Middle left, **c** - Center, **r** - Middle right * **bl** - Bottom left, **bc** - Bottom center, **br** - Bottom right ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/watermark-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"text": "PREVIEW", "position": "c", "fontSize": 48, "opacity": 0.3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12400000 } ``` ## Notes {#notes} * The watermark is permanently rendered into the video frames and cannot be removed after processing. * The watermark uses a sans-serif font built into FFmpeg. * For image watermarks, use the image Watermark tool instead. --- --- url: https://docs.snapotter.com/tools/video/stabilize-video.md description: Reduce camera shake with two-pass stabilization. --- # Stabilize Video {#stabilize-video} Reduce camera shake in handheld footage using FFmpeg's two-pass vidstab stabilization. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/stabilize-video` Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | smoothing | integer | No | `15` | Smoothing window size in frames (5-60). Higher values produce smoother motion | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/stabilize-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"smoothing": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Stabilization is a two-pass process: the first pass analyzes camera motion, and the second pass applies the correction. This takes roughly twice as long as single-pass tools. * Higher smoothing values remove more shake but may introduce a slight zoom crop at the edges. * Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. --- --- url: https://docs.snapotter.com/tools/video/gif-to-video.md description: Convert an animated GIF into an MP4, WebM, or MOV video. --- # GIF to Video {#gif-to-video} Convert an animated GIF into a compact MP4, WebM, or MOV video file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Accepts multipart form data with a GIF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Output format: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Converting GIF to video typically reduces file size by 80-90% while maintaining the same visual quality. * Only animated GIF files are accepted. Static images should use the image Convert tool. * MP4 and MOV use H.264 encoding, WebM uses VP9. --- --- url: https://docs.snapotter.com/tools/video/video-to-webp.md description: Convert a video clip into an animated WebP image. --- # Video to WebP {#video-to-webp} Convert a video clip into an animated WebP image with configurable frame rate, width, and quality. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-to-webp` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | integer | No | `12` | Output frame rate (1-30) | | width | integer | No | `480` | Output width in pixels (16-1920). Height scales proportionally | | quality | integer | No | `75` | WebP compression quality (1-100) | | loop | boolean | No | `true` | Loop the animation | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-to-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 15, "width": 640, "quality": 80}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.webp", "originalSize": 12500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Animated WebP produces smaller files than GIF with better color support (24-bit vs 8-bit palette). * Lower `quality` values produce smaller files at the cost of visual fidelity. * Set `loop` to `false` for animations that should play once and stop. --- --- url: https://docs.snapotter.com/tools/video/video-to-frames.md description: Extract frames from a video as a ZIP of images. --- # Video to Frames {#video-to-frames} Extract individual frames from a video and download them as a ZIP archive of PNG or JPG images. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-to-frames` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"all"` | Extraction mode: `all`, `nth`, `timestamps` | | n | integer | No | `10` | Extract every Nth frame (2-1000). Only used when mode is `"nth"` | | timestamps | string | No | `""` | Comma-separated timestamps in seconds. Required when mode is `"timestamps"` | | format | string | No | `"png"` | Image format for extracted frames: `png`, `jpg` | ## Example Request {#example-request} Extract every 30th frame as JPG: ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-to-frames \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"mode": "nth", "n": 30, "format": "jpg"}' ``` Extract frames at specific timestamps: ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-to-frames \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"mode": "timestamps", "timestamps": "1.5,5,12.3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip-frames.zip", "originalSize": 12500000, "processedSize": 45000000 } ``` ## Notes {#notes} * The `all` mode extracts every frame and can produce very large ZIP files for long videos. Use `nth` or `timestamps` mode for selective extraction. * PNG preserves full quality but produces larger files. JPG is smaller but lossy. * The response downloads as a ZIP archive containing sequentially numbered image files. --- --- url: https://docs.snapotter.com/tools/video/merge-videos.md description: Join multiple video clips into one file. --- # Merge Videos {#merge-videos} Join multiple video clips into a single MP4 file. All inputs are normalized to the first video's resolution and 30 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/merge-videos` Accepts multipart form data with two or more video files. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} This tool has no settings parameters. Upload 2-10 video files as multiple `file` parts. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/merge-videos \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@intro.mp4" \ -F "file=@main.mp4" \ -F "file=@outro.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Clips are concatenated in the order they are uploaded. * All clips are re-encoded to match the first clip's resolution, frame rate (30 fps), and codec (H.264). Mismatched inputs are automatically normalized. * Accepts 2-10 video files per request. * Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. --- --- url: https://docs.snapotter.com/tools/video/replace-audio.md description: Swap the audio track of a video with another file. --- # Replace Audio {#replace-audio} Swap the audio track of a video with an audio file. Upload both a video and an audio file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/replace-audio` Accepts multipart form data with exactly two files: a video file followed by an audio file. ## Parameters {#parameters} This tool has no settings parameters. Upload a video file and an audio file as two `file` parts. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/replace-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@voiceover.mp3" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13100000 } ``` ## Notes {#notes} * Exactly two files must be uploaded: the first must be a video, the second must be an audio file. * If the audio file is longer than the video, it is trimmed to match the video duration. If shorter, the remaining video plays in silence. * The video stream is copied without re-encoding, so there is no video quality loss. --- --- url: https://docs.snapotter.com/tools/video/burn-subtitles.md description: Permanently render subtitles onto video frames. --- # Burn Subtitles {#burn-subtitles} Permanently render (hard-code) subtitles from an SRT, VTT, or ASS file onto every frame of a video. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Accepts multipart form data with a video file and a subtitle file. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Subtitle font size in pixels (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Upload two files: the first must be a video, the second must be a subtitle file (.srt, .vtt, or .ass). * Burned subtitles are permanently part of the video and cannot be turned off by the viewer. For toggleable subtitles, use the Embed Subtitles tool instead. * Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. --- --- url: https://docs.snapotter.com/tools/video/embed-subtitles.md description: Mux a subtitle track into the video container. --- # Embed Subtitles {#embed-subtitles} Mux a subtitle file into the video container as a soft subtitle track that viewers can toggle on or off. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Accepts multipart form data with a video file and a subtitle file, plus a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B language code (3 lowercase letters, e.g. `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Upload two files: the first must be a video, the second must be a subtitle file (.srt, .vtt, or .ass). * Embedded (soft) subtitles can be toggled by the viewer in their media player. For permanently visible subtitles, use the Burn Subtitles tool instead. * The language code is stored as metadata in the container and helps media players label the subtitle track. --- --- url: https://docs.snapotter.com/tools/video/extract-subtitles.md description: Pull the subtitle track out of a video as an SRT file. --- # Extract Subtitles {#extract-subtitles} Extract the embedded subtitle track from a video container and download it as an SRT file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Accepts multipart form data with a video file. This tool has no configurable settings. ## Parameters {#parameters} This tool has no parameters. It extracts the first subtitle track found in the video container. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * The video must contain an embedded subtitle track. If no subtitle track is found, the request returns a 400 error. * If the video has multiple subtitle tracks, the first one is extracted. * The output format is SRT regardless of the original subtitle format in the container. --- --- url: https://docs.snapotter.com/tools/video/images-to-video.md description: Turn a set of images into a slideshow video. --- # Images to Video {#images-to-video} Turn a set of images into a slideshow video with configurable duration per image, resolution, and frame rate. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/images-to-video` Accepts multipart form data with two or more image files and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | secondsPerImage | number | No | `2` | Display duration per image in seconds (0.5-10) | | resolution | string | No | `"720p"` | Output resolution: `1080p`, `720p`, `square` | | fps | integer | No | `30` | Output frame rate (10-60) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/images-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slide1.jpg" \ -F "file=@slide2.jpg" \ -F "file=@slide3.jpg" \ -F "file=@slide4.jpg" \ -F 'settings={"secondsPerImage": 3, "resolution": "1080p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/slideshow.mp4", "originalSize": 3500000, "processedSize": 1200000 } ``` ## Notes {#notes} * Accepts 2-60 image files per request. Images appear in the video in upload order. * Images are resized and padded to fit the target resolution while preserving aspect ratio. * The `square` resolution option produces a 1080x1080 video, useful for social media. * Output format is always MP4 (H.264). --- --- url: https://docs.snapotter.com/tools/video/video-metadata.md description: Strip metadata from a video and report what was found. --- # Clean Video Metadata {#clean-video-metadata} Strip metadata (creation date, GPS coordinates, camera model, software tags, etc.) from a video and report what was removed. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Accepts multipart form data with a video file. This tool has no configurable settings. ## Parameters {#parameters} This tool has no parameters. It strips all metadata from the video container. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Metadata stripped includes creation timestamps, GPS/location data, camera/device info, and software tags. * The video and audio streams are copied without re-encoding, so there is no quality loss. * Useful for privacy before sharing videos publicly. --- --- url: https://docs.snapotter.com/tools/video/auto-subtitles.md description: Generate subtitle files from video audio tracks using AI. --- # Auto Subtitles {#auto-subtitles} Generate subtitle files from a video's audio track using AI-powered speech recognition (faster-whisper). Supports auto-detection and 10 explicit languages. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | Speech language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | No | `"srt"` | Output subtitle format: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * This is an AI tool that requires the **transcription** feature bundle to be installed. If the bundle is not installed, the API returns `501 Feature Not Installed` with instructions to install it via the admin UI. * The `auto` language option uses whisper's built-in language detection. Specifying the language explicitly improves accuracy and speed. * SRT is the most widely supported subtitle format. VTT (WebVTT) is the standard for web video players. * Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. --- --- url: https://docs.snapotter.com/tools/video/extract-audio.md description: Pull the audio track out of a video. --- # Extract Audio {#extract-audio} Extract the audio track from a video file and save it as MP3, WAV, M4A, or OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Accepts multipart form data with a video file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Output audio format: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * If the video has no audio track, the request returns a 400 error. * MP3 is lossy but widely compatible. WAV is lossless but large. M4A (AAC) offers a good balance of quality and size. OGG is available for open codec workflows. * When the source audio is already AAC and the output format is M4A, the audio stream is copied without re-encoding. --- --- url: https://docs.snapotter.com/tools/audio/convert-audio.md description: Convert audio between MP3, WAV, OGG, FLAC, and M4A formats. --- # Convert Audio {#convert-audio} Convert audio files between common formats including MP3, WAV, OGG, FLAC, and M4A, with configurable output bitrate and sample rate. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Output format: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | No | `192` | Output bitrate in kbps (32 to 320) | | sampleRate | integer | No | source rate | Output sample rate in Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000`, or `96000`. Omit to keep the source rate | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Supported input formats include MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF, and OPUS. * Bitrate only applies to lossy formats (MP3, OGG, M4A). Lossless formats like WAV and FLAC ignore this setting. * MP3 output supports sample rates up to 48000 Hz. The 96000 Hz option applies to WAV, OGG, FLAC, and M4A only. * MP3 bitrate is capped by the sample rate: at most 64 kbps at 8000 Hz and 160 kbps at 16000 or 22050 Hz. Requests above the cap are rejected instead of being silently lowered. * The output filename keeps the original name with the new extension. --- --- url: https://docs.snapotter.com/tools/audio/trim-audio.md description: Cut a section out of an audio file by specifying start and end times. --- # Trim Audio {#trim-audio} Cut a section out of an audio file by specifying start and end times in seconds. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/trim-audio` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | startS | number | No | `0` | Start time in seconds (minimum 0) | | endS | number | Yes | - | End time in seconds (must be after start) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/trim-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"startS": 10, "endS": 45}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 1575000 } ``` ## Notes {#notes} * Times are specified in seconds and can include decimals (e.g. `10.5`). * The `endS` value must be greater than `startS`. * If `endS` exceeds the audio duration, the file is trimmed to the end. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/volume-adjust.md description: Increase or decrease audio volume by a fixed gain in decibels. --- # Adjust Volume {#volume-adjust} Increase or decrease the volume of an audio file by applying a fixed gain in decibels. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/volume-adjust` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | gainDb | number | No | `3` | Volume adjustment in decibels (-30 to 30) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/volume-adjust \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"gainDb": 6}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Positive values increase volume; negative values decrease it. * Large positive gains can cause clipping. Use normalize-audio for loudness-safe leveling. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/normalize-audio.md description: Even out loudness to broadcast standard levels (EBU R128). --- # Normalize Audio {#normalize-audio} Even out audio loudness to broadcast standard levels using EBU R128 normalization (-16 LUFS). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/normalize-audio` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} This tool has no configurable parameters. It applies EBU R128 loudness normalization automatically. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/normalize-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Uses the EBU R128 loudness standard, targeting -16 LUFS. * Ideal for podcasts, audiobooks, and broadcast content where consistent loudness is important. * The source sample rate is preserved in the output. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/fade-audio.md description: Add fade-in and fade-out effects to audio. --- # Fade Audio {#fade-audio} Add fade-in and fade-out effects to the beginning and end of an audio file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fadeInS | number | No | `1` | Fade-in duration in seconds (0 to 30) | | fadeOutS | number | No | `1` | Fade-out duration in seconds (0 to 30) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Set either value to `0` to skip that fade direction. At least one must be greater than 0. * The fade duration is clamped to the audio length if it exceeds it. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/reverse-audio.md description: Reverse an audio file so it plays backwards. --- # Reverse Audio {#reverse-audio} Reverse an audio file so it plays backwards. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/reverse-audio` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} This tool has no configurable parameters. The entire audio file is reversed. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/reverse-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * The full audio track is reversed from end to start. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/audio-speed.md description: Speed up or slow down audio playback with a multiplier. --- # Audio Speed {#audio-speed} Speed up or slow down audio playback by applying a speed multiplier. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | factor | number | No | `1.5` | Speed multiplier (0.25 to 4). Values below 1 slow down; above 1 speed up. | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## Notes {#notes} * A factor of `0.25` plays at quarter speed (4x longer). A factor of `4` plays at quadruple speed (4x shorter). * Pitch is preserved while speed changes (time-stretch). Use pitch-shift to adjust pitch independently. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/pitch-shift.md description: Raise or lower audio pitch by semitones without changing speed. --- # Pitch Shift {#pitch-shift} Raise or lower the pitch of an audio file by a number of semitones without changing its playback speed. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/pitch-shift` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | semitones | integer | No | `3` | Semitones to shift (-12 to 12). Must be nonzero. | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/pitch-shift \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"semitones": -5}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Positive values raise the pitch; negative values lower it. * A shift of 12 semitones equals one octave up; -12 equals one octave down. * Playback duration stays the same regardless of the shift amount. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/audio-channels.md description: Convert between mono and stereo or swap left and right channels. --- # Audio Channels {#audio-channels} Convert audio between mono and stereo layouts, or swap the left and right channels of a stereo file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | Yes | - | Channel operation: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Notes {#notes} * `stereo-to-mono` mixes both channels into a single mono track. * `mono-to-stereo` duplicates the mono channel to both left and right. * `swap` exchanges the left and right channels of a stereo file. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/silence-removal.md description: Strip silent sections from an audio file. --- # Silence Removal {#silence-removal} Detect and remove silent sections from an audio file based on a configurable threshold and minimum duration. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/silence-removal` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | thresholdDb | number | No | `-50` | Silence threshold in dB (-80 to -20). Audio below this level is considered silent. | | minSilenceS | number | No | `0.5` | Minimum silence duration in seconds to remove (0.1 to 5) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/silence-removal \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"thresholdDb": -45, "minSilenceS": 1}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 3200000 } ``` ## Notes {#notes} * A higher (less negative) threshold is more aggressive and removes quieter passages as well as true silence. * Increase `minSilenceS` to only strip longer pauses while keeping short natural gaps. * Useful for cleaning up podcast recordings, lectures, and voice memos. * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/noise-reduction.md description: Reduce background noise from audio with FFT-based denoising. --- # Noise Reduction {#noise-reduction} Reduce background noise in an audio file using FFT-based denoising with selectable strength. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/noise-reduction` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | strength | string | No | `"medium"` | Denoising strength: `light`, `medium`, `strong` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/noise-reduction \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strength": "strong"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * `light` preserves more detail but removes less noise. `strong` removes more noise but may introduce subtle artifacts. * Best results on recordings with consistent background noise (fan hum, air conditioning, static). * Output usually keeps the input container. AAC input is written as M4A, and unsupported decode-only inputs fall back to MP3. --- --- url: https://docs.snapotter.com/tools/audio/merge-audio.md description: Combine multiple audio files into one sequential track. --- # Merge Audio {#merge-audio} Combine two or more audio files into a single sequential track, concatenated in the order they are uploaded. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/merge-audio` Accepts multipart form data with multiple audio files and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Output format: `mp3`, `wav`, `flac`, `m4a` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/merge-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@intro.mp3" \ -F "file=@main.mp3" \ -F "file=@outro.mp3" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.mp3", "originalSize": 9500000, "processedSize": 9200000 } ``` ## Notes {#notes} * Accepts 2 to 10 audio files per request. * Files are concatenated in upload order. * All input files are re-encoded to the chosen output format and sample rate for seamless joining. * Mixed input formats are supported (e.g. one WAV and one MP3). --- --- url: https://docs.snapotter.com/tools/audio/split-audio.md description: Split audio by time intervals, equal parts, or silence detection. --- # Split Audio {#split-audio} Split an audio file into segments by fixed time intervals, equal parts, or automatic silence detection. Returns a ZIP archive of the segments. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/split-audio` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"time"` | Split strategy: `time`, `parts`, `silence` | | segmentS | number | No | `60` | Segment length in seconds, 1 to 3600 (used when mode is `time`) | | parts | integer | No | `2` | Number of equal parts, 2 to 20 (used when mode is `parts`) | | thresholdDb | number | No | `-40` | Silence threshold in dB, -80 to -20 (used when mode is `silence`) | | minSilenceS | number | No | `0.3` | Minimum silence gap in seconds, 0.1 to 10 (used when mode is `silence`) | ## Example Request {#example-request} Split into 30-second segments: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "time", "segmentS": 30}' ``` Split by silence detection: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "silence", "thresholdDb": -35, "minSilenceS": 0.5}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio_parts.zip", "originalSize": 4500000, "processedSize": 4600000 } ``` ## Notes {#notes} * The `downloadUrl` points to a ZIP archive containing all segments. * Only the parameters relevant to the chosen `mode` are used; others are ignored. * Segment filenames are numbered sequentially (e.g. `part-000.mp3`, `part-001.mp3`). * Output format matches the input format. --- --- url: https://docs.snapotter.com/tools/audio/ringtone-maker.md description: Create a ringtone clip from any audio file. --- # Ringtone Maker {#ringtone-maker} Create a ringtone clip (.m4r) from any audio file by selecting a start time and duration. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/ringtone-maker` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | startS | number | No | `0` | Start time in seconds (minimum 0) | | durationS | number | No | `30` | Clip duration in seconds (1 to 30) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/ringtone-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"startS": 15, "durationS": 20}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.m4r", "originalSize": 4500000, "processedSize": 620000 } ``` ## Notes {#notes} * Output is always M4R format, compatible with iPhone ringtones. * Maximum ringtone duration is 30 seconds (Apple limit). * Any audio format can be used as input. --- --- url: https://docs.snapotter.com/tools/audio/waveform-image.md description: Generate a waveform visualization as a PNG image from an audio file. --- # Waveform Image {#waveform-image} Generate a waveform visualization as a PNG image from an audio file, with configurable dimensions and color. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/waveform-image` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | `1024` | Image width in pixels (256 to 3840) | | height | integer | No | `256` | Image height in pixels (64 to 1080) | | color | string | No | `"#4f46e5"` | Waveform hex color (e.g. `"#4f46e5"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/waveform-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"width": 1920, "height": 400, "color": "#e07832"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.png", "originalSize": 4500000, "processedSize": 45000 } ``` ## Notes {#notes} * The output is always a PNG image, regardless of the input audio format. * The waveform is rendered on a transparent background. * Useful for thumbnails, social media previews, or embedding in web pages. --- --- url: https://docs.snapotter.com/tools/audio/audio-metadata.md description: View, edit, or strip audio metadata tags (ID3). --- # Audio Metadata {#audio-metadata} View, edit, or strip audio metadata tags such as title, artist, and album (ID3 and similar tag formats). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | strip | boolean | No | `false` | Remove all existing metadata tags | | title | string | No | - | Set the title tag (max 500 characters) | | artist | string | No | - | Set the artist tag (max 500 characters) | | album | string | No | - | Set the album tag (max 500 characters) | ## Example Request {#example-request} Edit metadata tags: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` Strip all metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## Notes {#notes} * The response includes a `metadata` object with container format, duration, bitrate, and current tags. * When `strip` is `true`, all tag fields are ignored and every existing tag is removed. * Only the tags you provide are updated; unspecified tags remain unchanged. * Output format matches the input format. --- --- url: https://docs.snapotter.com/tools/audio/transcribe-audio.md description: Convert speech to text with AI-powered transcription. --- # Transcribe Audio {#transcribe-audio} Convert speech to text using AI-powered transcription (faster-whisper). Supports plain text, SRT, and VTT output formats with automatic or manual language selection. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/transcribe-audio` Accepts multipart form data with an audio file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | Language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | outputFormat | string | No | `"txt"` | Output format: `txt`, `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/transcribe-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"language": "en", "outputFormat": "srt"}' ``` ## Example Response {#example-response} This is an async tool. The API returns `202 Accepted` immediately: ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Track progress via SSE at `GET /api/v1/jobs/{jobId}/progress`. When the job completes, the SSE stream delivers the final result with a `downloadUrl`. ## Notes {#notes} * Requires the **transcription** feature bundle to be installed. Returns `501` with code `FEATURE_NOT_INSTALLED`, the missing `feature`, `featureName`, and `estimatedSize` if the bundle is not available. * Uses faster-whisper for transcription. Language `auto` detects the spoken language automatically. * `srt` and `vtt` formats include timestamps for each segment, suitable for subtitles. * `txt` format returns plain text without timestamps. * This is a long-running AI tool; processing time depends on audio length and server hardware. --- --- url: https://docs.snapotter.com/tools/pdf/pdf-to-image.md description: Convert PDF pages to high-quality images. --- # PDF to Image {#pdf-to-image} Convert PDF pages to high-quality raster images. Supports page selection, multiple output formats, DPI control, and color modes. Includes info and preview sub-routes for inspecting PDFs before conversion. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdf-to-image` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"png"` | Output format: `png`, `jpg`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl` | | dpi | number | No | 150 | Render resolution (36 to 2400). Higher DPI produces larger, more detailed images. | | quality | number | No | 85 | Output quality for lossy formats (1 to 100) | | colorMode | string | No | `"color"` | Color mode: `color`, `grayscale`, `bw` (black and white threshold) | | pages | string | No | `"all"` | Page selection: `all`, single page (`3`), range (`1-5`), or comma-separated (`1,3,5-8`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdf-to-image \ -F "file=@document.pdf" \ -F 'settings={"format":"png","dpi":300,"pages":"1-3","colorMode":"color"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "pageCount": 10, "selectedPages": [1, 2, 3], "format": "png", "pages": [ { "page": 1, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/page-1.png", "size": 234567 }, { "page": 2, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/page-2.png", "size": 198765 }, { "page": 3, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/page-3.png", "size": 210456 } ], "zipUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/pdf-pages.zip", "zipSize": 612345 } ``` ## Info Sub-Route {#info-sub-route} `POST /api/v1/tools/pdf/pdf-to-image/info` Returns the page count of a PDF without rendering any pages. ### Info Request {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdf-to-image/info \ -F "file=@document.pdf" ``` ### Info Response {#info-response} ```json { "pageCount": 10 } ``` ## Preview Sub-Route {#preview-sub-route} `POST /api/v1/tools/pdf/pdf-to-image/preview` Returns low-resolution JPEG thumbnails of all pages as base64 data URLs. Useful for building a page selection UI. ### Preview Request {#preview-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdf-to-image/preview \ -F "file=@document.pdf" ``` ### Preview Response {#preview-response} ```json { "pageCount": 10, "thumbnails": [ { "page": 1, "dataUrl": "data:image/jpeg;base64,/9j/4AAQ...", "width": 300, "height": 424 }, { "page": 2, "dataUrl": "data:image/jpeg;base64,/9j/4AAQ...", "width": 300, "height": 424 } ] } ``` ## Notes {#notes} * Uses MuPDF for PDF rendering, providing high-fidelity output with correct font rendering and vector graphics. * Password-protected PDFs are not supported and will return a 400 error. * The `pages` parameter supports flexible syntax: * `"all"` or `""` - all pages * `"3"` - single page * `"1-5"` - page range (inclusive) * `"1,3,5-8"` - mixed individual pages and ranges * Page numbers are 1-based. Specifying pages beyond the document length returns a 400 error. * The main endpoint always generates both individual page downloads and a ZIP containing all selected pages. * The preview endpoint renders at 72 DPI and scales to 300px width for fast thumbnail generation. Thumbnails are JPEG at 60% quality. * The preview endpoint respects the `MAX_PDF_PAGES` server configuration, limiting how many thumbnails are generated. * For large documents at high DPI, processing time increases proportionally. Consider using lower DPI (150) for web use and higher DPI (300-600) for print. --- --- url: https://docs.snapotter.com/tools/pdf/merge-pdf.md description: Combine multiple PDFs into a single document. --- # Merge PDFs {#merge-pdfs} Combine two or more PDF files into a single document, preserving the page order of each input file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/merge-pdf` Accepts multipart form data with two or more PDF files. No `settings` field is required. ## Parameters {#parameters} This tool has no settings parameters. Simply upload two or more PDF files. | Constraint | Value | |------------|-------| | Minimum files | 2 | | Maximum files | 20 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/merge-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document1.pdf" \ -F "file=@document2.pdf" \ -F "file=@document3.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.pdf", "originalSize": 4500000, "processedSize": 4200000 } ``` ## Notes {#notes} * Files are merged in the order they are uploaded. * At least two PDF files are required; the request will fail with a 400 error if fewer are provided. * The maximum number of input files is 20. * Encrypted PDFs must be unlocked before merging. --- --- url: https://docs.snapotter.com/tools/pdf/split-pdf.md description: Extract pages or split a PDF into parts. --- # Split PDF {#split-pdf} Extract a range of pages into a new PDF, or split a document into chunks of N pages. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/split-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"range"` | Split mode: `range` or `every` | | range | string | When mode is `range` | - | Page range in qpdf syntax, e.g. `"1-5,8,10-z"` | | everyN | integer | When mode is `every` | - | Split into chunks of N pages (1-500) | ## Example Request {#example-request} Extract specific pages: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "range", "range": "1-5,8"}' ``` Split into chunks of 10 pages: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "every", "everyN": 10}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 980000 } ``` ## Notes {#notes} * In `range` mode, a single PDF containing the selected pages is returned. * In `every` mode, the result is a ZIP archive containing the individual parts. * Page ranges use qpdf syntax: `1-5` for pages 1 through 5, `z` for the last page, and commas to combine ranges (e.g. `1-3,7,10-z`). --- --- url: https://docs.snapotter.com/tools/pdf/compress-pdf.md description: Shrink PDF file size by compressing embedded images. --- # Compress PDF {#compress-pdf} Reduce PDF file size by downsampling embedded images. Choose between a quality slider or a target file size. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Compression mode: `quality` or `targetSize` | | quality | integer | No | `75` | Compression quality, 1-100 (higher = less compression). Used in `quality` mode | | targetSizeKb | number | No | - | Target file size in kilobytes. Used in `targetSize` mode | ## Example Request {#example-request} Compress by quality: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Compress to a target size: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * In `quality` mode, lower values produce smaller files with more image degradation. * In `targetSize` mode, a binary search finds the highest DPI that fits the requested size. * If compression would enlarge the file, the original bytes are returned unchanged. * Text and vector content are not affected; only embedded raster images are downsampled. --- --- url: https://docs.snapotter.com/tools/pdf/rotate-pdf.md description: Rotate pages in a PDF by 90, 180, or 270 degrees. --- # Rotate PDF {#rotate-pdf} Rotate all or selected pages in a PDF by a specified angle. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/rotate-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | angle | integer | No | `90` | Rotation angle: `90`, `180`, or `270` | | range | string | No | `"1-z"` | Page range in qpdf syntax, e.g. `"1-5,8"` (`"1-z"` = all pages) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/rotate-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"angle": 90, "range": "1-3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2450000 } ``` ## Notes {#notes} * Rotation is clockwise. * Page ranges use qpdf syntax: `1-5` for pages 1 through 5, `z` for the last page, and commas to combine ranges. * The default range `"1-z"` rotates all pages. --- --- url: https://docs.snapotter.com/tools/pdf/extract-pages.md description: Pull selected pages from a PDF into a new document. --- # Extract Pages {#extract-pages} Pull selected pages from a PDF into a new, smaller document. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | Page range in qpdf syntax, e.g. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Page ranges use qpdf syntax: `1-5` for pages 1 through 5, `z` for the last page, and commas to combine ranges (e.g. `1-3,7,10-z`). * The extracted pages retain their original formatting, annotations, and links. --- --- url: https://docs.snapotter.com/tools/pdf/remove-pages.md description: Delete specific pages from a PDF. --- # Remove Pages {#remove-pages} Delete specific pages from a PDF, keeping all remaining pages intact. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/remove-pages` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pages | string | Yes | - | Page range to remove in qpdf syntax, e.g. `"3,5-7"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/remove-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"pages": "3,5-7"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 1800000 } ``` ## Notes {#notes} * You cannot remove every page from a document; at least one page must remain. * Page ranges use qpdf syntax: `3` for a single page, `5-7` for a range, and commas to combine (e.g. `1,3,5-7`). --- --- url: https://docs.snapotter.com/tools/pdf/organize-pdf.md description: Reorder pages in a PDF with an explicit page order. --- # Organize PDF {#organize-pdf} Reorder pages in a PDF by specifying the desired page sequence. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/organize-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | order | string | Yes | - | Desired page order in qpdf syntax, e.g. `"3,1,2,5-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/organize-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"order": "3,1,2,5-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2450000 } ``` ## Notes {#notes} * Page ranges use qpdf syntax: `3,1,2` reorders the first three pages, and `5-z` appends pages 5 through the last page. * Pages can be duplicated by listing them more than once (e.g. `"1,1,2,3"` duplicates page 1). * Pages not listed in the order string are omitted from the output. --- --- url: https://docs.snapotter.com/tools/pdf/protect-pdf.md description: Add password protection with AES-256 encryption to a PDF. --- # Protect PDF {#protect-pdf} Add password protection to a PDF using AES-256 encryption. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/protect-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | userPassword | string | Yes | - | Password required to open the PDF (1-256 characters) | | ownerPassword | string | No | Same as `userPassword` | Owner password for permissions (1-256 characters) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/protect-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"userPassword": "s3cret", "ownerPassword": "0wn3r"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2500000 } ``` ## Notes {#notes} * Encryption uses AES-256. * If `ownerPassword` is omitted, it defaults to the same value as `userPassword`. * Passwords are redacted from audit logs. * The encrypted PDF requires the user password to open and the owner password (if different) for full permissions. --- --- url: https://docs.snapotter.com/tools/pdf/unlock-pdf.md description: Remove password protection from a PDF. --- # Unlock PDF {#unlock-pdf} Remove password protection from an encrypted PDF by providing the correct password. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/unlock-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | password | string | Yes | - | Password to decrypt the PDF (1-256 characters) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/unlock-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"password": "s3cret"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2500000, "processedSize": 2450000 } ``` ## Notes {#notes} * The correct password must be provided; an incorrect password returns a 400 error. * Either the user password or the owner password will work for decryption. * Passwords are redacted from audit logs. --- --- url: https://docs.snapotter.com/tools/pdf/repair-pdf.md description: Attempt to repair a damaged or corrupted PDF. --- # Repair PDF {#repair-pdf} Attempt to repair a damaged or corrupted PDF by reconstructing its internal structure. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/repair-pdf` Accepts multipart form data with a PDF file. No `settings` field is required. ## Parameters {#parameters} This tool has no settings parameters. Upload the damaged PDF file directly. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/repair-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@damaged.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/damaged.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * Structural validation is skipped on input to allow malformed files through. * Repair is best-effort; severely corrupted files may not be fully recoverable. * The repaired PDF may differ slightly in size from the original due to reconstructed cross-reference tables. --- --- url: https://docs.snapotter.com/tools/pdf/linearize-pdf.md description: Linearize a PDF for fast web viewing (progressive download). --- # Web-Optimize PDF {#web-optimize-pdf} Linearize a PDF so it can be progressively downloaded and displayed in web browsers without waiting for the full file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/linearize-pdf` Accepts multipart form data with a PDF file. No `settings` field is required. ## Parameters {#parameters} This tool has no settings parameters. Upload the PDF file directly. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/linearize-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2460000 } ``` ## Notes {#notes} * Linearization rearranges the PDF's internal structure so the first page can render before the full file has downloaded. * The output file may be slightly larger than the input due to the added linearization data. * Already-linearized PDFs are re-linearized without issue. --- --- url: https://docs.snapotter.com/tools/pdf/grayscale-pdf.md description: Convert all colors in a PDF to grayscale. --- # Grayscale PDF {#grayscale-pdf} Convert all colors in a PDF to grayscale, producing a black-and-white version of the document. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Accepts multipart form data with a PDF file. No `settings` field is required. ## Parameters {#parameters} This tool has no settings parameters. Upload the PDF file directly. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * All color spaces (RGB, CMYK) are converted to grayscale, including embedded images, vector graphics, and text. * The output file is often smaller than the original because grayscale data requires fewer bytes per pixel. --- --- url: https://docs.snapotter.com/tools/pdf/pdfa-convert.md description: Convert a PDF to archival PDF/A-2 format for long-term preservation. --- # PDF/A Converter {#pdf-a-convert} Convert a PDF to the PDF/A-2 archival format, suitable for long-term preservation and regulatory compliance. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdfa-convert` Accepts multipart form data with a PDF file. No `settings` field is required. ## Parameters {#parameters} This tool has no settings parameters. Upload the PDF file directly. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdfa-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2600000 } ``` ## Notes {#notes} * The output conforms to the PDF/A-2 standard. * PDF/A embeds all fonts and disallows external references, so the output file may be larger than the original. * Encryption and JavaScript are stripped during conversion, as they are not permitted by the PDF/A standard. --- --- url: https://docs.snapotter.com/tools/pdf/crop-pdf.md description: Crop all pages of a PDF with a uniform margin. --- # Crop PDF {#crop-pdf} Crop all pages of a PDF by applying a uniform margin, trimming content from each edge equally. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | Uniform crop margin in points (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * The margin value is in PDF points (1 point = 1/72 inch). * The same margin is applied to all four edges of every page. * A margin of `0` removes all existing crop margins, showing the full media box. --- --- url: https://docs.snapotter.com/tools/pdf/nup-pdf.md description: Arrange multiple PDF pages per sheet (2-up, 4-up, etc.). --- # Pages Per Sheet (N-up) {#n-up-pdf} Arrange multiple pages per sheet to save paper when printing, such as 2-up or 4-up layouts. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/nup-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | Pages per sheet: `2`, `3`, `4`, `8`, `9`, `12`, or `16` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/nup-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2300000 } ``` ## Notes {#notes} * Pages are arranged in reading order (left to right, top to bottom). * The output page size matches the original; individual pages are scaled down to fit the grid. * A 20-page document with `perSheet: 4` produces a 5-page output. --- --- url: https://docs.snapotter.com/tools/pdf/booklet-pdf.md description: Arrange PDF pages for folding into a booklet. --- # Booklet PDF {#booklet-pdf} Impose pages for duplex printing so the printed sheets can be folded into a booklet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | Pages per sheet: `2`, `4`, `6`, or `8` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * The default `perSheet: 2` places two pages side by side on each sheet, which is the standard booklet layout for duplex printing. * Blank pages are added automatically if the total page count is not a multiple of the sheet size. * Print the output double-sided on short-edge binding, then fold and staple. --- --- url: https://docs.snapotter.com/tools/pdf/watermark-pdf.md description: Add a text watermark to every page of a PDF. --- # Watermark PDF {#watermark-pdf} Stamp a text watermark on every page of a PDF with configurable position, size, opacity, and rotation. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/watermark-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Watermark text (1-200 characters) | | position | string | No | `"c"` | Placement on the page: `tl`, `tc`, `tr`, `l`, `c`, `r`, `bl`, `bc`, `br` | | fontSize | integer | No | `48` | Font size in points (6-72) | | opacity | number | No | `0.3` | Watermark opacity (0.05-1) | | rotation | number | No | `45` | Rotation angle in degrees (-180 to 180) | ### Position Values {#position-values} * `tl` top-left, `tc` top-center, `tr` top-right * `l` center-left, `c` center, `r` center-right * `bl` bottom-left, `bc` bottom-center, `br` bottom-right ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/watermark-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"text": "CONFIDENTIAL", "position": "c", "opacity": 0.2, "rotation": 45}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2500000 } ``` ## Notes {#notes} * The watermark is rendered as a text overlay on each page. * The same watermark text, position, and style are applied uniformly to all pages. * Use lower opacity values (0.1-0.3) for subtle watermarks that do not obscure content. --- --- url: https://docs.snapotter.com/tools/pdf/pdf-page-numbers.md description: Add page numbers to every page of a PDF. --- # PDF Page Numbers {#pdf-page-numbers} Add "Page N of M" page numbers to every page of a PDF. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdf-page-numbers` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | position | string | No | `"bc"` | Page number placement: `bl`, `bc`, `br`, `tl`, `tc`, `tr` | | fontSize | integer | No | `10` | Font size in points (6-24) | ### Position Values {#position-values} * `tl` top-left, `tc` top-center, `tr` top-right * `bl` bottom-left, `bc` bottom-center, `br` bottom-right ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdf-page-numbers \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"position": "bc", "fontSize": 12}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2470000 } ``` ## Notes {#notes} * Page numbers are rendered in the format "Page 1 of 10". * Numbers are added to every page, including any existing title or cover pages. * The default position `"bc"` places numbers at the bottom center of each page. --- --- url: https://docs.snapotter.com/tools/pdf/flatten-pdf.md description: Bake forms and annotations into page content. --- # Flatten PDF {#flatten-pdf} Bake interactive form fields and annotations into the page content, producing a static PDF that looks the same everywhere. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Accepts multipart form data with a PDF file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a PDF and all forms and annotations will be flattened. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Accepted input format: `.pdf`. * This is a fast (synchronous) tool that returns the result directly. * Form field values are preserved as static text in the output. * Annotations (comments, highlights, sticky notes) become part of the page content and can no longer be edited. --- --- url: https://docs.snapotter.com/tools/pdf/redact-pdf.md description: Permanently remove text occurrences from a PDF (verified true redaction). --- # Redact PDF {#redact-pdf} Permanently remove specified text occurrences from a PDF using verified true redaction. The redacted text is completely removed from the file, not just covered with a black box. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/redact-pdf` Accepts multipart form data with a PDF file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | terms | string\[] | Yes | - | Text strings to redact (1-50 terms, each up to 200 characters) | | caseSensitive | boolean | No | `false` | Whether matching is case-sensitive | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/redact-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@contract.pdf" \ -F 'settings={"terms": ["John Doe", "555-0123"], "caseSensitive": false}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/contract.pdf", "originalSize": 245000, "processedSize": 243000, "found": 7 } ``` ## Notes {#notes} * Accepted input format: `.pdf`. * This is a fast (synchronous) tool that returns the result directly. * This performs true redaction: matched text is removed from the PDF content stream, not merely obscured visually. * The `found` field in the response indicates how many occurrences were redacted. * You can redact up to 50 terms in a single request. --- --- url: https://docs.snapotter.com/tools/pdf/sign-pdf.md description: Stamp uploaded signature images onto a PDF using normalized page placements. --- # Sign PDF {#sign-pdf} Stamp one or more uploaded signature PNG images onto any page of a PDF. This route uses a custom multipart contract because it needs the PDF, one or more signature images, and placement coordinates. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/sign-pdf` Accepts multipart form data. The PDF is sent as `file`; signatures are sent as `sig0`, `sig1`, and so on; placements are sent in a `placements` JSON field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | PDF file to sign | | sig0 | file | Yes | - | First signature image. Additional images use `sig1`, `sig2`, and so on | | placements | JSON string | Yes | - | Array of placement objects: `{ "sig": 0, "page": 0, "x": 0.2, "y": 0.7, "w": 0.25, "h": 0.08 }` | | clientJobId | string | No | - | Optional UUID for progress tracking via SSE | | fileId | string | No | - | Optional file library ID to save the signed result as a new version | ## Placement Coordinates {#placement-coordinates} | Field | Type | Description | |-------|------|-------------| | sig | integer | Signature image index. `0` maps to `sig0` | | page | integer | Zero-based PDF page index | | x | number | Left position as a page fraction | | y | number | Top position as a page fraction | | w | number | Signature width as a page fraction | | h | number | Signature height as a page fraction | Coordinates use a top-left origin. Values may bleed slightly beyond the page edge; the PDF renderer clips the final stamp to the page. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/sign-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@contract.pdf" \ -F "sig0=@signature.png" \ -F 'placements=[{"sig":0,"page":0,"x":0.64,"y":0.82,"w":0.22,"h":0.08}]' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/contract_signed.pdf", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/preview.png", "originalSize": 245000, "processedSize": 249000 } ``` If the request cannot finish inside the synchronous wait window, the API returns: ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Connect to `/api/v1/jobs//progress` and download the result when the job completes. ## Notes {#notes} * Accepted PDF input format: `.pdf`. * Signature images must be valid image files, typically PNG with transparency. * Up to 100 signature images and 100 placements are accepted. * `sign-pdf` is a custom route and does not use the standard tool `settings` JSON field. --- --- url: https://docs.snapotter.com/tools/pdf/pdf-to-text.md description: Extract plain text from a PDF. --- # PDF to Text {#pdf-to-text} Extract all readable plain text from a PDF document into a text file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdf-to-text` Accepts multipart form data with a PDF file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a PDF and its text content will be extracted. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdf-to-text \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/report.txt", "originalSize": 520000, "processedSize": 14300, "chars": 14300 } ``` ## Notes {#notes} * Accepted input format: `.pdf`. * This is a fast (synchronous) tool that returns the result directly. * The `chars` field in the response indicates the number of characters extracted. * Only digitally embedded text is extracted. For scanned documents or image-based PDFs, use the [PDF OCR](./ocr-pdf) tool instead. --- --- url: https://docs.snapotter.com/tools/pdf/pdf-to-word.md description: Convert a PDF to a Word document (DOCX). --- # PDF to Word {#pdf-to-word} Convert a text-based PDF to a Word document (DOCX). Best suited for PDFs with selectable text; scanned pages will need OCR first. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdf-to-word` Accepts multipart form data with a PDF file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a PDF and it will be converted to DOCX. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdf-to-word \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input format: `.pdf`. * Works best with text-based PDFs. Scanned or image-only pages will produce empty or minimal output; use [PDF OCR](./ocr-pdf) to add a text layer first. * Conversion is handled by LibreOffice running headless on the server. * Complex layouts (multi-column, overlapping elements) may not convert perfectly. --- --- url: https://docs.snapotter.com/tools/pdf/pdf-metadata.md description: Read and write PDF document metadata. --- # PDF Metadata {#pdf-metadata} Read and update PDF document metadata fields such as title, author, subject, and keywords. When no settings are provided, the existing metadata is returned without modification. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdf-metadata` Accepts multipart form data with a PDF file and an optional JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | title | string | No | - | Document title (max 500 characters) | | author | string | No | - | Document author (max 500 characters) | | subject | string | No | - | Document subject (max 500 characters) | | keywords | string | No | - | Document keywords (max 500 characters) | All parameters are optional. Omitted fields are left unchanged. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdf-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F 'settings={"title": "Q2 Report", "author": "Finance Team"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/report.pdf", "originalSize": 245000, "processedSize": 245200, "metadata": { "title": "Q2 Report", "author": "Finance Team", "subject": "", "keywords": "" } } ``` ## Notes {#notes} * Accepted input format: `.pdf`. * This is a fast (synchronous) tool that returns the result directly. * The `metadata` field in the response contains the resulting metadata after any updates. * To read metadata without modifying it, omit the `settings` field or send an empty object. * Each metadata field is limited to 500 characters. --- --- url: https://docs.snapotter.com/tools/pdf/ocr-pdf.md description: >- Extract text from scanned PDFs locally with built-in Tesseract or the optional high-accuracy RapidOCR runtime. --- # PDF OCR {#pdf-ocr} Extract text from scanned PDF documents page by page without sending the PDF to an external service. The built-in `fast` tier uses Tesseract. The optional `balanced` and `best` tiers use RapidOCR with pinned PP-OCR ONNX models. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/ocr-pdf` Accepts multipart form data with a PDF file and an optional JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | PDF file (multipart), up to 512 MiB encoded; a lower operator upload limit still applies | | quality | string | No | Dynamic | OCR quality tier: `fast`, `balanced`, or `best` | | language | string | No | `"auto"` | Document language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`. Fast does not support `ko` | | pages | string | No | `"all"` | Page selection, e.g. `"all"`, `"1-3"`, `"1,3,5"` | | enhance | boolean | No | Tier-dependent | Improve local contrast before recognition. Fast applies it directly; Balanced and Best retain the variant only when calibrated scoring improves the result. Defaults to `true` for `best` and `false` for `fast`/`balanced` | | engine | string | No | - | Deprecated compatibility alias. Use `quality` instead. `tesseract` maps to `fast`; the legacy `paddleocr` value maps to `balanced` but does not load PaddlePaddle | If `quality` and the deprecated `engine` field are both omitted, SnapOtter selects the highest available tier in this order: `best`, `balanced`, `fast`. Korean never selects `fast`; it uses `best`, then `balanced`, or returns the accurate-runtime install or compatibility error. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/ocr-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@scanned.pdf" \ -F 'settings={"quality": "best", "language": "en", "pages": "1-5", "enhance": true}' ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input format: `.pdf`. * `fast` is built in and adds about 25 MiB to the official image. `balanced` and `best` require the optional accurate OCR pack (about 208-234 MiB to download and 409-488 MiB installed, depending on the target). * Fast supports `auto`, `en`, `de`, `es`, `fr`, `zh`, and `ja`, but not Korean (`ko`). Korean requires the accurate pack and `balanced` or `best`. * The accurate pack supports official Linux amd64 and arm64 containers and uses ONNX Runtime on CPU, including on NVIDIA hosts. Unsupported hosts receive an explicit incompatibility error for Korean rather than a Fast fallback. * An explicitly requested tier is never silently downgraded. If `balanced` or `best` is unavailable, the API returns `501` with `FEATURE_NOT_INSTALLED` or `FEATURE_INCOMPATIBLE`. Explicit Fast or legacy `tesseract` with Korean returns `FEATURE_INCOMPATIBLE` and `fast-korean-unsupported` before queueing. * PDF pages are rasterized at high resolution before OCR. `best` runs the higher-accuracy medium PP-OCRv6 models and scores orientation and enhancement variants, improving recognition at the cost of speed. * The `auto` language setting enables recognition across the supported script set; an explicit hint can improve results for a known document language. * You can target specific pages using ranges (`"1-3"`), comma-separated lists (`"1,3,5"`), or `"all"` for every page. * A request can process at most 50 pages. Rasterized scratch data is capped at 512 MiB and the aggregate UTF-8 OCR response is capped at 1,000,000 bytes; over-limit jobs fail rather than returning partial text. * For PDFs that already contain selectable text, consider using the faster [PDF to Text](./pdf-to-text) tool instead. --- --- url: https://docs.snapotter.com/tools/files/convert-document.md description: Convert between Word, OpenDocument, RTF, and plain text formats. --- # Convert Document {#convert-document} Convert documents between Word (DOCX), OpenDocument (ODT), RTF, and plain text formats using LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Accepts multipart form data with a Word/ODT/RTF/TXT file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Output format: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Conversion is handled by LibreOffice running headless on the server. * Complex formatting (macros, embedded objects) may not survive conversion between formats. * The output format must differ from the input format. --- --- url: https://docs.snapotter.com/tools/files/convert-presentation.md description: Convert between PowerPoint and OpenDocument presentation formats. --- # Convert Presentation {#convert-presentation} Convert presentations between PowerPoint (PPTX) and OpenDocument Presentation (ODP) formats. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Accepts multipart form data with a PowerPoint/ODP file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Output format: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.pptx`, `.ppt`, `.odp`. * Conversion is handled by LibreOffice running headless on the server. * Animations and transition effects may not be preserved across formats. * The output format must differ from the input format. --- --- url: https://docs.snapotter.com/tools/files/convert-spreadsheet.md description: Convert between Excel, OpenDocument, and CSV formats. --- # Convert Spreadsheet {#convert-spreadsheet} Convert spreadsheets between Excel (XLSX), OpenDocument Spreadsheet (ODS), and CSV formats. Multi-sheet workbooks export the first sheet when converting to CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Accepts multipart form data with an Excel/ODS/CSV file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Output format: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.xlsx`, `.xls`, `.ods`, `.csv`. * When converting a multi-sheet workbook to CSV, only the first sheet is exported. * Formulas are evaluated and exported as static values in CSV output. * The output format must differ from the input format. --- --- url: https://docs.snapotter.com/tools/files/excel-to-pdf.md description: Convert spreadsheets to PDF. --- # Excel to PDF {#excel-to-pdf} Convert Excel, OpenDocument, or CSV spreadsheets to PDF. Wide sheets may paginate across multiple pages. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Accepts multipart form data with an Excel/ODS/CSV file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a spreadsheet and it will be converted to PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.xlsx`, `.xls`, `.ods`, `.csv`. * Wide sheets may be split across multiple pages in the resulting PDF. * Charts and conditional formatting are rendered in the PDF output. * Conversion is handled by LibreOffice running headless on the server. --- --- url: https://docs.snapotter.com/tools/files/word-to-pdf.md description: Convert Word documents to PDF. --- # Word to PDF {#word-to-pdf} Convert Word documents, OpenDocument text, RTF, or plain text files to PDF. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/word-to-pdf` Accepts multipart form data with a Word/ODT/RTF/TXT file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a document and it will be converted to PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/word-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Conversion is handled by LibreOffice running headless on the server. * Fonts embedded in the document are used when available; otherwise system fonts are substituted. * Headers, footers, tables, and images are preserved in the PDF output. --- --- url: https://docs.snapotter.com/tools/files/powerpoint-to-pdf.md description: Convert presentations to PDF. --- # PowerPoint to PDF {#powerpoint-to-pdf} Convert PowerPoint or OpenDocument presentations to PDF, with one slide per page. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/powerpoint-to-pdf` Accepts multipart form data with a PowerPoint/ODP file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a presentation and it will be converted to PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/powerpoint-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.pptx`, `.ppt`, `.odp`. * Each slide becomes one page in the PDF. * Conversion is handled by LibreOffice running headless on the server. * Animations and transitions are not included in the PDF output. --- --- url: https://docs.snapotter.com/tools/files/html-to-pdf.md description: Convert an HTML file to PDF. --- # HTML to PDF {#html-to-pdf} Convert an HTML file to a styled PDF document. Remote resources (external images, stylesheets, scripts) are disabled for privacy. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/html-to-pdf` Accepts multipart form data with an HTML file. ## Parameters {#parameters} This tool has no configurable parameters. Upload an HTML file and it will be converted to PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/html-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page.html" ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.html`, `.htm`. * Remote resources (images, stylesheets, scripts referenced via URLs) are not fetched for privacy and security. * Inline styles and embedded images (data URIs) are preserved. * Conversion is handled by WeasyPrint on the server. --- --- url: https://docs.snapotter.com/tools/files/markdown-to-docx.md description: Convert a Markdown file to a Word document (DOCX). --- # Markdown to Word {#markdown-to-word} Convert a Markdown file to a Word document (DOCX), preserving headings, lists, code blocks, and other formatting. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/markdown-to-docx` Accepts multipart form data with a Markdown file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a Markdown file and it will be converted to DOCX. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/markdown-to-docx \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@README.md" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/README.docx", "originalSize": 4500, "processedSize": 18200 } ``` ## Notes {#notes} * Accepted input formats: `.md`, `.markdown`. * This is a fast (synchronous) tool that returns the result directly. * Headings, bold, italic, links, code blocks, and lists are mapped to Word styles. * Conversion is handled by Pandoc on the server. --- --- url: https://docs.snapotter.com/tools/files/markdown-to-html.md description: Convert a Markdown file to a standalone HTML page. --- # Markdown to HTML {#markdown-to-html} Convert a Markdown file to a standalone HTML page. Remote images referenced in the source are left as-is in the output. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/markdown-to-html` Accepts multipart form data with a Markdown file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a Markdown file and it will be converted to HTML. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/markdown-to-html \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@notes.md" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/notes.html", "originalSize": 3200, "processedSize": 5800 } ``` ## Notes {#notes} * Accepted input formats: `.md`, `.markdown`. * This is a fast (synchronous) tool that returns the result directly. * The output is a self-contained HTML page with inline styles. * Remote image URLs in the Markdown source are preserved as-is and not fetched. --- --- url: https://docs.snapotter.com/tools/files/markdown-to-pdf.md description: Convert a Markdown file to a styled PDF. --- # Markdown to PDF {#markdown-to-pdf} Convert a Markdown file to a styled PDF document. Remote resources are disabled for privacy. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/markdown-to-pdf` Accepts multipart form data with a Markdown file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a Markdown file and it will be converted to PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/markdown-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.md" ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.md`, `.markdown`. * Remote resources (images, stylesheets referenced via URLs) are not fetched for privacy and security. * The Markdown is first rendered to HTML, then converted to PDF via WeasyPrint. * Code blocks, tables, and other Markdown elements are styled in the PDF output. --- --- url: https://docs.snapotter.com/tools/files/epub-convert.md description: Convert an EPUB to PDF, DOCX, HTML, or Markdown. --- # Convert from EPUB {#convert-epub} Convert an EPUB e-book to PDF, Word (DOCX), HTML, or Markdown. Remote resources inside the book are not fetched. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Accepts multipart form data with an EPUB file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Output format: `pdf`, `docx`, `html`, `md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input format: `.epub`. * Remote resources embedded in the EPUB (external images, fonts) are not fetched for security. * Image fidelity in the converted output may vary depending on the EPUB structure. * Conversion is handled by Pandoc on the server. --- --- url: https://docs.snapotter.com/tools/files/to-epub.md description: Convert Word, Markdown, HTML, or plain text files to EPUB. --- # Convert to EPUB {#convert-to-epub} Convert Word documents, Markdown, HTML, or plain text files into the EPUB e-book format. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` Accepts multipart form data with a Word/Markdown/HTML/TXT file. ## Parameters {#parameters} This tool has no configurable parameters. Upload a document and it will be converted to EPUB. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Accepted input formats: `.docx`, `.md`, `.html`, `.txt`. * The EPUB output follows the EPUB 3 specification. * Headings in the source document are used to generate the table of contents. * Conversion is handled by Pandoc on the server. --- --- url: https://docs.snapotter.com/tools/files/chart-maker.md description: Create bar, line, or pie charts from CSV or JSON data. --- # Chart Maker {#chart-maker} Create bar, line, or pie charts from CSV or JSON data. Returns a PNG image of the rendered chart. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Accepts multipart form data with a CSV or JSON file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Chart type: `bar`, `line`, `pie` | | title | string | No | - | Chart title (max 120 characters) | | width | integer | No | `960` | Chart width in pixels (320-2048) | | height | integer | No | `540` | Chart height in pixels (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Input must be a `.csv` or `.json` file. CSV files should have a header row with column names. * The first column is used as the category label; the second column must be numeric and provides the data values. Only two columns are used. * JSON input should be an array of `{label, value}` objects, or a plain object whose keys become labels and values become data points. * Maximum 100 data points. All values must be zero or greater. * Output is always a PNG image regardless of input format. --- --- url: https://docs.snapotter.com/tools/files/csv-excel.md description: Convert between CSV and Excel (XLSX), both directions. --- # CSV to Excel {#csv-to-excel} Convert between CSV and Excel (XLSX) formats in both directions. Upload a CSV or TSV file to get XLSX, or upload an XLSX file to get CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Accepts multipart form data with a CSV, TSV, or XLSX file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | Worksheet number to export when converting from XLSX (min 1) | ## Example Request {#example-request} CSV to Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Conversion direction is auto-detected from the input file extension: `.csv` or `.tsv` produces `.xlsx`, and `.xlsx` produces `.csv`. * The `sheet` parameter only applies when converting from XLSX. It selects which worksheet to export. * TSV (tab-separated values) files are supported alongside CSV. --- --- url: https://docs.snapotter.com/tools/files/csv-json.md description: Convert between CSV and JSON, both directions. --- # CSV to JSON {#csv-to-json} Convert between CSV and JSON formats in both directions. Upload a CSV or TSV file to get a JSON array of objects, or upload a JSON array to get a CSV file. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Accepts multipart form data with a CSV, TSV, or JSON file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | Pretty-print JSON output with indentation | ## Example Request {#example-request} CSV to JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Conversion direction is auto-detected from the input file extension: `.csv` or `.tsv` produces `.json`, and `.json` produces `.csv`. * The `pretty` parameter only affects JSON output. When set to `false`, the output is a compact single-line JSON string. * JSON input must be an array of objects with consistent keys. Each object becomes a row, and each key becomes a column header. * TSV (tab-separated values) files are supported alongside CSV. --- --- url: https://docs.snapotter.com/tools/files/json-xml.md description: Convert between JSON and XML, both directions. --- # JSON to XML {#json-to-xml} Convert between JSON and XML formats in both directions. Upload a JSON file to get XML, or upload an XML file to get JSON. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/json-xml` Accepts multipart form data with a JSON or XML file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | Pretty-print output with indentation | ## Example Request {#example-request} JSON to XML: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/json-xml \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.json" \ -F 'settings={"pretty": true}' ``` XML to JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/json-xml \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.xml" \ -F 'settings={"pretty": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.xml", "originalSize": 850, "processedSize": 1200 } ``` ## Notes {#notes} * Conversion direction is auto-detected from the input file extension: `.json` produces `.xml`, and `.xml` produces `.json`. * The `pretty` parameter applies to both directions. When `false`, the output is compact with no indentation. * XML attributes and nested structures are preserved during round-trip conversion where possible. --- --- url: https://docs.snapotter.com/tools/files/split-csv.md description: Split a CSV into smaller files by row count. --- # Split CSV {#split-csv} Split a large CSV or TSV file into smaller files by row count. Returns a ZIP archive containing the parts. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/split-csv` Accepts multipart form data with a CSV file and a JSON `settings` field. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | rowsPerFile | integer | No | `1000` | Number of data rows per output file (1-1,000,000) | | keepHeader | boolean | No | `true` | Repeat the header row in each output file | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Notes {#notes} * Output is always a ZIP archive containing the split CSV parts, named sequentially (e.g. `part-1.csv`, `part-2.csv`). * When `keepHeader` is `true`, each part includes the original header row so each file can be used independently. * Both CSV and TSV files are accepted as input. * The row count refers to data rows only; the header row is not counted. --- --- url: https://docs.snapotter.com/tools/files/merge-csvs.md description: Combine multiple CSV or TSV files with matching columns into one. --- # Merge CSVs {#merge-csvs} Combine multiple CSV or TSV files with matching columns into a single merged file. All input files must have the same column headers. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/merge-csvs` Accepts multipart form data with two or more CSV files. No settings field is required. ## Parameters {#parameters} This tool has no configurable parameters. Upload 2-20 CSV or TSV files with matching column headers. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/merge-csvs \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@january.csv" \ -F "file=@february.csv" \ -F "file=@march.csv" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", "originalSize": 30000, "processedSize": 28500 } ``` ## Notes {#notes} * Requires between 2 and 20 input files. * All files must share the same column headers. The merge will fail if columns do not match. * The header row is included once in the output; data rows from all files are concatenated in upload order. * Both CSV and TSV files are accepted, but all files in a single request should use the same delimiter. --- --- url: https://docs.snapotter.com/tools/files/yaml-json.md description: Convert between YAML and JSON, both directions. --- # Convert YAML / JSON {#yaml-json} Convert between YAML and JSON formats in both directions. Upload a YAML file to get JSON, or upload a JSON file to get YAML. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/yaml-json` Accepts multipart form data with a YAML or JSON file. No settings field is required. ## Parameters {#parameters} This tool has no configurable parameters. The conversion direction is determined by the input file extension. ## Example Request {#example-request} YAML to JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.yaml" ``` JSON to YAML: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.json" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.json", "originalSize": 620, "processedSize": 780 } ``` ## Notes {#notes} * Conversion direction is auto-detected from the input file extension: `.yaml` or `.yml` produces `.json`, and `.json` produces `.yaml`. * Both `.yaml` and `.yml` extensions are accepted. * Only the first document in a multi-document YAML file is converted; additional documents separated by `---` are ignored. --- --- url: https://docs.snapotter.com/tools/files/xml-to-csv.md description: Extract repeating elements from XML into a CSV table. --- # XML to CSV {#xml-to-csv} Extract repeating elements from an XML file into a flat CSV table. The tool automatically finds the first array of objects in the XML tree and maps each element to a row. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/xml-to-csv` Accepts multipart form data with an XML file. No settings field is required. ## Parameters {#parameters} This tool has no configurable parameters. The repeating element is auto-detected from the XML structure. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/xml-to-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@catalog.xml" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/catalog.csv", "originalSize": 4500, "processedSize": 1800 } ``` ## Notes {#notes} * Only `.xml` files are accepted as input. * The tool scans the XML tree for the first repeating set of sibling elements and uses those as rows. * Each unique child element or attribute name becomes a CSV column header. * This is a one-way conversion. For bidirectional JSON/XML conversion, use the [JSON to XML](/tools/files/json-xml) tool. --- --- url: https://docs.snapotter.com/tools/files/create-zip.md description: Bundle multiple files into a single ZIP archive. --- # Create ZIP {#create-zip} Bundle multiple files of any type into a single ZIP archive. Duplicate filenames are automatically deduplicated. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Accepts multipart form data with two or more files. No settings field is required. ## Parameters {#parameters} This tool has no configurable parameters. Upload 2-50 files of any type to bundle. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Requires between 2 and 50 input files. * Any file type is accepted; there are no restrictions on input format. * If multiple files share the same name, they are automatically deduplicated with numeric suffixes. * The output archive uses standard ZIP compression (deflate). --- --- url: https://docs.snapotter.com/tools/files/extract-zip.md description: Safely extract files from a ZIP archive with bomb protection. --- # Extract ZIP {#extract-zip} Safely extract files from a ZIP archive. Single-file archives return the contained file directly; multi-file archives return a flat ZIP with the extracted contents. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Accepts multipart form data with a ZIP file. No settings field is required. ## Parameters {#parameters} This tool has no configurable parameters. Upload a `.zip` file to extract. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Only `.zip` files are accepted as input. * If the archive contains a single file, that file is returned directly (not wrapped in a ZIP). * If the archive contains multiple files, a flat ZIP is returned with all files extracted to the root level (nested directory structure is flattened). * Built-in bomb protection rejects archives with excessive compression ratios or file counts to prevent resource exhaustion. --- --- url: https://docs.snapotter.com/api/rest.md description: >- Complete REST API reference. Tool endpoints, batch processing, pipelines, file library, authentication, teams, and admin operations. --- # REST API Reference {#rest-api-reference} Interactive API docs with request/response examples are available at . Machine-readable specs: * `/api/v1/openapi.yaml` - OpenAPI 3.1 spec * `/llms.txt` - LLM-friendly summary * `/llms-full.txt` - Complete LLM-friendly docs ## Authentication {#authentication} All endpoints require authentication unless `AUTH_ENABLED=false`. ### Session Token {#session-token} ```bash # Login curl -X POST http://localhost:1349/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin"}' # Returns: {"token":""} # Use token (tool routes are POST multipart) curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer " \ -F "file=@photo.jpg" \ -F 'settings={"width":800}' ``` Sessions expire after 7 days (configurable via `SESSION_DURATION_HOURS`). ### API Keys {#api-keys} ```bash # Create a key (returns key once - store it) curl -X POST http://localhost:1349/api/v1/api-keys \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"name":"my-script"}' # Returns: {"key":"si_<96 hex chars>","id":"...","name":"my-script"} # Use the key curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800}' ``` Keys are prefixed `si_` and stored as scrypt hashes - the raw key is shown once and never retrievable again. ### Auth Endpoints {#auth-endpoints} | Method | Path | Access | Description | |--------|------|--------|-------------| | `POST` | `/api/auth/login` | Public | Login, get session token | | `POST` | `/api/auth/logout` | Auth | Destroy current session | | `GET` | `/api/auth/session` | Auth | Validate current session | | `POST` | `/api/auth/change-password` | Auth | Change own password (invalidates all other sessions + API keys) | | `GET` | `/api/auth/users` | Admin | List all users | | `POST` | `/api/auth/register` | Admin (`users:manage`; proposed-role authority) | Create a new user | | `PUT` | `/api/auth/users/:id` | Admin (`users:manage`; target authority) | Update user role or team | | `POST` | `/api/auth/users/:id/reset-password` | Admin (`users:manage`; target authority) | Reset user's password | | `DELETE` | `/api/auth/users/:id` | Admin (`users:manage`; target authority) | Delete a user | | `GET` | `/api/v1/config/auth` | Public | Check if authentication is enabled (`{ authEnabled: bool }`) | | `POST` | `/api/auth/mfa/enroll` | Auth | Start TOTP MFA enrollment. Requires the enterprise `mfa` feature | | `POST` | `/api/auth/mfa/verify` | Auth | Confirm MFA enrollment with a TOTP code | | `POST` | `/api/auth/mfa/complete` | Public | Complete a pending MFA login challenge | | `POST` | `/api/auth/mfa/disable` | Auth | Disable MFA for the current user | | `POST` | `/api/auth/users/:id/mfa/reset` | Admin (`users:manage`; target authority) | Reset MFA for a user | | `GET` | `/api/auth/oidc/login` | Public | Start OIDC login when OIDC is enabled | | `GET` | `/api/auth/oidc/callback` | Public | OIDC authorization callback | | `GET` | `/api/auth/saml/metadata` | Public | SAML SP metadata XML when SAML is enabled | | `GET` | `/api/auth/saml/login` | Public | Start SAML login | | `POST` | `/api/auth/saml/callback` | Public | SAML assertion consumer service | When MFA is enabled for a user, `POST /api/auth/login` returns `{"requiresMfa":true,"mfaToken":"...","mfaRequired":true|false}` instead of a session token. Send that `mfaToken` plus a TOTP or recovery code to `/api/auth/mfa/complete`. ### Permissions {#permissions} | Permission | Admin | User | |-----------|:-----:|:----:| | Use tools | ✓ | ✓ | | Own files/pipelines/API keys | ✓ | ✓ | | See all users' files/pipelines/keys | ✓ | - | | Write settings | ✓ | - | | Manage users & teams | ✓ | - | | Manage branding | ✓ | - | ## Health Check {#health-check} | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/health` | Public | Basic health check. Returns `{"status":"healthy","version":"..."}` with 200, or `{"status":"unhealthy"}` with 503 if the database is unreachable. | | `GET` | `/api/v1/readyz` | Public | Readiness probe. Checks PostgreSQL, Redis, disk space, and S3 when configured. Returns 503 when the instance should not receive traffic. | | `GET` | `/api/v1/admin/health` | Admin (`system:health`) | Detailed diagnostics including uptime, storage mode, database status, queue state, and GPU availability. | ## Using Tools {#using-tools} Every tool follows the same pattern: ```bash # Single file curl -X POST http://localhost:1349/api/v1/tools/
/ \ -H "Authorization: Bearer " \ -F "file=@input.jpg" \ -F 'settings={"width":800,"height":600}' # Batch (returns ZIP) curl -X POST http://localhost:1349/api/v1/tools/
//batch \ -H "Authorization: Bearer " \ -F "files=@a.jpg" \ -F "files=@b.jpg" \ -F 'settings={...}' ``` `
` is one of `image`, `video`, `audio`, `pdf`, or `files`. * Upload is `multipart/form-data`. * `settings` is a JSON string with tool-specific options. * `clientJobId` is an optional form field for caller-supplied progress correlation. * `fileId` is an optional form field referencing an existing file library item. When present, the processed output is saved as a new version and the response includes `savedFileId`. * **Fast tools** usually return 200 JSON: `{"jobId":"...","downloadUrl":"/api/v1/download//","originalSize":1234,"processedSize":567}`. Fetch the processed file from `downloadUrl`. * **Any queued tool** can return 202 JSON if it is long-running or exceeds the synchronous wait window: `{"jobId":"...","async":true}`. Connect to SSE for progress, then download when complete (see [Progress Tracking](#progress-tracking)). * **Batch** routes return a ZIP archive streamed directly (with `X-Job-Id` header) for tools registered in the generic batch registry. ## Tools Reference {#tools-reference} ### Conversion Presets {#conversion-presets} The shared catalog includes 83 dedicated conversion preset endpoints such as `jpg-to-png`, `mov-to-mp4`, `m4a-to-mp3`, `pdf-to-jpg`, and `excel-to-csv`. Presets are first-class tool routes: `POST /api/v1/tools/
/` Each preset locks the output format and delegates to a base tool such as `convert`, `convert-video`, `extract-audio`, `convert-audio`, `image-to-pdf`, `pdf-to-image`, `svg-to-raster`, or `convert-spreadsheet`. See [Conversion Presets](/tools/conversion-presets) for the complete route table and optional settings. ### Essentials {#essentials} | Tool ID | Name | Key settings | |---------|------|-------------| | `resize` | Resize | `width`, `height`, `fit` (cover/contain/fill/inside/outside), `percentage`, `withoutEnlargement`, plus 23 social media presets | | `crop` | Crop | `left`, `top`, `width`, `height`, `unit` (px/percent) | | `rotate` | Rotate & Flip | `angle`, `horizontal` (bool), `vertical` (bool) | | `convert` | Convert | `format` (jpg/png/webp/avif/tiff/gif/heic/heif), `quality` | | `compress` | Compress | `mode` (quality/targetSize), `quality` (1–100), `targetSizeKb` | ### Optimization {#optimization} | Tool ID | Name | Key settings | |---------|------|-------------| | `optimize-for-web` | Optimize for Web | `format` (webp/jpeg/avif/png), `quality`, `maxWidth`, `maxHeight`, `progressive`, `stripMetadata` | | `strip-metadata` | Strip Metadata | - | | `edit-metadata` | Edit Metadata | `title`, `description`, `author`, `copyright`, `keywords`, `gps` (lat/lon), `dateTime` | | `bulk-rename` | Bulk Rename | `pattern` (supports `{n}`, `{date}`, `{original}`), `startIndex`, `padding` | | `image-to-pdf` | Image to PDF | `pageSize` (A4/Letter/...), `orientation`, `margin`, `targetSize` ({value, unit}) | | `favicon` | Favicon Generator | `padding`, `backgroundColor`, `borderRadius` - generates all standard sizes | ### Adjustments {#adjustments} | Tool ID | Name | Key settings | |---------|------|-------------| | `adjust-colors` | Adjust Colors | `brightness`, `contrast`, `exposure`, `saturation`, `temperature`, `tint`, `hue`, `sharpness`, `red`, `green`, `blue`, `effect` (none/grayscale/sepia/invert) | | `sharpening` | Sharpening | `method` (adaptive/unsharp-mask/high-pass), `sigma`, `m1`, `m2`, `x1`, `y2`, `y3`, `amount`, `radius`, `threshold`, `strength`, `kernelSize` (3/5), `denoise` (off/light/medium/strong) | | `replace-color` | Replace Color | `sourceColor`, `targetColor` (replacement), `makeTransparent`, `tolerance` | | `color-blindness` | Color Blindness Simulation | `simulationType` (protanopia/deuteranopia/tritanopia/protanomaly/deuteranomaly/tritanomaly/achromatopsia/blueConeMonochromacy, default "deuteranomaly") | | `duotone` | Duotone | `shadow` (hex), `highlight` (hex), `intensity` (0-100) | | `pixelate` | Pixelate | `blockSize` (2-128), `region` ({left, top, width, height} for partial pixelation) | | `vignette` | Vignette | `strength` (0.1-1), `color` (hex), `radius`, `softness`, `roundness`, `centerX`, `centerY` | ### AI Tools {#ai-tools} All AI tools run on your hardware: CPU by default, or NVIDIA CUDA when a supported NVIDIA GPU is available. Intel/AMD iGPU acceleration through VA-API, Quick Sync, or OpenCL is not supported for AI inference today. No internet required. | Tool ID | Name | AI Model | Key settings | |---------|------|---------|-------------| | `remove-background` | Remove Background | rembg (BiRefNet / U2-Net) | `model`, `backgroundType` (transparent/color/gradient/blur/image), `backgroundColor`, `gradientColor1`, `gradientColor2`, `gradientAngle`, `blurEnabled`, `blurIntensity`, `shadowEnabled`, `shadowOpacity` | | `upscale` | Image Upscaling | RealESRGAN | `scale` (2/4), `model`, `faceEnhance`, `denoise`, `format`, `quality` | | `erase-object` | Object Eraser | LaMa (ONNX) | Mask sent as second file part (fieldname `mask`), `format`, `quality` | | `ocr` | OCR / Text Extraction | Tesseract (fast); RapidOCR + PP-OCR ONNX (balanced/best) | `quality` (fast/balanced/best), `language`, `enhance` | | `blur-faces` | Face / PII Blur | MediaPipe | `blurRadius`, `sensitivity` | | `smart-crop` | Smart Crop | MediaPipe + Sharp | `mode` (subject/face/trim), `strategy` (attention/entropy), `width`, `height`, `padding`, `facePreset` (closeup/head-shoulders/upper-body/half-body), `sensitivity`, `threshold`, `padToSquare`, `padColor`, `targetSize`, `quality` | | `image-enhancement` | Image Enhancement | Analysis-based | `mode` (auto/exposure/contrast/color/sharpness), `strength` | | `enhance-faces` | Face Enhancement | GFPGAN / CodeFormer | `model` (gfpgan/codeformer), `strength`, `sensitivity`, `centerFace` | | `colorize` | AI Colorization | DDColor | `intensity`, `model` | | `noise-removal` | Noise Removal | Tiered denoising | `tier` (quick/balanced/quality/maximum), `strength`, `detailPreservation`, `colorNoise`, `format`, `quality` | | `red-eye-removal` | Red Eye Removal | Face landmark + color analysis | `sensitivity`, `strength` | | `restore-photo` | Photo Restoration | Multi-step pipeline | `mode` (auto/light/heavy), `scratchRemoval`, `faceEnhancement`, `fidelity`, `denoise`, `denoiseStrength`, `colorize` | | `passport-photo` | Passport Photo | MediaPipe landmarks | Two-phase flow. Analyze uses multipart `file`; generate uses JSON with `countryCode`, `bgColor`, `printLayout` (none/4x6/a4), landmarks, image dimensions | | `content-aware-resize` | Content-Aware Resize | Seam carving (caire) | `width`, `height`, `protectFaces`, `blurRadius`, `sobelThreshold`, `square` | | `transparency-fixer` | PNG Transparency Fixer | BiRefNet HR-matting | `defringe` (0-100), `outputFormat` (png/webp) | | `background-replace` | Background Replace | rembg (BiRefNet) | `backgroundType` (color/gradient), `color` (hex), `gradientColor1`, `gradientColor2`, `gradientAngle`, `feather` (0-20), `format` (png/webp) | | `blur-background` | Blur Background | rembg (BiRefNet) | `intensity` (1-100), `feather` (0-20), `format` (png/webp) | | `ai-canvas-expand` | AI Canvas Expand | LaMa (outpainting) | `extendTop`, `extendRight`, `extendBottom`, `extendLeft` (px), `tier` (fast/balanced/high), `format`, `quality` | ### Watermark & Overlay {#watermark-overlay} | Tool ID | Name | Key settings | |---------|------|-------------| | `watermark-text` | Text Watermark | `text`, `font`, `fontSize`, `color`, `opacity`, `position`, `rotation`, `tile` | | `watermark-image` | Image Watermark | `opacity`, `position`, `scale` - second file is the watermark | | `text-overlay` | Text Overlay | `text`, `font`, `fontSize`, `color`, `x`, `y`, `background`, `padding`, `borderRadius` | | `compose` | Image Composition | `x`, `y`, `opacity`, `blend` - second file is layered on top | | `meme-generator` | Meme Generator | `templateId`, `textLayout` (top-bottom/top-only/bottom-only/center/side-by-side), `textBoxes` (\[{id, text}]), `fontFamily` (anton/arial-black/comic-sans/montserrat/bebas-neue/permanent-marker/roboto), `fontSize`, `textColor`, `strokeColor`, `textAlign`, `allCaps`. Supports template mode (JSON body with `templateId`) or custom image mode (multipart with file). | ### Utilities {#utilities} | Tool ID | Name | Key settings | |---------|------|-------------| | `info` | Image Info | - (returns width, height, format, size, channels, hasAlpha, DPI, EXIF) | | `compare` | Image Compare | `mode` (side-by-side/overlay/diff), `diffThreshold` - second file is the comparison target | | `find-duplicates` | Find Duplicates | `threshold` (perceptual hash distance, default 8) - multi-file | | `color-palette` | Color Palette | `count` (dominant color count), `format` (hex/rgb) | | `qr-generate` | QR Code Generator | `data`, `size`, `margin`, `colorDark`, `colorLight`, `errorCorrectionLevel`, `dotStyle`, `cornerStyle`, `logo` (optional file) | | `barcode-read` | Barcode Reader | - (auto-detects QR, EAN, Code128, DataMatrix, etc.) | | `image-to-base64` | Image to Base64 | `format` (data-uri/plain), `mimeType` | | `html-to-image` | HTML to Image | `url`, `format` (png/jpg/webp), `quality`, `fullPage`, `devicePreset` (desktop/tablet/mobile/custom), `viewportWidth`, `viewportHeight` | | `histogram` | Histogram | `scale` (linear/log) - returns RGB histogram chart + per-channel stats | | `lqip-placeholder` | LQIP Placeholder | `width` (4-64), `blur`, `strategy` (blur/pixelate/solid), `format` (webp/png/jpeg), `quality` | | `barcode-generate` | Barcode Generator | `text`, `type` (code128/ean13/upca/code39/itf14/datamatrix), `scale` (1-8), `includeText` (bool). JSON body, no file upload. | ### Layout & Composition {#layout-composition} | Tool ID | Name | Key settings | |---------|------|-------------| | `collage` | Collage / Grid | `template` (25+ layouts), `gap`, `backgroundColor`, `borderRadius` - multi-file | | `stitch` | Stitch / Combine | `direction` (horizontal/vertical/grid), `gap`, `backgroundColor`, `alignment` - multi-file | | `split` | Image Splitting | `mode` (grid/rows/cols), `rows`, `cols`, `tileWidth`, `tileHeight` | | `border` | Border & Frame | `width`, `color`, `style` (solid/gradient/pattern), `borderRadius`, `padding`, `shadow` | | `beautify` | Beautify Screenshot | `backgroundType` (solid/linear-gradient/radial-gradient/image/transparent), `gradientStops`, `padding`, `borderRadius`, `shadowPreset`, `frame` (none/macos-light/macos-dark/windows-light/windows-dark/browser-light/browser-dark/iphone/macbook/ipad/...), `socialPreset` (none/twitter/linkedin/instagram-square/instagram-story/facebook/producthunt), `watermarkText`, `outputFormat` | | `circle-crop` | Circle Crop | `zoom` (1-5), `offsetX`, `offsetY`, `borderWidth`, `borderColor`, `background` (transparent/hex), `outputSize` | | `image-pad` | Image Pad | `target` (16:9/9:16/1:1/4:3/3:4/custom), `ratioW`, `ratioH`, `background` (color/transparent/blur), `color` (hex), `padding` (0-50%) | | `sprite-sheet` | Sprite Sheet | `columns` (1-16), `padding`, `background` (hex), `format` (png/webp/jpeg), `quality` - multi-file (2-64 images) | ### Format & Conversion {#format-conversion} | Tool ID | Name | Key settings | |---------|------|-------------| | `svg-to-raster` | SVG to Raster | `format` (png/jpeg/webp/avif/tiff/gif/heif), `width`, `height`, `scale`, `dpi`, `background` | | `vectorize` | Image to SVG | `colorMode` (bw/color), `threshold`, `colorPrecision`, `filterSpeckle`, `pathMode` (none/polygon/spline) | | `gif-tools` | GIF Tools | `action` (resize/optimize/reverse/speed/extract-frames/rotate/add-text), action-specific params | | `gif-webp` | GIF/WebP Converter | `quality` (1-100), `lossless` (bool), `resizePercent` (10-100) | ### Video Tools {#video-tools} | Tool ID | Name | Key settings | |---------|------|-------------| | `convert-video` | Convert Video | `format` (mp4/mov/webm/avi/mkv), `quality` (high/balanced/small) | | `compress-video` | Compress Video | `quality` (light/balanced/strong), `resolution` (original/1080p/720p/480p) | | `trim-video` | Trim Video | `startS`, `endS`, `precise` (bool, frame-accurate cut) | | `mute-video` | Mute Video | - | | `video-to-gif` | Video to GIF | `fps` (1-30), `width`, `startS`, `durationS` (max 60s) | | `resize-video` | Resize Video | `width`, `height`, `preset` (custom/2160p/1440p/1080p/720p/480p/360p) | | `crop-video` | Crop Video | `width`, `height`, `x`, `y` | | `rotate-video` | Rotate Video | `transform` (cw90/ccw90/180/hflip/vflip) | | `change-fps` | Change FPS | `fps` (1-120) | | `video-color` | Video Color | `brightness`, `contrast`, `saturation`, `gamma` | | `video-speed` | Video Speed | `factor` (0.25-4), `keepPitch` (bool) | | `reverse-video` | Reverse Video | - (max 5 minutes) | | `video-loudnorm` | Normalize Audio | - (EBU R128) | | `aspect-pad` | Aspect Pad | `target` (16:9/9:16/1:1/4:3/3:4), `color` (hex) | | `blur-pad` | Blur Pad | `target` (16:9/9:16/1:1/4:3/3:4), `blur` (2-50) | | `watermark-video` | Watermark Video | `text`, `position`, `fontSize`, `opacity`, `color` | | `stabilize-video` | Stabilize Video | `smoothing` (5-60, in frames) | | `gif-to-video` | GIF to Video | `format` (mp4/webm/mov) | | `video-to-webp` | Video to WebP | `fps`, `width`, `quality`, `loop` (bool) | | `video-to-frames` | Video to Frames | `mode` (all/nth/timestamps), `n`, `timestamps`, `format` (png/jpg) | | `merge-videos` | Merge Videos | - (multi-file, normalized to first video's resolution) | | `replace-audio` | Replace Audio | - (video + audio file, two files) | | `burn-subtitles` | Burn Subtitles | `fontSize` (8-72) - video + subtitle file | | `embed-subtitles` | Embed Subtitles | `language` (ISO 639-2/B code) - video + subtitle file | | `extract-subtitles` | Extract Subtitles | - (outputs SRT) | | `images-to-video` | Images to Video | `secondsPerImage` (0.5-10), `resolution` (1080p/720p/square), `fps` - multi-file | | `video-metadata` | Clean Video Metadata | - | | `auto-subtitles` | Auto Subtitles (AI) | `language` (auto/en/de/fr/es/zh/ja/ko/id/th/vi), `format` (srt/vtt) | | `extract-audio` | Extract Audio | `format` (mp3/wav/m4a/ogg) | ### Audio Tools {#audio-tools} | Tool ID | Name | Key settings | |---------|------|-------------| | `convert-audio` | Convert Audio | `format` (mp3/wav/ogg/flac/m4a), `bitrateKbps` (32-320) | | `trim-audio` | Trim Audio | `startS`, `endS` | | `volume-adjust` | Volume Adjust | `gainDb` (-30 to 30) | | `normalize-audio` | Normalize Audio | - (EBU R128, -16 LUFS) | | `fade-audio` | Fade Audio | `fadeInS` (0-30), `fadeOutS` (0-30) | | `reverse-audio` | Reverse Audio | - | | `audio-speed` | Audio Speed | `factor` (0.25-4) | | `pitch-shift` | Pitch Shift | `semitones` (-12 to 12) | | `audio-channels` | Audio Channels | `mode` (stereo-to-mono/mono-to-stereo/swap) | | `silence-removal` | Silence Removal | `thresholdDb` (-80 to -20), `minSilenceS` (0.1-5) | | `noise-reduction` | Noise Reduction | `strength` (light/medium/strong) | | `merge-audio` | Merge Audio | `format` (mp3/wav/flac/m4a) - multi-file | | `split-audio` | Split Audio | `mode` (time/parts/silence), `segmentS`, `parts`, `thresholdDb`, `minSilenceS` | | `ringtone-maker` | Ringtone Maker | `startS`, `durationS` (1-30) | | `waveform-image` | Waveform Image | `width`, `height`, `color` (hex) | | `audio-metadata` | Audio Metadata | `strip` (bool), `title`, `artist`, `album` | | `transcribe-audio` | Transcribe Audio (AI) | `language` (auto/en/de/fr/es/zh/ja/ko/id/th/vi), `outputFormat` (txt/srt/vtt) | ### Document Tools {#document-tools} | Tool ID | Name | Key settings | |---------|------|-------------| | `merge-pdf` | Merge PDFs | - (multi-file, up to 20 PDFs) | | `split-pdf` | Split PDF | `mode` (range/every), `range`, `everyN` (1-500) | | `compress-pdf` | Compress PDF | `mode` (quality/targetSize), `quality` (1-100), `targetSizeKb` | | `rotate-pdf` | Rotate PDF | `angle` (90/180/270), `range` (page range) | | `extract-pages` | Extract Pages | `range` (qpdf syntax, e.g. "1-5,8,10-z") | | `remove-pages` | Remove Pages | `pages` (qpdf range to remove) | | `organize-pdf` | Organize PDF | `order` (qpdf page order, e.g. "3,1,2,5-z") | | `protect-pdf` | Protect PDF | `userPassword`, `ownerPassword` (AES-256) | | `unlock-pdf` | Unlock PDF | `password` | | `repair-pdf` | Repair PDF | - | | `linearize-pdf` | Web-Optimize PDF | - (linearize for fast web viewing) | | `grayscale-pdf` | Grayscale PDF | - | | `pdfa-convert` | PDF/A Convert | - (archival PDF/A-2) | | `crop-pdf` | Crop PDF | `margin` (0-2000 points) | | `nup-pdf` | N-up PDF | `perSheet` (2/3/4/8/9/12/16) | | `booklet-pdf` | Booklet PDF | `perSheet` (2/4/6/8) | | `watermark-pdf` | Watermark PDF | `text`, `position`, `fontSize`, `opacity`, `rotation` | | `pdf-page-numbers` | PDF Page Numbers | `position` (bl/bc/br/tl/tc/tr), `fontSize` | | `flatten-pdf` | Flatten PDF | - (bakes forms and annotations) | | `redact-pdf` | Redact PDF | `terms` (string\[]), `caseSensitive` (bool) | | `sign-pdf` | Sign PDF | Custom multipart route with PDF `file`, signature files `sig0`, `sig1`, and `placements` JSON array | | `pdf-to-text` | PDF to Text | - | | `pdf-to-word` | PDF to Word | - | | `pdf-metadata` | PDF Metadata | `title`, `author`, `subject`, `keywords` | | `convert-document` | Convert Document | `format` (docx/odt/rtf/txt) | | `convert-presentation` | Convert Presentation | `format` (pptx/odp) | | `convert-spreadsheet` | Convert Spreadsheet | `format` (xlsx/ods/csv) | | `excel-to-pdf` | Excel to PDF | - | | `word-to-pdf` | Word to PDF | - | | `powerpoint-to-pdf` | PowerPoint to PDF | - | | `html-to-pdf` | HTML to PDF | - (remote resources disabled) | | `markdown-to-docx` | Markdown to Word | - | | `markdown-to-html` | Markdown to HTML | - | | `markdown-to-pdf` | Markdown to PDF | - (remote resources disabled) | | `epub-convert` | Convert EPUB | `format` (pdf/docx/html/md) | | `to-epub` | Convert to EPUB | - (accepts .docx, .md, .html, .txt) | | `ocr-pdf` | PDF OCR (AI) | `quality` (fast/balanced/best), `language` (auto/en/de/fr/es/zh/ja/ko), `pages` | | `pdf-to-image` | PDF to Image | `pages` (all/range), `format`, `dpi`, `quality` | | `pdf-to-jpg` | PDF to JPG | `pages`, `dpi`, `quality`, `colorMode` | | `pdf-to-png` | PDF to PNG | `pages`, `dpi`, `quality`, `colorMode` | | `pdf-to-tiff` | PDF to TIFF | `pages`, `dpi`, `quality`, `colorMode` | ### File Tools {#file-tools} | Tool ID | Name | Key settings | |---------|------|-------------| | `chart-maker` | Chart Maker | `kind` (bar/line/pie), `title`, `width`, `height` | | `csv-excel` | CSV to Excel | `sheet` (worksheet number for XLSX input) - bidirectional | | `csv-json` | CSV to JSON | `pretty` (bool) - bidirectional | | `json-xml` | JSON to XML | `pretty` (bool) - bidirectional | | `split-csv` | Split CSV | `rowsPerFile` (1-1000000), `keepHeader` (bool) | | `merge-csvs` | Merge CSVs | - (multi-file, matching columns) | | `yaml-json` | YAML / JSON | - (bidirectional) | | `xml-to-csv` | XML to CSV | - (auto-finds repeating elements) | | `excel-to-csv` | Excel to CSV | dedicated conversion preset backed by `convert-spreadsheet` | | `create-zip` | Create ZIP | - (multi-file, 2-50 files) | | `extract-zip` | Extract ZIP | - (bomb-protected) | ### HTML to Image {#html-to-image} Capture a webpage as an image. Unlike other tools, this endpoint accepts `application/json` instead of multipart form data (no file upload needed). **Endpoint:** `POST /api/v1/tools/image/html-to-image` **Content-Type:** `application/json` | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `url` | string | (required) | URL to capture (http/https only) | | `format` | string | `"png"` | Output format: `jpg`, `png`, `webp` | | `quality` | number | `90` | Quality 1-100 (JPG/WebP only) | | `fullPage` | boolean | `false` | Capture full scrollable page | | `devicePreset` | string | `"desktop"` | `desktop`, `tablet`, `mobile`, `custom` | | `viewportWidth` | number | `1280` | Custom viewport width 320-3840 | | `viewportHeight` | number | `720` | Custom viewport height 320-2160 | **Example:** ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"url": "https://snapotter.com", "format": "png", "devicePreset": "desktop"}' ``` **Response:** ```json { "jobId": "uuid", "downloadUrl": "/api/v1/download/{jobId}/screenshot.png", "originalSize": 0, "processedSize": 54321 } ``` ### Tool Sub-Routes {#tool-sub-routes} Some tools expose additional endpoints beyond the standard `POST /api/v1/tools/
/`: | Method | Path | Description | |--------|------|-------------| | `GET` | `/api/v1/tools/popular` | Return popular tool IDs, falling back to a curated default list when usage data is sparse | | `POST` | `/api/v1/tools/image/remove-background/effects` | Apply background effects (color/gradient/blur/shadow) without re-running AI. Uses cached mask from initial removal. | | `POST` | `/api/v1/tools/image/edit-metadata/inspect` | Read existing EXIF/IPTC/XMP metadata from an image | | `POST` | `/api/v1/tools/image/strip-metadata/inspect` | Inspect metadata fields before stripping | | `POST` | `/api/v1/tools/image/passport-photo/analyze` | Phase 1: AI face detection + background removal. Returns face landmarks and cached data. | | `POST` | `/api/v1/tools/image/passport-photo/generate` | Phase 2: Crop, resize, and tile using cached analysis. No AI re-run. | | `POST` | `/api/v1/tools/image/gif-tools/info` | Get GIF metadata (frame count, dimensions, duration) | | `POST` | `/api/v1/tools/pdf/pdf-to-image/info` | Get PDF metadata (page count, dimensions) | | `POST` | `/api/v1/tools/pdf/pdf-to-image/preview` | Generate a preview of a specific PDF page | | `POST` | `/api/v1/tools/pdf/pdf-to-jpg/info` | Get PDF metadata for the dedicated JPG preset | | `POST` | `/api/v1/tools/pdf/pdf-to-jpg/preview` | Generate a JPG preset PDF page preview | | `POST` | `/api/v1/tools/pdf/pdf-to-png/info` | Get PDF metadata for the dedicated PNG preset | | `POST` | `/api/v1/tools/pdf/pdf-to-png/preview` | Generate a PNG preset PDF page preview | | `POST` | `/api/v1/tools/pdf/pdf-to-tiff/info` | Get PDF metadata for the dedicated TIFF preset | | `POST` | `/api/v1/tools/pdf/pdf-to-tiff/preview` | Generate a TIFF preset PDF page preview | | `POST` | `/api/v1/tools/image/svg-to-raster/batch` | Batch convert multiple SVGs to raster | | `POST` | `/api/v1/tools/image/image-enhancement/analyze` | Analyze image quality and return enhancement recommendations | | `POST` | `/api/v1/tools/image/optimize-for-web/preview` | Lightweight preview for live parameter tuning. Returns optimized image with size headers. | ## Batch Processing {#batch-processing} Apply a generic batch-enabled tool to multiple files at once. Returns a ZIP archive. Custom multi-file or multi-step routes, such as PDF signing and PDF-to-image preset routes, use their own endpoint contract instead of the generic `/batch` route. The `ocr-pdf` tool supports this generic `/batch` route. ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress/batch \ -H "Authorization: Bearer " \ -F "files=@a.jpg" \ -F "files=@b.jpg" \ -F "files=@c.jpg" \ -F 'settings={"quality":80}' ``` Concurrency is controlled by `CONCURRENT_JOBS` (default: auto-detected from CPU cores). `MAX_BATCH_SIZE` limits the number of files per batch (default: 100; set 0 for unlimited). ## Pipelines {#pipelines} ### Execute a pipeline {#execute-a-pipeline} ```bash # Single file curl -X POST http://localhost:1349/api/v1/pipeline/execute \ -H "Authorization: Bearer " \ -F "file=@input.jpg" \ -F 'pipeline={"steps":[ {"toolId":"resize","settings":{"width":1200}}, {"toolId":"compress","settings":{"quality":80}}, {"toolId":"watermark-text","settings":{"text":"© 2025"}} ]}' # Batch (multiple files → ZIP) curl -X POST http://localhost:1349/api/v1/pipeline/batch \ -H "Authorization: Bearer " \ -F "files=@a.jpg" \ -F "files=@b.jpg" \ -F 'pipeline={"steps":[{"toolId":"resize","settings":{"width":800}}]}' ``` Each step's output is the next step's input. Pipelines allow 20 steps by default, configurable via `MAX_PIPELINE_STEPS`. Set `MAX_PIPELINE_STEPS=0` to remove the limit. ### Save and manage pipelines {#save-and-manage-pipelines} | Method | Path | Description | |--------|------|-------------| | `POST` | `/api/v1/pipeline/save` | Save a named pipeline (`name`, `description`, `steps[]`) | | `GET` | `/api/v1/pipeline/list` | List saved pipelines (admins see all; users see own) | | `DELETE` | `/api/v1/pipeline/:id` | Delete (owner or admin) | | `GET` | `/api/v1/pipeline/tools` | List tool IDs valid for pipeline steps | ## Progress Tracking {#progress-tracking} Long-running jobs, queued tools, batch jobs, and pipelines emit real-time progress via Server-Sent Events. The progress stream is public and keyed by job ID, so clients do not need to send an Authorization header to read it. ```bash # Connect to the SSE stream (jobId is in the JSON response body from the tool endpoint) curl -N http://localhost:1349/api/v1/jobs//progress ``` Event format: ``` data: {"jobId":"...","type":"single","phase":"processing","stage":"Upscaling","percent":42} data: {"jobId":"...","type":"single","phase":"complete","percent":100,"result":{"downloadUrl":"/api/v1/download/..."}} data: {"jobId":"...","type":"batch","status":"processing","completedFiles":2,"totalFiles":5,"failedFiles":0,"errors":[]} ``` You can request cancellation for a queued or running job with `POST /api/v1/jobs/:jobId/cancel`. The response is `{"canceled":true|false}`. ## File Library {#file-library} Persistent file storage with version history. | Method | Path | Description | |--------|------|-------------| | `POST` | `/api/v1/upload` | Upload files to workspace (temp processing) | | `POST` | `/api/v1/files/upload` | Upload files to the persistent file library | | `POST` | `/api/v1/files/save-result` | Save a tool processing result as a new file version | | `GET` | `/api/v1/files` | List saved files (paginated, with search) | | `GET` | `/api/v1/files/:id` | Get file metadata + version chain | | `GET` | `/api/v1/files/:id/download` | Download file | | `GET` | `/api/v1/files/:id/thumbnail` | Get 300px JPEG thumbnail | | `DELETE` | `/api/v1/files` | Bulk delete files and their version chains (body: `{ ids: [...] }`) | | `POST` | `/api/v1/fetch-urls` | Fetch remote URLs into the workspace for URL-based imports | | `POST` | `/api/v1/preview` | Generate a browser-compatible WebP preview (for HEIC/HEIF/RAW formats) | | `GET` | `/api/v1/files/:id/preview` | Stream a cached or generated browser-compatible preview for a saved PDF, office document, video, or audio file | | `POST` | `/api/v1/preview/generate` | Generate an on-demand MP4 or MP3 preview for an uploaded media file without saving it first | | `GET` | `/api/v1/download/:jobId/:filename` | Download a processed file from a workspace | To auto-save a tool result to the library, include `fileId` as a multipart form field referencing an existing library file. The processed result will be saved as a new version. ## API Key Management {#api-key-management} | Method | Path | Access | Description | |--------|------|--------|-------------| | `POST` | `/api/v1/api-keys` | Auth | Generate new key - shown once | | `GET` | `/api/v1/api-keys` | Auth | List keys (name, id, lastUsedAt - not raw key) | | `DELETE` | `/api/v1/api-keys/:id` | Auth | Delete key | ## Teams {#teams} | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/teams` | Admin (`teams:manage`) | List teams | | `POST` | `/api/v1/teams` | Admin (`teams:manage`) | Create team | | `PUT` | `/api/v1/teams/:id` | Admin (`teams:manage`) | Rename team | | `DELETE` | `/api/v1/teams/:id` | Admin (`teams:manage`) | Delete team (cannot delete default team or teams with members) | ## Settings {#settings} Runtime configuration uses a closed set of recognized keys. Reading requires `settings:read` and writing requires `settings:write`; security and compliance keys additionally require `security:manage` or `compliance:manage`. Secret settings require full-administrator authority, while credentials and state owned by dedicated endpoints are read-only here. Bulk updates are validated before any value is written. | Method | Path | Description | |--------|------|-------------| | `GET` | `/api/v1/settings` | Get all settings | | `PUT` | `/api/v1/settings` | Bulk update settings (JSON body with key-value pairs) | | `GET` | `/api/v1/settings/:key` | Get a specific setting by key | Representative keys: `disabledTools` (JSON array of tool IDs), `enableExperimentalTools` (boolean), `loginAttemptLimit` (security policy), and `auditRetentionDays` (compliance policy). Unknown keys are rejected. ## Preferences {#preferences} Per-user preferences are separate from instance settings. Any authenticated user can read and update their own preference map. | Method | Path | Description | |--------|------|-------------| | `GET` | `/api/v1/preferences` | Get the current user's preferences as `{ "preferences": { ... } }` | | `PUT` | `/api/v1/preferences` | Upsert one or more preference keys for the current user | ## Roles {#roles} Custom role management with granular permissions. Role creation and mutation are constrained by authority containment: the proposed or current role cannot outrank the actor, exceed the actor's effective permissions, or broaden the actor's tool scope. API-key scopes participate in this check. Deleting a custom role also requires authority to assign the built-in `user` fallback used for its members. | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/roles` | Admin (`audit:read`) | List all roles with user counts | | `POST` | `/api/v1/roles` | Admin (`security:manage`) | Create a custom role (`name`, `description`, `permissions`) | | `PUT` | `/api/v1/roles/:id` | Admin (`security:manage`) | Update a custom role (cannot modify built-in roles) | | `DELETE` | `/api/v1/roles/:id` | Admin (`security:manage`) | Delete a custom role (cannot delete built-in roles; affected users revert to `user` role) | Available permissions (17): `tools:use`, `files:own`, `files:all`, `apikeys:own`, `apikeys:all`, `pipelines:own`, `pipelines:all`, `settings:read`, `settings:write`, `users:manage`, `teams:manage`, `features:manage`, `system:health`, `audit:read`, `compliance:manage`, `webhooks:manage`, `security:manage`. ## Audit Log {#audit-log} Admin-only endpoint for reviewing security-relevant actions. | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/audit-log` | Admin (`audit:read`) | Paginated audit log with optional filters | Query parameters: | Parameter | Description | |-----------|-------------| | `page` | Page number (default: 1) | | `limit` | Entries per page (default: 50, max: 100) | | `action` | Filter by action type (e.g. `ROLE_CREATED`, `ROLE_DELETED`) | | `ip` | Filter by source IP address | | `from` | Filter entries after this ISO 8601 date | | `to` | Filter entries before this ISO 8601 date | ## Analytics {#analytics} | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/config/analytics` | Public | Get the effective analytics configuration (PostHog key, Sentry DSN, sample rate). Keys, DSN, and instance ID are blank when analytics is off, either from the compile-time bake or the instance `analyticsEnabled` setting. | | `POST` | `/api/v1/feedback` | Auth | Submit explicit user feedback to the configured PostHog project as `feedback_submitted`. The route respects the analytics gate, rate-limits submissions, strips contact fields unless `contactOk` is true, and never accepts file contents, file names, upload paths, or raw private error text. When analytics is disabled, it returns `{ "ok": true, "accepted": false }`. | | `PUT` | `/api/v1/settings` | Admin (`settings:write`) | Set the instance-wide opt-out. Send a JSON body `{ "analyticsEnabled": "false" }` to turn analytics off for everyone, or `"true"` to turn it back on. | ## Features / AI Bundles {#features-ai-bundles} Manage AI feature bundles (install/uninstall AI model packages in the Docker environment). Prefer the tool-level install endpoint when enabling a tool from custom automation: some AI tools need more than one shared bundle, and this endpoint skips already-installed bundles while queuing only the missing ones. OCR is an optional enhancement rather than a hard dependency. Its `fast` Tesseract tier works without a pack; `POST /api/v1/admin/features/ocr/install` installs the signed RapidOCR pack for `balanced` and `best` on Linux amd64 or arm64. The accurate OCR runtime uses CPU on CPU-only and NVIDIA hosts and requires at least 4 GiB of effective memory (the configured container cgroup limit, otherwise host memory). SnapOtter reports `requiredMemoryBytes`, `effectiveMemoryBytes`, and an `insufficient-memory` compatibility reason, and rejects an incompatible install before download. This memory requirement does not apply to `fast`. The pack is about 208-234 MiB to download and 409-488 MiB installed, depending on the target; the signed index binds the exact sizes enforced during installation. | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/features` | Auth | List all feature bundles and their install status | | `POST` | `/api/v1/admin/features/:bundleId/install` | Admin (`features:manage`) | Install a feature bundle (async, returns `jobId` for progress tracking) | | `POST` | `/api/v1/admin/tools/:toolId/features/install` | Admin (`features:manage`) | Install every bundle a tool requires; returns per-bundle queued/skipped status | | `POST` | `/api/v1/admin/features/:bundleId/uninstall` | Admin (`features:manage`) | Uninstall a feature bundle and clean up model files | | `GET` | `/api/v1/admin/features/disk-usage` | Admin (`features:manage`) | Get total disk usage of AI models | | `POST` | `/api/v1/admin/features/import` | Admin (`features:manage`) | Import a legacy AI bundle (`file`) or a signed offline OCR release (`index` plus `archive`) | An air-gapped OCR import must include the release's signed `ocr-runtime-index.json` and the matching platform archive. SnapOtter applies the same Ed25519 signature, artifact hash, compatibility, extraction, and smoke-test checks used by online installation: ```bash curl -X POST http://localhost:1349/api/v1/admin/features/import \ -H "Authorization: Bearer " \ -F "index=@ocr-runtime-index.json" \ -F "archive=@ocr-linux-amd64-cpu-py312.tar.gz" ``` Use the `linux-arm64-cpu-py311` archive on arm64. A signed artifact for another target is rejected rather than installed. ## Admin Operations {#admin-operations} Operational endpoints for observability, support, usage reporting, and backup status. | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/admin/log-level` | Admin (`settings:write`) | Read the current runtime log level | | `POST` | `/api/v1/admin/log-level` | Admin (`settings:write`) | Change the runtime log level (`fatal`, `error`, `warn`, `info`, `debug`, `trace`, or `silent`) | | `GET` | `/api/v1/metrics` | Admin (`system:health`) | Prometheus metrics in text format | | `GET` | `/api/v1/admin/support-bundle` | Admin (`system:health`) | Download a redacted diagnostic support bundle ZIP | | `GET` | `/api/v1/admin/usage` | Admin (`audit:read`) | Usage dashboard data, with optional `days` query parameter | | `GET` | `/api/v1/admin/backup-status` | Admin (`system:health`) | Read last backup metadata and freshness status | | `POST` | `/api/v1/admin/backup-status` | Admin (`system:health`) | Record a completed backup (`type`, optional `sizeBytes`, optional `notes`) | ## Enterprise APIs {#enterprise-apis} These routes are license-gated by their related enterprise feature. They still require the listed SnapOtter permission. **Full built-in admin** means the authenticated actor has the `admin` role and the complete effective admin permission set. An API-key scope that omits any admin permission does not qualify. | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/enterprise/audit/export` | Admin (`audit:read`) | Export audit entries as JSON or CSV with filters | | `GET` | `/api/v1/enterprise/config/export` | Full built-in admin | Export redacted instance config, custom roles, and teams | | `POST` | `/api/v1/enterprise/config/import` | Full built-in admin | Import config, with optional dry run | | `GET` | `/api/v1/enterprise/ip-allowlist` | Admin (`security:manage`) | Read configured CIDR allowlist | | `PUT` | `/api/v1/enterprise/ip-allowlist` | Admin (`security:manage`) | Update CIDR allowlist with self-lockout prevention | | `GET` | `/api/v1/enterprise/legal-hold` | Admin (`compliance:manage`) | List user and team legal holds | | `PUT` | `/api/v1/enterprise/legal-hold` | Admin (`compliance:manage`) | Apply or release a legal hold on a user or team | | `POST` | `/api/v1/enterprise/scim/token` | Full built-in admin | Generate a SCIM bearer token, returned once | | `DELETE` | `/api/v1/enterprise/scim/token` | Full built-in admin | Revoke the current SCIM bearer token | | `GET` | `/api/v1/enterprise/siem/config` | Admin (`webhooks:manage`) | Read SIEM forwarding config | | `PUT` | `/api/v1/enterprise/siem/config` | Admin (`webhooks:manage`) | Update SIEM forwarding config | | `GET` | `/api/v1/enterprise/webhooks` | Admin (`webhooks:manage`) | List webhook destinations | | `POST` | `/api/v1/enterprise/webhooks` | Admin (`webhooks:manage`) | Create a webhook destination | | `PUT` | `/api/v1/enterprise/webhooks/:index` | Admin (`webhooks:manage`) | Update a webhook destination | | `DELETE` | `/api/v1/enterprise/webhooks/:index` | Admin (`webhooks:manage`) | Delete a webhook destination | | `POST` | `/api/v1/enterprise/webhooks/:index/test` | Admin (`webhooks:manage`) | Send a test webhook payload | | `POST` | `/api/v1/enterprise/users/:id/export` | Admin (`compliance:manage`) | Start a GDPR user export job | | `GET` | `/api/v1/enterprise/users/:id/export/:jobId` | Admin (`compliance:manage`) | Read GDPR export status and download URL | | `DELETE` | `/api/v1/enterprise/users/:id/purge` | Admin (`compliance:manage`; target authority) | Permanently purge a user's data after confirmation | | `DELETE` | `/api/v1/enterprise/teams/:id/purge` | Admin (`compliance:manage`; all-member authority) | Permanently purge a team's data after confirmation | | `GET` | `/api/v1/admin/version` | Admin (`system:health`) | Read app, build, Node, and schema version metadata | | `GET` | `/api/v1/admin/migrations/pending` | Admin (`system:health`) | Compare packaged migrations with applied migrations | | `GET` | `/api/v1/admin/upgrade-check` | Admin (`system:health`) | Run upgrade readiness checks | ### SCIM 2.0 {#scim-2-0} SCIM discovery endpoints are public. User and group endpoints require the SCIM bearer token generated above. Legacy unversioned tokens are invalid and must be reissued as `so_scim_v2_...` tokens by a full built-in admin. | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/scim/v2/ServiceProviderConfig` | Public | SCIM server capabilities | | `GET` | `/api/v1/scim/v2/Schemas` | Public | SCIM schema discovery | | `GET` | `/api/v1/scim/v2/ResourceTypes` | Public | SCIM resource type discovery | | `GET` | `/api/v1/scim/v2/Users` | SCIM token | List users, with optional SCIM filter | | `POST` | `/api/v1/scim/v2/Users` | SCIM token | Create a user | | `GET` | `/api/v1/scim/v2/Users/:id` | SCIM token | Get a user | | `PUT` | `/api/v1/scim/v2/Users/:id` | SCIM token | Replace a user | | `DELETE` | `/api/v1/scim/v2/Users/:id` | SCIM token | Soft deactivate a user | | `GET` | `/api/v1/scim/v2/Groups` | SCIM token | List teams as SCIM groups | | `POST` | `/api/v1/scim/v2/Groups` | SCIM token | Create a team | | `GET` | `/api/v1/scim/v2/Groups/:id` | SCIM token | Get a team | | `PUT` | `/api/v1/scim/v2/Groups/:id` | SCIM token | Replace a team and group membership | | `DELETE` | `/api/v1/scim/v2/Groups/:id` | SCIM token | Delete a team | ## Meme Templates {#meme-templates} Supporting API for the meme generator tool. | Method | Path | Access | Description | |--------|------|--------|-------------| | `GET` | `/api/v1/meme-templates` | Auth | List all available meme templates with text box positions | | `GET` | `/api/v1/meme-templates/full/:filename` | Auth | Serve full-size template image | | `GET` | `/api/v1/meme-templates/thumbs/:filename` | Auth | Serve template thumbnail | | `GET` | `/api/v1/meme-templates/fonts/:filename` | Auth | Serve font file used for meme text rendering | ## Error Responses {#error-responses} All errors return JSON: ```json { "error": "Human-readable message", "code": "MACHINE_READABLE_CODE" } ``` | Status | Meaning | |--------|---------| | 400 | Invalid request / validation failed | | 401 | Not authenticated | | 403 | Insufficient permissions | | 404 | Resource not found | | 413 | File too large (see `MAX_UPLOAD_SIZE_MB`) | | 422 | Processing failed after validation | | 429 | Rate limited (see `RATE_LIMIT_PER_MIN`) | | 501 | Required AI feature bundle is not installed (`FEATURE_NOT_INSTALLED`) | | 500 | Internal server error | --- --- url: https://docs.snapotter.com/api/image-engine.md description: >- Image engine operations reference. All Sharp-based image processing operations and their parameters. --- # Image engine {#image-engine} The `@snapotter/image-engine` package handles all non-AI image operations. It wraps [Sharp](https://sharp.pixelplumbing.com/) and runs entirely in-process with no external dependencies. ## Operations {#operations} ### resize {#resize} Scale an image to specific dimensions or by percentage. | Parameter | Type | Description | |---|---|---| | `width` | number | Target width in pixels | | `height` | number | Target height in pixels | | `fit` | string | `cover`, `contain`, `fill`, `inside`, or `outside` | | `withoutEnlargement` | boolean | If true, won't upscale smaller images | | `percentage` | number | Scale by percentage instead of absolute dimensions | You can set `width`, `height`, or both. If you only set one, the other is calculated to maintain the aspect ratio. ### crop {#crop} Cut out a rectangular region from the image. | Parameter | Type | Description | |---|---|---| | `left` | number | X offset from the left edge | | `top` | number | Y offset from the top edge | | `width` | number | Width of the crop area | | `height` | number | Height of the crop area | | `unit` | string | `px` (default) or `percent` | ### rotate {#rotate} Rotate the image by a given angle. | Parameter | Type | Description | |---|---|---| | `angle` | number | Rotation angle in degrees (0-360) | | `background` | string | Fill color for exposed area (default: `#000000`). Only applies to non-90-degree angles. | ### flip {#flip} Mirror the image horizontally, vertically, or both. At least one must be true. | Parameter | Type | Description | |---|---|---| | `horizontal` | boolean | Mirror left to right | | `vertical` | boolean | Mirror top to bottom | ### convert {#convert} Change the image format. | Parameter | Type | Description | |---|---|---| | `format` | string | Target format: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `jxl`, `heic`, `heif`, `bmp`, `ico`, `jp2`, `qoi` | | `quality` | number | Compression quality (1-100, applies to lossy formats) | The first seven formats (`jpg` through `jxl`) are encoded by Sharp in-process. The remaining formats use external encoders at the API layer: `heic`/`heif` via heif-enc, `bmp`/`ico` via ImageMagick, `jp2` via opj\_compress, and `qoi` via an inline TypeScript codec. ### compress {#compress} Reduce file size while keeping the same format. | Parameter | Type | Description | |---|---|---| | `quality` | number | Target quality (1-100) | | `targetSizeBytes` | number | Optional target file size in bytes | | `format` | string | Optional format override | ### strip-metadata {#strip-metadata} Remove EXIF, IPTC, XMP, and ICC metadata from the image. With no parameters (or `stripAll: true`), strips everything. Pass individual flags for selective stripping. | Parameter | Type | Description | |---|---|---| | `stripAll` | boolean | Strip all metadata (default when no flags are set) | | `stripExif` | boolean | Strip EXIF data (including GPS if `stripGps` is not separately set) | | `stripGps` | boolean | Strip GPS location data | | `stripIcc` | boolean | Strip ICC color profile | | `stripXmp` | boolean | Strip XMP metadata | ### Color adjustments {#color-adjustments} These operations modify the color properties of an image. Each takes a single numeric value. | Operation | Parameter | Range | Description | |---|---|---|---| | `brightness` | `value` | -100 to 100 | Adjust brightness | | `contrast` | `value` | -100 to 100 | Adjust contrast | | `saturation` | `value` | -100 to 100 | Adjust color saturation | ### Color filters {#color-filters} These apply a fixed color transformation. They take no parameters. | Operation | Description | |---|---| | `grayscale` | Convert to grayscale | | `sepia` | Apply a sepia tone | | `invert` | Invert all colors | ### Color channels {#color-channels} Adjust individual RGB color channels. Values are multipliers where 100 = no change. | Parameter | Type | Description | |---|---|---| | `red` | number | Red channel multiplier (0 to 200, 100 = unchanged) | | `green` | number | Green channel multiplier (0 to 200, 100 = unchanged) | | `blue` | number | Blue channel multiplier (0 to 200, 100 = unchanged) | ### sharpen {#sharpen} Simple sharpening controlled by a single value. | Parameter | Type | Description | |---|---|---| | `value` | number | Sharpening intensity (0 to 100). Mapped to a Gaussian sigma of 0.5-10. | ### sharpen-advanced {#sharpen-advanced} Advanced sharpening with three selectable methods and an optional noise-reduction pre-pass. | Parameter | Type | Description | |---|---|---| | `method` | string | `adaptive`, `unsharp-mask`, or `high-pass` | | `sigma` | number | Gaussian blur radius, 0.5-10 (adaptive) | | `m1` | number | Flat-area sharpening, 0-10 (adaptive) | | `m2` | number | Textured-area sharpening, 0-20 (adaptive) | | `x1` | number | Flat/jagged threshold, 0-10 (adaptive) | | `y2` | number | Max brightening (halo clamp), 0-50 (adaptive) | | `y3` | number | Max darkening (halo clamp), 0-50 (adaptive) | | `amount` | number | Intensity percentage, 0-500 (unsharp-mask) | | `radius` | number | Blur radius, 0.1-5.0 (unsharp-mask) | | `threshold` | number | Minimum edge brightness, 0-255 (unsharp-mask) | | `strength` | number | Blend strength, 0-100 (high-pass) | | `kernelSize` | number | `3` or `5` for 3x3 / 5x5 kernel (high-pass) | | `denoise` | string | Noise reduction pre-pass: `off`, `light`, `medium`, or `strong` | Parameters are method-specific. Only supply the ones relevant to the chosen method. ### color-blindness {#color-blindness} Simulate a color vision deficiency using a 3x3 color-recombination matrix. | Parameter | Type | Description | |---|---|---| | `type` | string | One of: `protanopia`, `deuteranopia`, `tritanopia`, `protanomaly`, `deuteranomaly`, `tritanomaly`, `achromatopsia`, `blueConeMonochromacy` | ### edit-metadata {#edit-metadata} Write or remove individual EXIF/IPTC metadata fields without stripping the entire block. | Parameter | Type | Description | |---|---|---| | `artist` | string | EXIF Artist tag | | `copyright` | string | EXIF Copyright tag | | `imageDescription` | string | EXIF ImageDescription tag | | `software` | string | EXIF Software tag | | `dateTime` | string | EXIF DateTime tag | | `dateTimeOriginal` | string | EXIF DateTimeOriginal tag | | `clearGps` | boolean | Remove all GPS tags | | `fieldsToRemove` | string\[] | List of EXIF field names to delete | All parameters are optional. Fields listed in `fieldsToRemove` are deleted from the existing EXIF block. Fields set via the named parameters are written (or overwritten). Binary/unsafe keys like MakerNote are silently ignored. ## Format detection {#format-detection} The engine detects input formats automatically from file headers, not just file extensions. This means a `.jpg` file that is actually a PNG will be handled correctly. Detection uses a multi-layer approach: magic bytes first, then file extension as fallback. SnapOtter supports **55+ input formats** and **13 output formats**, including 23 camera RAW formats from 20+ brands, professional formats (PSD, EPS, OpenEXR, HDR), modern codecs (JPEG XL, AVIF, HEIC, QOI, JPEG 2000), and scientific/gaming formats (FITS, DDS). Decoding is handled by Sharp natively where possible, with automatic fallback to ImageMagick, LibRaw, and specialized CLI decoders. See the [Supported Formats](/guide/supported-formats) page for the complete list. ## Metadata extraction {#metadata-extraction} The `info` tool returns image metadata. See [Image Info](/tools/image/info) for the full field reference. ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` --- --- url: https://docs.snapotter.com/api/ai.md description: >- AI engine reference with all local ML tools. Background removal, upscaling, OCR, face detection, photo restoration, and more. --- # AI Engine Reference {#ai-engine-reference} The `@snapotter/ai` package coordinates native tools and Python runtimes for local ML operations. Most ML tools use a persistent Python sidecar for fast warm starts. OCR is intentionally separate: `fast` invokes the native Tesseract binary, while `balanced` and `best` use a dedicated persistent JSONL dispatcher pinned to the active immutable RapidOCR generation under `/data/ai/v3`. Each request holds a generation lease. During an upgrade, SnapOtter runs a smoke test on the candidate before activation, atomically switches to the new dispatcher, then drains the old generation before garbage collection. NVIDIA CUDA is auto-detected and used by runtimes that support it. OCR uses CPU on every host, including systems with NVIDIA GPUs, avoiding CUDA and driver coupling for this tool. Intel/AMD iGPU acceleration through VA-API, Quick Sync, or OpenCL is not supported for AI inference today. Mapping `/dev/dri` into a container does not accelerate these Python sidecar tools unless a CUDA-capable NVIDIA GPU is available. 19 Python sidecar AI tools across four modalities (image, audio, video, document), plus 2 tools with optional AI capabilities. All models run locally - no internet required after initial model download. ## Architecture {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` A separate "docs" dispatcher profile replaces the AI allowlist with document-processing scripts (`doc_pagecount`, `doc_health`, `doc_flatten`, `doc_redact`, `doc_text`, `doc_to_word`, `doc_metadata`, `doc_html_pdf`) and skips heavy ML imports. **Timeouts:** 300 s default; OCR and BiRefNet background removal get 600 s. ## Feature Bundles {#feature-bundles} AI models are packaged by shared dependency stack, not one archive per tool. A feature bundle can enable several tools when they use the same model family, Python wheels, or native libraries. This keeps the release Docker image smaller and avoids storing duplicate copies of the same background matting, face detection, OCR, restoration, and speech models. The Docker image ships the application plus the common runtime. Large model archives are downloaded on demand into the persistent `/data/ai` volume, then reused by every tool that needs them. If a bundle is already installed because another tool needed it, enabling a new dependent tool does not download that bundle again. Most AI tools require one or more feature bundles before they can run. The admin UI installs those by tool through `POST /api/v1/admin/tools/:toolId/features/install`, which resolves the full bundle list, skips bundles that are already installed, and queues only the missing downloads. For example, enabling Passport Photo on a fresh instance queues `background-removal` and `face-detection`; enabling it after Background Removal is already installed queues only `face-detection`. OCR is the exception because `fast` needs no pack; install its optional accurate runtime through the UI or `POST /api/v1/admin/features/ocr/install`. | Bundle | Size | Shared dependency group | Tools that use it | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet background matting | remove-background, passport-photo, transparency-fixer, background-replace, blur-background | | `face-detection` | 200-300 MB | MediaPipe face detection and landmarks | blur-faces, red-eye-removal, smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa inpainting/outpainting and DDColor | erase-object, colorize, ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN, GFPGAN / CodeFormer, denoising | upscale, enhance-faces, noise-removal | | `photo-restoration` | 4-5 GB | scratch repair and restoration pipeline | restore-photo | | `ocr` | ~208-234 MiB download / ~409-488 MiB installed | Optional RapidOCR 3.9.1, ONNX Runtime 1.20.1, and pinned PP-OCR models | ocr, ocr-pdf (`balanced` and `best` only) | | `transcription` | ~600 MB | faster-whisper speech-to-text models | transcribe-audio, auto-subtitles | Tools with cross-bundle dependencies: | Tool | Required bundles | Why | |------|------------------|-----| | `passport-photo` | `background-removal`, `face-detection` | Removes the background, then uses face landmarks to frame the crop to passport and ID photo rules. | | `enhance-faces` | `upscale-enhance`, `face-detection` | Detects faces before running GFPGAN or CodeFormer enhancement on the selected face regions. | A tool is available only when all of its required bundles are installed, except OCR: its built-in `fast` tier remains available without the optional OCR pack. Partial installs are valid and are handled incrementally: installed bundles are reused, missing bundles are shown as downloads, and queued installs run one at a time so the shared Python environment is not modified concurrently. ### Accurate OCR runtime installation {#accurate-ocr-runtime-installation} The accurate OCR pack is a platform-specific runtime for the official Linux amd64 or Linux arm64 container. The amd64 build uses Python 3.12; the arm64 build uses Python 3.11. Both builds run RapidOCR through ONNX Runtime's `CPUExecutionProvider`, so the same pack works on CPU-only and NVIDIA Docker hosts. The accurate runtime requires at least 4 GiB of effective memory: the configured container cgroup limit, otherwise host memory. A system below that signed compatibility minimum is rejected before download. This requirement does not apply to built-in Fast OCR. Bare-metal builds are rejected because their libc and Python ABI cannot be inferred safely; Fast OCR remains available when the host provides Tesseract and Ghostscript. Fast supports `auto`, `en`, `de`, `es`, `fr`, `zh`, and `ja`, but not Korean (`ko`). Korean therefore requires a supported accurate runtime and a `balanced` or `best` tier; unsupported hosts receive an explicit incompatibility response rather than a silent Fast fallback. The optional artifact is about 208-234 MiB compressed and 409-488 MiB extracted, depending on architecture. The signed index binds the exact compressed and extracted byte counts enforced by the installer. Built-in Tesseract adds about 25 MiB to the official image and needs no files in `/data/ai`. Online installation fetches a signed release index and the exact content-addressed artifact for the current platform. SnapOtter verifies the Ed25519 index signature, artifact size, SHA-256 digest, model digests, paths, file modes, and staged smoke test before atomically activating the new generation. A failed install leaves the prior healthy generation active. For air-gapped installation, upload both the release's `ocr-runtime-index.json` and matching OCR runtime archive to `POST /api/v1/admin/features/import` using multipart fields named `index` and `archive`. Offline import applies the same signature, hash, extraction, compatibility, and smoke-test checks as online installation; an archive without its trusted signed index is rejected. *** ## Background Removal {#background-removal} **Tool route:** `remove-background` **Model:** rembg with BiRefNet (default) or U2-Net variants | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `model` | string | - | Model variant (optional override) | | `backgroundType` | string | `"transparent"` | One of: `transparent`, `color`, `gradient`, `blur`, `image` | | `backgroundColor` | string | - | Hex color for solid background | | `gradientColor1` | string | - | First gradient color | | `gradientColor2` | string | - | Second gradient color | | `gradientAngle` | number | - | Gradient angle in degrees | | `blurEnabled` | boolean | - | Enable background blur effect | | `blurIntensity` | number (0-100) | - | Blur intensity | | `shadowEnabled` | boolean | - | Enable drop shadow on subject | | `shadowOpacity` | number (0-100) | - | Shadow opacity | | `outputFormat` | string | - | Output format: `png`, `webp`, or `avif` | | `edgeRefine` | integer (0-3) | - | Edge refinement level | | `decontaminate` | boolean | - | Remove color bleed from edges | ## Background Replace {#background-replace} **Tool route:** `background-replace` **Model:** rembg / BiRefNet (shared with remove-background) Removes the background and replaces it with a solid color or gradient. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | Background mode | | `color` | string | `"#ffffff"` | Background hex color (when `backgroundType` is `color`) | | `gradientColor1` | string | - | First gradient hex color | | `gradientColor2` | string | - | Second gradient hex color | | `gradientAngle` | integer (0-360) | `180` | Gradient angle in degrees | | `feather` | integer (0-20) | `0` | Edge feathering radius | | `format` | `"png"` | `"webp"` | `"png"` | Output format | ## Blur Background {#blur-background} **Tool route:** `blur-background` **Model:** rembg / BiRefNet (shared with remove-background) Blurs the background while keeping the subject sharp. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | Blur intensity | | `feather` | integer (0-20) | `0` | Edge feathering radius | | `format` | `"png"` | `"webp"` | `"png"` | Output format | ## Image Upscaling {#image-upscaling} **Tool route:** `upscale` **Model:** RealESRGAN (with Lanczos fallback when unavailable) | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `scale` | number | `2` | Upscale factor | | `model` | string | `"auto"` | Model variant | | `faceEnhance` | boolean | `false` | Apply GFPGAN face enhancement pass | | `denoise` | number | `0` | Denoising strength | | `format` | string | `"auto"` | Output format override | | `quality` | number | `95` | Output quality (1-100) | ## OCR / Text Extraction {#ocr-text-extraction} **Tool route:** `ocr` **Models:** Tesseract (`fast`); RapidOCR with PP-OCRv6 small models (`balanced`); PP-OCRv6 medium models with calibrated variant scoring (`best`) | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dynamic | Processing tier. Omitted quality selects the highest available tier in this order: `best`, `balanced`, `fast`. Korean never selects `fast`; without an accurate tier it returns the accurate-runtime install or compatibility error | | `language` | string | `"auto"` | Language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`. Fast does not support `ko` | | `enhance` | boolean | Tier-dependent | Improve local contrast. Fast applies it directly; accurate tiers keep the variant only when calibrated scoring improves OCR. Defaults on for Best | | `engine` | string | - | Deprecated compatibility alias. Maps `tesseract` to `fast` and the legacy `paddleocr` value to `balanced`; it does not load PaddlePaddle | Returns extracted text plus provenance metadata: engine, requested and actual quality, device, provider, degradation state, warnings, and accurate-runtime/model versions when applicable. Explicit quality requests never fall back to another tier. If `balanced` or `best` is unavailable, the API returns `FEATURE_NOT_INSTALLED` or `FEATURE_INCOMPATIBLE` instead of silently running `fast`. Explicit Fast or legacy `tesseract` with Korean returns `FEATURE_INCOMPATIBLE`, `compatibilityReason: "fast-korean-unsupported"`, and accurate-pack guidance before a job is queued. ## PDF OCR {#pdf-ocr} **Tool route:** `ocr-pdf` **Models:** Same tier system as image OCR Extracts text from scanned PDF documents using AI-powered OCR, page by page. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dynamic | Processing tier. Omitted quality selects the highest available tier in this order: `best`, `balanced`, `fast`. Korean never selects `fast`; without an accurate tier it returns the accurate-runtime install or compatibility error | | `language` | string | `"auto"` | Language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`. Fast does not support `ko` | | `pages` | string | `"all"` | Page selection: `"all"`, `"1-3"`, `"1,3,5"` | | `enhance` | boolean | Tier-dependent | Improve local contrast. Fast applies it directly; accurate tiers keep the variant only when calibrated scoring improves OCR. Defaults on for Best | | `engine` | string | - | Deprecated compatibility alias. Maps `tesseract` to `fast` and the legacy `paddleocr` value to `balanced`; it does not load PaddlePaddle | The same no-downgrade and Korean compatibility rules apply to PDF OCR. PDF pages are rasterized before recognition, and one request can select at most 50 pages. ## Face / PII Blur {#face-pii-blur} **Tool route:** `blur-faces` **Model:** MediaPipe face detection | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | Gaussian blur radius | | `sensitivity` | number (0-1) | `0.5` | Detection confidence threshold | ## Face Enhancement {#face-enhancement} **Tool route:** `enhance-faces` **Models:** GFPGAN, CodeFormer | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | Enhancement model | | `strength` | number (0-1) | `0.8` | Enhancement strength | | `sensitivity` | number (0-1) | `0.5` | Face detection threshold | | `onlyCenterFace` | boolean | `false` | Enhance only the most central face | ## AI Colorization {#ai-colorization} **Tool route:** `colorize` **Model:** DDColor (with OpenCV DNN fallback) Converts black-and-white or grayscale photos to full color. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | Color saturation strength | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | Model variant | ## Noise Removal {#noise-removal} **Tool route:** `noise-removal` **Model:** SCUNet (tiered denoising pipeline) | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | Processing tier | | `strength` | number (0-100) | `50` | Denoising strength | | `detailPreservation` | number (0-100) | `50` | How much detail to preserve; higher keeps more texture | | `colorNoise` | number (0-100) | `30` | Color noise reduction strength | | `format` | string | `"original"` | Output format: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | `quality` | number (1-100) | `90` | Output encoding quality | ## Red Eye Removal {#red-eye-removal} **Tool route:** `red-eye-removal` Detects face landmarks, locates eye regions, and corrects red-channel oversaturation. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | Red pixel detection threshold | | `strength` | number (0-100) | `70` | Correction strength | | `format` | string | - | Output format override (optional) | | `quality` | number (1-100) | `90` | Output quality | ## Photo Restoration {#photo-restoration} **Tool route:** `restore-photo` Multi-step pipeline for old or damaged photos: scratch/tear detection and repair, face enhancement, denoising, and optional colorization. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | Detect and repair scratches, tears | | `faceEnhancement` | boolean | `true` | Apply face enhancement pass | | `fidelity` | number (0-1) | `0.7` | Face enhancement strength (higher = more conservative) | | `denoise` | boolean | `true` | Apply denoising pass | | `denoiseStrength` | number (0-100) | `25` | Denoising strength | | `colorize` | boolean | `false` | Colorize after restoration | | `colorizeStrength` | number (0-100) | `85` | Colorization intensity | ## Passport Photo {#passport-photo} **Tool route:** `passport-photo` **Models:** MediaPipe face landmarks + BiRefNet background removal Two-phase workflow: analyze (detect face + remove background) then generate (crop, resize, tile). Supports 37+ countries across 6 regions. ### Phase 1: Analyze {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` Accepts an image file (multipart). Returns face landmark data, a base64 preview, and image dimensions. ### Phase 2: Generate {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` Accepts a JSON body with the Phase 1 results plus generation settings: | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `jobId` | string | (required) | Job ID from Phase 1 | | `filename` | string | (required) | Original filename from Phase 1 | | `countryCode` | string | (required) | ISO country code (e.g., `US`, `GB`, `IN`) | | `documentType` | string | `"passport"` | Document type | | `bgColor` | string | `"#FFFFFF"` | Background color hex | | `printLayout` | string | `"none"` | Print layout: `none`, `4x6`, `a4`, `letter` | | `maxFileSizeKb` | number | `0` | Max file size in KB (0 = no limit) | | `dpi` | number (72-1200) | `300` | Output DPI | | `customWidthMm` | number | - | Custom width in mm (overrides country spec) | | `customHeightMm` | number | - | Custom height in mm (overrides country spec) | | `zoom` | number (0.5-3) | `1` | Zoom factor | | `adjustX` | number | `0` | Horizontal position adjustment | | `adjustY` | number | `0` | Vertical position adjustment | | `landmarks` | object | (required) | Landmarks from Phase 1 | | `imageWidth` | number | (required) | Image width from Phase 1 | | `imageHeight` | number | (required) | Image height from Phase 1 | ## Object Erasing (Inpainting) {#object-erasing-inpainting} **Tool route:** `erase-object` **Model:** LaMa via ONNX Runtime The mask is sent as a **second file part** (fieldname `mask`), not as base64. White pixels in the mask indicate areas to erase. The `format` and `quality` settings are sent as top-level form fields. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `file` | file | (required) | Source image (multipart) | | `mask` | file | (required) | Mask image (multipart, fieldname `mask`, white = erase) | | `format` | string | `"auto"` | Output format: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Output quality | CUDA-accelerated when an NVIDIA GPU is available. ## AI Canvas Expand {#ai-canvas-expand} **Tool route:** `ai-canvas-expand` **Model:** LaMa-based outpainting Expands the canvas of an image in any direction and fills new areas with AI-generated content that matches the existing image. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | Pixels to extend at the top | | `extendRight` | integer | `0` | Pixels to extend at the right | | `extendBottom` | integer | `0` | Pixels to extend at the bottom | | `extendLeft` | integer | `0` | Pixels to extend at the left | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | Quality tier | | `format` | string | `"auto"` | Output format: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Output quality | At least one extend direction must be greater than 0. ## Smart Crop {#smart-crop} **Tool route:** `smart-crop` **Model:** MediaPipe face detection (face mode only) | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | Crop strategy: `subject`, `face`, `trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | Strategy for subject mode | | `width` | integer | - | Output width | | `height` | integer | - | Output height | | `padding` | integer (0-50) | `0` | Padding percentage around subject | | `facePreset` | string | `"head-shoulders"` | Preset framing when `mode=face` | | `sensitivity` | number (0-1) | `0.5` | Face detection threshold | | `threshold` | integer (0-255) | `30` | Background detection threshold (trim mode) | | `padToSquare` | boolean | `false` | Pad trimmed result to a square | | `padColor` | string | `"#ffffff"` | Background color for square padding | | `targetSize` | integer | - | Target size for padded output (pixels) | | `quality` | integer (1-100) | - | Output quality | Legacy `mode` values `attention` and `content` are accepted and mapped to `subject` and `trim` respectively. **Face presets:** | Preset | Best for | |--------|---------| | `closeup` | Headshots | | `head-shoulders` | Profile photos | | `upper-body` | LinkedIn / formal | | `half-body` | Full upper body | ## Transcribe Audio {#transcribe-audio} **Tool route:** `transcribe-audio` **Model:** faster-whisper Converts speech to text. Supports plain text, SRT, and VTT output formats. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | Output format | ## Auto Subtitles {#auto-subtitles} **Tool route:** `auto-subtitles` **Model:** faster-whisper (extracts audio from video, then transcribes) Generates subtitle files from a video's audio track. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | Output subtitle format | ## PNG Transparency Fixer {#png-transparency-fixer} **Tool route:** `transparency-fixer` **Model:** BiRefNet HR-matting (2048x2048 resolution) Fixes "fake transparent" PNGs where the background was removed but left behind fringing, halos, or semi-transparent artifacts. Uses BiRefNet's high-resolution matting model to produce a clean alpha channel, then applies configurable defringe processing to remove color contamination along edges. **OOM fallback chain:** If BiRefNet HR-matting exceeds available memory, the tool automatically falls back to `birefnet-general`, then to `u2net`. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | Edge defringe strength to remove color contamination | | `outputFormat` | `"png"` | `"webp"` | `"png"` | Output image format | | `removeWatermark` | boolean | `false` | Apply watermark removal pre-processing (median filter) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## Tools with Optional AI Capabilities {#tools-with-optional-ai-capabilities} The following tools are not Python sidecar tools but use AI features when certain options are enabled. ### Image Enhancement {#image-enhancement} **Tool route:** `image-enhancement` **Engine:** Analysis-based (Sharp histogram and statistics) Analyzes the image and applies automatic corrections for exposure, contrast, white balance, saturation, sharpness, and noise. Supports scene-specific modes. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | Scene mode for tuning corrections | | `intensity` | number (0-100) | `50` | Overall correction strength | | `corrections.exposure` | boolean | `true` | Apply exposure correction | | `corrections.contrast` | boolean | `true` | Apply contrast correction | | `corrections.whiteBalance` | boolean | `true` | Apply white balance correction | | `corrections.saturation` | boolean | `true` | Apply saturation correction | | `corrections.sharpness` | boolean | `true` | Apply sharpness correction | | `corrections.denoise` | boolean | `true` | Apply denoising | | `deepEnhance` | boolean | `false` | Enable AI noise removal via SCUNet (requires `upscale-enhance` bundle) | An additional analysis endpoint is available at `POST /api/v1/tools/image/image-enhancement/analyze` which returns the detected corrections without applying them. ### Content-Aware Resize (Seam Carving) {#content-aware-resize-seam-carving} **Tool route:** `content-aware-resize` **Engine:** Go `caire` binary (not Python - no GPU benefit) Intelligently resizes images by removing low-energy seams, preserving important content. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `width` | number | - | Target width | | `height` | number | - | Target height | | `protectFaces` | boolean | `false` | Protect detected face regions (requires `face-detection` bundle) | | `blurRadius` | number (0-20) | `4` | Pre-blur for energy calculation | | `sobelThreshold` | number (1-20) | `2` | Edge sensitivity threshold | | `square` | boolean | `false` | Force square output | --- --- url: https://docs.snapotter.com/changelog.md description: >- Release notes and version history for SnapOtter. See what's new, improved, and fixed in each release. --- # Changelog {#changelog} ## v2.2.0 {#v2-2-0} Most of 2.2 is hardening. A non-admin holding a delegated `users:manage` role could take over an instance, and every tool endpoint turned out to be missing its permission check. Upgrade if you run more than one user. The rest is the long tail of self-hosting: downloads that started and never finished, presets that broke the moment you added a second file, containers that crash-looped while Postgres was still coming up. Two new tools landed too. Docs and the website are now translated into 21 languages, and the interface finally clears WCAG AA contrast. > \[!IMPORTANT] > If you granted `users:manage` to a non-admin through a custom role, that role could take over administrator accounts on 2.0.0 through 2.1.0. Details in Security. ### Security {#v2-2-0-security} * **Privilege escalation through a delegated `users:manage` role (GHSA-9xgh-95qh-2x7h).** A non-admin holding `users:manage` through a custom role could reset the password of, or delete, a higher-privileged account, a built-in administrator included, and take over the instance. Password reset and account deletion now verify the caller's authority over the target, so a delegated role cannot reach above its own level. Affected: 2.0.0 through 2.1.0. Reported by 李春来 (Chunlai Li). (#616) * **Every tool endpoint is now gated.** Tool access was enforced route by route, so all 45 hand-written routes had to remember the same call and none of them did. A role without `tools:use` could still run image-to-pdf, erase-object, upscale, sign-pdf and the rest. The check now lives in one preHandler keyed off the matched route, so it covers sub-paths and any route added later. (#646) * **Rate limiting was bypassable on Docker installs.** The image shipped `TRUST_PROXY=true`, so the client IP came from a request header and a forged `X-Forwarded-For` walked past the login limiter. The default is now a private-network trust list. (#649) * **Settings writes are checked per setting**, not once at the door, and config import is now transactional so a rejected key cannot leave half a config applied. (#618) * **Library filenames cannot escape their storage root.** A crafted stored name, which a malicious 1.x SQLite import copies verbatim, could read or delete files outside the files directory. Only reachable after an operator imports an attacker-supplied 1.x SQLite database, which is the one path that lets a stored name be chosen. Reported by @Alpastx. (GHSA-55w2-8cqf-w969, #600) * **Job cancellation enforces ownership**, so an authenticated user can no longer cancel another user's job by its id. Reported by @Alpastx. (GHSA-wqxf-gj2p-689x, #599) * **A re-audit of the whole 2.0 tree caught what was still open**: a captured SAML assertion could be replayed, an MFA challenge survived any number of wrong codes, the per-request API-key lookup was a full table scan, `MAX_WORKSPACE_SIZE_GB` was dead config, and the SVG sanitizer let through unquoted `javascript:` hrefs. (#620) * **Nine disclosed CVEs patched**: fast-uri, svgo, sharp and tar transitively (#619), plus Pillow 12.3.0 (#517). RAW decoding on arm64 now builds LibRaw 0.22.2 from source instead of linking an unpatched system copy. (#649) ### New Features {#v2-2-0-new-features} * **Rounded Crop**: rounded-square and iOS-style squircle masks, with a corner-radius control. Built for favicons and app icons. (#602) * **Remove GIF Background**: strip the background from an animated GIF, WebP or APNG frame by frame and get a transparent animation back. (#502) * **Object Eraser lasso and High Quality mode**: drag a freeform loop instead of painting every pixel, and optionally install a diffusion inpainting bundle for cleaner large-area fills. (#503, #566) * **Save as new, or overwrite.** Editing a library file used to silently supersede the original. You now choose per edit, and the default keeps it. (#564, #577) * **Aspect-ratio presets in Resize.** Pick 1:1, 4:3 or 16:9 and the two dimensions stay locked, without upscaling. (#530) * **Two-tier OCR**: a fast tier is baked into the image and runs offline with no download, and a more accurate runtime installs on demand. (#519) * **Type anywhere to search.** Start typing on the dashboard or the homepage and it lands in the search box. (#644) * **Documentation and website in 21 languages**: the docs site, the landing pages and the API reference are all translated now, joining the app interface. A new low-resource deployment guide covers Raspberry Pi and 2 GB machines. (#548) * **Clearer tool names**: 18 ambiguous names now self-qualify, so "Compress" became "Compress Image". Tool ids and routes are unchanged, so nothing bookmarked breaks. (#520) ### Improvements {#v2-2-0-improvements} * **WCAG AA contrast across the interface**: the palette was retuned so vivid orange stays on fills while text and labels use accessible ink tokens, and all 57 focus indicators now clear the 3:1 non-text bar. (#567, #574) * **Upscale and background removal stop looking frozen**: the progress bar advances during inference instead of parking at 30%, and both tools now warn that a CPU-only host is much slower. (#605, #608) * **Timeout messages name the real cause** and account for CPU-only hosts instead of blaming the upload. (#596) * **SnapOtter waits for Postgres and Redis at startup** instead of crash-looping, in Compose and the all-in-one image alike. A Proxmox LXC install was restarting 76 times before this. (#537, #595) * **Downloads survive a reverse proxy**: SnapOtter asks nginx and compatible proxies not to buffer file responses, which is the usual reason a self-hosted download starts and never finishes. (#604, #607) * **Compress PDF lands near the target size**, and says so honestly when a target is out of reach. (#522) * **Mobile tool controls stay reachable** now that the app shells size to the dynamic viewport. (#559) * **Convert Audio exposes a sample-rate setting.** (#561) * **Admins can relax the minimum password length**, down to 1 for a trusted LAN instance. (#543) * **MFA is self-service**, the policy lockout is closed, and OIDC or SAML logins get a real MFA challenge instead of a hard block. (#531, #536) * **A bare `Error: Error` now names its cause.** Sharp encode failures, AI sidecar exits, non-JSON document sidecar output, and background-removal failures all used to arrive with the reason scrubbed off. (#532, #534, #535, #538, #612) * **The help dialog is translated.** Its shortcut labels and getting-started text were hardcoded English while finished translations sat unused in all 21 locale files. (#647) ### Bug Fixes {#v2-2-0-bug-fixes} * **iPhone HEIC files were rejected** as unreadable before they reached the decoder that handles them. (#631) * **Conversion presets failed on a second file**: jpg-to-pdf and its image-to-pdf siblings, plus pdf-to-png, pdf-to-jpg and pdf-to-tiff, all returned `Tool not found` once you uploaded two files. (#633, #643) * **PDF conversion presets lost their download button.** (#629) * **An unlimited processing timeout was not honored**, and stalled progress streams now recover instead of leaving the interface waiting. (#638) * **Downloads hung instead of failing** when a stored file turned out shorter than its recorded length. (#617) * **PDF page tools failed on short and encrypted files**: Remove Pages defaulted to a page range no document under six pages has, and password-protected PDFs failed cryptically inside the worker. (#594) * **PDF to Text silently returned an empty file** for scanned PDFs. It now points you at OCR and serves text as UTF-8. (#603) * **PDF to Word dropped colored text blocks** and split them across the page. (#500) * **Object Eraser left ghost remnants** and blurred small objects in high-resolution images. (#501) * **Stabilize Video wrote unplayable output** without faststart. (#593) * **Image editor repairs**: rotate, flip, resize, levels, curves, filters and layer lock. (#597) * **Sign PDF showed a blank canvas** instead of reporting why a PDF failed to load. (#545) * **The file library recorded 0x0 dimensions** and skipped previews for HEIC, RAW and PSD uploads. (#636, #637) * **Installing more than one AI bundle** left the shared virtualenv multi-versioned and quietly broke three tools. (#649) * **Converting to JXL at quality 1 through 4 returned a 500**, and a missing ffmpeg was reported to you as a corrupt upload. (#649) * **A transient Postgres outage stranded finished jobs**, leaving output on disk with no row pointing at it. A reconciler now adopts that work instead of dropping it. (#649) * **A Redis endpoint that changed address wedged every consumer** while health checks still answered 200. (#649) * **Website and docs fixes**: localized links no longer drop `#` fragments or lowercase `zh-CN`, the docs nav stays inside the viewport on tablets, and neither site calls the GitHub API from your browser any more. (#516, #562, #570, #560) ### Upgrade Notes {#v2-2-0-upgrade-notes} Nothing to migrate, but two shipped defaults changed: * **`TRUST_PROXY` now defaults to `loopback,linklocal,uniquelocal`** instead of trusting every peer. Docker bridge and Compose networks sit inside that range, so most setups need no change. If your reverse proxy reaches SnapOtter from a public address, set `TRUST_PROXY` explicitly, or rate limiting and audit logs will attribute every request to the proxy. * **`MAX_AI_JOBS_PER_USER` defaults to 5** in-flight single-file AI jobs per user. Batch and pipeline AI runs stay uncapped. New optional knobs: `DB_STARTUP_TIMEOUT_MS`, `SUBPROCESS_MEMORY_LIMIT_MB` (off by default) and `GIF_BG_MAX_FRAMES`. ### Acknowledgements {#v2-2-0-acknowledgements} A good part of this release started as someone else's bug report. Code and contributions: * **@mvanhorn** ❤️: Rewrote the remove-background timeout failure into a message that says what to do about it, instead of a bare timeout. (#518, #494) * **@EuanTop** ❤️: Restored the download action on PDF conversion preset pages by making the synchronous route return the standard tool-result contract. (#629, #623) * **@harshjainnn** ❤️: Diagnosed the download that starts and never finishes, and proposed the socket-reset direction the fix was built on. (#617, #590) Security disclosures: * **李春来 (Chunlai Li)** ❤️ ([@laijunyue](https://github.com/laijunyue)): Privately disclosed the privilege escalation through a delegated `users:manage` role, with a full source-to-sink analysis and a working exploit chain. (GHSA-9xgh-95qh-2x7h, #616) * **@Alpastx** ❤️ (Alpesh Bhagwatkar): Disclosed an authenticated IDOR on job cancellation, and a path traversal in library stored filenames reachable after a malicious 1.x SQLite import, with a working proof of concept for each. (#599, #600) Bug reports: * **@riz467** ❤️: Real iPhone HEIC files rejected at validation, with the root cause worked out in the report. (#622) * **@coupej** ❤️: PDF preset pages hanging forever, and jpg-to-pdf failing as soon as a second file was added. Two distinct bugs, correctly separated. (#623, #627) * **@linuxuser1** ❤️: `PROCESSING_TIMEOUT_S=0` documented as unlimited but capped at five minutes. (#630) * **@bezibaerchen** ❤️: Convert Audio hid the sample-rate setting its own description promised. (#558) * **@hell-toupee** ❤️: The accurate OCR bundle failing to install with a `libpaddle` error. (#505) * **@Michael1260** ❤️ and **@And-CSH** ❤️: Confirmed that OCR install failure independently and established that manual extraction works while the in-app installer does not, which pinned the bug to the installer. (#505) * **@TomErnst1972** ❤️: Enabling the MFA-required policy locking an admin out of their own instance. (#515) * **@thokich** ❤️: Object erasing producing blurry, unusable fills, which drove both the HD inpainting rewrite and the optional high-quality bundle. (#141) * **@Hennie-git** ❤️: A Proxmox LXC install restarting 76 times against a Postgres that was not yet accepting connections. (community-scripts/ProxmoxVE#15796) * **MickLesk** ❤️ (Proxmox VE community-scripts): Triaged that report in real time and produced the diagnosis the startup fix was built on. (#537) Feature requests and feedback: * **@LECOQQ** ❤️: Asked to relax password complexity on a home-server install. (#136) * **@killervette42** ❤️: Asked for an Unraid Community App, now published to the Unraid CA store. (#96) * **@alienatedsec** ❤️: Pointed out the GPU-falls-back-to-CPU fix was buried in a closed issue and undiscoverable, which is why it is in the deployment docs now. (#490, #587) * **@neilp316** ❤️: Confirmed the Blackwell GPU failure on an RTX 5060 and mapped a working CUDA 12.8 upgrade path. (#120) * **@Roiki11** ❤️: Argued for shared storage with path references over HTTP file transfer for off-box AI compute. (#189) Thank you as well to the community members who reported these over Discord and email, whose names we did not record: the squircle crop request (#602), the image-to-PDF download that started and never finished (#604, #607), the Delete Pages tool getting stuck (#594), Arabic text missing from pdf-to-text (#603), and the diagnosis behind the ONNX GPU fallback (#490). [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v2.1.0...v2.2.0) *** ## v2.0.0 {#v2-0-0} SnapOtter 2.0 turns the image toolkit into a full file-manipulation suite: 200+ tools across five modalities (Image, Video, Audio, PDF, and Files), rebuilt on Postgres 17 and a Redis-backed job queue, with a one-command `docker run`. This is a major release; read Breaking changes before upgrading from 1.x. ### New features {#new-features} * **Four new tool modalities**: Video, Audio, PDF, and Files join Image, taking the catalog to 200+ tools. * **Durable background jobs**: A Redis-backed queue (BullMQ) runs every tool as a tracked job with live SSE progress. * **All-in-one single-container mode**: One `docker run` boots a complete instance with embedded Postgres and Redis. * **On-demand AI bundles**: Background removal, OCR, transcription, upscaling, face detection and enhancement, object eraser, colorize, and photo restoration install from the UI. GPU acceleration is detected per framework. * **Sign PDF**: Draw, type, or upload a signature and place it on a PDF in the browser. * **Automate**: A visual pipeline builder that chains tools, with nine prebuilt templates. * **83 one-click conversion presets**: Dedicated JPG-to-PNG, MP4-to-GIF, and similar converters with fuzzy search. * **Layer-based image editor**: A Konva-powered editor at `/editor` with brushes, shapes, adjustments, filters, and curves. * **Files library**: Save any result and reuse it as input to another tool. * Pinned tools, in-canvas zoom and pan, 21 languages, and enterprise capabilities (OIDC/SSO, SAML, SCIM, S3 storage, per-tool permissions, audit export, distributed tracing). ### Improvements {#improvements} * Cancel a running process. (#137) * Full-resolution RAW decoding through LibRaw, including DNG. (#289) * Non-root and foreign-UID deployments (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Accurate AI install detection and a hardened install flow. (#214, #352) * Privacy hardening: no automatic third-party egress, plus an optional strict-offline mode. * Always-on feedback button, even with analytics off. ### Bug fixes {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` disables rate limiting for tool routes again. (#271) * Repaired AI virtualenv paths inside the Docker image. (#390) * sharp 0.35.2+ compatibility. (#362) * Image editor layout fixes: rulers, fill behavior, sidebar, and canvas sizing. (#258, #259) * Completed the Italian translation. (#231, #206, #425) * Audio normalize and loudnorm preserve the source sample rate. * SSRF hardening: numeric IPv6 CIDR matching and a broadened URL pre-scan. (#287) * Generated PDFs are stamped with SnapOtter as the Producer. * mediapipe installs on Python 3.13 and Debian 13. ### Breaking changes {#breaking-changes} 2.0 replaces the embedded SQLite database with Postgres 17 and adds Redis 8 for the job queue. Your 1.x data migrates automatically on first boot, but the container stack changed, so back up your whole `/data` volume first (1.x runs SQLite in WAL mode, so the committed data usually lives in `snapotter.db-wal`). Then pick the single-container image (embedded Postgres and Redis, root only) or the Compose stack (app plus Postgres 17 and Redis 8). See the [migration guide](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) and the [upgrade guide](/guide/upgrading). ### Upgrade {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Or with Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} New HTML to Image tool, WCAG 2.2 AA accessibility, security hardening from penetration testing, and 5 critical Docker fixes. ### New features {#new-features-1} * **HTML to Image**: Capture screenshots of URLs or raw HTML as PNG/JPEG/WebP. Full-page captures, custom viewports, dark mode. * **Docker \_FILE secret convention**: Mount sensitive env vars as files instead of plain-text. (#205) * **Enterprise licensing and S3 storage**: Optional commercial license key and S3-compatible object storage. * **Shape editor improvements**: Fill/stroke transparency, RGBA color picker, dash line styles. * **Pre-built release archives**: Download tarballs from GitHub Releases for non-Docker installs (Proxmox, bare metal, LXC). (#202) ### Improvements {#improvements-1} * **WCAG 2.2 AA accessibility**: Skip navigation, focus trapping, aria-live regions, reduced motion support, correct contrast ratios. (#209) * **Mobile responsiveness**: Responsive settings, SSE auto-reconnect on mobile tab switch. (#203, #204) * **Background removal quality**: Edge smoothing, color decontamination, output format selection. * **Italian translation**: ~145 new strings by @albanobattistella. (#206) * **Per-tool API documentation**: 53 doc pages with parameters, examples, and response formats. * **AI model downloads**: Retry logic with exponential backoff for HuggingFace. (#201) ### Bug fixes {#bug-fixes-1} * Fresh Docker containers were completely unusable (rate limit blocked all requests). * Face detection AI tools (blur-faces, red-eye-removal, enhance-faces, passport-photo) failed on all platforms. * HEIC files broken on ARM (libheif symbol mismatch). * Upscale and restore-photo AI bundles failed to install on ARM. * OCR used wrong CUDA version on GPU containers. * SSRF guard bypass via hex IPv4-mapped IPv6 addresses. (Credit: @tonghuaroot) * iPhone HEIC decoding with auxiliary images. (#183, #199) * Real-ESRGAN CUDA OOM on 8GB GPUs. (#200) * 6 production Sentry errors and 7 QA bugs. (#208) ### Security {#security} * 10 penetration test findings addressed (XFF bypass, malformed JSON crashes, unbounded pipelines, audit log XSS, TRACE method, and more). (#207) * SSRF hex IPv6 bypass blocked. (Credit: @tonghuaroot) * Dockerfile base images pinned by digest. ### Upgrade {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Or with Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Live demo, per-tool landing pages, and a batch of polish fixes. ### New features {#new-features-2} * **Live demo** - [demo.snapotter.com](https://demo.snapotter.com) lets people try SnapOtter without installing anything. * **Tools index page** - Browse all 50+ tools at `/tools` with search and category filters. * **50+ SEO landing pages** - Every tool now has a dedicated landing page with FAQs, use cases, and comparison tables. * **Background preview** - Before-after slider shows a checkered background behind transparent images. * **Strong password generator** - One-click button in the Add Members form. ### Bug fixes {#bug-fixes-2} * HEIC/HEIF info tool no longer fails (pre-decode added). * AI model bundle install shows better error messages and respects resource limits. * Library thumbnails load correctly (auth headers were missing). * Dropdown menus no longer clip in People and Teams settings tables. * Size comparison percentage hidden on non-compression tools. * Duplicate privacy policy link removed. * Italian translation added for AI features settings. * Renamed Lucide icons updated (Wand2, Columns). ### Infrastructure {#infrastructure} * OpenSSF Scorecard hardened from 4.3 to ~7.0. * CI tests parallelized into 4 shards with downsized fixtures. * 41 dependency updates. ### Upgrade {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Or with Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Five new tools, a full image editor, SSO login, 20 languages. Probably should have been three separate releases, but here we are. ### New features {#new-features-3} * **Image editor** - Layers, brushes, shapes, adjustments, filters, curves, keyboard shortcuts. Runs in your browser, processes on your hardware. * **OIDC / SSO authentication** - Login with Google, GitHub, Okta, or any OpenID Connect provider. Set a few env vars and your team uses their existing accounts. * **Meme generator** - 100 built-in templates with text rendering via opentype.js. Or upload your own image. * **Beautify** - Drop a screenshot in, get a polished image out. Device frames (macOS, Windows, browser), shadows, gradients, social media presets. * **Color blindness simulation** - Preview how images look with protanopia, deuteranopia, tritanopia, and other color vision deficiencies. * **PNG transparency fixer** - Detects fake-transparent PNGs and fixes them with BiRefNet HR-matting. Optional watermark removal via LaMa inpainting. * **AI canvas expand** - Extend image boundaries with AI fill. Three quality tiers (fast, balanced, quality) depending on how much GPU time you want to trade. * **20 languages** - Arabic, Chinese (Simplified/Traditional), Czech, Dutch, French, German, Hindi, Indonesian, Italian, Japanese, Korean, Polish, Portuguese, Russian, Spanish, Thai, Turkish, Ukrainian, Vietnamese. RTL works for Arabic. * **URL import** - Paste URLs into the dropzone or bulk-import from a list. Server-side fetch with SSRF protection. * **Multi-file eraser** - Draw erase masks across multiple images, process them all with one click. Strokes persist per-image. * **Pipeline import/export** - Save tool chains as JSON, share them with others. * **17 new camera RAW formats** via exiftool, plus QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ, and APNG input. New output codecs for BMP, ICO, JP2, QOI. AVIF, TIFF, GIF, JXL, and PSD export recovered from a previously lost branch. ### Improvements {#improvements-2} * **Image enhancement** - Replaced the old pipeline with CLAHE + normalise + gamma. New Deep Enhance toggle uses the AI model for more aggressive results. * **Restore photo** - Scratch detection rewritten with 8-angle Otsu filtering. LaMa inpainting now runs at native resolution. * **Exotic formats everywhere** - OCR, image-to-PDF, favicon generator, composition, stitch, and vectorize all decode HEIC, RAW, PSD now. * **Compress** - Target-size tolerance tightened from 5% to 1%. Target size is the default mode. Added stepper buttons and KB/MB unit selector. * **Sentry cleanup** - 644 non-actionable events filtered. Real errors now handled properly. * **GPU detection** - Better diagnostics for containers where CUDA is present but nvidia-smi is not. * **Auth-disabled mode** - Anonymous user is seeded in the DB with admin role. API keys, pipelines, and user files no longer break on FK constraints. * **2,705+ new tests** across unit, integration, and E2E. ### Bug fixes {#bug-fixes-3} * Upscale on CPU no longer times out on NAS boxes and low-power hardware. * QR code logo no longer makes the preview vanish permanently. * Crop overflow fixed for tall portrait images. * TIFF alpha files correctly force PNG output instead of producing corruption. * HDR/EXR decode converts to 8-bit before CLAHE, fixing decode failures. * Face landmarks input buffers converted to PNG before the Python sidecar, fixing crashes. * Find duplicates handles mixed-format batches and network errors. * Beautify preview updates in real time. * Progress bars for stitch and vectorize. * SVGZ handled by SVG-to-raster. * Non-ASCII filenames fixed via percent-encoded X-File-Results header. ### Upgrade {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Or with Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Unified Docker image with GPU auto-detection. One image handles both CPU and GPU workloads. Simplified compose to a single file with log rotation. Model pre-downloads now include verification and a smoke test. *** ## v1.13.0 {#v1-13-0} Role-based access control (RBAC). 14 granular permissions, three built-in roles (admin, editor, user), custom role support. Permission checks on all API routes. Frontend tabs filtered by user permissions. *** ## v1.12.0 {#v1-12-0} PDF to Image tool. Convert PDF pages to PNG, JPEG, WebP, or TIFF at custom DPI. Unified Docker image with GPU auto-detection. *** ## v1.11.0 {#v1-11-0} Auto-generated llms.txt via vitepress-plugin-llms for AI-friendly documentation. *** ## v1.10.0 {#v1-10-0} Content-aware resize (seam carving) with face protection. Resize images while preserving important content. *** ## v1.9.0 {#v1-9-0} Stitch / Combine tool. Join images side by side, stacked vertically, or in a custom grid. *** ## v1.8.0 {#v1-8-0} Edit Metadata tool. View and edit EXIF, IPTC, and XMP metadata with a granular strip/keep interface. *** ## Older releases {#older-releases} For the full commit-level changelog including patch releases, see [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/tr/guide/upgrading.md --- # 1.x sürümünden 2.0 sürümüne yükseltme {#upgrading-from-1-x-to-2-0} SnapOtter 1.x her şeyi tek bir SQLite dosyasında saklıyor ve tek bir konteyner olarak çalışıyordu. SnapOtter 2.0, PostgreSQL ve Redis kullanır. Bu kılavuz, bir 1.x kurulumunu veri kaybetmeden 2.0'a taşımayı adım adım anlatır. Kısa versiyonu: mevcut `/data` birimini (volume) yeniden kullanın; 2.0, ilk açılışta 1.x veritabanınızı otomatik olarak içe aktarır. Kullanıcılarınız, kayıtlı dosyalarınız, ayarlarınız, API anahtarlarınız ve işlem hatlarınız (pipeline) taşınır. Eski veritabanı asla değiştirilmez, bu nedenle her zaman geri dönebilirsiniz. ::: tip 1.x kullanıcılarımıza bir not Çoğunuz SnapOtter'a ilk günden beri güvendiniz ve geri bildirimleriniz bu sürüme şekil verdi. 2.0, kapağın altında pek çok şeyi değiştiriyor ve bu kılavuz, geçişin önemsediğiniz hiçbir şeye mal olmaması için var. Hesaplarınız, dosyalarınız, ayarlarınız, API anahtarlarınız ve işlem hatlarınız taşınır ve eski veritabanınıza asla dokunulmaz. Bizimle birlikte yükselttiğiniz için teşekkür ederiz. ::: ## Başlamadan önce: `/data` biriminin tamamını yedekleyin {#before-you-start-back-up-the-whole-data-volume} Bunu her seferinde ilk olarak yapın. Yalnızca `snapotter.db` dosyasını değil, **tüm** `/data` birimini yedekleyin. Bunun neden önemli olduğunu açıklayalım. 1.x, SQLite'ı WAL modunda çalıştırır; bu nedenle durdurulmuş bir 1.x konteyneri, işlenmiş verilerinin çoğunu neredeyse boş bir `snapotter.db` dosyasının yanındaki `snapotter.db-wal` dosyasında rutin olarak bırakır. Yalnızca `snapotter.db` dosyasını kopyalamak boş bir veritabanı yakalar ve sessizce her şeyi kaybeder. Birim; `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm` ve `files/` dizininizi bir arada taşır ve bunlar bir küme olarak taşınmalıdır. ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## Önce 1.17.2 sürümüne yükseltin {#upgrade-to-1-17-2-first} 2.0'a geçmeden önce 1.x kurulumunuzu en son 1.x sürümüne (1.17.2) yükseltin. Bu, 1.x'in kendi son şema geçişlerini (migration) çalıştırmasına olanak tanır, böylece 2.0, bilinen ve eksiksiz bir şemadan içe aktarır. Daha eski bir 1.x sürümünden doğrudan 2.0'a yükseltme desteklenmez. ## Birim adınızı kontrol edin {#check-your-volume-name} İçe aktarıcı, verilerinizi yalnızca 2.0 yığını (stack), 1.x kurulumunuzun kullandığı birimi bağlarsa görebilir. Docker birim adları büyük/küçük harfe duyarlıdır ve eski README parçacıkları küçük harfli `snapotter-data` kullanırken Compose dosyaları `SnapOtter-data` kullanır. Hangisine sahip olduğunuzu onaylayın: ```bash docker volume ls | grep -i snapotter ``` 2.0 yapılandırmanızda tam olarak o adı kullanın. ## Yol A: tek konteyner (en hızlısı) {#path-a-single-container-quickest} SnapOtter'ı tek bir `docker run` ile çalıştırıyorsanız, bunu yapmaya devam edin. 2.0, `DATABASE_URL` veya `REDIS_URL` ayarını yapmadığınızda konteyner içinde gömülü bir PostgreSQL ve Redis başlatır ve ilk açılışta `/data/snapotter.db` dosyasını otomatik olarak algılayıp içe aktarır. ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` Günlüklerde şuna benzer bir satır izleyin: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` Hepsi bu kadar. Mevcut kimlik bilgilerinizle giriş yapın. ## Yol B: Compose (üretim için önerilir) {#path-b-compose-recommended-for-production} 2.0 Compose yığını üç hizmet çalıştırır (uygulama, Postgres, Redis). Uygulama hizmeti için 1.x `/data` biriminizi yeniden kullanın. Uygulama, `/data/snapotter.db` dosyasını otomatik olarak algılar ve ilk açılışta Postgres'e içe aktarır. ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` Eski veritabanına açıkça işaret etmeyi tercih ederseniz, `SQLITE_MIGRATE_PATH=/data/snapotter.db` ayarını yapın. Açık bir yol her zaman otomatik algılamaya üstün gelir. ## Önce içe aktarımı önizleyin (isteğe bağlı) {#preview-the-import-first-optional} Hiçbir şey yazmadan tam olarak neyin içe aktarılacağını görmek için veritabanı dosyanıza karşı bir kuru çalıştırma (dry run) yapın: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` Tablo başına satır sayılarını, diskte bulduğu kayıtlı kitaplık dosyası sayısını ve normalleştireceği tüm iş durumlarını yazdırır. Çalışan bir Postgres'e ihtiyaç duymaz. ## Neler taşınır, neler taşınmaz {#what-carries-over-and-what-does-not} Taşınanlar: * Kullanıcılar ve giriş yapma yeteneği. Parola karmaları (hash) değişmez, bu nedenle aynı kullanıcı adı ve parola çalışır. * Ekipler, ayarlar (örnek kimliğiniz dahil), roller, API anahtarları (çalışmaya devam ederler) ve kayıtlı işlem hatları. * İş geçmişi kayıtları. * Hem kayıtlar hem de gerçek dosyalar olmak üzere kayıtlı dosya kitaplığınız, çünkü `/data/files` birimde korunur. Taşınmayanlar: * Giriş oturumları. Yükseltmeden sonra herkes bir kez giriş yapar. Kimlik bilgileri değişmez, bu nedenle bu tek seferlik bir yeniden giriştir, başka bir şey değil. * Eski işlem işlerinin girdi ve çıktı dosyaları. Bunlar geçici bir çalışma alanında bulunuyordu ve tasarım gereği gitti. İş geçmişi kayıtları kalır. * 1.x'ten kullanıcı başına analitik onay bayrakları; bunların 2.0 karşılığı yoktur (2.0 analitiği örnek düzeyinde bir ayardır). ## İçe aktarımı kapatma {#turning-the-import-off} Birimde bir `snapotter.db` mevcut olsa bile bilerek yeni bir veritabanı istiyorsanız, `SQLITE_MIGRATE_PATH=off` ayarını yapın. ## 2.0 örneğinde zaten veriniz varsa {#if-you-already-have-data-in-the-2-0-instance} İçe aktarıcı yalnızca boş bir veritabanına çalışır. 2.0'ı sıfırdan başlattıysanız (veri oluşturarak) ve daha sonra eski bir `snapotter.db` dosyasını bağladıysanız, 2.0 onu algılar ancak içe aktarmaz, çünkü iki veri kümesini birleştirmek kimliklerde (ID) çakışabilir. Günlüklerde bir uyarı görürsünüz. 1.x verilerini içe aktarmak için boş bir örneğe ihtiyacınız var: * 2.0 örneği yalnızca varsayılan yöneticiyi tutuyorsa (gerçekten kullanmadıysanız), yığını durdurun, Postgres birimini kaldırın (`SnapOtter-pgdata`) ve eski `/data` mevcutken yeniden başlatın. Temiz bir şekilde içe aktarır. Bu yalnızca kullanılmayan Postgres verilerini siler, 1.x veritabanınızı değil. * 2.0 örneği saklamak istediğiniz gerçek verileri tutuyorsa, iki veri kümesi otomatik olarak birleştirilemez. İhtiyacınız olanı dışa aktarın ve 1.x verilerini ayrı bir temiz dağıtıma içe aktarın. ## Geri alma {#rolling-back} Yükseltme, 1.x `snapotter.db` dosyanızı asla değiştirmez veya silmez. 1.x'e geri dönmeniz gerekiyorsa, 1.x görüntüsünü aynı birime karşı yeniden dağıtın. Yükseltmeden sonra 2.0'da oluşturduğunuz her şey Postgres'te bulunur ve 1.x veritabanında olmaz, bu nedenle geri dönecekseniz hemen geri dönün. --- --- url: https://docs.snapotter.com/hi/guide/upgrading.md --- # 1.x से 2.0 में अपग्रेड करना {#upgrading-from-1-x-to-2-0} SnapOtter 1.x सब कुछ एक ही SQLite फ़ाइल में संग्रहीत करता था और एक ही container के रूप में चलता था। SnapOtter 2.0 PostgreSQL और Redis का उपयोग करता है। यह गाइड बिना डेटा खोए 1.x इंस्टॉल को 2.0 में ले जाने का तरीका बताती है। संक्षेप में: अपने मौजूदा `/data` वॉल्यूम का पुनः उपयोग करें, और 2.0 पहली बूट पर आपके 1.x डेटाबेस को स्वचालित रूप से इम्पोर्ट कर लेता है। आपके उपयोगकर्ता, सहेजी गई फ़ाइलें, सेटिंग्स, API keys और pipelines सब साथ आ जाते हैं। पुराना डेटाबेस कभी संशोधित नहीं होता, इसलिए आप हमेशा रोल बैक कर सकते हैं। ::: tip हमारे 1.x उपयोगकर्ताओं के लिए एक नोट आप में से कई लोगों ने पहले दिन से SnapOtter पर भरोसा किया है, और आपकी प्रतिक्रिया ने इस रिलीज़ को आकार दिया है। 2.0 अंदरूनी तौर पर बहुत कुछ बदलता है, और यह गाइड इसलिए मौजूद है ताकि यह बदलाव आपको उन चीज़ों में से कुछ भी न खर्च कराए जिनकी आप परवाह करते हैं। आपके अकाउंट, फ़ाइलें, सेटिंग्स, API keys और pipelines साथ आते हैं, और आपका पुराना डेटाबेस कभी नहीं छुआ जाता। हमारे साथ अपग्रेड करने के लिए धन्यवाद। ::: ## शुरू करने से पहले: पूरे `/data` वॉल्यूम का बैकअप लें {#before-you-start-back-up-the-whole-data-volume} यह हर बार सबसे पहले करें। **पूरे** `/data` वॉल्यूम का बैकअप लें, केवल `snapotter.db` फ़ाइल का नहीं। यह क्यों मायने रखता है, यहाँ बताया गया है। 1.x SQLite को WAL मोड में चलाता है, इसलिए एक रुका हुआ 1.x container अक्सर अपने अधिकांश कमिट किए गए डेटा को `snapotter.db-wal` में छोड़ देता है, जिसके साथ एक लगभग-खाली `snapotter.db` होता है। केवल `snapotter.db` कॉपी करने से एक खाली डेटाबेस कैप्चर होता है और सब कुछ चुपचाप खो जाता है। वॉल्यूम `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm`, और आपकी `files/` डायरेक्टरी को एक साथ रखता है, और इन्हें एक सेट के रूप में साथ ले जाना चाहिए। ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## पहले 1.17.2 में अपग्रेड करें {#upgrade-to-1-17-2-first} 2.0 में जाने से पहले अपने 1.x इंस्टॉल को नवीनतम 1.x रिलीज़ (1.17.2) में अपग्रेड करें। इससे 1.x अपने अंतिम स्कीमा माइग्रेशन चला पाता है, ताकि 2.0 एक ज्ञात, पूर्ण स्कीमा से इम्पोर्ट करे। किसी पुराने 1.x से सीधे 2.0 में अपग्रेड करना समर्थित नहीं है। ## अपने वॉल्यूम का नाम जाँचें {#check-your-volume-name} इम्पोर्टर आपका डेटा केवल तभी देखता है जब 2.0 स्टैक वही वॉल्यूम माउंट करता है जो आपके 1.x इंस्टॉल ने उपयोग किया था। Docker वॉल्यूम नाम केस सेंसिटिव होते हैं, और पुराने README स्निपेट्स में एक लोअरकेस `snapotter-data` का उपयोग होता था जबकि Compose फ़ाइलें `SnapOtter-data` का उपयोग करती हैं। पुष्टि करें कि आपके पास कौन सा है: ```bash docker volume ls | grep -i snapotter ``` अपने 2.0 कॉन्फ़िगरेशन में ठीक वही नाम उपयोग करें। ## पथ A: सिंगल container (सबसे तेज़) {#path-a-single-container-quickest} यदि आप SnapOtter को एक ही `docker run` के साथ चलाते हैं, तो ऐसा करना जारी रखें। जब आप `DATABASE_URL` या `REDIS_URL` सेट नहीं करते, तो 2.0 container के अंदर एक एम्बेडेड PostgreSQL और Redis बूट करता है, और पहली बूट पर `/data/snapotter.db` को स्वतः-पहचानता और इम्पोर्ट करता है। ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` लॉग में इस तरह की एक पंक्ति देखें: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` बस इतना ही। अपने मौजूदा क्रेडेंशियल के साथ लॉग इन करें। ## पथ B: Compose (प्रोडक्शन के लिए अनुशंसित) {#path-b-compose-recommended-for-production} 2.0 Compose स्टैक तीन सेवाएँ चलाता है (app, Postgres, Redis)। app सेवा के लिए अपने 1.x `/data` वॉल्यूम का पुनः उपयोग करें। app पहली बूट पर `/data/snapotter.db` को स्वतः-पहचानता है और इसे Postgres में इम्पोर्ट करता है। ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` यदि आप पुराने डेटाबेस को स्पष्ट रूप से इंगित करना चाहें, तो `SQLITE_MIGRATE_PATH=/data/snapotter.db` सेट करें। एक स्पष्ट पथ हमेशा स्वतः-पहचान पर भारी पड़ता है। ## पहले इम्पोर्ट का पूर्वावलोकन करें (वैकल्पिक) {#preview-the-import-first-optional} बिना कुछ लिखे ठीक-ठीक देखने के लिए कि क्या इम्पोर्ट होगा, अपनी डेटाबेस फ़ाइल के विरुद्ध एक ड्राई रन चलाएँ: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` यह प्रति टेबल पंक्ति गणना, डिस्क पर मिली कितनी सहेजी-गई-लाइब्रेरी फ़ाइलें, और किसी भी जॉब स्थिति को जिसे वह सामान्यीकृत करेगा, प्रिंट करता है। इसे किसी चालू Postgres की आवश्यकता नहीं होती। ## क्या साथ आता है, और क्या नहीं {#what-carries-over-and-what-does-not} साथ आता है: * उपयोगकर्ता, और लॉग इन करने की क्षमता। पासवर्ड हैश अपरिवर्तित रहते हैं, इसलिए वही उपयोगकर्ता नाम और पासवर्ड काम करते हैं। * Teams, सेटिंग्स (आपकी इंस्टेंस पहचान सहित), roles, API keys (वे काम करते रहते हैं), और सहेजी गई pipelines। * जॉब इतिहास रिकॉर्ड। * आपकी सहेजी-गई-फ़ाइल लाइब्रेरी, रिकॉर्ड और वास्तविक फ़ाइलें दोनों, क्योंकि `/data/files` वॉल्यूम पर संरक्षित रहता है। साथ नहीं आता: * लॉगिन सत्र। अपग्रेड के बाद सभी एक बार साइन इन करते हैं। क्रेडेंशियल अपरिवर्तित रहते हैं, इसलिए यह एक बार का पुनः-लॉगिन है, इससे अधिक कुछ नहीं। * पुराने प्रोसेसिंग जॉब की इनपुट और आउटपुट फ़ाइलें। वे एक अस्थायी वर्कस्पेस में रहती थीं और डिज़ाइन के अनुसार चली जाती हैं। जॉब इतिहास रिकॉर्ड बने रहते हैं। * 1.x से प्रति-उपयोगकर्ता एनालिटिक्स-सहमति फ़्लैग, जिनका कोई 2.0 समकक्ष नहीं है (2.0 एनालिटिक्स एक इंस्टेंस-स्तरीय सेटिंग है)। ## इम्पोर्ट को बंद करना {#turning-the-import-off} यदि आप जानबूझकर एक ताज़ा डेटाबेस चाहते हैं, भले ही वॉल्यूम पर एक `snapotter.db` मौजूद हो, तो `SQLITE_MIGRATE_PATH=off` सेट करें। ## यदि 2.0 इंस्टेंस में आपके पास पहले से डेटा है {#if-you-already-have-data-in-the-2-0-instance} इम्पोर्टर केवल एक खाली डेटाबेस में ही चलता है। यदि आपने 2.0 को ताज़ा शुरू किया (डेटा बनाते हुए), फिर बाद में एक पुराना `snapotter.db` माउंट किया, तो 2.0 इसे पहचानेगा लेकिन इम्पोर्ट नहीं करेगा, क्योंकि दो डेटासेट मर्ज करने से IDs टकरा सकती हैं। आपको लॉग में एक चेतावनी दिखेगी। 1.x डेटा इम्पोर्ट करने के लिए आपको एक खाली इंस्टेंस चाहिए: * यदि 2.0 इंस्टेंस में केवल डिफ़ॉल्ट एडमिन है (आपने वास्तव में इसका उपयोग नहीं किया), तो स्टैक रोकें, Postgres वॉल्यूम हटाएँ (`SnapOtter-pgdata`), और पुराने `/data` के मौजूद रहते हुए फिर से बूट करें। यह साफ़ इम्पोर्ट कर लेगा। इससे केवल फेंकने-योग्य Postgres डेटा मिटता है, आपका 1.x डेटाबेस नहीं। * यदि 2.0 इंस्टेंस में वास्तविक डेटा है जिसे आप रखना चाहते हैं, तो दोनों डेटासेट स्वतः-मर्ज नहीं किए जा सकते। जो आपको चाहिए उसे एक्सपोर्ट करें और 1.x डेटा को एक अलग ताज़ा डिप्लॉयमेंट में इम्पोर्ट करें। ## रोल बैक करना {#rolling-back} अपग्रेड आपके 1.x `snapotter.db` को कभी संशोधित या हटाता नहीं है। यदि आपको 1.x पर वापस जाना है, तो उसी वॉल्यूम के विरुद्ध 1.x इमेज पुनः डिप्लॉय करें। अपग्रेड के बाद 2.0 में आपने जो कुछ भी बनाया वह Postgres में रहता है और 1.x डेटाबेस में नहीं होगा, इसलिए यदि आप वापस जाने वाले हैं तो तुरंत रोल बैक करें। --- --- url: https://docs.snapotter.com/ja/guide/upgrading.md --- # 1.x から 2.0 へのアップグレード {#upgrading-from-1-x-to-2-0} SnapOtter 1.x はすべてを 1 つの SQLite ファイルに保存し、単一のコンテナとして動作していました。SnapOtter 2.0 は PostgreSQL と Redis を使用します。このガイドでは、データを失わずに 1.x のインストールを 2.0 へ移行する手順を説明します。 要点はこうです。既存の `/data` ボリュームを再利用すれば、2.0 は初回起動時に 1.x のデータベースを自動的にインポートします。ユーザー、保存済みファイル、設定、API キー、パイプラインがそのまま引き継がれます。古いデータベースは一切変更されないため、いつでもロールバックできます。 ::: tip 1.x ユーザーの皆さんへ 多くの方が初日から SnapOtter を信頼してくださり、その声がこのリリースを形づくりました。2.0 は内部で多くを変えていますが、このガイドは、皆さんが大切にしているものを一切失わずに移行できるよう用意されています。アカウント、ファイル、設定、API キー、パイプラインは引き継がれ、古いデータベースには手を触れません。一緒にアップグレードしてくださり、ありがとうございます。 ::: ## 始める前に: `/data` ボリューム全体をバックアップする {#before-you-start-back-up-the-whole-data-volume} これは毎回、最初に行ってください。`snapotter.db` ファイルだけでなく、**`/data` ボリューム全体**をバックアップします。 これが重要な理由を説明します。1.x は SQLite を WAL モードで動作させるため、停止した 1.x コンテナは、コミット済みデータの大半をほぼ空の `snapotter.db` の隣にある `snapotter.db-wal` に残すことが日常的にあります。`snapotter.db` だけをコピーすると空のデータベースを取り込むことになり、すべてを静かに失います。ボリュームは `snapotter.db`、`snapotter.db-wal`、`snapotter.db-shm`、そしてあなたの `files/` ディレクトリをまとめて保持しており、これらは 1 つのセットとして一緒に移動させる必要があります。 ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## まず 1.17.2 にアップグレードする {#upgrade-to-1-17-2-first} 2.0 へ移行する前に、1.x のインストールを最新の 1.x リリース(1.17.2)へアップグレードしてください。そうすることで 1.x が自身の最終的なスキーマ移行を実行し、2.0 は既知の完全なスキーマからインポートできます。より古い 1.x から直接 2.0 へアップグレードすることはサポートされていません。 ## ボリューム名を確認する {#check-your-volume-name} インポーターは、2.0 スタックが 1.x のインストールで使用したのと同じボリュームをマウントしている場合にのみデータを認識します。Docker のボリューム名は大文字と小文字を区別し、古い README のスニペットは小文字の `snapotter-data` を使用していた一方で、Compose ファイルは `SnapOtter-data` を使用しています。どちらを使っているか確認してください: ```bash docker volume ls | grep -i snapotter ``` 2.0 の設定ではその正確な名前を使用してください。 ## パス A: 単一コンテナ(最速) {#path-a-single-container-quickest} SnapOtter を単一の `docker run` で実行している場合は、そのまま続けてください。2.0 は `DATABASE_URL` や `REDIS_URL` を設定していないと、コンテナ内で組み込みの PostgreSQL と Redis を起動し、初回起動時に `/data/snapotter.db` を自動検出してインポートします。 ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` ログに次のような行が出るのを確認してください: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` これで完了です。既存の認証情報でログインしてください。 ## パス B: Compose(本番環境で推奨) {#path-b-compose-recommended-for-production} 2.0 の Compose スタックは 3 つのサービス(app、Postgres、Redis)を実行します。app サービスには 1.x の `/data` ボリュームを再利用してください。app は `/data/snapotter.db` を自動検出し、初回起動時に Postgres へインポートします。 ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` 古いデータベースを明示的に指定したい場合は、`SQLITE_MIGRATE_PATH=/data/snapotter.db` を設定してください。明示的なパスは常に自動検出よりも優先されます。 ## 先にインポートをプレビューする(任意) {#preview-the-import-first-optional} 何も書き込まずにインポートされる内容を正確に確認するには、データベースファイルに対してドライランを実行します: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` テーブルごとの行数、ディスク上で見つかった保存ライブラリファイルの数、正規化されるジョブステータスを表示します。Postgres の起動は不要です。 ## 引き継がれるものと引き継がれないもの {#what-carries-over-and-what-does-not} 引き継がれるもの: * ユーザー、およびログインできること。パスワードハッシュは変更されないため、同じユーザー名とパスワードが機能します。 * チーム、設定(インスタンスのアイデンティティを含む)、ロール、API キー(引き続き機能します)、保存済みパイプライン。 * ジョブ履歴レコード。 * 保存ファイルライブラリ。`/data/files` がボリューム上に保持されるため、レコードと実際のファイルの両方が引き継がれます。 引き継がれないもの: * ログインセッション。アップグレード後は全員が一度サインインします。認証情報は変わらないため、単なる 1 回の再ログインに過ぎません。 * 古い処理ジョブの入力ファイルと出力ファイル。これらは一時的なワークスペースにあり、設計上失われます。ジョブ履歴レコードは残ります。 * 1.x のユーザーごとの分析同意フラグ。2.0 には対応するものがありません(2.0 の分析はインスタンスレベルの設定です)。 ## インポートをオフにする {#turning-the-import-off} ボリューム上に `snapotter.db` が存在していても意図的に新しいデータベースを使いたい場合は、`SQLITE_MIGRATE_PATH=off` を設定してください。 ## 2.0 インスタンスに既にデータがある場合 {#if-you-already-have-data-in-the-2-0-instance} インポーターは空のデータベースに対してのみ実行されます。2.0 を新規に起動してデータを作成し、後から古い `snapotter.db` をマウントした場合、2.0 はそれを検出しますが、2 つのデータセットのマージは ID の衝突を起こす可能性があるためインポートしません。ログに警告が表示されます。1.x データをインポートするには空のインスタンスが必要です: * 2.0 インスタンスにデフォルトの管理者しか存在しない(実質的に使っていない)場合は、スタックを停止し、Postgres ボリューム(`SnapOtter-pgdata`)を削除し、古い `/data` が存在する状態で再起動してください。クリーンにインポートされます。これは 1.x データベースではなく、使い捨ての Postgres データのみを消去します。 * 2.0 インスタンスに保持したい実データがある場合、2 つのデータセットは自動マージできません。必要なものをエクスポートし、1.x データを別の新規デプロイにインポートしてください。 ## ロールバック {#rolling-back} アップグレードは 1.x の `snapotter.db` を変更したり削除したりすることはありません。1.x に戻す必要がある場合は、同じボリュームに対して 1.x イメージを再デプロイしてください。アップグレード後に 2.0 で作成したものは Postgres に存在し、1.x データベースには含まれないため、戻す場合は速やかに行ってください。 --- --- url: https://docs.snapotter.com/ko/guide/upgrading.md --- # 1.x에서 2.0으로 업그레이드 {#upgrading-from-1-x-to-2-0} SnapOtter 1.x는 모든 것을 단일 SQLite 파일에 저장하고 하나의 컨테이너로 실행되었습니다. SnapOtter 2.0은 PostgreSQL과 Redis를 사용합니다. 이 가이드는 데이터 손실 없이 1.x 설치를 2.0으로 옮기는 과정을 안내합니다. 짧게 요약하면: 기존 `/data` 볼륨을 재사용하면 2.0이 첫 부팅 시 1.x 데이터베이스를 자동으로 가져옵니다. 사용자, 저장된 파일, 설정, API 키, 파이프라인이 모두 넘어옵니다. 기존 데이터베이스는 절대 수정되지 않으므로 언제든 롤백할 수 있습니다. ::: tip 1.x 사용자분들께 많은 분들이 처음부터 SnapOtter를 신뢰해 주셨고, 여러분의 피드백이 이번 릴리스를 만들었습니다. 2.0은 내부적으로 많은 것을 바꾸며, 이 가이드는 여러분이 소중히 여기는 것을 잃지 않고 이전할 수 있도록 존재합니다. 계정, 파일, 설정, API 키, 파이프라인이 그대로 이어지며 기존 데이터베이스는 절대 건드리지 않습니다. 함께 업그레이드해 주셔서 감사합니다. ::: ## 시작하기 전에: `/data` 볼륨 전체를 백업하세요 {#before-you-start-back-up-the-whole-data-volume} 매번 이것을 먼저 하세요. `snapotter.db` 파일만이 아니라 `/data` 볼륨 **전체**를 백업하세요. 이유는 다음과 같습니다. 1.x는 SQLite를 WAL 모드로 실행하므로, 중지된 1.x 컨테이너는 커밋된 데이터 대부분을 거의 비어 있는 `snapotter.db` 옆의 `snapotter.db-wal`에 남겨 두는 경우가 흔합니다. `snapotter.db`만 복사하면 빈 데이터베이스를 담게 되어 조용히 모든 것을 잃습니다. 볼륨은 `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm`, 그리고 `files/` 디렉터리를 함께 담고 있으며, 이들은 하나의 세트로 이동해야 합니다. ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## 먼저 1.17.2로 업그레이드하세요 {#upgrade-to-1-17-2-first} 2.0으로 옮기기 전에 1.x 설치를 최신 1.x 릴리스(1.17.2)로 업그레이드하세요. 그러면 1.x가 자체적으로 최종 스키마 마이그레이션을 실행하므로, 2.0이 알려진 완전한 스키마에서 가져올 수 있습니다. 오래된 1.x에서 곧바로 2.0으로 업그레이드하는 것은 지원되지 않습니다. ## 볼륨 이름 확인하기 {#check-your-volume-name} 임포터는 2.0 스택이 1.x 설치가 사용하던 것과 동일한 볼륨을 마운트할 때만 데이터를 인식합니다. Docker 볼륨 이름은 대소문자를 구분하며, 오래된 README 스니펫은 소문자 `snapotter-data`을 사용한 반면 Compose 파일은 `SnapOtter-data`을 사용합니다. 어느 쪽인지 확인하세요: ```bash docker volume ls | grep -i snapotter ``` 2.0 구성에서 정확히 그 이름을 사용하세요. ## 경로 A: 단일 컨테이너(가장 빠름) {#path-a-single-container-quickest} SnapOtter를 단일 `docker run`로 실행하고 있다면 계속 그렇게 하세요. `DATABASE_URL`이나 `REDIS_URL`을 설정하지 않으면 2.0은 컨테이너 내부에 내장 PostgreSQL과 Redis를 부팅하며, 첫 부팅 시 `/data/snapotter.db`을 자동 감지해 가져옵니다. ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` 다음과 같은 로그 줄을 지켜보세요: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` 그게 전부입니다. 기존 자격 증명으로 로그인하세요. ## 경로 B: Compose(프로덕션 권장) {#path-b-compose-recommended-for-production} 2.0 Compose 스택은 세 개의 서비스(앱, Postgres, Redis)를 실행합니다. 앱 서비스에는 1.x `/data` 볼륨을 재사용하세요. 앱은 `/data/snapotter.db`을 자동 감지해 첫 부팅 시 Postgres로 가져옵니다. ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` 기존 데이터베이스를 명시적으로 가리키고 싶다면 `SQLITE_MIGRATE_PATH=/data/snapotter.db`을 설정하세요. 명시적 경로는 항상 자동 감지보다 우선합니다. ## 먼저 임포트 미리보기(선택 사항) {#preview-the-import-first-optional} 아무것도 쓰지 않고 무엇이 가져와질지 정확히 확인하려면, 데이터베이스 파일에 대해 드라이 런을 실행하세요: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` 테이블별 행 수, 디스크에서 찾은 저장 라이브러리 파일 개수, 정규화할 작업 상태를 출력합니다. Postgres가 실행 중일 필요가 없습니다. ## 넘어오는 것과 넘어오지 않는 것 {#what-carries-over-and-what-does-not} 넘어오는 것: * 사용자 및 로그인 기능. 비밀번호 해시는 변경되지 않으므로 동일한 사용자 이름과 비밀번호가 그대로 작동합니다. * 팀, 설정(인스턴스 정체성 포함), 역할, API 키(계속 작동), 저장된 파이프라인. * 작업 이력 기록. * 저장 파일 라이브러리, 기록과 실제 파일 모두. `/data/files`이 볼륨에 보존되기 때문입니다. 넘어오지 않는 것: * 로그인 세션. 업그레이드 후 모두가 한 번 로그인합니다. 자격 증명은 변경되지 않으므로 단 한 번의 재로그인일 뿐이며 그 이상은 없습니다. * 오래된 처리 작업의 입력 및 출력 파일. 이들은 임시 작업 공간에 있었고 설계상 사라집니다. 작업 이력 기록은 남습니다. * 1.x의 사용자별 분석 동의 플래그. 2.0에는 대응하는 항목이 없습니다(2.0 분석은 인스턴스 수준 설정입니다). ## 임포트 끄기 {#turning-the-import-off} 볼륨에 `snapotter.db`이 있더라도 의도적으로 새 데이터베이스를 원한다면 `SQLITE_MIGRATE_PATH=off`을 설정하세요. ## 2.0 인스턴스에 이미 데이터가 있는 경우 {#if-you-already-have-data-in-the-2-0-instance} 임포터는 빈 데이터베이스에서만 실행됩니다. 2.0을 새로 시작해(데이터를 생성해) 나중에 오래된 `snapotter.db`을 마운트한 경우, 2.0은 이를 감지하지만 가져오지는 않습니다. 두 데이터셋을 병합하면 ID가 충돌할 수 있기 때문입니다. 로그에 경고가 표시됩니다. 1.x 데이터를 가져오려면 빈 인스턴스가 필요합니다: * 2.0 인스턴스가 기본 관리자만 담고 있다면(실제로 사용하지 않았다면), 스택을 중지하고 Postgres 볼륨(`SnapOtter-pgdata`)을 제거한 뒤, 오래된 `/data`이 있는 상태로 다시 부팅하세요. 깔끔하게 가져옵니다. 이는 1.x 데이터베이스가 아니라 버려도 되는 Postgres 데이터만 지웁니다. * 2.0 인스턴스가 유지하려는 실제 데이터를 담고 있다면 두 데이터셋을 자동 병합할 수 없습니다. 필요한 것을 내보내고 1.x 데이터를 별도의 새 배포로 가져오세요. ## 롤백하기 {#rolling-back} 업그레이드는 1.x `snapotter.db`을 절대 수정하거나 삭제하지 않습니다. 1.x로 되돌아가야 한다면 동일한 볼륨에 대해 1.x 이미지를 다시 배포하세요. 업그레이드 후 2.0에서 생성한 모든 것은 Postgres에 있어 1.x 데이터베이스에는 없으므로, 되돌릴 예정이라면 신속하게 롤백하세요. --- --- url: https://docs.snapotter.com/ja/tools/pdf/nup-pdf.md description: 1 枚のシートに複数の PDF ページを配置します(2-up、4-up など)。 --- # 1枚あたりのページ数 (N-up) {#n-up-pdf} 2-up や 4-up レイアウトのように 1 枚のシートに複数ページを配置し、印刷時の用紙を節約します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/nup-pdf` PDF ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | 1 シートあたりのページ数: `2`、`3`、`4`、`8`、`9`、`12`、または `16` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/nup-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2300000 } ``` ## Notes {#notes} * ページは読み順(左から右、上から下)に配置されます。 * 出力ページのサイズは元と同じです。各ページはグリッドに収まるよう縮小されます。 * 20 ページのドキュメントに `perSheet: 4` を適用すると、5 ページの出力になります。 --- --- url: https://docs.snapotter.com/nl/guide/getting-started.md description: >- Installeer SnapOtter met Docker in één commando. Inclusief Docker Compose-installatie, bouwen vanaf broncode en een volledig functieoverzicht. --- # Aan de slag {#getting-started} ::: tip Probeer voor je installeert Verken de volledige UI op [demo.snapotter.com](https://demo.snapotter.com) - geen aanmelding of installatie vereist. ::: ## Snelstart {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Deze enkele container voert alles uit wat hij nodig heeft: zonder `DATABASE_URL` ingesteld, start hij zijn eigen PostgreSQL en Redis op de loopback-interface (embedded mode) en bewaart hij alle gegevens in het `SnapOtter-data`-volume. Het is de snelste manier om SnapOtter uit te proberen of zelf te hosten op een thuislab. Gebruik voor productie de [canonieke Docker Compose-stack](#docker-compose), die PostgreSQL en Redis in hun eigen containers bewaart. De ingebouwde modus wordt uitgevoerd als root (standaard) en wordt automatisch uitgeschakeld zodra u `DATABASE_URL` instelt. Installeer je op een Raspberry Pi, een oude laptop of een kleine VPS? Zie [Setups met beperkte resources](/nl/guide/low-resource) voor een afgestemd stappenplan en wat je van beperkte hardware kunt verwachten. Je wordt bij de eerste login gevraagd je wachtwoord te wijzigen. ::: tip Anonieme Productanalytics SnapOtter bevat standaard anonieme productanalytics. Om het uit te schakelen, open je **Instellingen → Systeem → Privacy** en zet je **Anonieme Productanalytics** uit. Het stopt onmiddellijk voor de hele instance. Je kunt ook de omgevingsvariabele `SNAPOTTER_TELEMETRY=0` instellen (`false` en `off` werken ook) om alle telemetrie voor de instance uit te schakelen zonder herbouw. Foutmonitoring wordt aangedreven door [Sentry](https://sentry.io), dat SnapOtter sponsort via zijn open-source-programma. Zie [Wat SnapOtter verzamelt](/nl/guide/telemetry) voor details over wat er wordt verzameld. ::: ::: tip NVIDIA CUDA-versnelling Voeg `--gpus all` toe voor NVIDIA CUDA-versnelde achtergrondverwijdering, opschaling, gezichtsverbetering en restauratie. OCR blijft CPU-gebaseerd en werkt in dezelfde afbeelding met of zonder GPU-toegang: ```bash docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest ``` Vereist de [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). Valt automatisch terug naar de CPU wanneer CUDA niet beschikbaar is. Intel/AMD iGPU-versnelling via VA-API, Quick Sync of OpenCL wordt momenteel niet ondersteund voor AI-inferentie. Zie [Docker-tags](/nl/guide/docker-tags) voor benchmarks. Als AI-tools ondanks `--gpus all` op de CPU draaien, zie dan [GPU-versnelling verifiëren](/nl/guide/deployment#verify-gpu-acceleration). ::: ::: details Ook op GHCR ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snapotter-hq/snapotter:latest ``` Beide registries publiceren bij elke release dezelfde image. ::: ## Docker Componeer {#docker-compose} Gebruik het productiebestand dat bij elke release wordt onderhouden en getest in plaats van een verkort Compose-voorbeeld van deze pagina te kopiëren: ```bash install -d -m 700 snapotter && cd snapotter curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \ https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.2.0/docker/docker-compose.yml # Keep generated service credentials out of shell history and world-readable files. umask 077 POSTGRES_PASSWORD="$(openssl rand -hex 32)" REDIS_PASSWORD="$(openssl rand -hex 32)" printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \ "$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --no-build ``` De canonieke [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.2.0/docker/docker-compose.yml) omvat alle vier de runtimevolumes, gezondheidscontroles, resourcelimieten, duurzame Redis-configuratie, vastgezette database-/cache-images en de huidige containerverharding. Wijzig het standaard beheerderswachtwoord onmiddellijk na de eerste keer inloggen. Voor een reproduceerbare implementatie maakt u de SnapOtter-toepassingsimage vast aan de releasetag of -digest die u hebt geverifieerd, in plaats van `latest` te volgen. Zie [Configuratie](/nl/guide/configuration) voor alle omgevingsvariabelen en [Beveiliging en beveiliging](/nl/guide/security) voor geheimen, netwerkbeleid en back-uprichtlijnen. ## Bouwen vanaf broncode {#build-from-source} **Vereisten:** Node.js 22.22+, pnpm 9+, Docker (voor Postgres + Redis), Python 3.11+ (voor AI-functies), Git. ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` * Frontend: * Backend: ## Wat je kunt doen {#what-you-can-do} ### Bestandsverwerking (200+ tools) {#file-processing-200-tools} | Modaliteit | Aantal | Voorbeeldtools | |----------|-------|---------------| | **Afbeelding** | 107 | Formaat wijzigen, Bijsnijden, Comprimeren, Converteren, Achtergrond verwijderen, Upscale, OCR, Watermerk, Collage, Inkleuren, GIF-tools, formaatpresets | | **Video** | 57 | Trimmen, Bijsnijden, Comprimeren, Converteren, Samenvoegen, Audio extraheren, Automatische ondertitels, Video naar GIF, Formaat wijzigen, Stabiliseren, formaatpresets | | **Audio** | 27 | Trimmen, Samenvoegen, Converteren, Normaliseren, Ruisonderdrukking, Transcriberen, Pitch verschuiven, Fade, Beltoonmaker, formaatpresets | | **PDF / Document** | 29 | Samenvoegen, Splitsen, Comprimeren, OCR, Watermerk, Redigeren, Word naar PDF, Excel naar PDF, Roteren, Beveiligen, Repareren | | **Bestanden** | 23 | CSV naar JSON, JSON naar XML, CSV's samenvoegen, CSV splitsen, ZIP maken, ZIP uitpakken, Grafiekmaker, YAML/JSON | ### Pijplijnen {#pipelines} Koppel tools aan elkaar tot workflows met meerdere stappen en pas ze toe op één afbeelding of een hele batch: 1. Open **Pijplijnen** in de zijbalk. 2. Voeg stappen toe (elke tool, alle instellingen). 3. Draai op één bestand - of een hele batch tegelijk. 4. Sla de pijplijn op voor later hergebruik. Pijplijnen staan standaard 20 stappen toe. Stel `MAX_PIPELINE_STEPS=0` in om de limiet onbeperkt te maken. ### Bestandsbibliotheek {#file-library} Elk bestand dat je verwerkt, kan worden opgeslagen in je **Bestanden**-bibliotheek. SnapOtter houdt de volledige versiegeschiedenis bij zodat je elke verwerkingsstap kunt traceren van de oorspronkelijke upload tot de uiteindelijke uitvoer. Opslaan is expliciet: resultaten die je in de bibliotheek opslaat, blijven bewaard tot je ze verwijdert, terwijl resultaten die je verwerkt en niet opslaat automatisch na 72 uur worden gewist (configureerbaar via `FILE_MAX_AGE_HOURS`). ### REST API & API-sleutels {#rest-api-api-keys} Elke tool is toegankelijk via HTTP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800,"height":600,"fit":"cover"}' ``` Genereer API-sleutels onder **Instellingen → API-sleutels**. Zie de [REST API-referentie](/nl/api/rest) voor alle endpoints, of bezoek voor de interactieve referentie. ### Meerdere gebruikers & teams {#multi-user-teams} Schakel meerdere gebruikers in met op rollen gebaseerde toegangscontrole: * **Beheerder**: volledige toegang - beheer gebruikers, teams, instellingen, alle bestanden/pijplijnen/API-sleutels * **Gebruiker**: gebruik tools, beheer eigen bestanden/pijplijnen/API-sleutels Maak teams aan onder **Instellingen → Teams** om gebruikers te groeperen. Stel `AUTH_ENABLED=true` in (of `false` voor gebruik met één gebruiker/eigen gebruik zonder login). ## Gebruik het vanaf je telefoon {#use-it-from-your-phone} SnapOtter werkt in mobiele browsers, en je kunt het als app installeren. Open je instance op je telefoon en doe dan het volgende: * **iPhone / iPad (Safari)**: tik op Deel en dan op **Zet op beginscherm**. * **Android (Chrome)**: open het browsermenu en tik op **App installeren**. De geïnstalleerde app opent in een eigen venster, direct in je instance. Eén ding om te weten: browsers bieden de installatie alleen aan via HTTPS. Een gewoon HTTP-adres op je LAN werkt prima in een browsertabblad; voor de echte installatie zet je de instance achter een reverse proxy met een certificaat (zie de [implementatiegids](/nl/guide/deployment)). Op telefoons en tablets tonen de afbeeldingstools een knop **Foto maken** naast de uploadknop. Fotografeer een bonnetje of een whiteboard en het staat meteen in de tool. --- --- url: https://docs.snapotter.com/fr/tools/image/sharpening.md description: >- Accentue la netteté des images avec des méthodes adaptative, masque flou ou passe-haut, avec réduction du bruit facultative. --- # Accentuer la netteté d'une image {#sharpening} Outil avancé de renforcement de la netteté offrant trois méthodes : adaptative (intelligente et sensible aux contours), masque flou (rayon/quantité classiques) et passe-haut (accentuation des textures). Comprend une réduction du bruit intégrée pour éviter les artefacts de netteté. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/sharpening` Accepte des données de formulaire multipart avec un fichier image et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | method | string | Non | `"adaptive"` | Algorithme de netteté : `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | Non | `1.0` | Adaptative : sigma gaussien (0,5 à 10) | | m1 | number | Non | `1.0` | Adaptative : netteté des zones planes (0 à 10) | | m2 | number | Non | `3.0` | Adaptative : netteté des zones dentelées (0 à 20) | | x1 | number | Non | `2.0` | Adaptative : seuil plane/dentelée (0 à 10) | | y2 | number | Non | `12` | Adaptative : netteté maximale des zones planes (0 à 50) | | y3 | number | Non | `20` | Adaptative : netteté maximale des zones dentelées (0 à 50) | | amount | number | Non | `100` | Masque flou : quantité de netteté (0 à 1000) | | radius | number | Non | `1.0` | Masque flou : rayon de flou en pixels (0,1 à 5) | | threshold | number | Non | `0` | Masque flou : différence de luminosité minimale à accentuer (0 à 255) | | strength | number | Non | `50` | Passe-haut : force du filtre (0 à 100) | | kernelSize | number | Non | `3` | Passe-haut : taille du noyau de convolution (3 ou 5) | | denoise | string | Non | `"off"` | Réduction du bruit avant renforcement : `off`, `light`, `medium`, `strong` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Masque flou avec seuil pour protéger les zones lisses : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Remarques {#notes} * Seuls les paramètres pertinents pour la méthode choisie sont utilisés. Par exemple, `amount`, `radius` et `threshold` sont ignorés lorsque `method` vaut `adaptive`. * La méthode adaptative utilise le renforcement adaptatif intégré de Sharp, avec un comportement configurable pour les régions planes/dentelées. * L'option `denoise` applique une réduction du bruit avant le renforcement afin d'éviter l'amplification du bruit ou du grain. * Le renforcement passe-haut extrait les détails fins en soustrayant une version floutée de l'original, puis en la fusionnant à nouveau. * Le format de sortie correspond au format d'entrée. Les entrées HEIC, RAW, PSD et SVG sont automatiquement décodées avant le traitement. --- --- url: https://docs.snapotter.com/nl/tools/image/blur-background.md description: Vervaag de achtergrond terwijl het onderwerp scherp blijft met behulp van AI. --- # Achtergrond vervagen {#blur-background} Vervaag de achtergrond van een afbeelding terwijl het onderwerp scherp blijft. Het AI-model isoleert het onderwerp, past een vervaging toe op de originele achtergrond en plaatst het scherpe onderwerp erbovenop. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` Accepteert multipart form data met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | intensity | integer | Nee | `50` | Vervagingsintensiteit (1-100) | | feather | integer | Nee | `0` | Straal voor het verzachten van randen (0-20) | | format | string | Nee | `"png"` | Uitvoerformaat: `png` of `webp` | ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Volg de voortgang via SSE op `GET /api/v1/jobs/{jobId}/progress`. Wanneer de taak is voltooid, zendt de SSE-stream een `completed`-gebeurtenis uit met de download-URL. ## Opmerkingen {#notes} * Dit is een AI-gestuurde tool die `202 Accepted` retourneert en asynchroon verwerkt. Maak verbinding met het SSE-endpoint om voortgangsupdates en het eindresultaat te ontvangen. * Vereist dat de feature-bundel **background-removal** is geïnstalleerd. Retourneert `501` als de bundel niet beschikbaar is. * Hogere intensiteitswaarden produceren een sterker vervagingseffect. Waarden boven 80 creëren een uitgesproken bokeh-achtige scheiding. * HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór de verwerking. --- --- url: https://docs.snapotter.com/nl/tools/image/background-replace.md description: >- Vervang de achtergrond van een afbeelding door een effen kleur of verloop met behulp van AI. --- # Achtergrond vervangen {#background-replace} Vervang de achtergrond van een afbeelding door een effen kleur of verloop. Het AI-model detecteert het onderwerp, verwijdert de originele achtergrond en plaatst het onderwerp op de door jou gekozen achtergrond. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` Accepteert multipart form data met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | backgroundType | string | Nee | `"color"` | Achtergrondmodus: `color` of `gradient` | | color | string | Nee | `"#ffffff"` | Hex-kleur van de achtergrond (wanneer backgroundType `color` is) | | gradientColor1 | string | Nee | - | Eerste hex-kleur van het verloop | | gradientColor2 | string | Nee | - | Tweede hex-kleur van het verloop | | gradientAngle | integer | Nee | `180` | Verloophoek in graden (0-360) | | feather | integer | Nee | `0` | Straal voor het verzachten van randen (0-20) | | format | string | Nee | `"png"` | Uitvoerformaat: `png` of `webp` | ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Volg de voortgang via SSE op `GET /api/v1/jobs/{jobId}/progress`. Wanneer de taak is voltooid, zendt de SSE-stream een `completed`-gebeurtenis uit met de download-URL. ## Opmerkingen {#notes} * Dit is een AI-gestuurde tool die `202 Accepted` retourneert en asynchroon verwerkt. Maak verbinding met het SSE-endpoint om voortgangsupdates en het eindresultaat te ontvangen. * Vereist dat de feature-bundel **background-removal** is geïnstalleerd. Retourneert `501` als de bundel niet beschikbaar is. * HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór de verwerking. * De uitvoer is standaard PNG om de transparantie rond het onderwerp te behouden. --- --- url: https://docs.snapotter.com/es/guide/upgrading.md --- # Actualizar de la versión 1.x a la 2.0 {#upgrading-from-1-x-to-2-0} SnapOtter 1.x almacenaba todo en un único archivo SQLite y se ejecutaba como un solo contenedor. SnapOtter 2.0 usa PostgreSQL y Redis. Esta guía explica cómo migrar una instalación 1.x a 2.0 sin perder datos. La versión corta: reutiliza tu volumen `/data` existente y 2.0 importa tu base de datos 1.x automáticamente en el primer arranque. Tus usuarios, archivos guardados, configuración, claves de API y pipelines se conservan. La base de datos antigua nunca se modifica, así que siempre puedes revertir. ::: tip Una nota para nuestros usuarios de 1.x Muchos de ustedes han confiado en SnapOtter desde el primer día, y sus comentarios dieron forma a esta versión. La 2.0 cambia mucho por dentro, y esta guía existe para que la migración no les cueste nada de lo que les importa. Sus cuentas, archivos, configuración, claves de API y pipelines se conservan, y su base de datos antigua nunca se toca. Gracias por actualizar con nosotros. ::: ## Antes de empezar: haz una copia de seguridad del volumen `/data` completo {#before-you-start-back-up-the-whole-data-volume} Haz esto primero, siempre. Respalda el volumen `/data` **completo**, no solo el archivo `snapotter.db`. Aquí va el porqué. 1.x ejecuta SQLite en modo WAL, así que un contenedor 1.x detenido suele dejar la mayor parte de sus datos confirmados en `snapotter.db-wal` junto a un `snapotter.db` casi vacío. Copiar solo `snapotter.db` captura una base de datos vacía y pierde todo en silencio. El volumen lleva `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm` y tu directorio `files/` juntos, y deben viajar como un conjunto. ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## Actualiza primero a la 1.17.2 {#upgrade-to-1-17-2-first} Actualiza tu instalación 1.x a la última versión 1.x (1.17.2) antes de migrar a la 2.0. Eso permite que 1.x ejecute sus propias migraciones de esquema finales, para que 2.0 importe desde un esquema conocido y completo. No se admite actualizar de una versión 1.x más antigua directamente a la 2.0. ## Comprueba el nombre de tu volumen {#check-your-volume-name} El importador solo ve tus datos si el stack 2.0 monta el mismo volumen que usaba tu instalación 1.x. Los nombres de volumen de Docker distinguen entre mayúsculas y minúsculas, y fragmentos antiguos del README usaban `snapotter-data` en minúsculas mientras que los archivos de Compose usan `SnapOtter-data`. Confirma cuál tienes: ```bash docker volume ls | grep -i snapotter ``` Usa ese nombre exacto en tu configuración de 2.0. ## Ruta A: contenedor único (la más rápida) {#path-a-single-container-quickest} Si ejecutas SnapOtter con un único `docker run`, sigue haciéndolo. La 2.0 arranca un PostgreSQL y un Redis embebidos dentro del contenedor cuando no defines `DATABASE_URL` ni `REDIS_URL`, y detecta e importa `/data/snapotter.db` automáticamente en el primer arranque. ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` Vigila en los logs una línea como: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` Eso es todo. Inicia sesión con tus credenciales existentes. ## Ruta B: Compose (recomendada para producción) {#path-b-compose-recommended-for-production} El stack de Compose de 2.0 ejecuta tres servicios (app, Postgres, Redis). Reutiliza tu volumen `/data` de 1.x para el servicio de la app. La app detecta `/data/snapotter.db` automáticamente y lo importa a Postgres en el primer arranque. ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` Si prefieres apuntar a la base de datos antigua de forma explícita, establece `SQLITE_MIGRATE_PATH=/data/snapotter.db`. Una ruta explícita siempre gana sobre la detección automática. ## Previsualiza la importación primero (opcional) {#preview-the-import-first-optional} Para ver exactamente qué se importaría sin escribir nada, ejecuta una prueba en seco contra tu archivo de base de datos: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` Imprime el recuento de filas por tabla, cuántos archivos de la biblioteca guardada encontró en disco y cualquier estado de trabajo que vaya a normalizar. No necesita un Postgres en ejecución. ## Qué se conserva y qué no {#what-carries-over-and-what-does-not} Se conserva: * Los usuarios y la capacidad de iniciar sesión. Los hashes de contraseña no cambian, así que el mismo usuario y contraseña funcionan. * Equipos, configuración (incluida la identidad de tu instancia), roles, claves de API (siguen funcionando) y pipelines guardados. * Registros del historial de trabajos. * Tu biblioteca de archivos guardados, tanto los registros como los archivos reales, porque `/data/files` se conserva en el volumen. No se conserva: * Las sesiones de inicio de sesión. Todo el mundo inicia sesión una vez tras la actualización. Las credenciales no cambian, así que es un único reinicio de sesión, nada más. * Los archivos de entrada y salida de trabajos de procesamiento antiguos. Estos vivían en un espacio de trabajo temporal y desaparecen por diseño. Los registros del historial de trabajos permanecen. * Los indicadores de consentimiento de analítica por usuario de 1.x, que no tienen equivalente en 2.0 (la analítica de 2.0 es una configuración a nivel de instancia). ## Desactivar la importación {#turning-the-import-off} Si deliberadamente quieres una base de datos nueva aunque haya un `snapotter.db` presente en el volumen, establece `SQLITE_MIGRATE_PATH=off`. ## Si ya tienes datos en la instancia 2.0 {#if-you-already-have-data-in-the-2-0-instance} El importador solo se ejecuta sobre una base de datos vacía. Si arrancaste 2.0 desde cero (creando datos) y luego montaste un `snapotter.db` antiguo, 2.0 lo detectará pero no lo importará, porque fusionar dos conjuntos de datos puede colisionar en los IDs. Verás una advertencia en los logs. Para importar los datos de 1.x necesitas una instancia vacía: * Si la instancia 2.0 solo contiene el administrador predeterminado (no la has usado de verdad), detén el stack, elimina el volumen de Postgres (`SnapOtter-pgdata`) y arranca de nuevo con el `/data` antiguo presente. Se importará limpiamente. Esto borra solo los datos desechables de Postgres, no tu base de datos 1.x. * Si la instancia 2.0 contiene datos reales que quieres conservar, los dos conjuntos de datos no pueden fusionarse automáticamente. Exporta lo que necesites e importa los datos de 1.x en un despliegue nuevo e independiente. ## Revertir {#rolling-back} La actualización nunca modifica ni elimina tu `snapotter.db` de 1.x. Si necesitas volver a 1.x, vuelve a desplegar la imagen 1.x contra el mismo volumen. Todo lo que creaste en 2.0 tras la actualización vive en Postgres y no estaría en la base de datos 1.x, así que revierte pronto si vas a hacerlo. --- --- url: https://docs.snapotter.com/hi/tools/image/adjust-colors.md description: >- चमक, कंट्रास्ट, संतृप्ति, तापमान, ह्यू, चैनल समायोजित करें और रंग प्रभाव लागू करें। --- # Adjust Colors {#adjust-colors} एक ही एंडपॉइंट में चमक, कंट्रास्ट, एक्सपोज़र, संतृप्ति, तापमान, टिंट, ह्यू रोटेशन, प्रति-चैनल स्तर, और एक-क्लिक प्रभावों (ग्रेस्केल, सेपिया, इनवर्ट) को मिलाने वाला व्यापक रंग समायोजन टूल। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` एक छवि फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | चमक समायोजन (-100 से 100) | | contrast | number | No | `0` | कंट्रास्ट समायोजन (-100 से 100) | | exposure | number | No | `0` | एक्सपोज़र / मिडटोन गामा (-100 से 100) | | saturation | number | No | `0` | रंग संतृप्ति (-100 से 100) | | temperature | number | No | `0` | व्हाइट बैलेंस: ठंडा/नीला से गर्म/नारंगी (-100 से 100) | | tint | number | No | `0` | टिंट शिफ्ट: हरा से मैजेंटा (-100 से 100) | | hue | number | No | `0` | डिग्री में ह्यू रोटेशन (-180 से 180) | | sharpness | number | No | `0` | शार्पनिंग की ताकत (0 से 100) | | red | number | No | `100` | लाल चैनल स्तर (0 से 200, 100 = अपरिवर्तित) | | green | number | No | `100` | हरा चैनल स्तर (0 से 200, 100 = अपरिवर्तित) | | blue | number | No | `100` | नीला चैनल स्तर (0 से 200, 100 = अपरिवर्तित) | | effect | string | No | `"none"` | रंग प्रभाव: `none`, `grayscale`, `sepia`, `invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` एक गर्म विंटेज लुक लागू करें: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * सभी पैरामीटर तटस्थ मानों पर डिफ़ॉल्ट होते हैं ताकि आप केवल वही समायोजित कर सकें जिसकी आपको आवश्यकता है। * समायोजन इस क्रम में लागू किए जाते हैं: चमक, कंट्रास्ट, एक्सपोज़र, संतृप्ति/ह्यू, तापमान/टिंट, शार्पनेस, चैनल, प्रभाव। * तापमान नीले-नारंगी और हरे-मैजेंटा अक्षों पर एक 3x3 रंग पुनर्संयोजन मैट्रिक्स का उपयोग करता है। * एक्सपोज़र Sharp के गामा फ़ंक्शन से मैप होता है (धनात्मक मिडटोन को उज्ज्वल करता है, ऋणात्मक उन्हें गहरा करता है)। * यह एंडपॉइंट लेगेसी पथों `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels`, और `/api/v1/tools/image/color-effects` पर भी प्रतिक्रिया देता है। सभी एक ही स्कीमा का उपयोग करते हैं। * आउटपुट प्रारूप इनपुट प्रारूप से मेल खाता है। HEIC, RAW, PSD, और SVG इनपुट को प्रोसेसिंग से पहले स्वचालित रूप से डिकोड किया जाता है। --- --- url: https://docs.snapotter.com/ja/tools/image/adjust-colors.md description: 明るさ、コントラスト、彩度、色温度、色相、チャンネルを調整し、カラーエフェクトを適用します。 --- # Adjust Colors {#adjust-colors} 明るさ、コントラスト、露出、彩度、色温度、ティント、色相回転、チャンネルごとのレベル、ワンクリックエフェクト (グレースケール、セピア、反転) を 1 つのエンドポイントにまとめた包括的なカラー調整ツールです。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` 画像ファイルと JSON の `settings` フィールドを含むマルチパートフォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | 明るさの調整 (-100 ~ 100) | | contrast | number | No | `0` | コントラストの調整 (-100 ~ 100) | | exposure | number | No | `0` | 露出 / 中間調ガンマ (-100 ~ 100) | | saturation | number | No | `0` | 色の彩度 (-100 ~ 100) | | temperature | number | No | `0` | ホワイトバランス: 寒色/青から暖色/オレンジ (-100 ~ 100) | | tint | number | No | `0` | ティントのシフト: 緑からマゼンタ (-100 ~ 100) | | hue | number | No | `0` | 色相回転 (度) (-180 ~ 180) | | sharpness | number | No | `0` | シャープ化の強度 (0 ~ 100) | | red | number | No | `100` | 赤チャンネルのレベル (0 ~ 200、100 = 変更なし) | | green | number | No | `100` | 緑チャンネルのレベル (0 ~ 200、100 = 変更なし) | | blue | number | No | `100` | 青チャンネルのレベル (0 ~ 200、100 = 変更なし) | | effect | string | No | `"none"` | カラーエフェクト: `none`、`grayscale`、`sepia`、`invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` 暖かみのあるヴィンテージな見た目を適用する: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * すべてのパラメータはニュートラルな値がデフォルトになっているため、必要な項目だけを調整できます。 * 調整は次の順序で適用されます: 明るさ、コントラスト、露出、彩度/色相、色温度/ティント、シャープネス、チャンネル、エフェクト。 * 色温度は、青-オレンジ軸および緑-マゼンタ軸で 3x3 の色再結合行列を使用します。 * 露出は Sharp のガンマ関数にマッピングされます (正の値は中間調を明るくし、負の値は暗くします)。 * このエンドポイントはレガシーパス `/api/v1/tools/image/brightness-contrast`、`/api/v1/tools/image/saturation`、`/api/v1/tools/image/color-channels`、`/api/v1/tools/image/color-effects` でも応答します。すべて同じスキーマを使用します。 * 出力形式は入力形式と一致します。HEIC、RAW、PSD、SVG の入力は処理前に自動的にデコードされます。 --- --- url: https://docs.snapotter.com/ko/tools/image/adjust-colors.md description: 밝기, 대비, 채도, 색온도, 색조, 채널을 조정하고 색상 효과를 적용합니다. --- # Adjust Colors {#adjust-colors} 밝기, 대비, 노출, 채도, 색온도, 틴트, 색조 회전, 채널별 레벨, 원클릭 효과(회색조, 세피아, 반전)를 단일 엔드포인트에서 결합한 종합 색상 조정 도구입니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` 이미지 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | brightness | number | 아니요 | `0` | 밝기 조정 (-100 ~ 100) | | contrast | number | 아니요 | `0` | 대비 조정 (-100 ~ 100) | | exposure | number | 아니요 | `0` | 노출 / 중간톤 감마 (-100 ~ 100) | | saturation | number | 아니요 | `0` | 색상 채도 (-100 ~ 100) | | temperature | number | 아니요 | `0` | 화이트 밸런스: 차가운/파랑에서 따뜻한/주황 (-100 ~ 100) | | tint | number | 아니요 | `0` | 틴트 시프트: 초록에서 마젠타 (-100 ~ 100) | | hue | number | 아니요 | `0` | 색조 회전 각도 (-180 ~ 180) | | sharpness | number | 아니요 | `0` | 선명도 강도 (0 ~ 100) | | red | number | 아니요 | `100` | 빨강 채널 레벨 (0 ~ 200, 100 = 변경 없음) | | green | number | 아니요 | `100` | 초록 채널 레벨 (0 ~ 200, 100 = 변경 없음) | | blue | number | 아니요 | `100` | 파랑 채널 레벨 (0 ~ 200, 100 = 변경 없음) | | effect | string | 아니요 | `"none"` | 색상 효과: `none`, `grayscale`, `sepia`, `invert` | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` 따뜻한 빈티지 룩 적용: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## 참고 사항 {#notes} * 모든 매개변수는 중립 값을 기본값으로 하므로 필요한 것만 조정할 수 있습니다. * 조정은 다음 순서로 적용됩니다: 밝기, 대비, 노출, 채도/색조, 색온도/틴트, 선명도, 채널, 효과. * 색온도는 파랑-주황 및 초록-마젠타 축에서 3x3 색상 재결합 행렬을 사용합니다. * 노출은 Sharp의 감마 함수에 매핑됩니다(양수는 중간톤을 밝게, 음수는 어둡게). * 이 엔드포인트는 레거시 경로 `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels`, `/api/v1/tools/image/color-effects`에서도 응답합니다. 모두 동일한 스키마를 사용합니다. * 출력 형식은 입력 형식과 일치합니다. HEIC, RAW, PSD, SVG 입력은 처리 전에 자동으로 디코딩됩니다. --- --- url: https://docs.snapotter.com/th/tools/image/adjust-colors.md description: ปรับความสว่าง, คอนทราสต์, ความอิ่มตัว, อุณหภูมิ, สี, แชนเนล และใช้เอฟเฟกต์สี --- # Adjust Colors {#adjust-colors} เครื่องมือปรับสีแบบครอบคลุมที่รวมความสว่าง, คอนทราสต์, การเปิดรับแสง, ความอิ่มตัว, อุณหภูมิ, โทนสี, การหมุนเฉดสี, ระดับต่อแชนเนล และเอฟเฟกต์แบบคลิกเดียว (ขาวดำ, ซีเปีย, กลับสี) ไว้ในเอนด์พอยต์เดียว ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` รับข้อมูลแบบ multipart form data พร้อมไฟล์รูปภาพและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | การปรับความสว่าง (-100 ถึง 100) | | contrast | number | No | `0` | การปรับคอนทราสต์ (-100 ถึง 100) | | exposure | number | No | `0` | การเปิดรับแสง / แกมมาโทนกลาง (-100 ถึง 100) | | saturation | number | No | `0` | ความอิ่มตัวของสี (-100 ถึง 100) | | temperature | number | No | `0` | สมดุลแสงขาว: เย็น/น้ำเงิน ถึง อุ่น/ส้ม (-100 ถึง 100) | | tint | number | No | `0` | การปรับโทนสี: เขียว ถึง ม่วงแดง (-100 ถึง 100) | | hue | number | No | `0` | การหมุนเฉดสีเป็นองศา (-180 ถึง 180) | | sharpness | number | No | `0` | ความแรงของการเพิ่มความคม (0 ถึง 100) | | red | number | No | `100` | ระดับแชนเนลสีแดง (0 ถึง 200, 100 = ไม่เปลี่ยนแปลง) | | green | number | No | `100` | ระดับแชนเนลสีเขียว (0 ถึง 200, 100 = ไม่เปลี่ยนแปลง) | | blue | number | No | `100` | ระดับแชนเนลสีน้ำเงิน (0 ถึง 200, 100 = ไม่เปลี่ยนแปลง) | | effect | string | No | `"none"` | เอฟเฟกต์สี: `none`, `grayscale`, `sepia`, `invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` ใช้ลุควินเทจโทนอุ่น: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * พารามิเตอร์ทั้งหมดมีค่าเริ่มต้นเป็นค่ากลาง จึงปรับได้เฉพาะที่ต้องการ * การปรับจะใช้ตามลำดับนี้: ความสว่าง, คอนทราสต์, การเปิดรับแสง, ความอิ่มตัว/เฉดสี, อุณหภูมิ/โทนสี, ความคม, แชนเนล, เอฟเฟกต์ * อุณหภูมิใช้เมทริกซ์การรวมสีขนาด 3x3 บนแกนน้ำเงิน-ส้ม และเขียว-ม่วงแดง * การเปิดรับแสงแมปกับฟังก์ชันแกมมาของ Sharp (ค่าบวกทำให้โทนกลางสว่างขึ้น ค่าลบทำให้มืดลง) * เอนด์พอยต์นี้ยังตอบสนองที่พาธเดิม `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels` และ `/api/v1/tools/image/color-effects` ทั้งหมดใช้สคีมาเดียวกัน * รูปแบบเอาต์พุตตรงกับรูปแบบอินพุต อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนประมวลผล --- --- url: https://docs.snapotter.com/vi/tools/image/adjust-colors.md description: >- Điều chỉnh độ sáng, độ tương phản, độ bão hòa, nhiệt độ, sắc độ, kênh màu và áp dụng hiệu ứng màu. --- # Adjust Colors {#adjust-colors} Công cụ điều chỉnh màu toàn diện kết hợp độ sáng, độ tương phản, độ phơi sáng, độ bão hòa, nhiệt độ, tông màu, xoay sắc độ, mức độ theo từng kênh và các hiệu ứng một chạm (grayscale, sepia, invert) trong một endpoint duy nhất. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` Chấp nhận dữ liệu biểu mẫu multipart với một tệp hình ảnh và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | Điều chỉnh độ sáng (-100 đến 100) | | contrast | number | No | `0` | Điều chỉnh độ tương phản (-100 đến 100) | | exposure | number | No | `0` | Độ phơi sáng / gamma vùng trung (-100 đến 100) | | saturation | number | No | `0` | Độ bão hòa màu (-100 đến 100) | | temperature | number | No | `0` | Cân bằng trắng: lạnh/xanh dương đến ấm/cam (-100 đến 100) | | tint | number | No | `0` | Dịch tông màu: xanh lá đến hồng tím (-100 đến 100) | | hue | number | No | `0` | Xoay sắc độ theo độ (-180 đến 180) | | sharpness | number | No | `0` | Cường độ làm sắc nét (0 đến 100) | | red | number | No | `100` | Mức kênh đỏ (0 đến 200, 100 = không đổi) | | green | number | No | `100` | Mức kênh xanh lá (0 đến 200, 100 = không đổi) | | blue | number | No | `100` | Mức kênh xanh dương (0 đến 200, 100 = không đổi) | | effect | string | No | `"none"` | Hiệu ứng màu: `none`, `grayscale`, `sepia`, `invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` Áp dụng vẻ ngoài vintage ấm áp: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * Tất cả tham số mặc định về giá trị trung tính để bạn chỉ điều chỉnh những gì cần thiết. * Các điều chỉnh được áp dụng theo thứ tự này: độ sáng, độ tương phản, độ phơi sáng, độ bão hòa/sắc độ, nhiệt độ/tông màu, độ sắc nét, kênh màu, hiệu ứng. * Nhiệt độ dùng một ma trận tái kết hợp màu 3x3 trên các trục xanh dương-cam và xanh lá-hồng tím. * Độ phơi sáng ánh xạ tới hàm gamma của Sharp (giá trị dương làm sáng vùng trung, giá trị âm làm tối chúng). * Endpoint này cũng phản hồi tại các đường dẫn cũ `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels` và `/api/v1/tools/image/color-effects`. Tất cả đều dùng cùng một schema. * Định dạng đầu ra khớp với định dạng đầu vào. Các đầu vào HEIC, RAW, PSD và SVG được tự động giải mã trước khi xử lý. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/adjust-colors.md description: 调整亮度、对比度、饱和度、色温、色相、通道,并应用色彩效果。 --- # Adjust Colors {#adjust-colors} 综合性的色彩调整工具,在单一端点中集合了亮度、对比度、曝光、饱和度、色温、着色、色相旋转、逐通道级别以及一键效果(灰度、棕褐、反相)。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` 接受包含图像文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | 否 | `0` | 亮度调整(-100 到 100) | | contrast | number | 否 | `0` | 对比度调整(-100 到 100) | | exposure | number | 否 | `0` | 曝光 / 中间调伽马(-100 到 100) | | saturation | number | 否 | `0` | 色彩饱和度(-100 到 100) | | temperature | number | 否 | `0` | 白平衡:冷/蓝到暖/橙(-100 到 100) | | tint | number | 否 | `0` | 着色偏移:绿到品红(-100 到 100) | | hue | number | 否 | `0` | 色相旋转(角度,-180 到 180) | | sharpness | number | 否 | `0` | 锐化强度(0 到 100) | | red | number | 否 | `100` | 红色通道级别(0 到 200,100 = 不变) | | green | number | 否 | `100` | 绿色通道级别(0 到 200,100 = 不变) | | blue | number | 否 | `100` | 蓝色通道级别(0 到 200,100 = 不变) | | effect | string | 否 | `"none"` | 色彩效果:`none`、`grayscale`、`sepia`、`invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` 应用温暖的复古效果: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * 所有参数都默认为中性值,因此你只需调整所需的部分。 * 调整按以下顺序应用:亮度、对比度、曝光、饱和度/色相、色温/着色、锐化、通道、效果。 * 色温在蓝橙轴和绿品红轴上使用 3x3 色彩重组矩阵。 * 曝光映射到 Sharp 的伽马函数(正值提亮中间调,负值压暗它们)。 * 此端点也响应旧路径 `/api/v1/tools/image/brightness-contrast`、`/api/v1/tools/image/saturation`、`/api/v1/tools/image/color-channels` 和 `/api/v1/tools/image/color-effects`。它们都使用相同的 schema。 * 输出格式与输入格式一致。HEIC、RAW、PSD 和 SVG 输入在处理前会自动解码。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/adjust-colors.md description: 調整亮度、對比、飽和度、色溫、色相、色版,並套用色彩效果。 --- # Adjust Colors {#adjust-colors} 完整的色彩調整工具,在單一端點中整合了亮度、對比、曝光、飽和度、色溫、色調、色相旋轉、各色版色階,以及一鍵效果(灰階、懷舊、反相)。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` 接受包含影像檔案及 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | 亮度調整(-100 至 100) | | contrast | number | No | `0` | 對比調整(-100 至 100) | | exposure | number | No | `0` | 曝光 / 中間調 gamma(-100 至 100) | | saturation | number | No | `0` | 色彩飽和度(-100 至 100) | | temperature | number | No | `0` | 白平衡:冷/藍到暖/橙(-100 至 100) | | tint | number | No | `0` | 色調偏移:綠到洋紅(-100 至 100) | | hue | number | No | `0` | 色相旋轉角度(-180 至 180) | | sharpness | number | No | `0` | 銳化強度(0 至 100) | | red | number | No | `100` | 紅色版色階(0 至 200,100 = 不變) | | green | number | No | `100` | 綠色版色階(0 至 200,100 = 不變) | | blue | number | No | `100` | 藍色版色階(0 至 200,100 = 不變) | | effect | string | No | `"none"` | 色彩效果:`none`、`grayscale`、`sepia`、`invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` 套用溫暖的復古風格: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * 所有參數預設為中性值,因此你可以只調整需要的項目。 * 調整會依此順序套用:亮度、對比、曝光、飽和度/色相、色溫/色調、銳化、色版、效果。 * 色溫使用 3x3 色彩重組矩陣,作用於藍橙軸與綠洋紅軸。 * 曝光對應到 Sharp 的 gamma 函式(正值提亮中間調,負值壓暗中間調)。 * 此端點也回應舊版路徑 `/api/v1/tools/image/brightness-contrast`、`/api/v1/tools/image/saturation`、`/api/v1/tools/image/color-channels` 及 `/api/v1/tools/image/color-effects`。全部使用相同的結構描述。 * 輸出格式會與輸入格式相符。HEIC、RAW、PSD 及 SVG 輸入會在處理前自動解碼。 --- --- url: https://docs.snapotter.com/nl/tools/image/crop.md description: Snijd afbeeldingen bij door een gebied met positie en afmetingen op te geven. --- # Afbeelding bijsnijden {#crop} Snijd afbeeldingen bij door een rechthoekig gebied te definiëren met positie en grootte. Ondersteunt zowel pixel- als percentage-eenheden. ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/crop` Accepteert multipart-formuliergegevens met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | left | number | Ja | - | X-offset van het uitsnijgebied (vanaf de linkerrand) | | top | number | Ja | - | Y-offset van het uitsnijgebied (vanaf de bovenrand) | | width | number | Ja | - | Breedte van het uitsnijgebied | | height | number | Ja | - | Hoogte van het uitsnijgebied | | unit | string | Nee | `"px"` | Eenheid voor de waarden: `px` of `percent` | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 100, "top": 50, "width": 800, "height": 600}' ``` Bijsnijden met percentagewaarden: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 10, "top": 10, "width": 80, "height": 80, "unit": "percent"}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1200000 } ``` ## Opmerkingen {#notes} * Het uitsnijgebied moet binnen de grenzen van de afbeelding vallen. Als het gebied buiten de afbeelding valt, mislukt het verzoek. * Bij gebruik van de eenheid `percent` vertegenwoordigen de waarden percentages van de afbeeldingsafmetingen (bijv. `left: 10` betekent 10% vanaf de linkerrand). * Het uitvoerformaat komt overeen met het invoerformaat. * De EXIF-oriëntatie wordt automatisch toegepast vóór het bijsnijden, zodat de coördinaten overeenkomen met de visueel correcte oriëntatie. --- --- url: https://docs.snapotter.com/nl/tools/image/compress.md description: >- Verklein de bestandsgrootte van afbeeldingen op basis van kwaliteitsniveau of naar een doelbestandsgrootte. --- # Afbeelding comprimeren {#compress} Verklein de bestandsgrootte van afbeeldingen door een kwaliteitsniveau of een doelbestandsgrootte in kilobytes op te geven. De tool gebruikt iteratieve binaire zoekopdrachten om doelgroottes nauwkeurig te bereiken. ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/compress` Accepteert multipart-formuliergegevens met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | mode | string | Nee | `"quality"` | Compressiemodus: `quality` of `targetSize` | | quality | number | Nee | `80` | Kwaliteitsniveau (1-100). Gebruikt wanneer de modus `quality` is. | | targetSizeKb | number | Nee | - | Doelbestandsgrootte in kilobytes. Gebruikt wanneer de modus `targetSize` is. | ## Voorbeeldverzoek {#example-request} Comprimeren naar kwaliteit 60: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimeren naar een doelgrootte van 200 KB: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Opmerkingen {#notes} * In de modus `quality` leveren lagere waarden kleinere bestanden op met meer compressieartefacten. Een waarde van 80 is een goede standaard voor webgebruik. * In de modus `targetSize` voert de engine iteratieve compressie uit om zo dicht mogelijk bij het doel te komen zonder dit te overschrijden. * Het uitvoerformaat komt overeen met het invoerformaat. De compressie wordt toegepast op de eigen codering van het formaat (bijv. JPEG-kwaliteit voor JPEG-bestanden, WebP-kwaliteit voor WebP-bestanden). * Als de standaardkwaliteit (80) acceptabel is, kun je de parameter `quality` volledig weglaten. --- --- url: https://docs.snapotter.com/nl/tools/image/convert.md description: >- Converteer afbeeldingen tussen formaten, waaronder moderne formaten zoals AVIF, JXL en HEIC. --- # Afbeelding converteren {#convert} Converteer afbeeldingen tussen formaten. Ondersteunt gangbare webformaten en gespecialiseerde formaten zoals HEIC, JXL, BMP, ICO, JP2, QOI en PSD. ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/convert` Accepteert multipart-formuliergegevens met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Doelformaat: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | Nee | - | Uitvoerkwaliteit (1-100). Van toepassing op verliesgevende formaten zoals jpg, webp, avif, heic. | ## Ondersteunde uitvoerformaten {#supported-output-formats} | Formaat | Type | Opmerkingen | |--------|------|-------| | jpg | Verliesgevend | JPEG, beste compatibiliteit | | png | Verliesvrij | Ondersteunt transparantie | | webp | Beide | Modern webformaat, goede compressie | | avif | Verliesgevend | Next-gen-formaat, uitstekende compressie | | tiff | Beide | Print-/publicatieworkflows | | gif | Verliesvrij | Beperkt tot 256 kleuren | | heic / heif | Verliesgevend | Formaat van het Apple-ecosysteem | | jxl | Beide | JPEG XL, next-gen-formaat | | bmp | Verliesvrij | Ongecomprimeerde bitmap | | ico | Verliesvrij | Windows-pictogramformaat | | jp2 | Verliesgevend | JPEG 2000 | | qoi | Verliesvrij | Quite OK Image-formaat | | psd | Gelaagd | Adobe Photoshop (vereist ImageMagick) | | ppm | Verliesvrij | Portable Pixmap (PPM/PGM/PBM) | | eps | Vector | Encapsulated PostScript | | tga | Verliesvrij | Targa-afbeeldingsformaat | ## Voorbeeldverzoek {#example-request} Naar WebP converteren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` Naar PNG converteren (verliesvrij): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Opmerkingen {#notes} * De extensie van de uitvoerbestandsnaam wordt automatisch bijgewerkt zodat deze overeenkomt met het doelformaat. * SVG-invoer wordt vóór de conversie gerasterd op 300 DPI. * PSD-conversie vereist dat ImageMagick op de server is geïnstalleerd. * BMP, EPS, ICO, JP2, JXL, PPM, QOI en TGA gebruiken gespecialiseerde CLI-encoders en omzeilen de Sharp-verwerking. * HEIC/HEIF-codering gebruikt de HEIC-encoderbibliotheek van het systeem. * De invoerformaten zijn breed: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, enz.), PSD, SVG, BMP en meer. --- --- url: https://docs.snapotter.com/nl/tools/image/rotate.md description: Draai afbeeldingen onder elke hoek en spiegel ze horizontaal of verticaal. --- # Afbeelding draaien & spiegelen {#rotate-flip} Draai afbeeldingen onder een willekeurige hoek en/of spiegel ze horizontaal of verticaal. Draai- en spiegelbewerkingen kunnen in één verzoek worden gecombineerd. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/rotate` Accepteert multipart form data met een afbeeldingsbestand en een JSON `settings`-veld. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | angle | number | Nee | `0` | Draaihoek in graden (met de klok mee). Accepteert elke numerieke waarde. | | horizontal | boolean | Nee | `false` | De afbeelding horizontaal spiegelen | | vertical | boolean | Nee | `false` | De afbeelding verticaal spiegelen | ## Example Request {#example-request} 90 graden met de klok mee draaien: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 90}' ``` Horizontaal spiegelen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"horizontal": true}' ``` Draaien en spiegelen samen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 45, "vertical": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Notes {#notes} * De draaiing wordt eerst toegepast, daarna de spiegelbewerkingen. * Draaiingen die geen veelvoud van 90 graden zijn (bijv. 45 graden) vergroten het canvas om de gedraaide afbeelding te laten passen, met een transparante of zwarte vulling afhankelijk van het uitvoerformaat. * Veelgebruikte waarden: 90, 180, 270 voor kwartslagdraaiingen. * EXIF-oriëntatie wordt automatisch toegepast voordat er verwerkt wordt, dus de draaiing is relatief ten opzichte van de visuele oriëntatie. --- --- url: https://docs.snapotter.com/nl/tools/image/resize.md description: Verklein of vergroot afbeeldingen op pixels, percentage of met fit-modi. --- # Afbeelding herschalen {#resize} Pas de grootte van afbeeldingen aan door exacte pixelafmetingen op te geven, een percentageschaalfactor of een fit-modus die bepaalt hoe de afbeelding zich aanpast aan de doelafmetingen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/resize` Accepteert multipart form data met een afbeeldingsbestand en een JSON `settings`-veld. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | width | integer | Nee | - | Doelbreedte in pixels (max. 16383) | | height | integer | Nee | - | Doelhoogte in pixels (max. 16383) | | fit | string | Nee | `"contain"` | Hoe de afbeelding in de afmetingen past: `contain`, `cover`, `fill`, `inside`, `outside` | | withoutEnlargement | boolean | Nee | `false` | Opschalen voorkomen als de afbeelding kleiner is dan het doel | | percentage | number | Nee | - | Schalen met een percentage (bijv. 50 voor de helft van de grootte) | Ten minste een van `width`, `height` of `percentage` moet worden opgegeven. ### Fit Modes {#fit-modes} * **contain** - Pas de grootte aan zodat deze binnen de afmetingen past, met behoud van de beeldverhouding (kan lege ruimte overlaten) * **cover** - Pas de grootte aan zodat de afmetingen worden gevuld, met behoud van de beeldverhouding (kan bijsnijden) * **fill** - Uitrekken om exact overeen te komen met de afmetingen (negeert de beeldverhouding) * **inside** - Zoals `contain`, maar verkleint alleen, vergroot nooit * **outside** - Zoals `cover`, maar verkleint alleen, vergroot nooit ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"width": 800, "height": 600, "fit": "contain"}' ``` Grootte aanpassen met een percentage: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"percentage": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 980000 } ``` ## Notes {#notes} * De maximale afmeting is 16383 pixels op beide assen (limiet van Sharp/libvips). * Het uitvoerformaat komt overeen met het invoerformaat. HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd voordat deze wordt verwerkt. * EXIF-oriëntatie wordt automatisch toegepast voordat de grootte wordt aangepast. * De vlag `withoutEnlargement` is handig voor batchverwerking waarbij sommige afbeeldingen mogelijk al kleiner zijn dan het doel. --- --- url: https://docs.snapotter.com/nl/tools/image/image-to-base64.md description: >- Converteer afbeeldingen naar base64 data-URI's om in te bedden in HTML, CSS en meer. --- # Afbeelding naar Base64 {#image-to-base64} Converteer een of meer afbeeldingen naar base64-gecodeerde strings en data-URI's. Ondersteunt optionele formaatconversie, kwaliteitsbeheer en vergroten/verkleinen. Handig om afbeeldingen rechtstreeks in te bedden in HTML, CSS, JSON of e-mailsjablonen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-to-base64` Accepteert multipart-formuliergegevens met een of meer afbeeldingsbestanden en een optioneel JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | outputFormat | string | Nee | `"original"` | Converteren vóór codering: `original`, `jpeg`, `png`, `webp`, `avif`, `jxl` | | quality | number | Nee | `80` | Uitvoerkwaliteit voor lossy formaten (1 tot 100) | | maxWidth | number | Nee | `0` | Maximale breedte in pixels (0 = niet vergroten/verkleinen, zal niet vergroten) | | maxHeight | number | Nee | `0` | Maximale hoogte in pixels (0 = niet vergroten/verkleinen, zal niet vergroten) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon.png" \ -F 'settings={"outputFormat": "webp", "quality": 80, "maxWidth": 200}' ``` Meerdere bestanden: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon1.png" \ -F "file=@icon2.png" \ -F "file=@icon3.png" \ -F 'settings={"outputFormat": "original"}' ``` ## Voorbeeldantwoord {#example-response} ```json { "results": [ { "filename": "icon.png", "mimeType": "image/webp", "width": 200, "height": 200, "originalSize": 45000, "encodedSize": 28800, "overheadPercent": -36.0, "base64": "UklGRlYAAABXRUJQ...", "dataUri": "data:image/webp;base64,UklGRlYAAABXRUJQ..." } ], "errors": [] } ``` ## Antwoordvelden {#response-fields} | Veld | Type | Beschrijving | |-------|------|-------------| | results | array | Succesvol geconverteerde afbeeldingen | | errors | array | Afbeeldingen die niet verwerkt konden worden (met bestandsnaam en foutmelding) | ### Result-object {#result-object} | Veld | Type | Beschrijving | |-------|------|-------------| | filename | string | Oorspronkelijke bestandsnaam | | mimeType | string | MIME-type van de gecodeerde uitvoer | | width | number | Uiteindelijke breedte in pixels (na eventueel vergroten/verkleinen) | | height | number | Uiteindelijke hoogte in pixels (na eventueel vergroten/verkleinen) | | originalSize | number | Oorspronkelijke bestandsgrootte in bytes | | encodedSize | number | Grootte van de base64-string in bytes | | overheadPercent | number | Procentueel groottevers chil ten opzichte van het origineel (positief = groter, negatief = kleiner) | | base64 | string | Ruwe base64-gecodeerde afbeeldingsgegevens | | dataUri | string | Volledige data-URI klaar voor gebruik in `src`-attributen | ## Opmerkingen {#notes} * Base64-codering vergroot de grootte doorgaans met ongeveer 33% in vergelijking met het binaire bestand. Het veld `overheadPercent` toont het werkelijke verschil. * Wanneer `outputFormat` `"original"` is, worden HEIC/HEIF-bestanden geconverteerd naar JPEG (aangezien browsers HEIC niet kunnen weergeven in data-URI's). * De opties `maxWidth` en `maxHeight` verkleinen met `fit: inside` en `withoutEnlargement`, zodat afbeeldingen kleiner dan de opgegeven afmetingen niet worden vergroot. * Meerdere bestanden kunnen in één verzoek worden verwerkt. Elk bestand wordt onafhankelijk verwerkt, en fouten verhinderen niet dat andere bestanden slagen. * SVG-bestanden worden doorgegeven als `image/svg+xml` zonder hercodering (tenzij een formaatconversie wordt aangevraagd). * Dit is een alleen-lezen endpoint. Het produceert geen downloadbaar bestand of `jobId`. De base64-gegevens worden rechtstreeks in de antwoordbody geretourneerd. --- --- url: https://docs.snapotter.com/nl/tools/image/image-to-pdf.md description: >- Combineer een of meer afbeeldingen tot een PDF-document met opties voor paginagrootte, oriëntatie en doelbestandsgrootte. --- # Afbeelding naar PDF {#image-to-pdf} Combineer een of meer afbeeldingen tot een PDF-document. Ondersteunt meerdere paginagroottes, oriëntaties, marges en optionele doelbestandsgrootte via kwaliteitsaanpassing. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-to-pdf` Accepteert multipart-formuliergegevens met een of meer afbeeldingsbestanden en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | pageSize | string | Nee | `"A4"` | Paginagrootte: `A4`, `Letter`, `A3`, `A5` | | orientation | string | Nee | `"portrait"` | Pagina-oriëntatie: `portrait` of `landscape` | | margin | number | Nee | `20` | Paginamarge in punten (0-500) | | targetSize | object | Nee | - | Beperking van de doelbestandsgrootte (zie hieronder) | | collate | boolean | Nee | `true` | Combineer alle afbeeldingen tot één PDF. Indien `false`, maak één PDF per afbeelding. | ### Target Size-object {#target-size-object} | Veld | Type | Vereist | Beschrijving | |-------|------|----------|-------------| | value | number | Ja | Waarde van de doelgrootte | | unit | string | Ja | Eenheid: `KB` of `MB` | De minimale doelgrootte is 50 KB. ## Voorbeeldverzoek {#example-request} Basis-PDF met meerdere afbeeldingen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page1.jpg" \ -F "file=@page2.jpg" \ -F "file=@page3.jpg" \ -F 'settings={"pageSize": "A4", "orientation": "portrait", "margin": 20}' ``` Met doelbestandsgrootte: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@scan1.jpg" \ -F "file=@scan2.jpg" \ -F 'settings={"pageSize": "Letter", "targetSize": {"value": 2, "unit": "MB"}}' ``` Eén PDF per afbeelding: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F 'settings={"collate": false}' ``` ## Voorbeeldantwoord (gecollationeerd) {#example-response-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 5000000, "processedSize": 1200000, "pages": 3 } ``` ## Voorbeeldantwoord (niet-gecollationeerd) {#example-response-non-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.zip", "originalSize": 5000000, "processedSize": 2400000, "pages": 2, "collated": false } ``` ## Voorbeeldantwoord (met doelgrootte) {#example-response-with-target-size} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 10000000, "processedSize": 2000000, "pages": 5, "compression": { "targetRequested": 2097152, "targetMet": true, "jpegQuality": 72 } } ``` ## Opmerkingen {#notes} * Afbeeldingen worden op de pagina gecentreerd en geschaald om binnen de marges te passen met behoud van de beeldverhouding. Afbeeldingen worden nooit vergroot. * Wanneer `collate` `false` is, wordt elke afbeelding een afzonderlijk PDF-bestand, en de download is een ZIP-archief met alle PDF's. * De functie voor doelgrootte gebruikt iteratief binair zoeken over JPEG-kwaliteitsniveaus (10-95) om de beste kwaliteit te vinden die binnen het budget past. * Transparante afbeeldingen worden samengevoegd op wit voordat ze in de PDF worden ingebed. * Ondersteunde invoerformaten: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW, PSD, SVG en meer. * EXIF-oriëntatie wordt automatisch toegepast vóór het inbedden. --- --- url: https://docs.snapotter.com/nl/tools/image/vectorize.md description: >- Rasterafbeeldingen converteren naar SVG met zwart-wit (potrace) en volledige-kleur, meerlaagse vectorisatie. --- # Afbeelding naar SVG {#image-to-svg} Vectoriseer rasterafbeeldingen naar SVG met traceeralgoritmen. Ondersteunt zwart-wittracering (potrace) en volledige-kleur, meerlaagse vectorisatie. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/vectorize` ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | colorMode | string | Nee | `"bw"` | Traceermodus: `bw` (zwart-wit) of `color` (meerkleurige lagen) | | threshold | number | Nee | 128 | Helderheidsdrempel voor de zwart-witmodus (0 tot 255). Pixels daaronder worden zwart. | | colorPrecision | number | Nee | 6 | Precisie van kleurkwantisatie voor de kleurmodus (1 tot 16). Hogere waarden produceren meer onderscheidende kleurlagen. | | layerDifference | number | Nee | 6 | Minimaal kleurverschil tussen lagen in de kleurmodus (1 tot 128) | | filterSpeckle | number | Nee | 4 | Minimale oppervlakte voor getraceerde vormen in pixels (1 tot 256). Verwijdert ruis/spikkels. | | pathMode | string | Nee | `"spline"` | Padvergladding: `none` (gekarteld), `polygon` (rechte segmenten), `spline` (vloeiende curves) | | cornerThreshold | number | Nee | 60 | Hoekdrempel voor hoekdetectie in de kleurmodus (0 tot 180 graden) | | invert | boolean | Nee | `false` | De afbeelding vóór het traceren inverteren (zwart/wit omwisselen) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@logo.png" \ -F 'settings={"colorMode":"bw","threshold":128,"filterSpeckle":4,"pathMode":"spline"}' ``` ### Kleurvectorisatie {#color-vectorization} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@illustration.png" \ -F 'settings={"colorMode":"color","colorPrecision":8,"layerDifference":6,"filterSpeckle":4}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logo.svg", "originalSize": 45678, "processedSize": 12345 } ``` ## Opmerkingen {#notes} * De uitvoer is altijd een SVG-bestand, ongeacht het invoerformaat. * Ondersteunt HEIC-, RAW-, PSD- en SVG-invoerformaten (automatisch gedecodeerd naar raster vóór het traceren). * De zwart-witmodus gebruikt het potrace-algoritme. De afbeelding wordt eerst omgezet naar grijswaarden en vervolgens met een drempel gezet naar puur zwart/wit voordat er wordt getraceerd. * De kleurmodus gebruikt een meerlaagse aanpak: de afbeelding wordt gekwantiseerd in kleurlagen, elk apart getraceerd en gestapeld in de SVG-uitvoer. * Lagere `filterSpeckle`-waarden behouden meer detail, maar produceren grotere SVG-bestanden met meer paden. * De instelling `pathMode` heeft een aanzienlijke invloed op de bestandsgrootte: `none` produceert de meeste paden, `spline` produceert de vloeiendste (en meestal kleinste) uitvoer. * Gebruik voor de beste resultaten met logo's en pictogrammen de zwart-witmodus met een schone invoer met hoog contrast. Gebruik voor foto's of illustraties de kleurmodus met een hogere `colorPrecision`. --- --- url: https://docs.snapotter.com/nl/tools/image/upscale.md description: >- Afbeeldingen 2x tot 4x opschalen met Real-ESRGAN AI-superresolutie met behoud van fijne details. --- # Afbeelding Opschalen {#image-upscaling} AI-superresolutieverbetering met Real-ESRGAN. Schaalt afbeeldingen 2x-4x op met behoud van details. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/upscale` **Verwerking:** Asynchroon (retourneert 202, poll `/api/v1/jobs/{jobId}/progress` voor de status via SSE) **Modelbundel:** `upscale-enhance` (5-6 GB) ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Afbeeldingsbestand (multipart) | | scale | number | Nee | `2` | Opschaalfactor (bijv. 2, 3, 4) | | model | string | Nee | `"auto"` | Te gebruiken model (bijv. `auto`, specifieke modelnamen) | | faceEnhance | boolean | Nee | `false` | Pas gezichtsverbetering toe tijdens het opschalen | | denoise | number | Nee | `0` | Sterkte van ruisonderdrukking (0 = uit) | | format | string | Nee | `"auto"` | Uitvoerformaat: `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | Nee | `95` | Uitvoerkwaliteit (1-100) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Respons {#response} ### Eerste respons (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Voortgang (SSE op `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Eindresultaat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Opmerkingen {#notes} * Vereist dat de modelbundel `upscale-enhance` is geïnstalleerd (5-6 GB). * Gebruikt Real-ESRGAN indien beschikbaar; valt terug op Lanczos-interpolatie als het AI-model niet beschikbaar is. * De optie `faceEnhance` past GFPGAN-gezichtsherstel toe tijdens het opschalen voor een betere gezichtskwaliteit. * Voor uitvoerformaten die niet in de browser kunnen worden bekeken (HEIC, JXL, TIFF) wordt naast de hoofduitvoer een WebP-voorbeeld gegenereerd. * Ondersteunt HEIC-/HEIF-, RAW-, TGA-, PSD-, EXR- en HDR-invoerformaten via automatische decodering. --- --- url: https://docs.snapotter.com/nl/tools/image/image-pad.md description: >- Vul een afbeelding op tot een doelbeeldverhouding met een effen kleur, transparante of vervaagde achtergrond. --- # Afbeelding opvullen {#image-pad} Vul een afbeelding op tot een doelbeeldverhouding door er een effen kleur, transparante of vervaagde achtergrond omheen toe te voegen. Handig om afbeeldingen in vaste beeldverhoudingen te passen voor sociale media of print zonder bij te snijden. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-pad` Accepteert multipart-formuliergegevens met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | target | string | Nee | `"1:1"` | Doelbeeldverhouding: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` of `custom` | | ratioW | integer | Nee | `1` | Aangepaste verhoudingsbreedte (1-100, gebruikt wanneer target `custom` is) | | ratioH | integer | Nee | `1` | Aangepaste verhoudingshoogte (1-100, gebruikt wanneer target `custom` is) | | background | string | Nee | `"color"` | Achtergrondmodus: `color`, `transparent` of `blur` | | color | string | Nee | `"#ffffff"` | Achtergrondkleur in hex (wanneer background `color` is) | | padding | integer | Nee | `0` | Extra padding als percentage van het canvas (0-50) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 3100000 } ``` ## Opmerkingen {#notes} * De achtergrondmodus `blur` maakt een vervaagde kopie van de oorspronkelijke afbeelding als opvulling, wat een visueel samenhangend resultaat oplevert. * Bij gebruik van de achtergrond `transparent` wordt de uitvoer geconverteerd naar PNG om het alfakanaal te behouden. * Het uitvoerformaat komt overeen met het invoerformaat, tenzij er transparantie in het spel is. HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór de verwerking. * Stel `target` in op `custom` en geef `ratioW` en `ratioH` op voor willekeurige beeldverhoudingen (bijv. `ratioW: 3, ratioH: 2` voor 3:2). --- --- url: https://docs.snapotter.com/nl/tools/image/split.md description: >- Eén afbeelding opsplitsen in rastertegels op basis van rijen en kolommen of op pixelgrootte, geretourneerd als ZIP-archief. --- # Afbeelding splitsen {#image-splitting} Splits één afbeelding op in rastertegels op basis van het aantal kolommen/rijen of specifieke pixelafmetingen. Retourneert een ZIP-archief met alle tegels. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/split` ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | columns | integer | Nee | 3 | Aantal kolommen om in op te splitsen (1 tot 100) | | rows | integer | Nee | 3 | Aantal rijen om in op te splitsen (1 tot 100) | | tileWidth | integer | Nee | - | Tegelbreedte in pixels (min. 10). Overschrijft `columns` wanneer zowel `tileWidth` als `tileHeight` zijn ingesteld. | | tileHeight | integer | Nee | - | Tegelhoogte in pixels (min. 10). Overschrijft `rows` wanneer zowel `tileWidth` als `tileHeight` zijn ingesteld. | | outputFormat | string | Nee | `"original"` | Uitvoerformaat voor tegels: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | Nee | 90 | Uitvoerkwaliteit voor lossy formaten (1 tot 100) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Voorbeeldrespons {#example-response} De respons wordt rechtstreeks gestreamd als een ZIP-bestand met `Content-Type: application/zip`. De bestandsnaam volgt het patroon `split-.zip`. Elke tegel in de ZIP heet `_r_c.` (bijv. `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Opmerkingen {#notes} * Accepteert één afbeeldingsbestand. * Ondersteunt HEIC-, RAW-, PSD- en SVG-invoerformaten (automatisch gedecodeerd). * Wanneer zowel `tileWidth` als `tileHeight` zijn opgegeven, krijgen deze voorrang boven `columns`/`rows`. De rasterafmetingen worden berekend als `ceil(imageWidth / tileWidth)` en `ceil(imageHeight / tileHeight)`. * Randtegels (meest rechtse kolom, onderste rij) kunnen kleiner zijn dan de opgegeven tegelgrootte als de afbeeldingsafmetingen niet gelijkmatig deelbaar zijn. * De maximale rastergrootte is begrensd op 100x100 (10.000 tegels). * De respons streamt de ZIP rechtstreeks, dus er is geen JSON-responsbody. Gebruik `--output` met curl om het bestand op te slaan. --- --- url: https://docs.snapotter.com/nl/tools/image/sharpening.md description: >- Afbeeldingen verscherpen met adaptieve, unsharp mask- of high-passmethoden, met optionele ruisonderdrukking. --- # Afbeelding verscherpen {#sharpening} Geavanceerd verscherpingsgereedschap met drie methoden: adaptief (slim, randbewust), unsharp mask (klassiek radius/hoeveelheid) en high-pass (nadruk op textuur). Bevat ingebouwde ruisonderdrukking om verscherpingsartefacten te voorkomen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/sharpening` Accepteert multipart form data met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | method | string | Nee | `"adaptive"` | Verscherpingsalgoritme: `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | Nee | `1.0` | Adaptief: Gaussische sigma (0.5 tot 10) | | m1 | number | Nee | `1.0` | Adaptief: verscherping van vlakke gebieden (0 tot 10) | | m2 | number | Nee | `3.0` | Adaptief: verscherping van gekartelde gebieden (0 tot 20) | | x1 | number | Nee | `2.0` | Adaptief: drempel vlak/gekarteld (0 tot 10) | | y2 | number | Nee | `12` | Adaptief: maximale verscherping vlak (0 tot 50) | | y3 | number | Nee | `20` | Adaptief: maximale verscherping gekarteld (0 tot 50) | | amount | number | Nee | `100` | Unsharp mask: verscherpingshoeveelheid (0 tot 1000) | | radius | number | Nee | `1.0` | Unsharp mask: vervagingsradius in pixels (0.1 tot 5) | | threshold | number | Nee | `0` | Unsharp mask: minimaal helderheidsverschil om te verscherpen (0 tot 255) | | strength | number | Nee | `50` | High-pass: filtersterkte (0 tot 100) | | kernelSize | number | Nee | `3` | High-pass: grootte van de convolutiekernel (3 of 5) | | denoise | string | Nee | `"off"` | Ruisonderdrukking vóór verscherpen: `off`, `light`, `medium`, `strong` | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Unsharp mask met drempel om gladde gebieden te beschermen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Opmerkingen {#notes} * Alleen de parameters die relevant zijn voor de gekozen methode worden gebruikt. Bijvoorbeeld: `amount`, `radius` en `threshold` worden genegeerd wanneer `method` `adaptive` is. * De adaptieve methode gebruikt de ingebouwde adaptieve verscherping van Sharp met configureerbaar gedrag voor vlakke/gekartelde gebieden. * De optie `denoise` past ruisonderdrukking toe vóór het verscherpen om versterking van ruis/korrel te voorkomen. * High-passverscherping haalt fijne details naar voren door een vervaagde versie van het origineel af te trekken en dat vervolgens terug te mengen. * Het uitvoerformaat komt overeen met het invoerformaat. HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór verwerking. --- --- url: https://docs.snapotter.com/nl/tools/image/stitch.md description: >- Afbeeldingen naast elkaar, gestapeld of in een raster samenvoegen, met controle over uitlijning, tussenruimtes, randen en schaalmodus. --- # Afbeeldingen samenvoegen {#stitch-combine} Voeg meerdere afbeeldingen naast elkaar, verticaal gestapeld of gerangschikt in een raster samen. Ondersteunt uitlijning, tussenruimte, rand, hoekradius en meerdere schaalmodi. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/stitch` ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | direction | string | Nee | `"horizontal"` | Lay-outrichting: `horizontal`, `vertical`, `grid` | | gridColumns | integer | Nee | 2 | Aantal kolommen wanneer de richting `grid` is (2 tot 100) | | resizeMode | string | Nee | `"fit"` | Hoe afbeeldingen worden geschaald: `fit`, `original`, `stretch`, `crop` | | alignment | string | Nee | `"center"` | Uitlijning op de dwarsas: `start`, `center`, `end` | | gap | number | Nee | 0 | Tussenruimte tussen afbeeldingen in pixels (0 tot 1000) | | border | number | Nee | 0 | Breedte van de buitenrand in pixels (0 tot 500) | | cornerRadius | number | Nee | 0 | Hoekradius toegepast op de uiteindelijke uitvoer (0 tot 500) | | backgroundColor | string | Nee | `"#FFFFFF"` | Achtergrond-/randkleur als hex (bijv. `#FF0000`) | | format | string | Nee | `"png"` | Uitvoerformaat: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Nee | 90 | Uitvoerkwaliteit (1 tot 100) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/stitch \ -F "file=@image1.png" \ -F "file=@image2.png" \ -F "file=@image3.png" \ -F 'settings={"direction":"horizontal","resizeMode":"fit","gap":10,"backgroundColor":"#FFFFFF","format":"png"}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stitch.png", "originalSize": 1234567, "processedSize": 987654 } ``` ## Opmerkingen {#notes} * Vereist ten minste 2 afbeeldingen. Upload meerdere afbeeldingsbestanden in het multipart-verzoek. * Ondersteunt HEIC-, RAW-, PSD- en SVG-invoerformaten (automatisch gedecodeerd). * Schaalmodi: * `fit` - Schaal afbeeldingen zodat ze overeenkomen met de kleinste afmeting langs de samenvoegas. * `original` - Behoud de oorspronkelijke afmetingen (kan ongelijke randen opleveren). * `stretch` - Dwing afbeeldingen om overeen te komen met de kleinste afmeting zonder de beeldverhouding te behouden. * `crop` - Snijd afbeeldingen dekkend bij om overeen te komen met de kleinste afmeting. * In de modus `grid` worden cellen op de mediane afmetingen van alle afbeeldingen geschaald. * De `cornerRadius` wordt toegepast op de gehele uiteindelijke uitvoer, niet op individuele afbeeldingen. * De canvasgrootte wordt begrensd door de serverconfiguratie `MAX_CANVAS_PIXELS` om geheugenuitputting te voorkomen. --- --- url: https://docs.snapotter.com/nl/tools/image/compare.md description: >- Vergelijk twee afbeeldingen naast elkaar met een verschilvisualisatie op pixelniveau en een gelijkeniscore. --- # Afbeeldingen vergelijken {#image-compare} Upload twee afbeeldingen om een verschilkaart op pixelniveau en een numeriek gelijkenispercentage te berekenen. De uitvoer is een verschilafbeelding die gewijzigde gebieden in het rood markeert. ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/compare` Accepteert multipart-formuliergegevens met **twee** afbeeldingsbestanden. Er is geen instellingenveld nodig. ## Parameters {#parameters} Deze tool heeft geen configureerbare parameters. Upload precies twee afbeeldingsbestanden. | Veld | Type | Vereist | Beschrijving | |-------|------|----------|-------------| | file (eerste) | file | Ja | De eerste afbeelding | | file (tweede) | file | Ja | De tweede afbeelding | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Antwoordvelden {#response-fields} | Veld | Type | Beschrijving | |-------|------|-------------| | jobId | string | Taakidentificatie voor het downloaden van de verschilafbeelding | | similarity | number | Procentuele gelijkenis tussen de twee afbeeldingen (0 tot 100) | | dimensions | object | Breedte en hoogte gebruikt voor de vergelijking | | downloadUrl | string | URL om de gegenereerde verschilafbeelding te downloaden | | originalSize | number | Gecombineerde grootte van beide invoerafbeeldingen in bytes | | processedSize | number | Grootte van de verschiluitvoerafbeelding in bytes | ## Opmerkingen {#notes} * Beide afbeeldingen worden vóór de vergelijking naar dezelfde afmetingen verkleind (het maximum van elke as). * De verschilafbeelding markeert verschillen in het rood met een dekking die evenredig is aan de mate van verandering. Identieke of vrijwel identieke pixels (verschil < 10) worden weergegeven als semitransparante versies van het origineel. * De gelijkenis wordt berekend als de inverse van het gemiddelde pixelverschil over alle pixels, uitgedrukt als percentage. * Een gelijkenis van 100% betekent dat de afbeeldingen pixel-identiek zijn (bij de vergelijkingsresolutie). * De verschiluitvoer is altijd in PNG-formaat, ongeacht de invoerformaten. * Beide afbeeldingen worden gevalideerd en gedecodeerd (HEIC, RAW, PSD, SVG worden ondersteund) vóór de vergelijking. * De EXIF-oriëntatie wordt automatisch toegepast op beide afbeeldingen vóór de verwerking. --- --- url: https://docs.snapotter.com/nl/tools/image/compose.md description: >- Leg afbeeldingen over elkaar met positie, dekking en overvloeimodi voor compositie. --- # Afbeeldingscompositie {#image-composition} Leg een overlay-afbeelding over een basisafbeelding met configureerbare positie, dekking en overvloeimodus. Nuttig voor het samenstellen van logo's, graphics of het combineren van meerdere afbeeldingen. ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/compose` Accepteert multipart-formuliergegevens met **twee** afbeeldingsbestanden en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | x | number | Nee | `0` | Horizontale offset van de overlay vanaf de linkerbovenhoek in pixels (min. 0) | | y | number | Nee | `0` | Verticale offset van de overlay vanaf de linkerbovenhoek in pixels (min. 0) | | opacity | number | Nee | `100` | Dekkingspercentage van de overlay (0 tot 100) | | blendMode | string | Nee | `"over"` | Overvloeimodus voor compositie | ### Overvloeimodi {#blend-modes} | Waarde | Beschrijving | |-------|-------------| | `over` | Normale overlay (standaard) | | `multiply` | Donkerder maken door pixelwaarden te vermenigvuldigen | | `screen` | Lichter maken door te inverteren, te vermenigvuldigen en opnieuw te inverteren | | `overlay` | Combineert multiply en screen op basis van de helderheid van de basis | | `darken` | Houd de donkerste pixel van elke laag | | `lighten` | Houd de lichtste pixel van elke laag | | `hard-light` | Sterke contrastoverlay | | `soft-light` | Subtiele contrastoverlay | | `difference` | Absoluut verschil tussen lagen | | `exclusion` | Vergelijkbaar met difference maar met lager contrast | ### Bestandsvelden {#file-fields} | Veldnaam | Vereist | Beschrijving | |------------|----------|-------------| | file | Ja | De basis-/achtergrondafbeelding | | overlay | Ja | De overlay-/voorgrondafbeelding | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Met de overvloeimodus multiply: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Opmerkingen {#notes} * Beide afbeeldingen worden gevalideerd en gedecodeerd (HEIC, RAW, PSD, SVG worden ondersteund) vóór de compositie. * De overlay wordt geplaatst op de exacte pixelcoördinaten die zijn opgegeven met `x` en `y`. De overlay wordt niet passend gemaakt. * Als de dekking lager is dan 100, wordt vóór het overvloeien een alfamasker op de overlay toegepast. * De overlay kan buiten de grenzen van de basisafbeelding uitsteken (het gedeelte daarbuiten wordt afgeknipt). * De EXIF-oriëntatie wordt automatisch toegepast op beide afbeeldingen vóór de verwerking. * De uitvoerafmetingen komen overeen met de afmetingen van de basisafbeelding. --- --- url: https://docs.snapotter.com/nl/tools/image/info.md description: >- Bekijk gedetailleerde afbeeldingsmetadata, eigenschappen en histogramstatistieken per kanaal. --- # Afbeeldingsinfo {#image-info} Alleen-lezen analysehulpmiddel dat uitgebreide afbeeldingsmetadata retourneert, waaronder afmetingen, formaat, kleurruimte, aanwezigheid van EXIF/ICC/XMP en histogramstatistieken per kanaal. Produceert geen verwerkt uitvoerbestand. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/info` Accepteert multipart-formuliergegevens met een afbeeldingsbestand. Er is geen instellingenveld nodig. ## Parameters {#parameters} Dit hulpmiddel heeft geen configureerbare parameters. Upload gewoon het afbeeldingsbestand. | Veld | Type | Vereist | Beschrijving | |-------|------|----------|-------------| | file | file | Ja | De te analyseren afbeelding | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/info \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Voorbeeldantwoord {#example-response} ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "orientation": 1, "hasProfile": true, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` ## Antwoordvelden {#response-fields} | Veld | Type | Beschrijving | |-------|------|-------------| | filename | string | Opgeschoonde bestandsnaam | | fileSize | number | Bestandsgrootte in bytes | | width | number | Afbeeldingsbreedte in pixels | | height | number | Afbeeldingshoogte in pixels | | format | string | Gedetecteerd formaat (jpeg, png, webp, enz.) | | channels | number | Aantal kleurkanalen | | hasAlpha | boolean | Of de afbeelding een alfakanaal heeft | | colorSpace | string | Kleurruimte (srgb, cmyk, enz.) | | density | number of null | DPI/PPI-resolutie | | isProgressive | boolean | Of de JPEG progressieve codering gebruikt | | orientation | number of null | EXIF-oriëntatiewaarde (1-8) | | hasProfile | boolean | Of er een ICC-profiel is ingebed | | hasExif | boolean | Of er EXIF-metadata aanwezig is | | hasIcc | boolean | Of er een ICC-kleurprofiel aanwezig is | | hasXmp | boolean | Of er XMP-metadata aanwezig is | | bitDepth | string of null | Bits per sample | | pages | number | Aantal pagina's (voor formaten met meerdere pagina's zoals TIFF, GIF) | | histogram | array | Statistieken per kanaal (min, max, gemiddelde, standaarddeviatie) | ## Opmerkingen {#notes} * Dit is een alleen-lezen endpoint. Het produceert geen downloadbaar uitvoerbestand of `jobId`. * Voor afbeeldingen in RAW-formaat (DNG, CR2, NEF, ARW, enz.) wordt ExifTool gebruikt om de werkelijke sensorafmetingen en metadatavlaggen te extraheren die Sharp niet rechtstreeks kan lezen. * HEIC/HEIF-bestanden worden intern gedecodeerd naar PNG om pixelstatistieken te extraheren, aangezien Sharp geen HEVC-pixels kan decoderen. * Het histogram geeft min/max/gemiddelde/stdev per kanaal, niet een volledige verdeling met 256 bins. * Het veld `density` weerspiegelt de ingebedde DPI-metadata, indien aanwezig. --- --- url: https://docs.snapotter.com/nl/tools/image/edit-metadata.md description: >- Bewerk EXIF-, IPTC-, GPS- en XMP-metadatavelden in afbeeldingen zonder de pixels opnieuw te coderen. --- # Afbeeldingsmetadata bewerken {#edit-metadata} Bewerk metadatavelden van afbeeldingen, waaronder EXIF, IPTC, GPS-coördinaten, datums en trefwoorden. Gebruikt ExifTool onder de motorkap, zodat de metadata ter plaatse wordt geschreven zonder de pixels opnieuw te coderen, waardoor de volledige beeldkwaliteit behouden blijft. ## API-eindpunten {#api-endpoints} ### Metadata bewerken {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Schrijft metadatavelden naar de afbeelding en geeft het gewijzigde bestand terug. ### Metadata inspecteren {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Geeft de volledige metadata van de afbeelding terug via ExifTool als JSON. Wijzigt de afbeelding niet. ## Parameters (Bewerken) {#parameters-edit} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | title | string | Nee | - | Titel van de afbeelding (XMP/EXIF) | | author | string | Nee | - | Naam van de auteur | | artist | string | Nee | - | Naam van de kunstenaar (EXIF Artist-tag) | | copyright | string | Nee | - | Auteursrechtvermelding | | imageDescription | string | Nee | - | Beschrijving van de afbeelding (EXIF) | | software | string | Nee | - | Software-tag | | dateTime | string | Nee | - | EXIF DateTime-waarde | | dateTimeOriginal | string | Nee | - | EXIF DateTimeOriginal-waarde | | setAllDates | string | Nee | - | Alle datumvelden tegelijk instellen | | dateShift | string | Nee | - | Verschuif alle datums met een offset (formaat: `+HH:MM` of `-HH:MM`) | | clearGps | boolean | Nee | `false` | Verwijder alle GPS-gegevens | | gpsLatitude | number | Nee | - | Stel de GPS-breedtegraad in (-90 tot 90) | | gpsLongitude | number | Nee | - | Stel de GPS-lengtegraad in (-180 tot 180) | | gpsAltitude | number | Nee | - | Stel de GPS-hoogte in meters in | | keywords | string\[] | Nee | - | Toe te voegen of in te stellen trefwoorden/tags | | keywordsMode | string | Nee | `"add"` | Hoe trefwoorden moeten worden verwerkt: `add` (toevoegen) of `set` (vervangen) | | fieldsToRemove | string\[] | Nee | `[]` | Lijst met specifieke metadataveldnamen die moeten worden verwijderd | | iptcTitle | string | Nee | - | IPTC Object Name | | iptcHeadline | string | Nee | - | IPTC Headline | | iptcCity | string | Nee | - | IPTC City | | iptcState | string | Nee | - | IPTC Province/State | | iptcCountry | string | Nee | - | IPTC Country | ## Voorbeeldverzoek {#example-request} Auteur en auteursrecht instellen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` GPS-coördinaten instellen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` GPS verwijderen en trefwoorden toevoegen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Metadata inspecteren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Voorbeeldantwoord (Bewerken) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Opmerkingen {#notes} * Deze tool vereist dat ExifTool op de server is geïnstalleerd. Het is opgenomen in de Docker-image. * Metadata wordt ter plaatse geschreven, zodat er geen pixels opnieuw worden gecodeerd. De verandering in bestandsgrootte is minimaal (alleen de metadatabytes). * De parameter `dateShift` verschuift alle datumvelden met de opgegeven offset, wat nuttig is voor het corrigeren van tijdzonefouten (bijv. `+02:00` of `-05:30`). * Als er geen wijzigingen worden aangevraagd (alle parameters weggelaten of leeg), wordt het originele bestand ongewijzigd teruggegeven. * Ondersteunde formaten: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * Voor formaten die niet in de browser kunnen worden bekeken (HEIF, TIFF) bevat het antwoord een `previewUrl`-veld met een WebP-voorbeeld. --- --- url: https://docs.snapotter.com/nl/tools/image/strip-metadata.md description: >- EXIF-, GPS-, ICC- en XMP-metadata uit afbeeldingen verwijderen voor privacy en kleinere bestandsgroottes. --- # Afbeeldingsmetadata verwijderen {#remove-metadata} Verwijder EXIF-, GPS-, ICC-kleurprofielen en XMP-metadata uit afbeeldingen. Handig voor privacy (het verwijderen van GPS-coördinaten, camera-informatie) en het verkleinen van de bestandsgrootte. ## API Endpoints {#api-endpoints} ### Metadata Verwijderen {#strip-metadata} `POST /api/v1/tools/image/strip-metadata` Verwerkt de afbeelding en retourneert een opgeschoonde versie waaruit de geselecteerde metadata is verwijderd. ### Metadata Inspecteren {#inspect-metadata} `POST /api/v1/tools/image/strip-metadata/inspect` Retourneert de geparseerde metadata als JSON zonder de afbeelding te wijzigen. Handig om te bekijken welke metadata aanwezig is voordat je deze verwijdert. ## Parameters (Verwijderen) {#parameters-strip} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | stripExif | boolean | Nee | `false` | EXIF-gegevens verwijderen (camera-instellingen, datums, enz.) | | stripGps | boolean | Nee | `false` | Alleen GPS-/locatiegegevens verwijderen | | stripIcc | boolean | Nee | `false` | ICC-kleurprofiel verwijderen | | stripXmp | boolean | Nee | `false` | XMP-metadata verwijderen (Adobe, IPTC) | | stripAll | boolean | Nee | `true` | Alle metadata in één keer verwijderen | Wanneer `stripAll` `true` is, overschrijft dit de individuele vlaggen en wordt alles verwijderd. ## Voorbeeldverzoek {#example-request} Alle metadata verwijderen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": true}' ``` Alleen GPS-gegevens verwijderen (camera-informatie en kleurprofiel behouden): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": false, "stripGps": true}' ``` Metadata inspecteren zonder te wijzigen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Voorbeeldrespons (Verwijderen) {#example-response-strip} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Voorbeeldrespons (Inspecteren) {#example-response-inspect} ```json { "filename": "photo.jpg", "fileSize": 2450000, "exif": { "Make": "Canon", "Model": "EOS R5", "DateTimeOriginal": "2024:03:15 14:30:00", "ExposureTime": "1/250", "FNumber": 2.8, "ISO": 400 }, "gps": { "GPSLatitudeRef": "N", "GPSLatitude": [37, 46, 30], "_latitude": 37.775, "_longitude": -122.4183 }, "icc": { "Profile Size": "3144 bytes", "Color Space": "RGB", "Description": "sRGB IEC61966-2.1" }, "xmp": { "CreatorTool": "Adobe Photoshop 25.0" } } ``` ## Opmerkingen {#notes} * De afbeelding wordt na het verwijderen opnieuw gecodeerd in het oorspronkelijke formaat. JPEG gebruikt mozjpeg met kwaliteit 90, PNG gebruikt compressieniveau 9, WebP gebruikt kwaliteit 85. * Het verwijderen van ICC-profielen kan subtiele kleurverschuivingen veroorzaken als de afbeelding met een niet-sRGB-profiel was gemarkeerd. Gebruik `stripIcc: false` als kleurnauwkeurigheid van belang is. * Het inspecteer-endpoint parseert GPS-coördinaten voor het gemak naar decimale breedte-/lengtegraadwaarden (met een underscore als voorvoegsel). * Ondersteunde invoerformaten: JPEG, PNG, WebP, AVIF, TIFF, GIF. --- --- url: https://docs.snapotter.com/nl/tools/image/image-enhancement.md description: >- Automatische verbetering met één klik die een afbeelding analyseert en de belichting, het contrast, de witbalans, de verzadiging en de scherpte corrigeert. --- # Afbeeldingsverbetering {#image-enhancement} Automatische verbetering met één klik en slimme analyse. Analyseert de afbeelding en past correcties toe voor belichting, contrast, witbalans, verzadiging, scherpte en ruisonderdrukking. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **Verwerking:** Synchroon (gebruikt de `createToolRoute`-factory, retourneert het resultaat rechtstreeks) **Modelbundel:** Geen vereist voor basisverbetering. De bundel `upscale-enhance` (5-6 GB) wordt alleen gebruikt wanneer `deepEnhance` is ingeschakeld (voor AI-ruisonderdrukking via SCUNet). ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Afbeeldingsbestand (multipart) | | mode | string | Nee | `"auto"` | Verbeteringsmodus: `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | Nee | `50` | Algehele verbeteringsintensiteit (0-100) | | corrections | object | Nee | alle `true` | Selectieve correcties om toe te passen (zie hieronder) | | deepEnhance | boolean | Nee | `false` | Schakel AI-aangedreven ruisonderdrukking in (vereist dat het hulpmiddel `noise-removal` is geïnstalleerd) | ### Corrections-object {#corrections-object} | Veld | Type | Standaard | Beschrijving | |-------|------|---------|-------------| | exposure | boolean | `true` | Belichting automatisch corrigeren | | contrast | boolean | `true` | Contrast automatisch corrigeren | | whiteBalance | boolean | `true` | Witbalans automatisch corrigeren | | saturation | boolean | `true` | Verzadiging automatisch corrigeren | | sharpness | boolean | `true` | Automatisch verscherpen | | denoise | boolean | `true` | Lichte ruisonderdrukking | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Antwoord (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Analyze-endpoint {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Analyseert een afbeelding en retourneert correctie-aanbevelingen zonder ze toe te passen. ### Parameters {#parameters-1} | Parameter | Type | Vereist | Beschrijving | |-----------|------|----------|-------------| | file | file | Ja | Afbeeldingsbestand (multipart) | ### Voorbeeldverzoek {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Antwoord (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Opmerkingen {#notes} * Dit hulpmiddel gebruikt de synchrone `createToolRoute`-factory, dus het retourneert een standaardantwoord (geen 202 async). * De parameter `mode` past aan hoe correcties worden gewogen (bijvoorbeeld: de portretmodus is voorzichtiger met huidtinten, de landschapsmodus versterkt de verzadiging). * Wanneer `deepEnhance` is ingeschakeld en het hulpmiddel `noise-removal` (SCUNet) is geïnstalleerd, wordt een extra AI-ruisonderdrukkingsstap toegepast na de standaardcorrecties. * Het analyze-endpoint is handig om te bekijken welke correcties zouden worden toegepast voordat je ze toepast. * Ondersteunt de invoerformaten HEIC/HEIF, RAW, TGA, PSD, EXR en HDR via automatische decodering. --- --- url: https://docs.snapotter.com/nl/tools/image/watermark-image.md description: >- Een logo of afbeelding als watermerk overleggen met configureerbare positie, dekking en schaal. --- # Afbeeldingswatermerk {#image-watermark} Leg een logo of secundaire afbeelding als watermerk over een basisafbeelding. Het watermerk wordt geschaald ten opzichte van de breedte van de basisafbeelding en in een hoek of in het midden geplaatst. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/watermark-image` Accepteert multipart form data met **twee** afbeeldingsbestanden en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | position | string | Nee | `"bottom-right"` | Plaatsing van het watermerk: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` | | opacity | number | Nee | `50` | Dekkingspercentage van het watermerk (0 tot 100) | | scale | number | Nee | `25` | Watermerkbreedte als percentage van de breedte van de hoofdafbeelding (1 tot 100) | ### Bestandsvelden {#file-fields} | Veldnaam | Vereist | Beschrijving | |------------|----------|-------------| | file | Ja | De hoofd-/basisafbeelding | | watermark | Ja | De watermerk-/logoafbeelding | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "watermark=@logo.png" \ -F 'settings={"position": "bottom-right", "opacity": 60, "scale": 20}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2520000 } ``` ## Opmerkingen {#notes} * Beide afbeeldingen worden gevalideerd en gedecodeerd (HEIC, RAW, PSD, SVG ondersteund). * Het watermerk wordt proportioneel geschaald zodat de breedte gelijk is aan `scale`% van de breedte van de hoofdafbeelding. * De dekking wordt toegepast via een alfamasker dat wordt samengesteld met `dest-in`-menging. * Hoekposities gebruiken een opvulling van 20px vanaf de rand van de afbeelding. * Als de watermerkafbeelding transparantie heeft (bijv. een PNG-logo), blijft deze behouden tijdens het samenstellen. * De EXIF-oriëntatie wordt automatisch toegepast op beide afbeeldingen vóór verwerking. --- --- url: https://docs.snapotter.com/it/guide/upgrading.md --- # Aggiornamento da 1.x a 2.0 {#upgrading-from-1-x-to-2-0} SnapOtter 1.x memorizzava tutto in un unico file SQLite e girava come un singolo container. SnapOtter 2.0 usa PostgreSQL e Redis. Questa guida illustra come spostare un'installazione 1.x su 2.0 senza perdere dati. In breve: riutilizza il tuo volume `/data` esistente e la 2.0 importa automaticamente il tuo database 1.x al primo avvio. I tuoi utenti, i file salvati, le impostazioni, le chiavi API e le pipeline vengono trasferiti. Il vecchio database non viene mai modificato, quindi puoi sempre tornare indietro. ::: tip Una nota per i nostri utenti 1.x Molti di voi si fidano di SnapOtter fin dal primo giorno e il vostro feedback ha dato forma a questa release. La 2.0 cambia molto sotto il cofano, e questa guida esiste affinché il passaggio non vi costi nulla di ciò a cui tenete. I vostri account, i file, le impostazioni, le chiavi API e le pipeline vengono trasferiti, e il vostro vecchio database non viene mai toccato. Grazie per aver aggiornato con noi. ::: ## Prima di iniziare: fai il backup dell'intero volume `/data` {#before-you-start-back-up-the-whole-data-volume} Fai questo per primo, ogni volta. Esegui il backup dell'**intero** volume `/data`, non solo del file `snapotter.db`. Ecco perché è importante. La 1.x esegue SQLite in modalità WAL, quindi un container 1.x arrestato lascia abitualmente la maggior parte dei suoi dati confermati in `snapotter.db-wal` accanto a un `snapotter.db` quasi vuoto. Copiare solo `snapotter.db` acquisisce un database vuoto e perde silenziosamente tutto. Il volume contiene insieme `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm` e la tua directory `files/`, e devono viaggiare come un insieme. ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## Aggiorna prima alla 1.17.2 {#upgrade-to-1-17-2-first} Aggiorna la tua installazione 1.x all'ultima release 1.x (1.17.2) prima di passare alla 2.0. Questo consente alla 1.x di eseguire le proprie migrazioni finali dello schema, così la 2.0 importa da uno schema noto e completo. L'aggiornamento da una 1.x più vecchia direttamente alla 2.0 non è supportato. ## Verifica il nome del tuo volume {#check-your-volume-name} L'importatore vede i tuoi dati solo se lo stack 2.0 monta lo stesso volume usato dalla tua installazione 1.x. I nomi dei volumi Docker distinguono maiuscole e minuscole, e i vecchi frammenti del README usavano un `snapotter-data` minuscolo mentre i file Compose usano `SnapOtter-data`. Verifica quale dei due hai: ```bash docker volume ls | grep -i snapotter ``` Usa esattamente quel nome nella tua configurazione 2.0. ## Percorso A: container singolo (il più rapido) {#path-a-single-container-quickest} Se esegui SnapOtter con un singolo `docker run`, continua a farlo. La 2.0 avvia un PostgreSQL e un Redis incorporati all'interno del container quando non imposti `DATABASE_URL` o `REDIS_URL`, e rileva e importa automaticamente `/data/snapotter.db` al primo avvio. ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` Controlla nei log una riga come: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` Tutto qui. Accedi con le tue credenziali esistenti. ## Percorso B: Compose (consigliato per la produzione) {#path-b-compose-recommended-for-production} Lo stack Compose 2.0 esegue tre servizi (app, Postgres, Redis). Riutilizza il tuo volume `/data` della 1.x per il servizio app. L'app rileva automaticamente `/data/snapotter.db` e lo importa in Postgres al primo avvio. ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` Se preferisci puntare esplicitamente al vecchio database, imposta `SQLITE_MIGRATE_PATH=/data/snapotter.db`. Un percorso esplicito ha sempre la precedenza sul rilevamento automatico. ## Anteprima dell'importazione (opzionale) {#preview-the-import-first-optional} Per vedere esattamente cosa verrebbe importato senza scrivere nulla, esegui una prova a vuoto sul tuo file di database: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` Stampa il conteggio delle righe per tabella, quanti file della libreria salvata ha trovato su disco e gli eventuali stati dei job che normalizzerà. Non ha bisogno di un Postgres in esecuzione. ## Cosa viene trasferito e cosa no {#what-carries-over-and-what-does-not} Trasferito: * Utenti e la possibilità di accedere. Gli hash delle password sono invariati, quindi lo stesso nome utente e password funzionano. * Team, impostazioni (inclusa l'identità della tua istanza), ruoli, chiavi API (continuano a funzionare) e pipeline salvate. * Record della cronologia dei job. * La tua libreria di file salvati, sia i record sia i file effettivi, perché `/data/files` è preservata sul volume. Non trasferito: * Le sessioni di accesso. Tutti effettuano l'accesso una volta dopo l'aggiornamento. Le credenziali sono invariate, quindi è un singolo nuovo accesso, niente di più. * I file di input e output dei vecchi job di elaborazione. Risiedevano in uno spazio di lavoro temporaneo e sono scomparsi per progettazione. I record della cronologia dei job rimangono. * I flag di consenso agli analytics per singolo utente della 1.x, che non hanno equivalente nella 2.0 (gli analytics della 2.0 sono un'impostazione a livello di istanza). ## Disattivare l'importazione {#turning-the-import-off} Se vuoi deliberatamente un database nuovo anche se sul volume è presente un `snapotter.db`, imposta `SQLITE_MIGRATE_PATH=off`. ## Se hai già dei dati nell'istanza 2.0 {#if-you-already-have-data-in-the-2-0-instance} L'importatore viene eseguito solo su un database vuoto. Se hai avviato la 2.0 da zero (creando dati) e in seguito hai montato un vecchio `snapotter.db`, la 2.0 lo rileverà ma non lo importerà, perché la fusione di due dataset può creare conflitti sugli ID. Vedrai un avviso nei log. Per importare i dati 1.x ti serve un'istanza vuota: * Se l'istanza 2.0 contiene solo l'amministratore predefinito (non l'hai davvero usata), ferma lo stack, rimuovi il volume Postgres (`SnapOtter-pgdata`) e riavvia con il vecchio `/data` presente. L'importazione avverrà in modo pulito. Questo cancella solo i dati Postgres usa e getta, non il tuo database 1.x. * Se l'istanza 2.0 contiene dati reali che vuoi conservare, i due dataset non possono essere uniti automaticamente. Esporta ciò che ti serve e importa i dati 1.x in una distribuzione separata e nuova. ## Tornare indietro {#rolling-back} L'aggiornamento non modifica né elimina mai il tuo `snapotter.db` della 1.x. Se hai bisogno di tornare alla 1.x, ridistribuisci l'immagine 1.x sullo stesso volume. Tutto ciò che hai creato nella 2.0 dopo l'aggiornamento risiede in Postgres e non sarebbe presente nel database 1.x, quindi torna indietro tempestivamente se hai intenzione di farlo. --- --- url: https://docs.snapotter.com/fr/tools/image/upscale.md description: >- Agrandit les images de 2x à 4x avec la super-résolution par IA Real-ESRGAN tout en préservant les détails fins. --- # Agrandissement d'image {#image-upscaling} Amélioration par super-résolution IA à l'aide de Real-ESRGAN. Agrandit les images de 2x à 4x tout en préservant les détails. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/upscale` **Traitement :** asynchrone (renvoie 202, interroger `/api/v1/jobs/{jobId}/progress` pour le statut via SSE) **Bundle de modèle :** `upscale-enhance` (5-6 Go) ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | file | file | Oui | - | Fichier image (multipart) | | scale | number | Non | `2` | Facteur d'agrandissement (par exemple 2, 3, 4) | | model | string | Non | `"auto"` | Modèle à utiliser (par exemple `auto`, noms de modèles spécifiques) | | faceEnhance | boolean | Non | `false` | Applique une amélioration des visages pendant l'agrandissement | | denoise | number | Non | `0` | Force du débruitage (0 = désactivé) | | format | string | Non | `"auto"` | Format de sortie : `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | Non | `95` | Qualité de sortie (1-100) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Réponse {#response} ### Réponse initiale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progression (SSE sur `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Résultat final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Remarques {#notes} * Nécessite l'installation du bundle de modèle `upscale-enhance` (5-6 Go). * Utilise Real-ESRGAN lorsqu'il est disponible ; revient à l'interpolation Lanczos si le modèle IA n'est pas disponible. * L'option `faceEnhance` applique la restauration de visages GFPGAN pendant l'agrandissement pour une meilleure qualité des visages. * Pour les formats de sortie non prévisualisables dans le navigateur (HEIC, JXL, TIFF), un aperçu WebP est généré en parallèle de la sortie principale. * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR via un décodage automatique. --- --- url: https://docs.snapotter.com/fr/tools/image/ai-canvas-expand.md description: >- Agrandit le canevas d'une image par outpainting IA, en l'étendant dans n'importe quelle direction et en remplissant les nouvelles zones pour qu'elles correspondent à l'original. --- # Agrandissement de canevas par IA {#ai-canvas-expand} Agrandit le canevas d'une image grâce à un remplissage assisté par IA (outpainting). Étend l'image dans n'importe quelle direction et remplit les nouvelles zones avec un contenu généré par IA qui correspond à l'image existante. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Traitement :** asynchrone (renvoie 202, interrogez `/api/v1/jobs/{jobId}/progress` pour connaître le statut via SSE) **Bundle de modèles :** `object-eraser-colorize` (1 à 2 Go) ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | file | fichier | Oui | - | Fichier image (multipart) | | extendTop | entier | Non | `0` | Pixels à ajouter en haut | | extendRight | entier | Non | `0` | Pixels à ajouter à droite | | extendBottom | entier | Non | `0` | Pixels à ajouter en bas | | extendLeft | entier | Non | `0` | Pixels à ajouter à gauche | | tier | chaîne | Non | `"balanced"` | Niveau de qualité : `fast`, `balanced`, `high` | | format | chaîne | Non | `"auto"` | Format de sortie : `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | entier | Non | `95` | Qualité de sortie (1 à 100) | Au moins une direction d'extension doit être supérieure à 0. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Réponse {#response} ### Réponse initiale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progression (SSE sur `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Résultat final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Remarques {#notes} * Nécessite l'installation du bundle de modèles `object-eraser-colorize` (1 à 2 Go). * Utilise l'outpainting basé sur LaMa pour générer le contenu des régions agrandies. * Le paramètre `tier` arbitre entre vitesse et qualité : `fast` produit des résultats rapidement, avec de possibles artefacts, tandis que `high` prend plus de temps mais produit des remplissages plus lisses et plus cohérents. * Les valeurs d'extension sont en pixels. Les dimensions finales de l'image seront : largeur d'origine + extendLeft + extendRight par hauteur d'origine + extendTop + extendBottom. * Pour les formats de sortie non prévisualisables dans le navigateur (HEIC, JXL, TIFF), un aperçu WebP est généré en parallèle de la sortie principale. * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR via un décodage automatique. --- --- url: https://docs.snapotter.com/hi/tools/image/ai-canvas-expand.md description: >- AI आउटपेंटिंग से किसी छवि के कैनवास का विस्तार करें, इसे किसी भी दिशा में बढ़ाएँ और नए क्षेत्रों को मूल से मेल खाने के लिए भरें। --- # AI Canvas Expand {#ai-canvas-expand} AI-संचालित फिल (आउटपेंटिंग) से किसी छवि के कैनवास का विस्तार करें। छवि को किसी भी दिशा में बढ़ाता है और नए क्षेत्रों को मौजूदा छवि से मेल खाने वाली AI-जनित सामग्री से भरता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Processing:** असिंक्रोनस (202 लौटाता है, स्थिति के लिए SSE के ज़रिए `/api/v1/jobs/{jobId}/progress` पोल करें) **Model bundle:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | छवि फ़ाइल (multipart) | | extendTop | integer | No | `0` | शीर्ष पर विस्तार करने के लिए पिक्सेल | | extendRight | integer | No | `0` | दाईं ओर विस्तार करने के लिए पिक्सेल | | extendBottom | integer | No | `0` | नीचे विस्तार करने के लिए पिक्सेल | | extendLeft | integer | No | `0` | बाईं ओर विस्तार करने के लिए पिक्सेल | | tier | string | No | `"balanced"` | गुणवत्ता श्रेणी: `fast`, `balanced`, `high` | | format | string | No | `"auto"` | आउटपुट प्रारूप: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | आउटपुट गुणवत्ता (1-100) | कम से कम एक विस्तार दिशा 0 से अधिक होनी चाहिए। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * इसके लिए `object-eraser-colorize` मॉडल बंडल का इंस्टॉल होना आवश्यक है (1-2 GB)। * विस्तारित क्षेत्रों के लिए सामग्री उत्पन्न करने हेतु LaMa-आधारित आउटपेंटिंग का उपयोग करता है। * `tier` पैरामीटर गति और गुणवत्ता के बीच समझौता करता है: `fast` संभावित आर्टिफ़ैक्ट के साथ त्वरित परिणाम देता है, `high` अधिक समय लेता है लेकिन अधिक चिकने, अधिक सुसंगत फिल देता है। * विस्तार मान पिक्सेल में होते हैं। अंतिम छवि आयाम होंगे: मूल चौड़ाई + extendLeft + extendRight गुणा मूल ऊँचाई + extendTop + extendBottom। * गैर-ब्राउज़र-पूर्वावलोकन योग्य आउटपुट प्रारूपों (HEIC, JXL, TIFF) के लिए, मुख्य आउटपुट के साथ एक WebP पूर्वावलोकन उत्पन्न किया जाता है। * स्वचालित डिकोडिंग के ज़रिए HEIC/HEIF, RAW, TGA, PSD, EXR, और HDR इनपुट प्रारूपों का समर्थन करता है। --- --- url: https://docs.snapotter.com/ja/tools/image/ai-canvas-expand.md description: AI アウトペインティングで画像キャンバスを拡張し、任意の方向に広げて新しい領域を元の画像に合わせて埋めます。 --- # AI Canvas Expand {#ai-canvas-expand} AI 対応のフィル (アウトペインティング) で画像のキャンバスを拡張します。任意の方向に画像を広げ、既存の画像に合わせた AI 生成コンテンツで新しい領域を埋めます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **処理:** 非同期 (202 を返し、SSE でステータスを `/api/v1/jobs/{jobId}/progress` からポーリング) **モデルバンドル:** `object-eraser-colorize` (1 ~ 2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | 画像ファイル (マルチパート) | | extendTop | integer | No | `0` | 上方向に拡張するピクセル数 | | extendRight | integer | No | `0` | 右方向に拡張するピクセル数 | | extendBottom | integer | No | `0` | 下方向に拡張するピクセル数 | | extendLeft | integer | No | `0` | 左方向に拡張するピクセル数 | | tier | string | No | `"balanced"` | 品質ティア: `fast`、`balanced`、`high` | | format | string | No | `"auto"` | 出力形式: `auto`、`png`、`jpg`、`jpeg`、`webp`、`tiff`、`gif`、`avif`、`heic`、`heif`、`jxl` | | quality | integer | No | `95` | 出力品質 (1 ~ 100) | 拡張方向のうち少なくとも 1 つは 0 より大きくする必要があります。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * `object-eraser-colorize` モデルバンドルのインストールが必要です (1 ~ 2 GB)。 * LaMa ベースのアウトペインティングを使用して、拡張された領域のコンテンツを生成します。 * `tier` パラメータは速度と品質のトレードオフです。`fast` はアーティファクトが生じる可能性はあるものの素早く結果を生成し、`high` はより時間がかかりますが、より滑らかで一貫性のあるフィルを生成します。 * 拡張値はピクセル単位です。最終的な画像サイズは、元の幅 + extendLeft + extendRight × 元の高さ + extendTop + extendBottom になります。 * ブラウザでプレビューできない出力形式 (HEIC、JXL、TIFF) の場合、メイン出力とともに WebP プレビューが生成されます。 * HEIC/HEIF、RAW、TGA、PSD、EXR、HDR の入力形式を自動デコードでサポートします。 --- --- url: https://docs.snapotter.com/ko/tools/image/ai-canvas-expand.md description: AI 아웃페인팅으로 이미지 캔버스를 확장하여 어느 방향으로든 늘리고 새 영역을 원본과 어울리게 채웁니다. --- # AI Canvas Expand {#ai-canvas-expand} AI 기반 채우기(아웃페인팅)로 이미지 캔버스를 확장합니다. 이미지를 어느 방향으로든 늘리고 기존 이미지와 어울리는 AI 생성 콘텐츠로 새 영역을 채웁니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **처리:** 비동기 (202를 반환하며, SSE를 통해 상태를 위해 `/api/v1/jobs/{jobId}/progress`을(를) 폴링) **모델 번들:** `object-eraser-colorize` (1-2 GB) ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | file | file | 예 | - | 이미지 파일 (multipart) | | extendTop | integer | 아니요 | `0` | 위쪽으로 확장할 픽셀 수 | | extendRight | integer | 아니요 | `0` | 오른쪽으로 확장할 픽셀 수 | | extendBottom | integer | 아니요 | `0` | 아래쪽으로 확장할 픽셀 수 | | extendLeft | integer | 아니요 | `0` | 왼쪽으로 확장할 픽셀 수 | | tier | string | 아니요 | `"balanced"` | 품질 등급: `fast`, `balanced`, `high` | | format | string | 아니요 | `"auto"` | 출력 형식: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | 아니요 | `95` | 출력 품질 (1-100) | 확장 방향 중 하나 이상이 0보다 커야 합니다. ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## 응답 {#response} ### 초기 응답 (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### 진행 상황 (`/api/v1/jobs/{jobId}/progress`의 SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### 최종 결과 (SSE를 통해) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## 참고 사항 {#notes} * `object-eraser-colorize` 모델 번들이 설치되어 있어야 합니다 (1-2 GB). * LaMa 기반 아웃페인팅을 사용하여 확장된 영역의 콘텐츠를 생성합니다. * `tier` 매개변수는 속도와 품질을 절충합니다. `fast`은(는) 잠재적 아티팩트와 함께 빠르게 결과를 생성하고, `high`은(는) 더 오래 걸리지만 더 매끄럽고 일관된 채우기를 생성합니다. * 확장 값은 픽셀 단위입니다. 최종 이미지 크기는 다음과 같습니다: 원본 너비 + extendLeft + extendRight, 원본 높이 + extendTop + extendBottom. * 브라우저에서 미리 볼 수 없는 출력 형식(HEIC, JXL, TIFF)의 경우, 메인 출력과 함께 WebP 미리보기가 생성됩니다. * 자동 디코딩을 통해 HEIC/HEIF, RAW, TGA, PSD, EXR, HDR 입력 형식을 지원합니다. --- --- url: https://docs.snapotter.com/th/tools/image/ai-canvas-expand.md description: >- ขยายผืนผ้าใบของรูปภาพด้วย AI outpainting โดยขยายไปในทิศทางใดก็ได้และเติมพื้นที่ใหม่ให้เข้ากับต้นฉบับ --- # AI Canvas Expand {#ai-canvas-expand} ขยายผืนผ้าใบของรูปภาพด้วยการเติมที่ขับเคลื่อนด้วย AI (outpainting) ขยายรูปภาพไปในทิศทางใดก็ได้และเติมพื้นที่ใหม่ด้วยเนื้อหาที่ AI สร้างขึ้นให้เข้ากับรูปภาพเดิม ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **การประมวลผล:** แบบอะซิงโครนัส (ส่งคืน 202, สำรวจ `/api/v1/jobs/{jobId}/progress` เพื่อดูสถานะผ่าน SSE) **ชุดโมเดล:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | ไฟล์รูปภาพ (multipart) | | extendTop | integer | No | `0` | พิกเซลที่จะขยายด้านบน | | extendRight | integer | No | `0` | พิกเซลที่จะขยายด้านขวา | | extendBottom | integer | No | `0` | พิกเซลที่จะขยายด้านล่าง | | extendLeft | integer | No | `0` | พิกเซลที่จะขยายด้านซ้าย | | tier | string | No | `"balanced"` | ระดับคุณภาพ: `fast`, `balanced`, `high` | | format | string | No | `"auto"` | รูปแบบเอาต์พุต: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | คุณภาพเอาต์พุต (1-100) | อย่างน้อยหนึ่งทิศทางการขยายต้องมากกว่า 0 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * ต้องติดตั้งชุดโมเดล `object-eraser-colorize` (1-2 GB) * ใช้ outpainting บนพื้นฐาน LaMa เพื่อสร้างเนื้อหาสำหรับบริเวณที่ขยาย * พารามิเตอร์ `tier` แลกเปลี่ยนความเร็วกับคุณภาพ: `fast` ให้ผลลัพธ์อย่างรวดเร็วโดยอาจมีสิ่งแปลกปลอม ส่วน `high` ใช้เวลานานกว่าแต่ให้การเติมที่นุ่มนวลและกลมกลืนกว่า * ค่าการขยายเป็นพิกเซล ขนาดรูปภาพสุดท้ายจะเป็น: ความกว้างต้นฉบับ + extendLeft + extendRight คูณ ความสูงต้นฉบับ + extendTop + extendBottom * สำหรับรูปแบบเอาต์พุตที่ไม่สามารถแสดงตัวอย่างในเบราว์เซอร์ได้ (HEIC, JXL, TIFF) จะสร้างตัวอย่าง WebP ควบคู่ไปกับเอาต์พุตหลัก * รองรับรูปแบบอินพุต HEIC/HEIF, RAW, TGA, PSD, EXR และ HDR ผ่านการถอดรหัสอัตโนมัติ --- --- url: https://docs.snapotter.com/vi/tools/image/ai-canvas-expand.md description: >- Mở rộng canvas của hình ảnh bằng outpainting AI, kéo dài nó theo mọi hướng và lấp đầy các vùng mới cho khớp với ảnh gốc. --- # AI Canvas Expand {#ai-canvas-expand} Mở rộng canvas của một hình ảnh bằng cách lấp đầy dựa trên AI (outpainting). Kéo dài hình ảnh theo mọi hướng và lấp đầy các vùng mới bằng nội dung do AI tạo ra khớp với hình ảnh hiện có. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Xử lý:** Bất đồng bộ (trả về 202, hỏi vòng `/api/v1/jobs/{jobId}/progress` để lấy trạng thái qua SSE) **Gói mô hình:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Tệp hình ảnh (multipart) | | extendTop | integer | No | `0` | Số pixel kéo dài ở phía trên | | extendRight | integer | No | `0` | Số pixel kéo dài ở bên phải | | extendBottom | integer | No | `0` | Số pixel kéo dài ở phía dưới | | extendLeft | integer | No | `0` | Số pixel kéo dài ở bên trái | | tier | string | No | `"balanced"` | Cấp chất lượng: `fast`, `balanced`, `high` | | format | string | No | `"auto"` | Định dạng đầu ra: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | Chất lượng đầu ra (1-100) | Ít nhất một hướng kéo dài phải lớn hơn 0. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * Yêu cầu cài đặt gói mô hình `object-eraser-colorize` (1-2 GB). * Sử dụng outpainting dựa trên LaMa để tạo nội dung cho các vùng đã mở rộng. * Tham số `tier` đánh đổi tốc độ lấy chất lượng: `fast` tạo kết quả nhanh nhưng có thể có nhiễu, `high` mất nhiều thời gian hơn nhưng tạo ra phần lấp đầy mượt mà, mạch lạc hơn. * Giá trị kéo dài tính bằng pixel. Kích thước hình ảnh cuối cùng sẽ là: chiều rộng gốc + extendLeft + extendRight nhân chiều cao gốc + extendTop + extendBottom. * Với các định dạng đầu ra không thể xem trước trên trình duyệt (HEIC, JXL, TIFF), một bản xem trước WebP được tạo cùng với đầu ra chính. * Hỗ trợ các định dạng đầu vào HEIC/HEIF, RAW, TGA, PSD, EXR và HDR thông qua giải mã tự động. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/ai-canvas-expand.md description: 使用 AI 外绘扩展图像画布,向任意方向延伸并填充与原图匹配的新区域。 --- # AI Canvas Expand {#ai-canvas-expand} 使用 AI 驱动的填充(外绘)扩展图像画布。向任意方向延伸图像,并用与现有图像匹配的 AI 生成内容填充新区域。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **处理方式:** 异步(返回 202,通过 SSE 轮询 `/api/v1/jobs/{jobId}/progress` 获取状态) **模型包:** `object-eraser-colorize`(1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | 是 | - | 图像文件(multipart) | | extendTop | integer | 否 | `0` | 顶部要扩展的像素数 | | extendRight | integer | 否 | `0` | 右侧要扩展的像素数 | | extendBottom | integer | 否 | `0` | 底部要扩展的像素数 | | extendLeft | integer | 否 | `0` | 左侧要扩展的像素数 | | tier | string | 否 | `"balanced"` | 质量档位:`fast`、`balanced`、`high` | | format | string | 否 | `"auto"` | 输出格式:`auto`、`png`、`jpg`、`jpeg`、`webp`、`tiff`、`gif`、`avif`、`heic`、`heif`、`jxl` | | quality | integer | 否 | `95` | 输出质量(1-100) | 至少有一个扩展方向必须大于 0。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * 需要安装 `object-eraser-colorize` 模型包(1-2 GB)。 * 使用基于 LaMa 的外绘为扩展区域生成内容。 * `tier` 参数在速度和质量之间权衡:`fast` 能快速产出结果但可能有瑕疵,`high` 耗时更长但能产出更平滑、更连贯的填充。 * 扩展值以像素为单位。最终图像尺寸将为:原始宽度 + extendLeft + extendRight 乘以 原始高度 + extendTop + extendBottom。 * 对于浏览器无法预览的输出格式(HEIC、JXL、TIFF),会在主输出旁生成一个 WebP 预览。 * 通过自动解码支持 HEIC/HEIF、RAW、TGA、PSD、EXR 和 HDR 输入格式。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/ai-canvas-expand.md description: 以 AI 外延繪製擴展影像畫布,可朝任意方向延伸並填補新區域以與原圖相符。 --- # AI Canvas Expand {#ai-canvas-expand} 以 AI 驅動的填補(外延繪製)擴展影像畫布。可朝任意方向延伸影像,並以與現有影像相符的 AI 生成內容填補新區域。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **處理方式:** 非同步(回傳 202,透過 SSE 輪詢 `/api/v1/jobs/{jobId}/progress` 取得狀態) **模型套件:** `object-eraser-colorize`(1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | 影像檔案(multipart) | | extendTop | integer | No | `0` | 頂部延伸的像素數 | | extendRight | integer | No | `0` | 右側延伸的像素數 | | extendBottom | integer | No | `0` | 底部延伸的像素數 | | extendLeft | integer | No | `0` | 左側延伸的像素數 | | tier | string | No | `"balanced"` | 品質等級:`fast`、`balanced`、`high` | | format | string | No | `"auto"` | 輸出格式:`auto`、`png`、`jpg`、`jpeg`、`webp`、`tiff`、`gif`、`avif`、`heic`、`heif`、`jxl` | | quality | integer | No | `95` | 輸出品質(1-100) | 至少要有一個延伸方向大於 0。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * 需要安裝 `object-eraser-colorize` 模型套件(1-2 GB)。 * 使用基於 LaMa 的外延繪製,為擴展區域生成內容。 * `tier` 參數在速度與品質之間取捨:`fast` 能快速產生結果但可能有瑕疵,`high` 耗時較久但能產生更平滑、更連貫的填補。 * 延伸值以像素為單位。最終影像尺寸為:原始寬度 + extendLeft + extendRight,乘以 原始高度 + extendTop + extendBottom。 * 對於無法在瀏覽器預覽的輸出格式(HEIC、JXL、TIFF),會在主要輸出旁一併產生 WebP 預覽。 * 透過自動解碼支援 HEIC/HEIF、RAW、TGA、PSD、EXR 及 HDR 輸入格式。 --- --- url: https://docs.snapotter.com/ar/tools/image/colorize.md description: >- تلوين الصور بالأبيض والأسود أو بتدرّج الرمادي تلقائيًا باستخدام نموذج الذكاء الاصطناعي DDColor. --- # AI Colorization {#ai-colorization} حوّل الصور بالأبيض والأسود أو بتدرّج الرمادي إلى ألوان كاملة باستخدام الذكاء الاصطناعي (نموذج DDColor مع OpenCV DNN كخيار احتياطي). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/colorize` **المعالجة:** غير متزامنة (تُعيد 202، استعلِم من `/api/v1/jobs/{jobId}/progress` عن الحالة عبر SSE) **حزمة النموذج:** `object-eraser-colorize` (1-2 غيغابايت) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | ملف الصورة (multipart) | | intensity | number | No | `1.0` | شدة اللون (0-1). القيم الأقل تنتج تلوينًا أكثر خفوتًا | | model | string | No | `"auto"` | النموذج المستخدم: `auto`، `ddcolor`، `opencv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notes {#notes} * يتطلب تثبيت حزمة النموذج `object-eraser-colorize` (1-2 غيغابايت). * ينتج DDColor نتائج أعلى جودة لكنه أبطأ؛ وOpenCV DNN أسرع بجودة أقل قليلًا. يستخدم `auto` نموذج DDColor عند توفره مع OpenCV كخيار احتياطي. * يمزج المُعامِل `intensity` بين النسخة الأصلية بتدرّج الرمادي والنتيجة الملوّنة بالذكاء الاصطناعي. استخدم 1.0 للون الكامل، والقيم الأقل لمظهر عتيق جزئي التشبّع. * صيغة الإخراج تطابق صيغة الإدخال تلقائيًا. * لصيغ الإخراج غير القابلة للمعاينة في المتصفح، تُولَّد معاينة WebP إلى جانب الإخراج الرئيسي. * يدعم صيغ الإدخال HEIC/HEIF وRAW وTGA وPSD وEXR وHDR عبر فكّ الشفرة التلقائي. --- --- url: https://docs.snapotter.com/hi/tools/image/colorize.md description: >- DDColor AI मॉडल के साथ श्वेत-श्याम या ग्रेस्केल तस्वीरों को स्वचालित रूप से रंगीन करें। --- # AI Colorization {#ai-colorization} AI (OpenCV DNN फ़ॉलबैक के साथ DDColor मॉडल) का उपयोग करके श्वेत-श्याम या ग्रेस्केल तस्वीरों को पूर्ण रंग में परिवर्तित करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/colorize` **Processing:** अतुल्यकालिक (202 लौटाता है, SSE के माध्यम से स्थिति के लिए `/api/v1/jobs/{jobId}/progress` पर पोल करें) **Model bundle:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | छवि फ़ाइल (मल्टीपार्ट) | | intensity | number | No | `1.0` | रंग तीव्रता (0-1)। कम मान अधिक सूक्ष्म रंगीनीकरण उत्पन्न करते हैं | | model | string | No | `"auto"` | उपयोग करने के लिए मॉडल: `auto`, `ddcolor`, `opencv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notes {#notes} * `object-eraser-colorize` मॉडल बंडल का स्थापित होना आवश्यक है (1-2 GB)। * DDColor उच्च गुणवत्ता वाले परिणाम उत्पन्न करता है लेकिन धीमा है; OpenCV DNN थोड़ी कम गुणवत्ता के साथ तेज़ है। `auto` उपलब्ध होने पर DDColor का उपयोग करता है और OpenCV फ़ॉलबैक के साथ। * `intensity` पैरामीटर मूल ग्रेस्केल और AI-रंगीन परिणाम के बीच मिश्रण करता है। पूर्ण रंग के लिए 1.0 का उपयोग करें, आंशिक रूप से असंतृप्त विंटेज लुक के लिए कम मान। * आउटपुट फ़ॉर्मेट स्वचालित रूप से इनपुट फ़ॉर्मेट से मेल खाता है। * गैर-ब्राउज़र-पूर्वावलोकन योग्य आउटपुट फ़ॉर्मेट के लिए, मुख्य आउटपुट के साथ एक WebP पूर्वावलोकन उत्पन्न किया जाता है। * स्वचालित डिकोडिंग के माध्यम से HEIC/HEIF, RAW, TGA, PSD, EXR, और HDR इनपुट फ़ॉर्मेट का समर्थन करता है। --- --- url: https://docs.snapotter.com/th/tools/image/colorize.md description: ลงสีภาพขาวดำหรือภาพโทนสีเทาโดยอัตโนมัติด้วยโมเดล AI DDColor --- # AI Colorization {#ai-colorization} แปลงภาพขาวดำหรือภาพโทนสีเทาให้เป็นภาพสีเต็มรูปแบบด้วย AI (โมเดล DDColor พร้อมตัวสำรอง OpenCV DNN) ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/colorize` **การประมวลผล:** แบบอะซิงโครนัส (ส่งคืน 202, ดึงสถานะจาก `/api/v1/jobs/{jobId}/progress` ผ่าน SSE) **ชุดโมเดล:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | ไฟล์ภาพ (multipart) | | intensity | number | No | `1.0` | ความเข้มของสี (0-1) ค่าที่ต่ำกว่าจะให้การลงสีที่นุ่มนวลกว่า | | model | string | No | `"auto"` | โมเดลที่จะใช้: `auto`, `ddcolor`, `opencv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notes {#notes} * ต้องติดตั้งชุดโมเดล `object-eraser-colorize` ก่อน (1-2 GB) * DDColor ให้ผลลัพธ์คุณภาพสูงกว่าแต่ช้ากว่า ส่วน OpenCV DNN เร็วกว่าโดยมีคุณภาพต่ำกว่าเล็กน้อย `auto` ใช้ DDColor เมื่อพร้อมใช้งานพร้อมตัวสำรอง OpenCV * พารามิเตอร์ `intensity` ผสมระหว่างภาพโทนสีเทาต้นฉบับกับผลลัพธ์ที่ลงสีด้วย AI ใช้ 1.0 สำหรับสีเต็ม ค่าที่ต่ำกว่าสำหรับลุควินเทจที่ลดความอิ่มตัวของสีบางส่วน * รูปแบบเอาต์พุตตรงกับรูปแบบอินพุตโดยอัตโนมัติ * สำหรับรูปแบบเอาต์พุตที่ไม่สามารถแสดงตัวอย่างในเบราว์เซอร์ได้ ระบบจะสร้างตัวอย่าง WebP ควบคู่ไปกับเอาต์พุตหลัก * รองรับรูปแบบอินพุต HEIC/HEIF, RAW, TGA, PSD, EXR และ HDR ผ่านการถอดรหัสอัตโนมัติ --- --- url: https://docs.snapotter.com/uk/tools/image/colorize.md description: >- Автоматично розфарбовуйте чорно-білі або відтінки сірого фотографії за допомогою AI-моделі DDColor. --- # AI Colorization {#ai-colorization} Перетворюйте чорно-білі фотографії або фотографії у відтінках сірого на повнокольорові за допомогою AI (модель DDColor із резервним варіантом OpenCV DNN). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/colorize` **Processing:** Асинхронна (повертає 202, опитуйте `/api/v1/jobs/{jobId}/progress` для отримання статусу через SSE) **Model bundle:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Файл зображення (multipart) | | intensity | number | No | `1.0` | Інтенсивність кольору (0-1). Нижчі значення дають більш ненав'язливе розфарбовування | | model | string | No | `"auto"` | Модель для використання: `auto`, `ddcolor`, `opencv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notes {#notes} * Потрібно встановити пакет моделі `object-eraser-colorize` (1-2 GB). * DDColor дає результати вищої якості, але працює повільніше; OpenCV DNN швидший із дещо нижчою якістю. `auto` використовує DDColor за наявності з резервним варіантом OpenCV. * Параметр `intensity` змішує оригінал у відтінках сірого з результатом розфарбовування AI. Використовуйте 1.0 для повного кольору, нижчі значення для частково знебарвленого вінтажного вигляду. * Вихідний формат автоматично збігається з вхідним. * Для вихідних форматів, які не можна переглянути в браузері, поряд з основним виводом генерується попередній перегляд WebP. * Підтримує вхідні формати HEIC/HEIF, RAW, TGA, PSD, EXR та HDR через автоматичне декодування. --- --- url: https://docs.snapotter.com/tr/api/ai.md description: >- Tüm yerel ML araçlarını içeren AI motoru referansı. Arka plan kaldırma, büyütme, OCR, yüz algılama, fotoğraf onarımı ve daha fazlası. --- # AI Motoru Referansı {#ai-engine-reference} `@snapotter/ai` paketi, yerel ML işlemleri için yerel araçları ve Python çalışma zamanlarını koordine eder. Çoğu ML aleti, hızlı ısınma başlatmaları için kalıcı bir Python sidecar kullanır. OCR kasıtlı olarak ayrıdır: `fast`, yerel Tesseract ikili dosyasını çağırırken, `balanced` ve `best`, `/data/ai/v3` altında aktif değişmez RapidOCR nesline sabitlenmiş özel bir kalıcı JSONL dispatcher kullanır. Her istek bir generation lease içerir. Yükseltme sırasında SnapOtter, etkinleştirmeden önce aday üzerinde bir smoke test çalıştırır, atomik olarak yeni dispatcher'ye geçer ve ardından garbage collection'den önce eski nesli boşaltır. NVIDIA CUDA, onu destekleyen çalışma zamanları tarafından otomatik olarak algılanır ve kullanılır. OCR, her ana bilgisayarda CPU'yi kullanır, NVIDIA GPU'lu sistemler dahil, bu alet için CUDA ve sürücü bağlantısından kaçınılması. VA-API, Quick Sync veya OpenCL üzerinden Intel/AMD iGPU hızlandırma bugün AI çıkarımı için desteklenmiyor. `/dev/dri` öğesini bir konteynere eşlemek, CUDA yeteneğine sahip bir NVIDIA GPU mevcut olmadıkça bu Python sidecar araçlarını hızlandırmaz. Dört modalite (image, audio, video, document) genelinde 19 Python sidecar AI aracı, artı isteğe bağlı AI yetenekleri olan 2 araç. Tüm modeller yerel olarak çalışır; ilk model indirmesinden sonra internet gerekmez. ::: info Korece OCR uyumluluğu Hızlı OCR `auto`, `en`, `de`, `es`, `fr`, `zh` ve `ja` dillerini destekler, ancak Koreceyi (`ko`) desteklemez. Korece için doğru OCR paketi ve `balanced` ya da `best` gerekir. Paket resmi Linux amd64 ve arm64 kapsayıcılarında, OCR’nin CPU’da kaldığı NVIDIA ana bilgisayarları dahil çalışır. Desteklenmeyen sistemler açık bir uyumluluk hatası alır ve sessizce `fast` seçeneğine dönülmez. Korece ile `fast` veya eski `tesseract` diğer adı kuyruk öncesinde `FEATURE_INCOMPATIBLE` ve `fast-korean-unsupported` ile reddedilir. ::: ## Mimari {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` Ayrı bir "docs" dispatcher profili, AI izin listesini belge işleme betikleriyle (`doc_pagecount`, `doc_health`, `doc_flatten`, `doc_redact`, `doc_text`, `doc_to_word`, `doc_metadata`, `doc_html_pdf`) değiştirir ve ağır ML içe aktarmalarını atlar. **Zaman aşımları:** varsayılan 300 s; OCR ve BiRefNet arka plan kaldırma 600 s alır. ## Özellik Paketleri {#feature-bundles} AI modelleri, araç başına bir arşiv olarak değil, paylaşılan bağımlılık yığınına göre paketlenir. Bir özellik paketi, araçlar aynı model ailesini, Python wheel'lerini veya yerel kütüphaneleri kullandığında birden fazla aracı etkinleştirebilir. Bu, yayın Docker imgesini daha küçük tutar ve aynı arka plan matlama, yüz algılama, OCR, onarım ve konuşma modellerinin yinelenen kopyalarının saklanmasını önler. Docker imgesi, uygulamayı artı ortak çalışma zamanını içerir. Büyük model arşivleri, talep üzerine kalıcı `/data/ai` birimine indirilir, ardından ihtiyaç duyan her araç tarafından yeniden kullanılır. Bir paket, başka bir araç ihtiyaç duyduğu için zaten yüklüyse, ona bağımlı yeni bir aracı etkinleştirmek o paketi tekrar indirmez. Çoğu AI aracının çalıştırılmadan önce bir veya daha fazla özellik paketine ihtiyacı vardır. Yönetici kullanıcı arayüzü bunları `POST /api/v1/admin/tools/:toolId/features/install` aracılığıyla araçla yükler; bu, tam paket listesini çözer, önceden yüklenmiş olan paketleri atlar ve yalnızca eksik indirmeleri sıraya koyar. Örneğin, yeni bir örnekte Pasaport Fotoğrafını etkinleştirmek `background-removal` ve `face-detection` sıralarını oluşturur; Arka Plan Kaldırma zaten yüklendikten sonra etkinleştirildiğinde yalnızca `face-detection` sıraya alınır. OCR bir istisnadır çünkü `fast`'nin pakete ihtiyacı yoktur; isteğe bağlı doğru çalışma süresini kullanıcı arayüzü veya `POST /api/v1/admin/features/ocr/install` aracılığıyla yükleyin. | Paket | Boyut | Paylaşılan bağımlılık grubu | Onu kullanan araçlar | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet arka plan matlama | remove-background, passport-photo, transparency-fixer, background-replace, blur-background | | `face-detection` | 200-300 MB | MediaPipe yüz algılama ve işaret noktaları | blur-faces, red-eye-removal, smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa inpainting/outpainting ve DDColor | erase-object, colorize, ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN, GFPGAN / CodeFormer, gürültü giderme | upscale, enhance-faces, noise-removal | | `photo-restoration` | 4-5 GB | çizik onarımı ve restorasyon hattı | restore-photo | | `ocr` | ~208-234 MiB indir / ~409-488 MiB kuruldu | İsteğe bağlı RapidOCR 3.9.1, ONNX Runtime 1.20.1 ve sabitlenmiş PP-OCR modelleri | ocr, ocr-pdf (yalnızca `balanced` ve `best`) | | `transcription` | ~600 MB | faster-whisper konuşmadan metne modelleri | transcribe-audio, auto-subtitles | Çapraz paket bağımlılıkları olan araçlar: | Araç | Gerekli paketler | Neden | |------|------------------|-----| | `passport-photo` | `background-removal`, `face-detection` | Arka planı kaldırır, ardından kırpmayı pasaport ve kimlik fotoğrafı kurallarına göre çerçevelemek için yüz işaret noktalarını kullanır. | | `enhance-faces` | `upscale-enhance`, `face-detection` | Seçilen yüz bölgelerinde GFPGAN veya CodeFormer iyileştirmesini çalıştırmadan önce yüzleri algılar. | Bir araç yalnızca OCR hariç gerekli tüm paketler yüklendiğinde kullanılabilir: yerleşik `fast` katmanı, isteğe bağlı OCR paketi olmadan kullanılabilir durumda kalır. Kısmi kurulumlar geçerlidir ve artımlı olarak işlenir: kurulu paketler yeniden kullanılır, eksik paketler indirmeler olarak gösterilir ve sıraya alınmış kurulumlar birer birer çalıştırılır, böylece paylaşılan Python ortamı aynı anda değiştirilmez. ### Doğru OCR çalışma zamanı kurulumu {#accurate-ocr-runtime-installation} Doğru OCR paketi, resmi Linux amd64 veya Linux arm64 konteyneri için platforma özel bir çalışma zamanıdır. amd64 yapısı Python 3.12'yi kullanır; arm64 yapısı Python 3.11'i kullanır. Her iki yapı da ONNX Runtime'nin `CPUExecutionProvider`'si aracılığıyla RapidOCR'yi çalıştırır, dolayısıyla aynı paket yalnızca CPU ve NVIDIA Docker ana bilgisayarlarında çalışır. Doğru çalışma zamanı en az 4 GiB etkili bellek gerektirir: yapılandırılmış kapsayıcı cgroup sınırı, aksi takdirde ana bilgisayar belleği. İmzalı uyumluluk minimumunun altındaki bir sistem indirmeden önce reddedilir. Bu gereksinim yerleşik Fast OCR için geçerli değildir. Bare-metal yapıları, libc ve Python ABI güvenli bir şekilde çıkarılamadığından reddedilir; Ana bilgisayar Tesseract ve Ghostscript sağladığında hızlı OCR kullanılabilir durumda kalır. İsteğe bağlı yapı, mimariye bağlı olarak yaklaşık 208-234 MiB sıkıştırılmış ve 409-488 MiB çıkartılmıştır. İmzalı dizin, yükleyici tarafından zorunlu kılınan sıkıştırılmış ve çıkartılmış bayt sayımlarını tam olarak bağlar. Yerleşik Tesseract, resmi görüntüye yaklaşık 25 MiB ekler ve `/data/ai`'de hiçbir dosyaya ihtiyaç duymaz. Çevrimiçi kurulum, imzalı bir sürüm dizinini ve geçerli platform için tam içerik adresli yapıyı getirir. SnapOtter, yeni nesli atomik olarak etkinleştirmeden önce Ed25519 dizin imzasını, yapı boyutunu, SHA-256 özetini, model özetlerini, yolları, dosya modlarını ve aşamalı smoke test'yi doğrular. Başarısız bir yükleme önceki sağlıklı nesli etkin bırakır. Hava boşluklu kurulum için, `index` ve `archive` adlı çok parçalı alanları kullanarak hem sürümün `ocr-runtime-index.json`'sini hem de eşleşen OCR çalışma zamanı arşivini `POST /api/v1/admin/features/import`'ye yükleyin. Çevrimdışı içe aktarma, çevrimiçi kurulumla aynı imza, karma, çıkarma, uyumluluk ve duman testi kontrollerini uygular; güvenilir imzalı dizini olmayan bir arşiv reddedilir. *** ## Arka Plan Kaldırma {#background-removal} **Araç rotası:** `remove-background`\ **Model:** BiRefNet (varsayılan) veya U2-Net varyantları ile rembg | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `model` | string | - | Model varyantı (isteğe bağlı geçersiz kılma) | | `backgroundType` | string | `"transparent"` | Şunlardan biri: `transparent`, `color`, `gradient`, `blur`, `image` | | `backgroundColor` | string | - | Düz arka plan için hex renk | | `gradientColor1` | string | - | Birinci gradyan rengi | | `gradientColor2` | string | - | İkinci gradyan rengi | | `gradientAngle` | number | - | Derece cinsinden gradyan açısı | | `blurEnabled` | boolean | - | Arka plan bulanıklaştırma efektini etkinleştir | | `blurIntensity` | number (0-100) | - | Bulanıklaştırma yoğunluğu | | `shadowEnabled` | boolean | - | Özne üzerinde gölge düşürmeyi etkinleştir | | `shadowOpacity` | number (0-100) | - | Gölge opaklığı | | `outputFormat` | string | - | Çıktı biçimi: `png`, `webp` veya `avif` | | `edgeRefine` | integer (0-3) | - | Kenar iyileştirme düzeyi | | `decontaminate` | boolean | - | Kenarlardan renk taşmasını kaldır | ## Arka Plan Değiştirme {#background-replace} **Araç rotası:** `background-replace`\ **Model:** rembg / BiRefNet (remove-background ile paylaşılır) Arka planı kaldırır ve düz bir renk veya gradyanla değiştirir. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | Arka plan modu | | `color` | string | `"#ffffff"` | Arka plan hex rengi (`backgroundType` değeri `color` olduğunda) | | `gradientColor1` | string | - | Birinci gradyan hex rengi | | `gradientColor2` | string | - | İkinci gradyan hex rengi | | `gradientAngle` | integer (0-360) | `180` | Derece cinsinden gradyan açısı | | `feather` | integer (0-20) | `0` | Kenar yumuşatma yarıçapı | | `format` | `"png"` | `"webp"` | `"png"` | Çıktı biçimi | ## Arka Planı Bulanıklaştırma {#blur-background} **Araç rotası:** `blur-background`\ **Model:** rembg / BiRefNet (remove-background ile paylaşılır) Özneyi keskin tutarken arka planı bulanıklaştırır. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | Bulanıklaştırma yoğunluğu | | `feather` | integer (0-20) | `0` | Kenar yumuşatma yarıçapı | | `format` | `"png"` | `"webp"` | `"png"` | Çıktı biçimi | ## Görüntü Büyütme {#image-upscaling} **Araç rotası:** `upscale`\ **Model:** RealESRGAN (kullanılamadığında Lanczos yedeği ile) | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `scale` | number | `2` | Büyütme faktörü | | `model` | string | `"auto"` | Model varyantı | | `faceEnhance` | boolean | `false` | GFPGAN yüz iyileştirme geçişi uygula | | `denoise` | number | `0` | Gürültü giderme gücü | | `format` | string | `"auto"` | Çıktı biçimi geçersiz kılma | | `quality` | number | `95` | Çıktı kalitesi (1-100) | ## OCR / Metin Çıkarma {#ocr-text-extraction} **Araç rotası:** `ocr`\ **Modeller:** Tesseract (`fast`); PP-OCRv6 küçük modellerle (`balanced`) RapidOCR; Kalibre edilmiş varyant puanlamasına sahip PP-OCRv6 orta modeller (`best`) | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dinamik | `quality` ve `engine` belirtilmezse SnapOtter kullanılabilir en iyi katmanı şu sırayla seçer: `best`, `balanced`, `fast`. Korece için `fast` hiçbir zaman seçilmez; `best`, ardından `balanced` kullanılır veya doğru çalışma zamanının kurulum ya da uyumluluk hatası döndürülür. | | `language` | string | `"auto"` | Dil: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `enhance` | boolean | Seviyeye bağlı | Yerel kontrastı iyileştirin. Hızlı doğrudan uygular; doğru katmanlar, yalnızca kalibre edilmiş puanlama OCR'yi iyileştirdiğinde varyantı korur. En İyi için Varsayılanlar Açıktır | | `engine` | sicim | - | Kullanımdan kaldırılan uyumluluk takma adı. `tesseract`'yi `fast`'ye ve eski `paddleocr` değerini `balanced`'ye eşler; PaddlePaddle yüklenmiyor | Çıkarılan metni artı kaynak meta verilerini döndürür: motor, istenen ve gerçek kalite, cihaz, sağlayıcı, bozulma durumu, uyarılar ve uygun olduğunda doğru çalışma zamanı/model sürümleri. Açık kalite istekleri hiçbir zaman başka bir katmana geri dönmez. `balanced` veya `best` kullanılamıyorsa API, `fast`'yi sessizce çalıştırmak yerine `FEATURE_NOT_INSTALLED` veya `FEATURE_INCOMPATIBLE`'yi döndürür. ## PDF OCR {#pdf-ocr} **Araç rotası:** `ocr-pdf`\ **Modeller:** Görüntü OCR ile aynı katman sistemi Yapay zeka destekli OCR kullanarak taranmış PDF belgelerinden sayfa sayfa metin çıkarır. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dinamik | `quality` ve `engine` belirtilmezse SnapOtter kullanılabilir en iyi katmanı şu sırayla seçer: `best`, `balanced`, `fast`. Korece için `fast` hiçbir zaman seçilmez; `best`, ardından `balanced` kullanılır veya doğru çalışma zamanının kurulum ya da uyumluluk hatası döndürülür. | | `language` | string | `"auto"` | Dil: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `pages` | string | `"all"` | Sayfa seçimi: `"all"`, `"1-3"`, `"1,3,5"` | | `enhance` | boolean | Seviyeye bağlı | Yerel kontrastı iyileştirin. Hızlı doğrudan uygular; doğru katmanlar, yalnızca kalibre edilmiş puanlama OCR'yi iyileştirdiğinde varyantı korur. En İyi için Varsayılanlar Açıktır | | `engine` | sicim | - | Kullanımdan kaldırılan uyumluluk takma adı. `tesseract`'yi `fast`'ye ve eski `paddleocr` değerini `balanced`'ye eşler; PaddlePaddle yüklenmiyor | Aynı sürüm düşürmeme kuralı PDF OCR için de geçerlidir. PDF sayfaları tanınmadan önce rasterleştirilir ve bir istek en fazla 50 sayfa seçebilir. ## Yüz / PII Bulanıklaştırma {#face-pii-blur} **Araç rotası:** `blur-faces`\ **Model:** MediaPipe yüz algılama | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | Gauss bulanıklaştırma yarıçapı | | `sensitivity` | number (0-1) | `0.5` | Algılama güven eşiği | ## Yüz İyileştirme {#face-enhancement} **Araç rotası:** `enhance-faces`\ **Modeller:** GFPGAN, CodeFormer | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | İyileştirme modeli | | `strength` | number (0-1) | `0.8` | İyileştirme gücü | | `sensitivity` | number (0-1) | `0.5` | Yüz algılama eşiği | | `onlyCenterFace` | boolean | `false` | Yalnızca en merkezi yüzü iyileştir | ## AI Renklendirme {#ai-colorization} **Araç rotası:** `colorize`\ **Model:** DDColor (OpenCV DNN yedeği ile) Siyah-beyaz veya gri tonlamalı fotoğrafları tam renge dönüştürür. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | Renk doygunluğu gücü | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | Model varyantı | ## Gürültü Giderme {#noise-removal} **Araç rotası:** `noise-removal`\ **Model:** SCUNet (katmanlı gürültü giderme hattı) | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | İşleme katmanı | | `strength` | number (0-100) | `50` | Gürültü giderme gücü | | `detailPreservation` | number (0-100) | `50` | Ne kadar ayrıntı korunacağı; daha yüksek değer daha fazla doku tutar | | `colorNoise` | number (0-100) | `30` | Renk gürültüsü azaltma gücü | | `format` | string | `"original"` | Çıktı biçimi: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | `quality` | number (1-100) | `90` | Çıktı kodlama kalitesi | ## Kırmızı Göz Giderme {#red-eye-removal} **Araç rotası:** `red-eye-removal` Yüz işaret noktalarını algılar, göz bölgelerini bulur ve kırmızı kanal aşırı doygunluğunu düzeltir. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | Kırmızı piksel algılama eşiği | | `strength` | number (0-100) | `70` | Düzeltme gücü | | `format` | string | - | Çıktı biçimi geçersiz kılma (isteğe bağlı) | | `quality` | number (1-100) | `90` | Çıktı kalitesi | ## Fotoğraf Onarımı {#photo-restoration} **Araç rotası:** `restore-photo` Eski veya hasarlı fotoğraflar için çok adımlı hat: çizik/yırtık algılama ve onarım, yüz iyileştirme, gürültü giderme ve isteğe bağlı renklendirme. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | Çizikleri, yırtıkları algıla ve onar | | `faceEnhancement` | boolean | `true` | Yüz iyileştirme geçişi uygula | | `fidelity` | number (0-1) | `0.7` | Yüz iyileştirme gücü (yüksek = daha temkinli) | | `denoise` | boolean | `true` | Gürültü giderme geçişi uygula | | `denoiseStrength` | number (0-100) | `25` | Gürültü giderme gücü | | `colorize` | boolean | `false` | Onarımdan sonra renklendir | | `colorizeStrength` | number (0-100) | `85` | Renklendirme yoğunluğu | ## Pasaport Fotoğrafı {#passport-photo} **Araç rotası:** `passport-photo`\ **Modeller:** MediaPipe yüz işaret noktaları + BiRefNet arka plan kaldırma İki aşamalı iş akışı: analiz et (yüzü algıla + arka planı kaldır) ardından oluştur (kırp, yeniden boyutlandır, döşe). 6 bölgede 37+ ülkeyi destekler. ### Aşama 1: Analiz {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` Bir görüntü dosyası (multipart) kabul eder. Yüz işaret noktası verisi, base64 önizleme ve görüntü boyutları döndürür. ### Aşama 2: Oluştur {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` Aşama 1 sonuçlarını artı oluşturma ayarlarını içeren bir JSON gövdesi kabul eder: | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `jobId` | string | (gerekli) | Aşama 1'den iş kimliği | | `filename` | string | (gerekli) | Aşama 1'den orijinal dosya adı | | `countryCode` | string | (gerekli) | ISO ülke kodu (örneğin, `US`, `GB`, `IN`) | | `documentType` | string | `"passport"` | Belge türü | | `bgColor` | string | `"#FFFFFF"` | Arka plan rengi hex | | `printLayout` | string | `"none"` | Baskı düzeni: `none`, `4x6`, `a4`, `letter` | | `maxFileSizeKb` | number | `0` | KB cinsinden maks dosya boyutu (0 = sınır yok) | | `dpi` | number (72-1200) | `300` | Çıktı DPI | | `customWidthMm` | number | - | mm cinsinden özel genişlik (ülke özelliğini geçersiz kılar) | | `customHeightMm` | number | - | mm cinsinden özel yükseklik (ülke özelliğini geçersiz kılar) | | `zoom` | number (0.5-3) | `1` | Yakınlaştırma faktörü | | `adjustX` | number | `0` | Yatay konum ayarı | | `adjustY` | number | `0` | Dikey konum ayarı | | `landmarks` | object | (gerekli) | Aşama 1'den işaret noktaları | | `imageWidth` | number | (gerekli) | Aşama 1'den görüntü genişliği | | `imageHeight` | number | (gerekli) | Aşama 1'den görüntü yüksekliği | ## Nesne Silme (Inpainting) {#object-erasing-inpainting} **Araç rotası:** `erase-object`\ **Model:** ONNX Runtime üzerinden LaMa Maske, base64 olarak değil, **ikinci bir dosya parçası** (alan adı `mask`) olarak gönderilir. Maskedeki beyaz pikseller silinecek alanları belirtir. `format` ve `quality` ayarları üst düzey form alanları olarak gönderilir. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `file` | file | (gerekli) | Kaynak görüntü (multipart) | | `mask` | file | (gerekli) | Maske görüntüsü (multipart, alan adı `mask`, beyaz = sil) | | `format` | string | `"auto"` | Çıktı biçimi: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Çıktı kalitesi | Bir NVIDIA GPU mevcut olduğunda CUDA hızlandırmalıdır. ## AI Tuval Genişletme {#ai-canvas-expand} **Araç rotası:** `ai-canvas-expand`\ **Model:** LaMa tabanlı outpainting Bir görüntünün tuvalini herhangi bir yönde genişletir ve yeni alanları mevcut görüntüyle eşleşen AI tarafından üretilen içerikle doldurur. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | Üstte genişletilecek piksel | | `extendRight` | integer | `0` | Sağda genişletilecek piksel | | `extendBottom` | integer | `0` | Altta genişletilecek piksel | | `extendLeft` | integer | `0` | Solda genişletilecek piksel | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | Kalite katmanı | | `format` | string | `"auto"` | Çıktı biçimi: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Çıktı kalitesi | En az bir genişletme yönü 0'dan büyük olmalıdır. ## Akıllı Kırpma {#smart-crop} **Araç rotası:** `smart-crop`\ **Model:** MediaPipe yüz algılama (yalnızca yüz modu) | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | Kırpma stratejisi: `subject`, `face`, `trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | Özne modu için strateji | | `width` | integer | - | Çıktı genişliği | | `height` | integer | - | Çıktı yüksekliği | | `padding` | integer (0-50) | `0` | Özne çevresindeki dolgu yüzdesi | | `facePreset` | string | `"head-shoulders"` | `mode=face` olduğunda ön ayarlı çerçeveleme | | `sensitivity` | number (0-1) | `0.5` | Yüz algılama eşiği | | `threshold` | integer (0-255) | `30` | Arka plan algılama eşiği (kırpma modu) | | `padToSquare` | boolean | `false` | Kırpılan sonucu kareye doldur | | `padColor` | string | `"#ffffff"` | Kare dolgusu için arka plan rengi | | `targetSize` | integer | - | Dolgulu çıktı için hedef boyut (piksel) | | `quality` | integer (1-100) | - | Çıktı kalitesi | Eski `mode` değerleri `attention` ve `content` kabul edilir ve sırasıyla `subject` ve `trim` ile eşlenir. **Yüz ön ayarları:** | Ön ayar | En uygun kullanım | |--------|---------| | `closeup` | Portre çekimleri | | `head-shoulders` | Profil fotoğrafları | | `upper-body` | LinkedIn / resmi | | `half-body` | Tam üst gövde | ## Sesi Yazıya Dök {#transcribe-audio} **Araç rotası:** `transcribe-audio`\ **Model:** faster-whisper Konuşmayı metne dönüştürür. Düz metin, SRT ve VTT çıktı biçimlerini destekler. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Dil: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | Çıktı biçimi | ## Otomatik Altyazılar {#auto-subtitles} **Araç rotası:** `auto-subtitles`\ **Model:** faster-whisper (videodan sesi çıkarır, ardından yazıya döker) Bir videonun ses parçasından altyazı dosyaları oluşturur. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Dil: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | Çıktı altyazı biçimi | ## PNG Saydamlık Düzeltici {#png-transparency-fixer} **Araç rotası:** `transparency-fixer`\ **Model:** BiRefNet HR-matting (2048x2048 çözünürlük) Arka planın kaldırıldığı ancak arkada saçaklanma, hale veya yarı saydam kalıntılar bırakıldığı "sahte saydam" PNG'leri düzeltir. Temiz bir alfa kanalı üretmek için BiRefNet'in yüksek çözünürlüklü matlama modelini kullanır, ardından kenarlar boyunca renk kirlenmesini kaldırmak için yapılandırılabilir saçak giderme işlemi uygular. **OOM yedek zinciri:** BiRefNet HR-matting mevcut belleği aşarsa, araç otomatik olarak önce `birefnet-general` değerine, ardından `u2net` değerine geri döner. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | Renk kirlenmesini kaldırmak için kenar saçak giderme gücü | | `outputFormat` | `"png"` | `"webp"` | `"png"` | Çıktı görüntü biçimi | | `removeWatermark` | boolean | `false` | Filigran kaldırma ön işlemesi uygula (medyan filtresi) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## İsteğe Bağlı AI Yetenekleri Olan Araçlar {#tools-with-optional-ai-capabilities} Aşağıdaki araçlar Python sidecar araçları değildir ancak belirli seçenekler etkinleştirildiğinde AI özelliklerini kullanır. ### Görüntü İyileştirme {#image-enhancement} **Araç rotası:** `image-enhancement`\ **Motor:** Analiz tabanlı (Sharp histogramı ve istatistikleri) Görüntüyü analiz eder ve pozlama, kontrast, beyaz dengesi, doygunluk, keskinlik ve gürültü için otomatik düzeltmeler uygular. Sahneye özgü modları destekler. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | Düzeltmeleri ayarlamak için sahne modu | | `intensity` | number (0-100) | `50` | Genel düzeltme gücü | | `corrections.exposure` | boolean | `true` | Pozlama düzeltmesi uygula | | `corrections.contrast` | boolean | `true` | Kontrast düzeltmesi uygula | | `corrections.whiteBalance` | boolean | `true` | Beyaz dengesi düzeltmesi uygula | | `corrections.saturation` | boolean | `true` | Doygunluk düzeltmesi uygula | | `corrections.sharpness` | boolean | `true` | Keskinlik düzeltmesi uygula | | `corrections.denoise` | boolean | `true` | Gürültü giderme uygula | | `deepEnhance` | boolean | `false` | SCUNet üzerinden AI gürültü giderme etkinleştir (`upscale-enhance` paketi gerektirir) | `POST /api/v1/tools/image/image-enhancement/analyze` adresinde, algılanan düzeltmeleri uygulamadan döndüren ek bir analiz uç noktası mevcuttur. ### İçerik Duyarlı Yeniden Boyutlandırma (Seam Carving) {#content-aware-resize-seam-carving} **Araç rotası:** `content-aware-resize`\ **Motor:** Go `caire` ikilisi (Python değil, GPU avantajı yok) Düşük enerjili dikişleri kaldırarak görüntüleri akıllıca yeniden boyutlandırır, önemli içeriği korur. | Parametre | Tür | Varsayılan | Açıklama | |-----------|------|---------|-------------| | `width` | number | - | Hedef genişlik | | `height` | number | - | Hedef yükseklik | | `protectFaces` | boolean | `false` | Algılanan yüz bölgelerini koru (`face-detection` paketi gerektirir) | | `blurRadius` | number (0-20) | `4` | Enerji hesaplaması için ön bulanıklaştırma | | `sobelThreshold` | number (1-20) | `2` | Kenar hassasiyeti eşiği | | `square` | boolean | `false` | Kare çıktıyı zorla | --- --- url: https://docs.snapotter.com/tr/tools/image/colorize.md description: >- Siyah beyaz veya gri tonlamalı fotoğrafları DDColor AI modeliyle otomatik olarak renklendirin. --- # AI Renklendirme {#ai-colorization} Siyah beyaz veya gri tonlamalı fotoğrafları AI kullanarak (OpenCV DNN yedeği ile DDColor modeli) tam renkli hale getirin. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/colorize` **İşleme:** Eşzamansız (202 döndürür, durum için SSE aracılığıyla `/api/v1/jobs/{jobId}/progress` yoklaması yapın) **Model paketi:** `object-eraser-colorize` (1-2 GB) ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | file | Evet | - | Görüntü dosyası (çok parçalı) | | intensity | number | Hayır | `1.0` | Renk yoğunluğu (0-1). Daha düşük değerler daha ince renklendirme üretir | | model | string | Hayır | `"auto"` | Kullanılacak model: `auto`, `ddcolor`, `opencv` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Yanıt {#response} ### İlk Yanıt (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### İlerleme (`/api/v1/jobs/{jobId}/progress` konumunda SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Nihai Sonuç (SSE aracılığıyla) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notlar {#notes} * `object-eraser-colorize` model paketinin kurulu olmasını gerektirir (1-2 GB). * DDColor daha yüksek kaliteli sonuçlar üretir ancak daha yavaştır; OpenCV DNN biraz daha düşük kaliteyle daha hızlıdır. `auto`, kullanılabilir olduğunda OpenCV yedeği ile DDColor kullanır. * `intensity` parametresi, orijinal gri tonlama ile AI ile renklendirilmiş sonuç arasında harmanlama yapar. Tam renk için 1.0, kısmen doygunluğu azaltılmış vintage bir görünüm için daha düşük değerler kullanın. * Çıktı biçimi otomatik olarak giriş biçimiyle eşleşir. * Tarayıcıda önizlenemeyen çıktı biçimleri için ana çıktının yanı sıra bir WebP önizlemesi oluşturulur. * Otomatik çözme yoluyla HEIC/HEIF, RAW, TGA, PSD, EXR ve HDR giriş biçimlerini destekler. --- --- url: https://docs.snapotter.com/tr/tools/image/ai-canvas-expand.md description: >- Bir görsel tuvalini AI outpainting ile genişletin, her yöne uzatın ve yeni alanları özgün görsele uyacak şekilde doldurun. --- # AI Tuval Genişletme {#ai-canvas-expand} Bir görselin tuvalini AI destekli dolgu (outpainting) ile genişletin. Görseli her yöne uzatır ve yeni alanları mevcut görselle eşleşen AI tarafından üretilen içerikle doldurur. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **İşleme:** Eşzamansız (202 döndürür, durum için `/api/v1/jobs/{jobId}/progress` SSE üzerinden yoklanır) **Model paketi:** `object-eraser-colorize` (1-2 GB) ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | dosya | Evet | - | Görsel dosyası (multipart) | | extendTop | tam sayı | Hayır | `0` | Üstten uzatılacak piksel sayısı | | extendRight | tam sayı | Hayır | `0` | Sağdan uzatılacak piksel sayısı | | extendBottom | tam sayı | Hayır | `0` | Alttan uzatılacak piksel sayısı | | extendLeft | tam sayı | Hayır | `0` | Soldan uzatılacak piksel sayısı | | tier | dize | Hayır | `"balanced"` | Kalite kademesi: `fast`, `balanced`, `high` | | format | dize | Hayır | `"auto"` | Çıktı biçimi: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | tam sayı | Hayır | `95` | Çıktı kalitesi (1-100) | En az bir uzatma yönü 0'dan büyük olmalıdır. ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Yanıt {#response} ### İlk Yanıt (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### İlerleme (`/api/v1/jobs/{jobId}/progress` adresinde SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Nihai Sonuç (SSE üzerinden) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notlar {#notes} * `object-eraser-colorize` model paketinin yüklü olmasını gerektirir (1-2 GB). * Genişletilen bölgeler için içerik üretmek amacıyla LaMa tabanlı outpainting kullanır. * `tier` parametresi hız ile kaliteyi dengeler: `fast` sonuçları olası eserlerle hızlıca üretir, `high` daha uzun sürer ancak daha pürüzsüz ve tutarlı dolgular üretir. * Uzatma değerleri piksel cinsindendir. Nihai görsel boyutları şöyle olur: özgün genişlik + extendLeft + extendRight, özgün yükseklik + extendTop + extendBottom. * Tarayıcıda önizlenemeyen çıktı biçimleri (HEIC, JXL, TIFF) için ana çıktının yanında bir WebP önizlemesi üretilir. * Otomatik çözme yoluyla HEIC/HEIF, RAW, TGA, PSD, EXR ve HDR giriş biçimlerini destekler. --- --- url: https://docs.snapotter.com/hi/api/ai.md description: >- सभी लोकल ML टूल के साथ AI इंजन संदर्भ। बैकग्राउंड हटाना, अपस्केलिंग, OCR, फेस डिटेक्शन, फोटो रिस्टोरेशन, और बहुत कुछ। --- # AI इंजन संदर्भ {#ai-engine-reference} `@snapotter/ai` पैकेज स्थानीय ML संचालन के लिए मूल उपकरण और Python रनटाइम का समन्वय करता है। अधिकांश ML उपकरण तेज़ वार्म स्टार्ट के लिए लगातार Python sidecar का उपयोग करते हैं। OCR जानबूझकर अलग है: `fast` मूल Tesseract बाइनरी को आमंत्रित करता है, जबकि `balanced` और `best` एक समर्पित निरंतर JSONL dispatcher का उपयोग करते हैं जो सक्रिय अपरिवर्तनीय RapidOCR पीढ़ी के अंतर्गत पिन किया गया है। `/data/ai/v3`. प्रत्येक अनुरोध में एक generation lease होता है। अपग्रेड के दौरान, SnapOtter सक्रियण से पहले उम्मीदवार पर एक smoke test चलाता है, परमाणु रूप से नए dispatcher पर स्विच करता है, फिर garbage collection से पहले पुरानी पीढ़ी को हटा देता है। NVIDIA CUDA का स्वत: पता लगाया जाता है और इसका समर्थन करने वाले रनटाइम द्वारा उपयोग किया जाता है। OCR प्रत्येक होस्ट पर CPU का उपयोग करता है, जिसमें NVIDIA GPU वाले सिस्टम भी शामिल हैं, इस टूल के लिए CUDA और ड्राइवर कपलिंग से बचा जाता है। VA-API, Quick Sync, या OpenCL के माध्यम से Intel/AMD iGPU त्वरण आज AI इन्फेरेंस के लिए समर्थित नहीं है। किसी कंटेनर में `/dev/dri` को मैप करना इन Python साइडकार टूल को तेज़ नहीं करता जब तक कोई CUDA-सक्षम NVIDIA GPU उपलब्ध न हो। चार मोडैलिटी (image, audio, video, document) में 19 Python साइडकार AI टूल, साथ ही वैकल्पिक AI क्षमताओं वाले 2 टूल। सभी मॉडल लोकल रूप से चलते हैं; प्रारंभिक मॉडल डाउनलोड के बाद इंटरनेट की आवश्यकता नहीं। ::: info कोरियाई OCR संगतता तेज़ OCR `auto`, `en`, `de`, `es`, `fr`, `zh` और `ja` का समर्थन करता है, लेकिन कोरियाई (`ko`) का नहीं। कोरियाई के लिए सटीक OCR पैक और `balanced` या `best` आवश्यक है। पैक आधिकारिक Linux amd64 और arm64 कंटेनरों पर चलता है; NVIDIA होस्ट पर भी OCR CPU पर ही चलता है। असमर्थित सिस्टम स्पष्ट संगतता त्रुटि लौटाते हैं और चुपचाप `fast` पर वापस नहीं जाते। कोरियाई के साथ `fast` या पुराने `tesseract` नाम को कतार में डालने से पहले `FEATURE_INCOMPATIBLE` और `fast-korean-unsupported` के साथ अस्वीकार किया जाता है। ::: ## आर्किटेक्चर {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` एक अलग "docs" डिस्पैचर प्रोफ़ाइल AI अनुमति सूची को दस्तावेज़-प्रसंस्करण स्क्रिप्ट (`doc_pagecount`, `doc_health`, `doc_flatten`, `doc_redact`, `doc_text`, `doc_to_word`, `doc_metadata`, `doc_html_pdf`) से बदल देती है और भारी ML आयातों को छोड़ देती है। **टाइमआउट:** 300 s डिफ़ॉल्ट; OCR और BiRefNet बैकग्राउंड हटाने को 600 s मिलते हैं। ## फ़ीचर बंडल {#feature-bundles} AI मॉडल साझा डिपेंडेंसी स्टैक द्वारा पैकेज किए जाते हैं, प्रति टूल एक आर्काइव नहीं। एक फ़ीचर बंडल कई टूल को सक्षम कर सकता है जब वे एक ही मॉडल परिवार, Python wheels, या नेटिव लाइब्रेरी का उपयोग करते हैं। इससे रिलीज़ Docker इमेज छोटी रहती है और एक ही बैकग्राउंड मैटिंग, फेस डिटेक्शन, OCR, रिस्टोरेशन, और स्पीच मॉडल की डुप्लिकेट प्रतियाँ संग्रहीत करने से बचा जाता है। Docker इमेज एप्लिकेशन के साथ-साथ सामान्य रनटाइम भेजती है। बड़े मॉडल आर्काइव माँग पर स्थायी `/data/ai` वॉल्यूम में डाउनलोड किए जाते हैं, फिर हर उस टूल द्वारा पुनः उपयोग किए जाते हैं जिसे उनकी आवश्यकता होती है। यदि कोई बंडल पहले से इंस्टॉल है क्योंकि किसी अन्य टूल को उसकी आवश्यकता थी, तो एक नया आश्रित टूल सक्षम करना उस बंडल को दोबारा डाउनलोड नहीं करता। अधिकांश एआई टूल को चलने से पहले एक या अधिक फीचर बंडलों की आवश्यकता होती है। व्यवस्थापक यूआई उन्हें `POST /api/v1/admin/tools/:toolId/features/install` के माध्यम से टूल द्वारा इंस्टॉल करता है, जो पूर्ण बंडल सूची को हल करता है, पहले से इंस्टॉल किए गए बंडलों को छोड़ देता है, और केवल लापता डाउनलोड को कतार में रखता है। उदाहरण के लिए, पासपोर्ट फोटो को ताजा इंस्टेंस कतारों `background-removal` और `face-detection` पर सक्षम करना; बैकग्राउंड रिमूवल के बाद इसे सक्षम करने से केवल `face-detection` कतारें पहले से ही स्थापित हैं। OCR अपवाद है क्योंकि `fast` को किसी पैक की आवश्यकता नहीं है; UI या `POST /api/v1/admin/features/ocr/install` के माध्यम से इसका वैकल्पिक सटीक रनटाइम स्थापित करें। | बंडल | आकार | साझा डिपेंडेंसी समूह | इसका उपयोग करने वाले टूल | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet बैकग्राउंड मैटिंग | remove-background, passport-photo, transparency-fixer, background-replace, blur-background | | `face-detection` | 200-300 MB | MediaPipe फेस डिटेक्शन और लैंडमार्क | blur-faces, red-eye-removal, smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa इनपेंटिंग/आउटपेंटिंग और DDColor | erase-object, colorize, ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN, GFPGAN / CodeFormer, डीनॉइज़िंग | upscale, enhance-faces, noise-removal | | `photo-restoration` | 4-5 GB | स्क्रैच रिपेयर और रिस्टोरेशन पाइपलाइन | restore-photo | | `ocr` | ~208-234 MiB डाउनलोड / ~409-488 MiB स्थापित | वैकल्पिक RapidOCR 3.9.1, ONNX Runtime 1.20.1, और पिन किए गए PP-OCR मॉडल | ओसीआर, ओसीआर-पीडीएफ (केवल `balanced` और `best`) | | `transcription` | ~600 MB | faster-whisper स्पीच-टू-टेक्स्ट मॉडल | transcribe-audio, auto-subtitles | क्रॉस-बंडल डिपेंडेंसी वाले टूल: | टूल | आवश्यक बंडल | क्यों | |------|------------------|-----| | `passport-photo` | `background-removal`, `face-detection` | बैकग्राउंड हटाता है, फिर पासपोर्ट और ID फोटो नियमों के अनुसार क्रॉप को फ्रेम करने के लिए फेस लैंडमार्क का उपयोग करता है। | | `enhance-faces` | `upscale-enhance`, `face-detection` | चयनित फेस क्षेत्रों पर GFPGAN या CodeFormer एन्हांसमेंट चलाने से पहले फेस का पता लगाता है। | एक उपकरण तभी उपलब्ध होता है जब OCR को छोड़कर उसके सभी आवश्यक बंडल इंस्टॉल हो जाते हैं: इसका अंतर्निहित `fast` टियर वैकल्पिक OCR पैक के बिना उपलब्ध रहता है। आंशिक इंस्टॉल मान्य हैं और इन्हें क्रमिक रूप से प्रबंधित किया जाता है: इंस्टॉल किए गए बंडलों का पुन: उपयोग किया जाता है, लापता बंडलों को डाउनलोड के रूप में दिखाया जाता है, और कतारबद्ध इंस्टॉल एक समय में एक चलते हैं इसलिए साझा Python वातावरण को समवर्ती रूप से संशोधित नहीं किया जाता है। ### सटीक OCR रनटाइम इंस्टॉलेशन {#accurate-ocr-runtime-installation} सटीक OCR पैक आधिकारिक Linux amd64 या Linux arm64 कंटेनर के लिए एक प्लेटफ़ॉर्म-विशिष्ट रनटाइम है। amd64 बिल्ड Python 3.12 का उपयोग करता है; arm64 बिल्ड Python 3.11 का उपयोग करता है। दोनों बिल्ड RapidOCR को ONNX Runtime के `CPUExecutionProvider` के माध्यम से चलाते हैं, तो वही पैक केवल CPU और NVIDIA Docker होस्ट पर काम करता है। सटीक रनटाइम के लिए कम से कम 4 GiB प्रभावी मेमोरी की आवश्यकता होती है: कॉन्फ़िगर कंटेनर cgroup सीमा, अन्यथा होस्ट मेमोरी। उस हस्ताक्षरित अनुकूलता न्यूनतम से नीचे की प्रणाली को डाउनलोड से पहले अस्वीकार कर दिया जाता है। यह आवश्यकता बिल्ट-इन फास्ट OCR पर लागू नहीं होती है। Bare-metal बिल्ड को अस्वीकार कर दिया गया है क्योंकि उनके libc और Python ABI का सुरक्षित रूप से अनुमान नहीं लगाया जा सकता है; जब होस्ट Tesseract और Ghostscript प्रदान करता है तो तेज़ OCR उपलब्ध रहता है। आर्किटेक्चर के आधार पर वैकल्पिक आर्टिफैक्ट लगभग 208-234 MiB संपीड़ित और 409-488 MiB निकाला गया है। हस्ताक्षरित सूचकांक इंस्टॉलर द्वारा लागू सटीक संपीड़ित और निकाले गए बाइट गिनती को बांधता है। अंतर्निहित Tesseract आधिकारिक छवि में लगभग 25 MiB जोड़ता है और `/data/ai` में किसी फ़ाइल की आवश्यकता नहीं है। ऑनलाइन इंस्टॉलेशन एक हस्ताक्षरित रिलीज़ इंडेक्स और वर्तमान प्लेटफ़ॉर्म के लिए सटीक सामग्री-संबोधित आर्टिफैक्ट लाता है। SnapOtter नई पीढ़ी को परमाणु रूप से सक्रिय करने से पहले Ed25519 इंडेक्स हस्ताक्षर, आर्टिफैक्ट आकार, SHA-256 डाइजेस्ट, मॉडल डाइजेस्ट, पथ, फ़ाइल मोड और चरणबद्ध smoke test को सत्यापित करता है। एक असफल इंस्टालेशन पूर्व स्वस्थ पीढ़ी को सक्रिय छोड़ देता है। एयर-गैप्ड इंस्टॉलेशन के लिए, `index` और `archive` नामक मल्टीपार्ट फ़ील्ड का उपयोग करके रिलीज़ के `ocr-runtime-index.json` और मिलान वाले OCR रनटाइम संग्रह को `POST /api/v1/admin/features/import` पर अपलोड करें। ऑफ़लाइन आयात ऑनलाइन इंस्टॉलेशन के समान ही हस्ताक्षर, हैश, निष्कर्षण, संगतता और धुआं-परीक्षण जांच लागू करता है; विश्वसनीय हस्ताक्षरित अनुक्रमणिका के बिना एक संग्रह अस्वीकार कर दिया जाता है। *** ## बैकग्राउंड हटाना {#background-removal} **टूल रूट:** `remove-background`\ **मॉडल:** BiRefNet (डिफ़ॉल्ट) या U2-Net वेरिएंट के साथ rembg | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `model` | string | - | मॉडल वेरिएंट (वैकल्पिक ओवरराइड) | | `backgroundType` | string | `"transparent"` | इनमें से एक: `transparent`, `color`, `gradient`, `blur`, `image` | | `backgroundColor` | string | - | ठोस बैकग्राउंड के लिए Hex रंग | | `gradientColor1` | string | - | पहला ग्रेडिएंट रंग | | `gradientColor2` | string | - | दूसरा ग्रेडिएंट रंग | | `gradientAngle` | number | - | डिग्री में ग्रेडिएंट कोण | | `blurEnabled` | boolean | - | बैकग्राउंड ब्लर प्रभाव सक्षम करें | | `blurIntensity` | number (0-100) | - | ब्लर तीव्रता | | `shadowEnabled` | boolean | - | विषय पर ड्रॉप शैडो सक्षम करें | | `shadowOpacity` | number (0-100) | - | शैडो अपारदर्शिता | | `outputFormat` | string | - | आउटपुट प्रारूप: `png`, `webp`, या `avif` | | `edgeRefine` | integer (0-3) | - | एज रिफाइनमेंट स्तर | | `decontaminate` | boolean | - | किनारों से रंग रिसाव हटाएँ | ## बैकग्राउंड बदलना {#background-replace} **टूल रूट:** `background-replace`\ **मॉडल:** rembg / BiRefNet (remove-background के साथ साझा) बैकग्राउंड हटाता है और उसे ठोस रंग या ग्रेडिएंट से बदल देता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | बैकग्राउंड मोड | | `color` | string | `"#ffffff"` | बैकग्राउंड hex रंग (जब `backgroundType` `color` हो) | | `gradientColor1` | string | - | पहला ग्रेडिएंट hex रंग | | `gradientColor2` | string | - | दूसरा ग्रेडिएंट hex रंग | | `gradientAngle` | integer (0-360) | `180` | डिग्री में ग्रेडिएंट कोण | | `feather` | integer (0-20) | `0` | एज फेदरिंग त्रिज्या | | `format` | `"png"` | `"webp"` | `"png"` | आउटपुट प्रारूप | ## बैकग्राउंड ब्लर {#blur-background} **टूल रूट:** `blur-background`\ **मॉडल:** rembg / BiRefNet (remove-background के साथ साझा) विषय को शार्प रखते हुए बैकग्राउंड को ब्लर करता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | ब्लर तीव्रता | | `feather` | integer (0-20) | `0` | एज फेदरिंग त्रिज्या | | `format` | `"png"` | `"webp"` | `"png"` | आउटपुट प्रारूप | ## इमेज अपस्केलिंग {#image-upscaling} **टूल रूट:** `upscale`\ **मॉडल:** RealESRGAN (अनुपलब्ध होने पर Lanczos फ़ॉलबैक के साथ) | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `scale` | number | `2` | अपस्केल कारक | | `model` | string | `"auto"` | मॉडल वेरिएंट | | `faceEnhance` | boolean | `false` | GFPGAN फेस एन्हांसमेंट पास लागू करें | | `denoise` | number | `0` | डीनॉइज़िंग शक्ति | | `format` | string | `"auto"` | आउटपुट प्रारूप ओवरराइड | | `quality` | number | `95` | आउटपुट गुणवत्ता (1-100) | ## OCR / टेक्स्ट निष्कर्षण {#ocr-text-extraction} **टूल रूट:** `ocr`\ **मॉडल:** Tesseract (`fast`); RapidOCR PP-OCRv6 छोटे मॉडल (`balanced`) के साथ; कैलिब्रेटेड वैरिएंट स्कोरिंग के साथ PP-OCRv6 मध्यम मॉडल (`best`) | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | गतिशील | जब `quality` और `engine` नहीं दिए जाते, SnapOtter इस क्रम में सर्वोत्तम उपलब्ध टियर चुनता है: `best`, `balanced`, `fast`। कोरियाई के लिए `fast` कभी नहीं चुना जाता; `best`, फिर `balanced` उपयोग होता है, अन्यथा सटीक रनटाइम का इंस्टॉलेशन या संगतता त्रुटि लौटती है। | | `language` | string | `"auto"` | भाषा: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `enhance` | बूलियन | स्तर पर निर्भर | स्थानीय कंट्रास्ट में सुधार करें. फास्ट इसे सीधे लागू करता है; सटीक स्तर केवल तभी भिन्न होते हैं जब कैलिब्रेटेड स्कोरिंग OCR में सुधार करती है। सर्वश्रेष्ठ के लिए डिफ़ॉल्ट चालू | | `engine` | डोरी | - | अस्वीकृत अनुकूलता उपनाम. `tesseract` को `fast` और पुराने `paddleocr` मान को `balanced` में मैप करें; यह PaddlePaddle लोड नहीं करता है | निकाले गए पाठ और उद्गम मेटाडेटा को लौटाता है: इंजन, अनुरोधित और वास्तविक गुणवत्ता, उपकरण, प्रदाता, गिरावट की स्थिति, चेतावनियां, और लागू होने पर सटीक-रनटाइम/मॉडल संस्करण। स्पष्ट गुणवत्ता अनुरोध कभी भी दूसरे स्तर पर नहीं आते। यदि `balanced` या `best` अनुपलब्ध है, तो API चुपचाप `fast` चलाने के बजाय `FEATURE_NOT_INSTALLED` या `FEATURE_INCOMPATIBLE` लौटाता है। ## PDF OCR {#pdf-ocr} **टूल रूट:** `ocr-pdf`\ **मॉडल:** इमेज OCR जैसी ही स्तर प्रणाली AI-संचालित OCR का उपयोग करके स्कैन किए गए PDF दस्तावेज़ों से पृष्ठ दर पृष्ठ टेक्स्ट निकालता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | गतिशील | जब `quality` और `engine` नहीं दिए जाते, SnapOtter इस क्रम में सर्वोत्तम उपलब्ध टियर चुनता है: `best`, `balanced`, `fast`। कोरियाई के लिए `fast` कभी नहीं चुना जाता; `best`, फिर `balanced` उपयोग होता है, अन्यथा सटीक रनटाइम का इंस्टॉलेशन या संगतता त्रुटि लौटती है। | | `language` | string | `"auto"` | भाषा: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `pages` | string | `"all"` | पृष्ठ चयन: `"all"`, `"1-3"`, `"1,3,5"` | | `enhance` | बूलियन | स्तर पर निर्भर | स्थानीय कंट्रास्ट में सुधार करें. फास्ट इसे सीधे लागू करता है; सटीक स्तर केवल तभी भिन्न होते हैं जब कैलिब्रेटेड स्कोरिंग OCR में सुधार करती है। सर्वश्रेष्ठ के लिए डिफ़ॉल्ट चालू | | `engine` | डोरी | - | अस्वीकृत अनुकूलता उपनाम. `tesseract` को `fast` और पुराने `paddleocr` मान को `balanced` में मैप करें; यह PaddlePaddle लोड नहीं करता है | वही नो-डाउनग्रेड नियम PDF OCR पर लागू होता है। PDF पृष्ठों को पहचान से पहले रैस्टराइज़ किया जाता है, और एक अनुरोध अधिकतम 50 पृष्ठों का चयन कर सकता है। ## फेस / PII ब्लर {#face-pii-blur} **टूल रूट:** `blur-faces`\ **मॉडल:** MediaPipe फेस डिटेक्शन | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | गॉसियन ब्लर त्रिज्या | | `sensitivity` | number (0-1) | `0.5` | डिटेक्शन कॉन्फ़िडेंस थ्रेशोल्ड | ## फेस एन्हांसमेंट {#face-enhancement} **टूल रूट:** `enhance-faces`\ **मॉडल:** GFPGAN, CodeFormer | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | एन्हांसमेंट मॉडल | | `strength` | number (0-1) | `0.8` | एन्हांसमेंट शक्ति | | `sensitivity` | number (0-1) | `0.5` | फेस डिटेक्शन थ्रेशोल्ड | | `onlyCenterFace` | boolean | `false` | केवल सबसे केंद्रीय फेस को एन्हांस करें | ## AI कलराइज़ेशन {#ai-colorization} **टूल रूट:** `colorize`\ **मॉडल:** DDColor (OpenCV DNN फ़ॉलबैक के साथ) ब्लैक-एंड-व्हाइट या ग्रेस्केल फोटो को पूर्ण रंग में बदलता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | रंग संतृप्ति शक्ति | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | मॉडल वेरिएंट | ## नॉइज़ हटाना {#noise-removal} **टूल रूट:** `noise-removal`\ **मॉडल:** SCUNet (स्तरीय डीनॉइज़िंग पाइपलाइन) | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | प्रसंस्करण स्तर | | `strength` | number (0-100) | `50` | डीनॉइज़िंग शक्ति | | `detailPreservation` | number (0-100) | `50` | कितना विवरण संरक्षित करना है; अधिक होने पर अधिक टेक्सचर बना रहता है | | `colorNoise` | number (0-100) | `30` | कलर नॉइज़ कमी शक्ति | | `format` | string | `"original"` | आउटपुट प्रारूप: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | `quality` | number (1-100) | `90` | आउटपुट एन्कोडिंग गुणवत्ता | ## रेड आई हटाना {#red-eye-removal} **टूल रूट:** `red-eye-removal` फेस लैंडमार्क का पता लगाता है, आँख क्षेत्रों को खोजता है, और रेड-चैनल ओवरसैचुरेशन को ठीक करता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | रेड पिक्सेल डिटेक्शन थ्रेशोल्ड | | `strength` | number (0-100) | `70` | सुधार शक्ति | | `format` | string | - | आउटपुट प्रारूप ओवरराइड (वैकल्पिक) | | `quality` | number (1-100) | `90` | आउटपुट गुणवत्ता | ## फोटो रिस्टोरेशन {#photo-restoration} **टूल रूट:** `restore-photo` पुरानी या क्षतिग्रस्त फोटो के लिए बहु-चरण पाइपलाइन: स्क्रैच/फटने का पता लगाना और मरम्मत, फेस एन्हांसमेंट, डीनॉइज़िंग, और वैकल्पिक कलराइज़ेशन। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | स्क्रैच, फटने का पता लगाएँ और मरम्मत करें | | `faceEnhancement` | boolean | `true` | फेस एन्हांसमेंट पास लागू करें | | `fidelity` | number (0-1) | `0.7` | फेस एन्हांसमेंट शक्ति (अधिक = अधिक संरक्षी) | | `denoise` | boolean | `true` | डीनॉइज़िंग पास लागू करें | | `denoiseStrength` | number (0-100) | `25` | डीनॉइज़िंग शक्ति | | `colorize` | boolean | `false` | रिस्टोरेशन के बाद कलराइज़ करें | | `colorizeStrength` | number (0-100) | `85` | कलराइज़ेशन तीव्रता | ## पासपोर्ट फोटो {#passport-photo} **टूल रूट:** `passport-photo`\ **मॉडल:** MediaPipe फेस लैंडमार्क + BiRefNet बैकग्राउंड हटाना दो-चरण वर्कफ़्लो: विश्लेषण (फेस का पता लगाना + बैकग्राउंड हटाना) फिर जनरेट (क्रॉप, आकार बदलना, टाइल)। 6 क्षेत्रों में 37+ देशों का समर्थन करता है। ### चरण 1: विश्लेषण {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` एक इमेज फ़ाइल (multipart) स्वीकार करता है। फेस लैंडमार्क डेटा, एक base64 प्रीव्यू, और इमेज आयाम लौटाता है। ### चरण 2: जनरेट {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` चरण 1 के परिणामों के साथ-साथ जनरेशन सेटिंग्स वाला एक JSON बॉडी स्वीकार करता है: | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `jobId` | string | (आवश्यक) | चरण 1 से Job ID | | `filename` | string | (आवश्यक) | चरण 1 से मूल फ़ाइल नाम | | `countryCode` | string | (आवश्यक) | ISO देश कोड (जैसे, `US`, `GB`, `IN`) | | `documentType` | string | `"passport"` | दस्तावेज़ प्रकार | | `bgColor` | string | `"#FFFFFF"` | बैकग्राउंड रंग hex | | `printLayout` | string | `"none"` | प्रिंट लेआउट: `none`, `4x6`, `a4`, `letter` | | `maxFileSizeKb` | number | `0` | KB में अधिकतम फ़ाइल आकार (0 = कोई सीमा नहीं) | | `dpi` | number (72-1200) | `300` | आउटपुट DPI | | `customWidthMm` | number | - | mm में कस्टम चौड़ाई (देश स्पेक को ओवरराइड करती है) | | `customHeightMm` | number | - | mm में कस्टम ऊँचाई (देश स्पेक को ओवरराइड करती है) | | `zoom` | number (0.5-3) | `1` | ज़ूम कारक | | `adjustX` | number | `0` | क्षैतिज स्थिति समायोजन | | `adjustY` | number | `0` | ऊर्ध्वाधर स्थिति समायोजन | | `landmarks` | object | (आवश्यक) | चरण 1 से लैंडमार्क | | `imageWidth` | number | (आवश्यक) | चरण 1 से इमेज चौड़ाई | | `imageHeight` | number | (आवश्यक) | चरण 1 से इमेज ऊँचाई | ## ऑब्जेक्ट मिटाना (इनपेंटिंग) {#object-erasing-inpainting} **टूल रूट:** `erase-object`\ **मॉडल:** ONNX Runtime के माध्यम से LaMa मास्क को एक **दूसरे फ़ाइल भाग** (fieldname `mask`) के रूप में भेजा जाता है, base64 के रूप में नहीं। मास्क में सफेद पिक्सेल मिटाने वाले क्षेत्रों को इंगित करते हैं। `format` और `quality` सेटिंग्स शीर्ष-स्तरीय फ़ॉर्म फ़ील्ड के रूप में भेजी जाती हैं। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `file` | file | (आवश्यक) | स्रोत इमेज (multipart) | | `mask` | file | (आवश्यक) | मास्क इमेज (multipart, fieldname `mask`, सफेद = मिटाएँ) | | `format` | string | `"auto"` | आउटपुट प्रारूप: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | आउटपुट गुणवत्ता | NVIDIA GPU उपलब्ध होने पर CUDA-त्वरित। ## AI कैनवास विस्तार {#ai-canvas-expand} **टूल रूट:** `ai-canvas-expand`\ **मॉडल:** LaMa-आधारित आउटपेंटिंग किसी इमेज के कैनवास को किसी भी दिशा में विस्तारित करता है और नए क्षेत्रों को AI-जनित सामग्री से भरता है जो मौजूदा इमेज से मेल खाती है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | शीर्ष पर विस्तारित करने के लिए पिक्सेल | | `extendRight` | integer | `0` | दाईं ओर विस्तारित करने के लिए पिक्सेल | | `extendBottom` | integer | `0` | नीचे विस्तारित करने के लिए पिक्सेल | | `extendLeft` | integer | `0` | बाईं ओर विस्तारित करने के लिए पिक्सेल | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | गुणवत्ता स्तर | | `format` | string | `"auto"` | आउटपुट प्रारूप: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | आउटपुट गुणवत्ता | कम से कम एक विस्तार दिशा 0 से अधिक होनी चाहिए। ## स्मार्ट क्रॉप {#smart-crop} **टूल रूट:** `smart-crop`\ **मॉडल:** MediaPipe फेस डिटेक्शन (केवल फेस मोड) | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | क्रॉप रणनीति: `subject`, `face`, `trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | विषय मोड के लिए रणनीति | | `width` | integer | - | आउटपुट चौड़ाई | | `height` | integer | - | आउटपुट ऊँचाई | | `padding` | integer (0-50) | `0` | विषय के चारों ओर पैडिंग प्रतिशत | | `facePreset` | string | `"head-shoulders"` | `mode=face` होने पर प्रीसेट फ्रेमिंग | | `sensitivity` | number (0-1) | `0.5` | फेस डिटेक्शन थ्रेशोल्ड | | `threshold` | integer (0-255) | `30` | बैकग्राउंड डिटेक्शन थ्रेशोल्ड (ट्रिम मोड) | | `padToSquare` | boolean | `false` | ट्रिम किए गए परिणाम को वर्ग में पैड करें | | `padColor` | string | `"#ffffff"` | वर्ग पैडिंग के लिए बैकग्राउंड रंग | | `targetSize` | integer | - | पैड किए गए आउटपुट के लिए लक्ष्य आकार (पिक्सेल) | | `quality` | integer (1-100) | - | आउटपुट गुणवत्ता | लेगेसी `mode` मान `attention` और `content` स्वीकार किए जाते हैं और क्रमशः `subject` और `trim` पर मैप किए जाते हैं। **फेस प्रीसेट:** | प्रीसेट | किसके लिए सर्वश्रेष्ठ | |--------|---------| | `closeup` | हेडशॉट | | `head-shoulders` | प्रोफ़ाइल फोटो | | `upper-body` | LinkedIn / औपचारिक | | `half-body` | पूरा ऊपरी शरीर | ## ऑडियो ट्रांसक्राइब {#transcribe-audio} **टूल रूट:** `transcribe-audio`\ **मॉडल:** faster-whisper स्पीच को टेक्स्ट में बदलता है। सादा टेक्स्ट, SRT, और VTT आउटपुट प्रारूपों का समर्थन करता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `language` | string | `"auto"` | भाषा: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | आउटपुट प्रारूप | ## ऑटो सबटाइटल {#auto-subtitles} **टूल रूट:** `auto-subtitles`\ **मॉडल:** faster-whisper (वीडियो से ऑडियो निकालता है, फिर ट्रांसक्राइब करता है) किसी वीडियो के ऑडियो ट्रैक से सबटाइटल फ़ाइलें जनरेट करता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `language` | string | `"auto"` | भाषा: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | आउटपुट सबटाइटल प्रारूप | ## PNG ट्रांसपेरेंसी फिक्सर {#png-transparency-fixer} **टूल रूट:** `transparency-fixer`\ **मॉडल:** BiRefNet HR-मैटिंग (2048x2048 रिज़ॉल्यूशन) "नकली पारदर्शी" PNG को ठीक करता है जहाँ बैकग्राउंड हटा दिया गया था लेकिन फ्रिंजिंग, हेलो, या अर्ध-पारदर्शी आर्टिफैक्ट पीछे छूट गए। साफ अल्फा चैनल उत्पन्न करने के लिए BiRefNet के उच्च-रिज़ॉल्यूशन मैटिंग मॉडल का उपयोग करता है, फिर किनारों के साथ रंग संदूषण हटाने के लिए कॉन्फ़िगर करने योग्य डिफ्रिंज प्रसंस्करण लागू करता है। **OOM फ़ॉलबैक शृंखला:** यदि BiRefNet HR-मैटिंग उपलब्ध मेमोरी से अधिक हो जाती है, तो टूल स्वतः `birefnet-general` पर, फिर `u2net` पर फ़ॉलबैक करता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | रंग संदूषण हटाने के लिए एज डिफ्रिंज शक्ति | | `outputFormat` | `"png"` | `"webp"` | `"png"` | आउटपुट इमेज प्रारूप | | `removeWatermark` | boolean | `false` | वॉटरमार्क हटाने की पूर्व-प्रसंस्करण लागू करें (median filter) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## वैकल्पिक AI क्षमताओं वाले टूल {#tools-with-optional-ai-capabilities} निम्नलिखित टूल Python साइडकार टूल नहीं हैं लेकिन कुछ विकल्प सक्षम होने पर AI फ़ीचर का उपयोग करते हैं। ### इमेज एन्हांसमेंट {#image-enhancement} **टूल रूट:** `image-enhancement`\ **इंजन:** विश्लेषण-आधारित (Sharp हिस्टोग्राम और सांख्यिकी) इमेज का विश्लेषण करता है और एक्सपोज़र, कंट्रास्ट, व्हाइट बैलेंस, सैचुरेशन, शार्पनेस, और नॉइज़ के लिए स्वचालित सुधार लागू करता है। दृश्य-विशिष्ट मोड का समर्थन करता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | सुधारों को ट्यून करने के लिए दृश्य मोड | | `intensity` | number (0-100) | `50` | कुल सुधार शक्ति | | `corrections.exposure` | boolean | `true` | एक्सपोज़र सुधार लागू करें | | `corrections.contrast` | boolean | `true` | कंट्रास्ट सुधार लागू करें | | `corrections.whiteBalance` | boolean | `true` | व्हाइट बैलेंस सुधार लागू करें | | `corrections.saturation` | boolean | `true` | सैचुरेशन सुधार लागू करें | | `corrections.sharpness` | boolean | `true` | शार्पनेस सुधार लागू करें | | `corrections.denoise` | boolean | `true` | डीनॉइज़िंग लागू करें | | `deepEnhance` | boolean | `false` | SCUNet के माध्यम से AI नॉइज़ हटाना सक्षम करें (`upscale-enhance` बंडल की आवश्यकता है) | एक अतिरिक्त विश्लेषण एंडपॉइंट `POST /api/v1/tools/image/image-enhancement/analyze` पर उपलब्ध है जो पहचाने गए सुधार लागू किए बिना लौटाता है। ### सामग्री-जागरूक आकार बदलना (सीम कार्विंग) {#content-aware-resize-seam-carving} **टूल रूट:** `content-aware-resize`\ **इंजन:** Go `caire` बाइनरी (Python नहीं; कोई GPU लाभ नहीं) कम-ऊर्जा सीम हटाकर इमेज का बुद्धिमानी से आकार बदलता है, महत्वपूर्ण सामग्री को संरक्षित करता है। | पैरामीटर | प्रकार | डिफ़ॉल्ट | विवरण | |-----------|------|---------|-------------| | `width` | number | - | लक्ष्य चौड़ाई | | `height` | number | - | लक्ष्य ऊँचाई | | `protectFaces` | boolean | `false` | पहचाने गए फेस क्षेत्रों की रक्षा करें (`face-detection` बंडल की आवश्यकता है) | | `blurRadius` | number (0-20) | `4` | ऊर्जा गणना के लिए पूर्व-ब्लर | | `sobelThreshold` | number (1-20) | `2` | एज संवेदनशीलता थ्रेशोल्ड | | `square` | boolean | `false` | वर्गाकार आउटपुट बाध्य करें | --- --- url: https://docs.snapotter.com/ko/api/ai.md description: 모든 로컬 ML 도구를 다루는 AI 엔진 레퍼런스. 배경 제거, 업스케일링, OCR, 얼굴 감지, 사진 복원 등. --- # AI 엔진 레퍼런스 {#ai-engine-reference} `@snapotter/ai` 패키지는 로컬 ML 작업을 위해 기본 도구와 Python 런타임을 조정합니다. 대부분의 ML 도구는 빠른 웜 스타트를 위해 영구 Python sidecar 를 사용합니다. OCR 는 의도적으로 분리되어 있습니다. `fast`는 기본 Tesseract 바이너리를 호출하는 반면, `balanced` 및 `best`는 `/data/ai/v3` 아래의 활성 불변 RapidOCR 세대에 고정된 전용 영구 JSONL dispatcher 를 사용합니다. 각 요청에는 generation lease 가 포함됩니다. 업그레이드 중에 SnapOtter 는 활성화하기 전에 후보에서 smoke test 를 실행하고 새로운 dispatcher 로 원자적으로 전환한 다음 garbage collection 이전의 이전 세대를 제거합니다. NVIDIA CUDA 는 이를 지원하는 런타임에서 자동 감지되고 사용됩니다. OCR 는 NVIDIA GPU가 있는 시스템을 포함하여 모든 호스트에서 CPU 를 사용하여 이 도구에 대한 CUDA 및 드라이버 결합을 방지합니다. VA-API, Quick Sync, OpenCL을 통한 Intel/AMD iGPU 가속은 현재 AI 추론에 지원되지 않는다. CUDA를 지원하는 NVIDIA GPU가 없는 한, 컨테이너에 `/dev/dri`를 매핑해도 이러한 Python 사이드카 도구는 가속되지 않는다. 네 가지 모달리티(이미지, 오디오, 비디오, 문서)에 걸쳐 19개의 Python 사이드카 AI 도구가 있으며, 여기에 선택적 AI 기능을 갖춘 2개의 도구가 추가된다. 모든 모델은 로컬에서 실행되며, 최초 모델 다운로드 이후에는 인터넷이 필요하지 않다. ::: info 한국어 OCR 호환성 빠른 OCR은 `auto`, `en`, `de`, `es`, `fr`, `zh`, `ja`를 지원하지만 한국어(`ko`)는 지원하지 않습니다. 한국어에는 정확한 OCR 팩과 `balanced` 또는 `best`가 필요합니다. 이 팩은 공식 Linux amd64 및 arm64 컨테이너에서 작동하며 NVIDIA 호스트에서도 OCR은 CPU에서 실행됩니다. 지원되지 않는 시스템은 명시적인 호환성 오류를 반환하며 조용히 `fast`로 대체하지 않습니다. 한국어에 `fast` 또는 이전 `tesseract` 별칭을 지정하면 큐에 넣기 전에 `FEATURE_INCOMPATIBLE` 및 `fast-korean-unsupported`로 거부됩니다. ::: ## 아키텍처 {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` 별도의 "docs" 디스패처 프로파일은 AI 허용 목록을 문서 처리 스크립트(`doc_pagecount`, `doc_health`, `doc_flatten`, `doc_redact`, `doc_text`, `doc_to_word`, `doc_metadata`, `doc_html_pdf`)로 대체하고 무거운 ML 임포트를 건너뛴다. **타임아웃:** 기본 300초. OCR과 BiRefNet 배경 제거는 600초가 주어진다. ## 기능 번들 {#feature-bundles} AI 모델은 도구별로 아카이브 하나씩이 아니라 공유 의존성 스택 단위로 패키징된다. 하나의 기능 번들은 여러 도구가 동일한 모델 계열, Python 휠, 또는 네이티브 라이브러리를 사용할 때 그 도구들을 함께 활성화할 수 있다. 이렇게 하면 릴리스 Docker 이미지가 더 작게 유지되고, 동일한 배경 매팅, 얼굴 감지, OCR, 복원, 음성 모델의 중복 사본을 저장하는 일을 피할 수 있다. Docker 이미지는 애플리케이션과 공통 런타임을 함께 제공한다. 대용량 모델 아카이브는 필요할 때 상시 유지되는 `/data/ai` 볼륨으로 다운로드된 뒤, 이를 필요로 하는 모든 도구가 재사용한다. 다른 도구가 이미 필요로 해서 어떤 번들이 이미 설치되어 있다면, 새로 의존하는 도구를 활성화해도 그 번들을 다시 다운로드하지 않는다. 대부분의 AI 도구를 실행하려면 하나 이상의 기능 번들이 필요합니다. 관리 UI는 전체 번들 목록을 확인하고 이미 설치된 번들을 건너뛰며 누락된 다운로드만 대기열에 추가하는 `POST /api/v1/admin/tools/:toolId/features/install`를 통해 도구로 해당 항목을 설치합니다. 예를 들어, 새로운 인스턴스 큐 `background-removal` 및 `face-detection`에서 여권 사진을 활성화합니다. 백그라운드 제거가 이미 설치된 후에 활성화하면 `face-detection`만 대기열에 추가됩니다. OCR 는 예외입니다. `fast`에는 팩이 필요하지 않기 때문입니다. UI 또는 `POST /api/v1/admin/features/ocr/install`를 통해 선택적 정확한 런타임을 설치합니다. | 번들 | 크기 | 공유 의존성 그룹 | 사용하는 도구 | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet 배경 매팅 | remove-background, passport-photo, transparency-fixer, background-replace, blur-background | | `face-detection` | 200-300 MB | MediaPipe 얼굴 감지 및 랜드마크 | blur-faces, red-eye-removal, smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa 인페인팅/아웃페인팅 및 DDColor | erase-object, colorize, ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN, GFPGAN / CodeFormer, 노이즈 제거 | upscale, enhance-faces, noise-removal | | `photo-restoration` | 4-5 GB | 스크래치 복구 및 복원 파이프라인 | restore-photo | | `ocr` | ~208-234 MiB 다운로드 / ~409-488 MiB 설치됨 | 옵션 RapidOCR 3.9.1, ONNX Runtime 1.20.1 및 고정형 PP-OCR 모델 | ocr, ocr-pdf(`balanced` 및 `best`에만 해당) | | `transcription` | ~600 MB | faster-whisper 음성-텍스트 변환 모델 | transcribe-audio, auto-subtitles | 교차 번들 의존성을 갖는 도구: | 도구 | 필요한 번들 | 이유 | |------|------------------|-----| | `passport-photo` | `background-removal`, `face-detection` | 배경을 제거한 뒤, 얼굴 랜드마크를 사용해 여권 및 신분증 사진 규정에 맞게 크롭 구도를 잡는다. | | `enhance-faces` | `upscale-enhance`, `face-detection` | 선택된 얼굴 영역에 GFPGAN 또는 CodeFormer 보정을 적용하기 전에 얼굴을 감지한다. | 도구는 OCR 를 제외하고 모든 필수 번들이 설치된 경우에만 사용할 수 있습니다. 내장된 `fast` 계층은 선택적 OCR 팩 없이도 계속 사용할 수 있습니다. 부분 설치는 유효하며 증분적으로 처리됩니다. 설치된 번들은 재사용되고, 누락된 번들은 다운로드로 표시되며, 대기 중인 설치는 한 번에 하나씩 실행되므로 공유 Python 환경이 동시에 수정되지 않습니다. ### 정확한 OCR 런타임 설치 {#accurate-ocr-runtime-installation} 정확한 OCR 팩은 공식 Linux amd64 또는 Linux arm64 컨테이너를 위한 플랫폼별 런타임입니다. amd64 빌드는 Python 3.12를 사용하고 arm64 빌드는 Python 3.11을 사용합니다. 두 빌드 모두 ONNX Runtime의 `CPUExecutionProvider`를 통해 RapidOCR를 실행하므로 동일한 팩이 CPU 전용 및 NVIDIA Docker 호스트에서 작동합니다. 정확한 런타임에는 최소 4 GiB의 유효 메모리(구성된 컨테이너 cgroup 제한, 없으면 호스트 메모리)가 필요합니다. 서명된 호환성 최소값 미만의 시스템은 다운로드 전에 거부됩니다. 이 요구 사항은 내장 Fast OCR에는 적용되지 않습니다. Bare-metal 빌드는 libc 및 Python ABI를 안전하게 추론할 수 없으므로 거부됩니다. 호스트가 Tesseract와 Ghostscript를 제공하면 Fast OCR는 계속 사용할 수 있습니다. 선택적 아티팩트는 아키텍처에 따라 약 208-234 MiB 압축 및 409-488 MiB 추출입니다. 서명된 인덱스는 설치 프로그램에서 적용한 정확한 압축 및 추출 바이트 수를 바인딩합니다. 내장된 Tesseract 는 공식 이미지에 약 25개의 MiB 를 추가하며 `/data/ai`에는 파일이 필요하지 않습니다. 온라인 설치는 현재 플랫폼에 대한 서명된 릴리스 색인과 정확한 콘텐츠 주소 지정 아티팩트를 가져옵니다. SnapOtter 는 새로운 세대를 원자적으로 활성화하기 전에 Ed25519 인덱스 서명, 아티팩트 크기, SHA-256 다이제스트, 모델 다이제스트, 경로, 파일 모드 및 스테이지된 smoke test 를 확인합니다. 설치가 실패하면 이전 정상 세대가 활성 상태로 유지됩니다. 에어갭 설치의 경우 `index` 및 `archive`라는 다중 부분 필드를 사용하여 릴리스의 `ocr-runtime-index.json` 및 일치하는 OCR 런타임 아카이브를 모두 `POST /api/v1/admin/features/import`에 업로드합니다. 오프라인 가져오기는 온라인 설치와 동일한 서명, 해시, 추출, 호환성 및 스모크 테스트 검사를 적용합니다. 신뢰할 수 있는 서명된 인덱스가 없는 아카이브는 거부됩니다. *** ## 배경 제거 {#background-removal} **도구 경로:** `remove-background`\ **모델:** rembg with BiRefNet (기본값) 또는 U2-Net 변형 | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `model` | string | - | 모델 변형 (선택적 재정의) | | `backgroundType` | string | `"transparent"` | 다음 중 하나: `transparent`, `color`, `gradient`, `blur`, `image` | | `backgroundColor` | string | - | 단색 배경용 Hex 색상 | | `gradientColor1` | string | - | 첫 번째 그라디언트 색상 | | `gradientColor2` | string | - | 두 번째 그라디언트 색상 | | `gradientAngle` | number | - | 그라디언트 각도(도 단위) | | `blurEnabled` | boolean | - | 배경 블러 효과 활성화 | | `blurIntensity` | number (0-100) | - | 블러 강도 | | `shadowEnabled` | boolean | - | 피사체에 드롭 섀도 활성화 | | `shadowOpacity` | number (0-100) | - | 그림자 불투명도 | | `outputFormat` | string | - | 출력 형식: `png`, `webp`, 또는 `avif` | | `edgeRefine` | integer (0-3) | - | 가장자리 정제 수준 | | `decontaminate` | boolean | - | 가장자리의 색상 번짐 제거 | ## 배경 교체 {#background-replace} **도구 경로:** `background-replace`\ **모델:** rembg / BiRefNet (remove-background와 공유) 배경을 제거하고 단색 또는 그라디언트로 교체한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | 배경 모드 | | `color` | string | `"#ffffff"` | 배경 hex 색상 (`backgroundType`이 `color`일 때) | | `gradientColor1` | string | - | 첫 번째 그라디언트 hex 색상 | | `gradientColor2` | string | - | 두 번째 그라디언트 hex 색상 | | `gradientAngle` | integer (0-360) | `180` | 그라디언트 각도(도 단위) | | `feather` | integer (0-20) | `0` | 가장자리 페더링 반경 | | `format` | `"png"` | `"webp"` | `"png"` | 출력 형식 | ## 배경 블러 {#blur-background} **도구 경로:** `blur-background`\ **모델:** rembg / BiRefNet (remove-background와 공유) 피사체는 선명하게 유지하면서 배경을 흐리게 만든다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | 블러 강도 | | `feather` | integer (0-20) | `0` | 가장자리 페더링 반경 | | `format` | `"png"` | `"webp"` | `"png"` | 출력 형식 | ## 이미지 업스케일링 {#image-upscaling} **도구 경로:** `upscale`\ **모델:** RealESRGAN (사용 불가 시 Lanczos 폴백) | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `scale` | number | `2` | 업스케일 배율 | | `model` | string | `"auto"` | 모델 변형 | | `faceEnhance` | boolean | `false` | GFPGAN 얼굴 보정 패스 적용 | | `denoise` | number | `0` | 노이즈 제거 강도 | | `format` | string | `"auto"` | 출력 형식 재정의 | | `quality` | number | `95` | 출력 품질 (1-100) | ## OCR / 텍스트 추출 {#ocr-text-extraction} **도구 경로:** `ocr`\ **모델:** Tesseract(`fast`); RapidOCR(PP-OCRv6 소형 모델 포함)(`balanced`); 보정된 변형 점수가 포함된 PP-OCRv6 중형 모델(`best`) | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 동적 | `quality`와 `engine`을 생략하면 SnapOtter는 `best`, `balanced`, `fast` 순으로 사용 가능한 최상위 등급을 선택합니다. 한국어에서는 `fast`를 선택하지 않으며 `best`, 그다음 `balanced`를 사용하고, 둘 다 없으면 정확한 런타임의 설치 또는 호환성 오류를 반환합니다. | | `language` | string | `"auto"` | 언어: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `enhance` | 부울 | 계층에 따라 다름 | 로컬 대비를 향상시킵니다. 빠르게 직접 적용합니다. 정확한 계층은 보정된 점수가 OCR 를 향상시키는 경우에만 변형을 유지합니다. 최고에 대한 기본값은 켜져 있습니다. | | `engine` | 끈 | - | 더 이상 사용되지 않는 호환성 별칭입니다. `tesseract`를 `fast`에 매핑하고 레거시 `paddleocr` 값을 `balanced`에 매핑합니다. PaddlePaddle 를 로드하지 않습니다. | 추출된 텍스트와 출처 메타데이터(엔진, 요청 및 실제 품질, 장치, 공급자, 성능 저하 상태, 경고, 해당되는 경우 정확한 런타임/모델 버전)를 반환합니다. 명시적인 품질 요청은 다른 계층으로 돌아가지 않습니다. `balanced` 또는 `best`를 사용할 수 없는 경우 API 는 `fast`를 자동으로 실행하는 대신 `FEATURE_NOT_INSTALLED` 또는 `FEATURE_INCOMPATIBLE`를 반환합니다. ## PDF OCR {#pdf-ocr} **도구 경로:** `ocr-pdf`\ **모델:** 이미지 OCR와 동일한 등급 체계 AI 기반 OCR을 사용해 스캔된 PDF 문서에서 페이지별로 텍스트를 추출한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 동적 | `quality`와 `engine`을 생략하면 SnapOtter는 `best`, `balanced`, `fast` 순으로 사용 가능한 최상위 등급을 선택합니다. 한국어에서는 `fast`를 선택하지 않으며 `best`, 그다음 `balanced`를 사용하고, 둘 다 없으면 정확한 런타임의 설치 또는 호환성 오류를 반환합니다. | | `language` | string | `"auto"` | 언어: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `pages` | string | `"all"` | 페이지 선택: `"all"`, `"1-3"`, `"1,3,5"` | | `enhance` | 부울 | 계층에 따라 다름 | 로컬 대비를 향상시킵니다. 빠르게 직접 적용합니다. 정확한 계층은 보정된 점수가 OCR 를 향상시키는 경우에만 변형을 유지합니다. 최고에 대한 기본값은 켜져 있습니다. | | `engine` | 끈 | - | 더 이상 사용되지 않는 호환성 별칭입니다. `tesseract`를 `fast`에 매핑하고 레거시 `paddleocr` 값을 `balanced`에 매핑합니다. PaddlePaddle 를 로드하지 않습니다. | PDF OCR 에도 동일한 다운그레이드 금지 규칙이 적용됩니다. PDF 페이지는 인식되기 전에 래스터화되며, 한 요청으로 최대 50페이지를 선택할 수 있습니다. ## 얼굴 / PII 블러 {#face-pii-blur} **도구 경로:** `blur-faces`\ **모델:** MediaPipe 얼굴 감지 | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | 가우시안 블러 반경 | | `sensitivity` | number (0-1) | `0.5` | 감지 신뢰도 임계값 | ## 얼굴 보정 {#face-enhancement} **도구 경로:** `enhance-faces`\ **모델:** GFPGAN, CodeFormer | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | 보정 모델 | | `strength` | number (0-1) | `0.8` | 보정 강도 | | `sensitivity` | number (0-1) | `0.5` | 얼굴 감지 임계값 | | `onlyCenterFace` | boolean | `false` | 가장 중앙에 있는 얼굴만 보정 | ## AI 컬러화 {#ai-colorization} **도구 경로:** `colorize`\ **모델:** DDColor (OpenCV DNN 폴백) 흑백 또는 그레이스케일 사진을 풀컬러로 변환한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | 색상 채도 강도 | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | 모델 변형 | ## 노이즈 제거 {#noise-removal} **도구 경로:** `noise-removal`\ **모델:** SCUNet (등급형 노이즈 제거 파이프라인) | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | 처리 등급 | | `strength` | number (0-100) | `50` | 노이즈 제거 강도 | | `detailPreservation` | number (0-100) | `50` | 보존할 디테일 정도. 높을수록 텍스처가 더 많이 유지됨 | | `colorNoise` | number (0-100) | `30` | 컬러 노이즈 감소 강도 | | `format` | string | `"original"` | 출력 형식: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | `quality` | number (1-100) | `90` | 출력 인코딩 품질 | ## 적목 현상 제거 {#red-eye-removal} **도구 경로:** `red-eye-removal` 얼굴 랜드마크를 감지하고 눈 영역을 찾아 적색 채널 과포화를 보정한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | 적색 픽셀 감지 임계값 | | `strength` | number (0-100) | `70` | 보정 강도 | | `format` | string | - | 출력 형식 재정의 (선택 사항) | | `quality` | number (1-100) | `90` | 출력 품질 | ## 사진 복원 {#photo-restoration} **도구 경로:** `restore-photo` 오래되거나 손상된 사진을 위한 다단계 파이프라인: 스크래치/찢김 감지 및 복구, 얼굴 보정, 노이즈 제거, 그리고 선택적 컬러화. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | 스크래치, 찢김 감지 및 복구 | | `faceEnhancement` | boolean | `true` | 얼굴 보정 패스 적용 | | `fidelity` | number (0-1) | `0.7` | 얼굴 보정 강도 (높을수록 더 보수적) | | `denoise` | boolean | `true` | 노이즈 제거 패스 적용 | | `denoiseStrength` | number (0-100) | `25` | 노이즈 제거 강도 | | `colorize` | boolean | `false` | 복원 후 컬러화 | | `colorizeStrength` | number (0-100) | `85` | 컬러화 강도 | ## 여권 사진 {#passport-photo} **도구 경로:** `passport-photo`\ **모델:** MediaPipe 얼굴 랜드마크 + BiRefNet 배경 제거 두 단계 워크플로: 분석(얼굴 감지 + 배경 제거) 후 생성(크롭, 크기 조정, 타일 배치). 6개 지역에 걸쳐 37개 이상의 국가를 지원한다. ### 1단계: 분석 {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` 이미지 파일(multipart)을 받는다. 얼굴 랜드마크 데이터, base64 미리보기, 이미지 치수를 반환한다. ### 2단계: 생성 {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` 1단계 결과와 생성 설정이 담긴 JSON 본문을 받는다: | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `jobId` | string | (필수) | 1단계의 작업 ID | | `filename` | string | (필수) | 1단계의 원본 파일 이름 | | `countryCode` | string | (필수) | ISO 국가 코드 (예: `US`, `GB`, `IN`) | | `documentType` | string | `"passport"` | 문서 유형 | | `bgColor` | string | `"#FFFFFF"` | 배경 색상 hex | | `printLayout` | string | `"none"` | 인쇄 레이아웃: `none`, `4x6`, `a4`, `letter` | | `maxFileSizeKb` | number | `0` | 최대 파일 크기(KB) (0 = 제한 없음) | | `dpi` | number (72-1200) | `300` | 출력 DPI | | `customWidthMm` | number | - | 사용자 지정 너비(mm) (국가 사양을 재정의) | | `customHeightMm` | number | - | 사용자 지정 높이(mm) (국가 사양을 재정의) | | `zoom` | number (0.5-3) | `1` | 줌 배율 | | `adjustX` | number | `0` | 수평 위치 조정 | | `adjustY` | number | `0` | 수직 위치 조정 | | `landmarks` | object | (필수) | 1단계의 랜드마크 | | `imageWidth` | number | (필수) | 1단계의 이미지 너비 | | `imageHeight` | number | (필수) | 1단계의 이미지 높이 | ## 객체 지우기 (인페인팅) {#object-erasing-inpainting} **도구 경로:** `erase-object`\ **모델:** ONNX Runtime을 통한 LaMa 마스크는 base64가 아니라 **두 번째 파일 파트**(fieldname `mask`)로 전송된다. 마스크에서 흰색 픽셀은 지울 영역을 나타낸다. `format`와 `quality` 설정은 최상위 폼 필드로 전송된다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `file` | file | (필수) | 원본 이미지 (multipart) | | `mask` | file | (필수) | 마스크 이미지 (multipart, fieldname `mask`, 흰색 = 지우기) | | `format` | string | `"auto"` | 출력 형식: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | 출력 품질 | NVIDIA GPU가 있을 때 CUDA 가속된다. ## AI 캔버스 확장 {#ai-canvas-expand} **도구 경로:** `ai-canvas-expand`\ **모델:** LaMa 기반 아웃페인팅 이미지의 캔버스를 어느 방향으로든 확장하고, 새 영역을 기존 이미지와 어울리는 AI 생성 콘텐츠로 채운다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | 위쪽으로 확장할 픽셀 | | `extendRight` | integer | `0` | 오른쪽으로 확장할 픽셀 | | `extendBottom` | integer | `0` | 아래쪽으로 확장할 픽셀 | | `extendLeft` | integer | `0` | 왼쪽으로 확장할 픽셀 | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | 품질 등급 | | `format` | string | `"auto"` | 출력 형식: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | 출력 품질 | 확장 방향 중 하나 이상이 0보다 커야 한다. ## 스마트 크롭 {#smart-crop} **도구 경로:** `smart-crop`\ **모델:** MediaPipe 얼굴 감지 (얼굴 모드 전용) | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | 크롭 전략: `subject`, `face`, `trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | 피사체 모드 전략 | | `width` | integer | - | 출력 너비 | | `height` | integer | - | 출력 높이 | | `padding` | integer (0-50) | `0` | 피사체 주변 여백 백분율 | | `facePreset` | string | `"head-shoulders"` | `mode=face`일 때의 프리셋 구도 | | `sensitivity` | number (0-1) | `0.5` | 얼굴 감지 임계값 | | `threshold` | integer (0-255) | `30` | 배경 감지 임계값 (트림 모드) | | `padToSquare` | boolean | `false` | 트림된 결과를 정사각형으로 패딩 | | `padColor` | string | `"#ffffff"` | 정사각형 패딩용 배경 색상 | | `targetSize` | integer | - | 패딩된 출력의 목표 크기(픽셀) | | `quality` | integer (1-100) | - | 출력 품질 | 레거시 `mode` 값 `attention`와 `content`은 허용되며 각각 `subject`와 `trim`로 매핑된다. **얼굴 프리셋:** | 프리셋 | 적합한 용도 | |--------|---------| | `closeup` | 헤드샷 | | `head-shoulders` | 프로필 사진 | | `upper-body` | LinkedIn / 격식 있는 용도 | | `half-body` | 상반신 전체 | ## 오디오 전사 {#transcribe-audio} **도구 경로:** `transcribe-audio`\ **모델:** faster-whisper 음성을 텍스트로 변환한다. 일반 텍스트, SRT, VTT 출력 형식을 지원한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 언어: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | 출력 형식 | ## 자동 자막 {#auto-subtitles} **도구 경로:** `auto-subtitles`\ **모델:** faster-whisper (비디오에서 오디오를 추출한 뒤 전사) 비디오의 오디오 트랙에서 자막 파일을 생성한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 언어: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | 출력 자막 형식 | ## PNG 투명도 수정 {#png-transparency-fixer} **도구 경로:** `transparency-fixer`\ **모델:** BiRefNet HR-매팅 (2048x2048 해상도) 배경은 제거되었지만 프린징, 헤일로, 반투명 아티팩트가 남은 "가짜 투명" PNG를 수정한다. BiRefNet의 고해상도 매팅 모델을 사용해 깨끗한 알파 채널을 만든 다음, 구성 가능한 디프린지 처리를 적용해 가장자리를 따라 남은 색상 오염을 제거한다. **OOM 폴백 체인:** BiRefNet HR-매팅이 가용 메모리를 초과하면, 도구는 자동으로 `birefnet-general`로, 그다음 `u2net`로 폴백한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | 색상 오염을 제거하는 가장자리 디프린지 강도 | | `outputFormat` | `"png"` | `"webp"` | `"png"` | 출력 이미지 형식 | | `removeWatermark` | boolean | `false` | 워터마크 제거 사전 처리 적용 (미디안 필터) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## 선택적 AI 기능을 갖춘 도구 {#tools-with-optional-ai-capabilities} 다음 도구는 Python 사이드카 도구는 아니지만 특정 옵션이 활성화되면 AI 기능을 사용한다. ### 이미지 향상 {#image-enhancement} **도구 경로:** `image-enhancement`\ **엔진:** 분석 기반 (Sharp 히스토그램 및 통계) 이미지를 분석하여 노출, 대비, 화이트 밸런스, 채도, 선명도, 노이즈에 대한 자동 보정을 적용한다. 장면별 모드를 지원한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | 보정 튜닝용 장면 모드 | | `intensity` | number (0-100) | `50` | 전체 보정 강도 | | `corrections.exposure` | boolean | `true` | 노출 보정 적용 | | `corrections.contrast` | boolean | `true` | 대비 보정 적용 | | `corrections.whiteBalance` | boolean | `true` | 화이트 밸런스 보정 적용 | | `corrections.saturation` | boolean | `true` | 채도 보정 적용 | | `corrections.sharpness` | boolean | `true` | 선명도 보정 적용 | | `corrections.denoise` | boolean | `true` | 노이즈 제거 적용 | | `deepEnhance` | boolean | `false` | SCUNet을 통한 AI 노이즈 제거 활성화 (`upscale-enhance` 번들 필요) | 적용하지 않고 감지된 보정만 반환하는 추가 분석 엔드포인트를 `POST /api/v1/tools/image/image-enhancement/analyze`에서 사용할 수 있다. ### 콘텐츠 인식 크기 조정 (심 카빙) {#content-aware-resize-seam-carving} **도구 경로:** `content-aware-resize`\ **엔진:** Go `caire` 바이너리 (Python이 아니므로 GPU 이점 없음) 저에너지 심을 제거하여 중요한 콘텐츠를 보존하면서 이미지 크기를 지능적으로 조정한다. | 매개변수 | 타입 | 기본값 | 설명 | |-----------|------|---------|-------------| | `width` | number | - | 목표 너비 | | `height` | number | - | 목표 높이 | | `protectFaces` | boolean | `false` | 감지된 얼굴 영역 보호 (`face-detection` 번들 필요) | | `blurRadius` | number (0-20) | `4` | 에너지 계산을 위한 사전 블러 | | `sobelThreshold` | number (1-20) | `2` | 가장자리 민감도 임계값 | | `square` | boolean | `false` | 정사각형 출력 강제 | --- --- url: https://docs.snapotter.com/ko/tools/image/colorize.md description: DDColor AI 모델로 흑백 또는 회색조 사진을 자동으로 컬러화합니다. --- # AI 컬러화 {#ai-colorization} AI(OpenCV DNN 대체 기능이 있는 DDColor 모델)를 사용하여 흑백 또는 회색조 사진을 완전한 컬러로 변환합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/colorize` **처리 방식:** 비동기(202를 반환하고 SSE를 통해 상태를 확인하려면 `/api/v1/jobs/{jobId}/progress`을(를) 폴링) **모델 번들:** `object-eraser-colorize` (1~2 GB) ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | file | file | 예 | - | 이미지 파일(multipart) | | intensity | number | 아니요 | `1.0` | 색상 강도(0~1). 값이 낮을수록 더 은은한 컬러화가 됩니다 | | model | string | 아니요 | `"auto"` | 사용할 모델: `auto`, `ddcolor`, `opencv` | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## 응답 {#response} ### 초기 응답 (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### 진행 상황 (`/api/v1/jobs/{jobId}/progress`의 SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### 최종 결과 (SSE를 통해) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## 참고 사항 {#notes} * `object-eraser-colorize` 모델 번들이 설치되어 있어야 합니다(1~2 GB). * DDColor는 더 높은 품질의 결과를 생성하지만 속도가 느리고, OpenCV DNN은 더 빠르지만 품질이 약간 낮습니다. `auto`은(는) 가능한 경우 DDColor를 사용하고 OpenCV로 대체합니다. * `intensity` 매개변수는 원본 회색조와 AI 컬러화 결과 사이를 혼합합니다. 완전한 컬러를 원하면 1.0을, 부분적으로 탈채도된 빈티지 느낌을 원하면 더 낮은 값을 사용하세요. * 출력 형식은 입력 형식과 자동으로 일치합니다. * 브라우저에서 미리 볼 수 없는 출력 형식의 경우, 주 출력과 함께 WebP 미리 보기가 생성됩니다. * HEIC/HEIF, RAW, TGA, PSD, EXR, HDR 입력 형식을 자동 디코딩으로 지원합니다. --- --- url: https://docs.snapotter.com/ja/api/ai.md description: すべてのローカル ML ツールを網羅した AI エンジンリファレンス。背景除去、アップスケーリング、OCR、顔検出、写真復元など。 --- # AI エンジンリファレンス {#ai-engine-reference} `@snapotter/ai` パッケージは、ローカルの ML 操作のためにネイティブ ツールと Python ランタイムを調整します。 ほとんどの ML ツールは、高速ウォーム スタートのために永続的な Python sidecar を使用します。 OCR は意図的に分離されています。 `fast` はネイティブ Tesseract バイナリを呼び出します。 一方、`balanced` および `best` は、`/data/ai/v3` の下でアクティブで不変の RapidOCR 世代に固定された専用の永続 JSONL dispatcher を使用します。 各リクエストは generation lease を保持します。 アップグレード中、SnapOtter はアクティブ化する前に候補に対して smoke test を実行し、新しい dispatcher にアトミックに切り替えてから、garbage collection の前に古い世代を排出します。 NVIDIA CUDA は自動検出され、それをサポートするランタイムによって使用されます。 OCR はすべてのホストで CPU を使用します。 NVIDIA GPU を搭載したシステムを含む、 このツールの CUDA とドライバーの結合を回避します。 VA-API、Quick Sync、OpenCL を介した Intel/AMD の iGPU アクセラレーションは、現時点では AI 推論に対応していません。`/dev/dri` をコンテナにマッピングしても、CUDA 対応の NVIDIA GPU が利用できない限り、これらの Python サイドカーツールは高速化されません。 4 つのモダリティ(画像、音声、動画、ドキュメント)にわたる 19 個の Python サイドカー AI ツールに加え、AI 機能をオプションで備えた 2 個のツールがあります。すべてのモデルはローカルで動作します。初回のモデルダウンロード後はインターネットは不要です。 ::: info 韓国語 OCR の互換性 高速 OCR は `auto`、`en`、`de`、`es`、`fr`、`zh`、`ja` に対応しますが、韓国語 (`ko`) には対応しません。韓国語には高精度 OCR パックと `balanced` または `best` が必要です。パックは公式 Linux amd64/arm64 コンテナで動作し、NVIDIA ホストでも OCR は CPU 上で実行されます。非対応システムでは明示的な互換性エラーを返し、暗黙に `fast` へ切り替えません。韓国語で `fast` または旧 `tesseract` エイリアスを指定すると、キュー投入前に `FEATURE_INCOMPATIBLE` と `fast-korean-unsupported` で拒否されます。 ::: ## アーキテクチャ {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` 別の「docs」ディスパッチャープロファイルは、AI 許可リストをドキュメント処理スクリプト(`doc_pagecount`、`doc_health`、`doc_flatten`、`doc_redact`、`doc_text`、`doc_to_word`、`doc_metadata`、`doc_html_pdf`)に置き換え、重い ML インポートをスキップします。 **タイムアウト:** デフォルトは 300 秒。OCR と BiRefNet 背景除去は 600 秒です。 ## フィーチャーバンドル {#feature-bundles} AI モデルは、ツールごとに 1 つのアーカイブとしてではなく、共有される依存関係スタックによってパッケージ化されています。フィーチャーバンドルは、同じモデルファミリー、Python ホイール、またはネイティブライブラリを使用するツールをまとめて有効化できます。これにより、リリース用の Docker イメージが小さく保たれ、同じ背景マッティング、顔検出、OCR、復元、音声モデルの重複コピーの保存を避けられます。 Docker イメージには、アプリケーションと共通ランタイムが同梱されています。大きなモデルアーカイブはオンデマンドで永続的な `/data/ai` ボリュームにダウンロードされ、それを必要とするすべてのツールで再利用されます。別のツールがすでに必要としたためにバンドルがインストール済みの場合、新たに依存するツールを有効化してもそのバンドルは再ダウンロードされません。 ほとんどの AI ツールは、実行する前に 1 つ以上の機能バンドルを必要とします。 管理 UI は、`POST /api/v1/admin/tools/:toolId/features/install` を介してツールによってこれらをインストールします。これにより、完全なバンドル リストが解決され、すでにインストールされているバンドルがスキップされ、不足しているダウンロードのみがキューに入れられます。 たとえば、新しいインスタンス キュー `background-removal` および `face-detection` でパスポート写真を有効にすると、 バックグラウンド削除がすでにインストールされている後に有効にすると、`face-detection` のみがキューに追加されます。 OCR は例外です。 `fast` パックは必要ありません。 UI または `POST /api/v1/admin/features/ocr/install` を通じて、オプションの正確なランタイムをインストールします。 | バンドル | サイズ | 共有依存関係グループ | 使用するツール | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet 背景マッティング | remove-background, passport-photo, transparency-fixer, background-replace, blur-background | | `face-detection` | 200-300 MB | MediaPipe 顔検出とランドマーク | blur-faces, red-eye-removal, smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa インペインティング/アウトペインティングと DDColor | erase-object, colorize, ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN、GFPGAN / CodeFormer、ノイズ除去 | upscale, enhance-faces, noise-removal | | `photo-restoration` | 4-5 GB | 傷の修復と復元パイプライン | restore-photo | | `ocr` | ~208-234 MiB ダウンロード / ~409-488 MiB インストール済み | オプションの RapidOCR 3.9.1、ONNX Runtime 1.20.1、および固定された PP-OCR モデル | ocr、ocr-pdf (`balanced` および `best` のみ) | | `transcription` | ~600 MB | faster-whisper 音声認識モデル | transcribe-audio, auto-subtitles | 複数バンドルにまたがる依存関係を持つツール: | ツール | 必要なバンドル | 理由 | |------|------------------|-----| | `passport-photo` | `background-removal`, `face-detection` | 背景を除去した後、顔のランドマークを使って、パスポートや ID 写真の規則に合わせてクロップを構図します。 | | `enhance-faces` | `upscale-enhance`, `face-detection` | 選択した顔の領域で GFPGAN または CodeFormer による補正を実行する前に、顔を検出します。 | ツールは、OCR を除き、必要なバンドルがすべてインストールされている場合にのみ使用できます。その組み込みの `fast` 層は、オプションの OCR パックがなくても引き続き使用できます。 部分インストールは有効であり、段階的に処理されます。インストールされたバンドルは再利用され、不足しているバンドルはダウンロードとして表示され、キューに入れられたインストールは一度に 1 つずつ実行されるため、共有 Python 環境は同時に変更されません。 ### 正確な OCR ランタイム インストール {#accurate-ocr-runtime-installation} 正確な OCR パックは、公式 Linux amd64 または Linux arm64 コンテナー用のプラットフォーム固有のランタイムです。 amd64 ビルドは Python 3.12 を使用します。 arm64 ビルドは Python 3.11 を使用します。 どちらのビルドも ONNX Runtime の `CPUExecutionProvider` を介して RapidOCR を実行するため、同じパックが CPU のみおよび NVIDIA Docker ホストで動作します。 正確なランタイムには、少なくとも 4 GiB の有効メモリ (構成されたコンテナーの cgroup 制限、それ以外の場合はホスト メモリ) が必要です。 署名された互換性の最小値を下回るシステムは、ダウンロード前に拒否されます。 この要件は、組み込みの Fast OCR には適用されません。 Bare-metal ビルドは、libc および Python ABI を安全に推論できないため拒否されます。 ホストが Tesseract および Ghostscript を提供する場合、高速 OCR は引き続き利用可能です。 オプションのアーティファクトは、アーキテクチャに応じて、圧縮すると約 208 ~ 234 MiB、抽出すると約 409 ~ 488 MiB になります。 署名付きインデックスは、インストーラーによって強制された正確な圧縮バイト数と抽出バイト数をバインドします。 組み込みの Tesseract は、約 25 の MiB を公式イメージに追加し、`/data/ai` 内のファイルは必要ありません。 オンライン インストールでは、署名付きリリース インデックスと、現在のプラットフォームの正確なコンテンツ アドレス指定されたアーティファクトが取得されます。 SnapOtter は、新しい世代をアトミックにアクティブ化する前に、Ed25519 インデックス署名、アーティファクト サイズ、SHA-256 ダイジェスト、モデル ダイジェスト、パス、ファイル モード、およびステージングされた smoke test を検証します。 インストールが失敗すると、以前の正常な世代がアクティブなままになります。 エアギャップ インストールの場合は、`index` および `archive` という名前のマルチパート フィールドを使用して、リリースの `ocr-runtime-index.json` と一致する OCR ランタイム アーカイブの両方を `POST /api/v1/admin/features/import` にアップロードします。 オフライン インポートでは、オンライン インストールと同じ署名、ハッシュ、抽出、互換性、およびスモーク テスト チェックが適用されます。 信頼された署名付きインデックスのないアーカイブは拒否されます。 *** ## 背景除去 {#background-removal} **ツールルート:** `remove-background`\ **モデル:** BiRefNet(デフォルト)または U2-Net バリアントを用いた rembg | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `model` | string | - | モデルバリアント(任意の上書き) | | `backgroundType` | string | `"transparent"` | 次のいずれか: `transparent`, `color`, `gradient`, `blur`, `image` | | `backgroundColor` | string | - | 単色背景の 16 進カラー | | `gradientColor1` | string | - | グラデーションの 1 色目 | | `gradientColor2` | string | - | グラデーションの 2 色目 | | `gradientAngle` | number | - | グラデーションの角度(度) | | `blurEnabled` | boolean | - | 背景ぼかし効果を有効化 | | `blurIntensity` | number (0-100) | - | ぼかしの強度 | | `shadowEnabled` | boolean | - | 被写体にドロップシャドウを有効化 | | `shadowOpacity` | number (0-100) | - | シャドウの不透明度 | | `outputFormat` | string | - | 出力形式: `png`, `webp`, または `avif` | | `edgeRefine` | integer (0-3) | - | エッジ精細化レベル | | `decontaminate` | boolean | - | エッジからの色にじみを除去 | ## 背景の置き換え {#background-replace} **ツールルート:** `background-replace`\ **モデル:** rembg / BiRefNet(remove-background と共有) 背景を除去し、単色またはグラデーションに置き換えます。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | 背景モード | | `color` | string | `"#ffffff"` | 背景の 16 進カラー(`backgroundType` が `color` の場合) | | `gradientColor1` | string | - | グラデーションの 1 色目(16 進) | | `gradientColor2` | string | - | グラデーションの 2 色目(16 進) | | `gradientAngle` | integer (0-360) | `180` | グラデーションの角度(度) | | `feather` | integer (0-20) | `0` | エッジのぼかし半径 | | `format` | `"png"` | `"webp"` | `"png"` | 出力形式 | ## 背景をぼかす {#blur-background} **ツールルート:** `blur-background`\ **モデル:** rembg / BiRefNet(remove-background と共有) 被写体をシャープに保ちながら背景をぼかします。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | ぼかしの強度 | | `feather` | integer (0-20) | `0` | エッジのぼかし半径 | | `format` | `"png"` | `"webp"` | `"png"` | 出力形式 | ## 画像のアップスケーリング {#image-upscaling} **ツールルート:** `upscale`\ **モデル:** RealESRGAN(利用できない場合は Lanczos にフォールバック) | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `scale` | number | `2` | アップスケール倍率 | | `model` | string | `"auto"` | モデルバリアント | | `faceEnhance` | boolean | `false` | GFPGAN による顔補正パスを適用 | | `denoise` | number | `0` | ノイズ除去の強度 | | `format` | string | `"auto"` | 出力形式の上書き | | `quality` | number | `95` | 出力品質(1-100) | ## OCR / テキスト抽出 {#ocr-text-extraction} **ツールルート:** `ocr`\ **モデル:** Tesseract (`fast`); RapidOCR と PP-OCRv6 小型モデル (`balanced`)。調整されたバリアント スコアリングを備えた PP-OCRv6 中モデル (`best`) | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 動的 | `quality` と `engine` を省略すると、SnapOtter は `best`、`balanced`、`fast` の順で利用可能な最上位の層を選びます。韓国語では `fast` を選択せず、`best`、次に `balanced` を使用し、どちらもなければ高精度ランタイムのインストールまたは互換性エラーを返します。 | | `language` | string | `"auto"` | 言語: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `enhance` | ブール値 | ティアに依存 | 局所的なコントラストを改善します。高速ではそれを直接適用します。正確な階層は、調整されたスコアによって OCR が向上した場合にのみバリアントを保持します。デフォルトで最良の状態 | | `engine` | 弦 | - | 非推奨の互換性エイリアス。 `tesseract` を `fast` にマップし、従来の `paddleocr` 値を `balanced` にマップします。 PaddlePaddle はロードされません | 抽出されたテキストと来歴メタデータを返します: エンジン、要求された品質と実際の品質、デバイス、プロバイダー、劣化状態、警告、および該当する場合は正確なランタイム/モデルのバージョン。 明示的な品質要求が別の層にフォー​​ルバックすることはありません。 `balanced` または `best` が使用できない場合、API は、`fast` をサイレントに実行する代わりに、`FEATURE_NOT_INSTALLED` または `FEATURE_INCOMPATIBLE` を返します。 ## PDF OCR {#pdf-ocr} **ツールルート:** `ocr-pdf`\ **モデル:** 画像 OCR と同じティアシステム AI ベースの OCR を使用して、スキャンされた PDF ドキュメントからページごとにテキストを抽出します。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 動的 | `quality` と `engine` を省略すると、SnapOtter は `best`、`balanced`、`fast` の順で利用可能な最上位の層を選びます。韓国語では `fast` を選択せず、`best`、次に `balanced` を使用し、どちらもなければ高精度ランタイムのインストールまたは互換性エラーを返します。 | | `language` | string | `"auto"` | 言語: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `pages` | string | `"all"` | ページ選択: `"all"`, `"1-3"`, `"1,3,5"` | | `enhance` | ブール値 | ティアに依存 | 局所的なコントラストを改善します。高速ではそれを直接適用します。正確な階層は、調整されたスコアによって OCR が向上した場合にのみバリアントを保持します。デフォルトで最良の状態 | | `engine` | 弦 | - | 非推奨の互換性エイリアス。 `tesseract` を `fast` にマップし、従来の `paddleocr` 値を `balanced` にマップします。 PaddlePaddle はロードされません | 同じダウングレードなしルールが PDF OCR にも適用されます。 PDF ページは認識前にラスタライズされ、1 つのリクエストで最大 50 ページを選択できます。 ## 顔 / 個人情報のぼかし {#face-pii-blur} **ツールルート:** `blur-faces`\ **モデル:** MediaPipe 顔検出 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | ガウスぼかしの半径 | | `sensitivity` | number (0-1) | `0.5` | 検出信頼度のしきい値 | ## 顔補正 {#face-enhancement} **ツールルート:** `enhance-faces`\ **モデル:** GFPGAN, CodeFormer | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | 補正モデル | | `strength` | number (0-1) | `0.8` | 補正の強度 | | `sensitivity` | number (0-1) | `0.5` | 顔検出のしきい値 | | `onlyCenterFace` | boolean | `false` | 最も中央にある顔のみを補正 | ## AI カラー化 {#ai-colorization} **ツールルート:** `colorize`\ **モデル:** DDColor(OpenCV DNN にフォールバック) 白黒またはグレースケールの写真をフルカラーに変換します。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | 色の彩度の強さ | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | モデルバリアント | ## ノイズ除去 {#noise-removal} **ツールルート:** `noise-removal`\ **モデル:** SCUNet(ティア方式のノイズ除去パイプライン) | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | 処理ティア | | `strength` | number (0-100) | `50` | ノイズ除去の強度 | | `detailPreservation` | number (0-100) | `50` | 保持するディテール量。高いほどテクスチャがより多く残ります | | `colorNoise` | number (0-100) | `30` | カラーノイズ低減の強度 | | `format` | string | `"original"` | 出力形式: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | `quality` | number (1-100) | `90` | 出力エンコード品質 | ## 赤目除去 {#red-eye-removal} **ツールルート:** `red-eye-removal` 顔のランドマークを検出し、目の領域を特定して、赤チャンネルの過飽和を補正します。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | 赤ピクセル検出のしきい値 | | `strength` | number (0-100) | `70` | 補正の強度 | | `format` | string | - | 出力形式の上書き(任意) | | `quality` | number (1-100) | `90` | 出力品質 | ## 写真復元 {#photo-restoration} **ツールルート:** `restore-photo` 古い写真や損傷した写真のためのマルチステップパイプライン: 傷やちぎれの検出と修復、顔補正、ノイズ除去、任意のカラー化。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | 傷やちぎれを検出して修復 | | `faceEnhancement` | boolean | `true` | 顔補正パスを適用 | | `fidelity` | number (0-1) | `0.7` | 顔補正の強度(高いほど控えめ) | | `denoise` | boolean | `true` | ノイズ除去パスを適用 | | `denoiseStrength` | number (0-100) | `25` | ノイズ除去の強度 | | `colorize` | boolean | `false` | 復元後にカラー化 | | `colorizeStrength` | number (0-100) | `85` | カラー化の強度 | ## パスポート写真 {#passport-photo} **ツールルート:** `passport-photo`\ **モデル:** MediaPipe 顔ランドマーク + BiRefNet 背景除去 2 フェーズのワークフロー: 分析(顔を検出 + 背景を除去)してから生成(クロップ、リサイズ、タイル配置)します。6 地域にわたる 37 か国以上に対応しています。 ### フェーズ 1: 分析 {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` 画像ファイル(マルチパート)を受け付けます。顔のランドマークデータ、base64 のプレビュー、画像の寸法を返します。 ### フェーズ 2: 生成 {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` フェーズ 1 の結果に加えて生成設定を含む JSON ボディを受け付けます: | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `jobId` | string | (必須) | フェーズ 1 のジョブ ID | | `filename` | string | (必須) | フェーズ 1 の元のファイル名 | | `countryCode` | string | (必須) | ISO 国コード(例: `US`, `GB`, `IN`) | | `documentType` | string | `"passport"` | ドキュメントの種類 | | `bgColor` | string | `"#FFFFFF"` | 背景色の 16 進 | | `printLayout` | string | `"none"` | 印刷レイアウト: `none`, `4x6`, `a4`, `letter` | | `maxFileSizeKb` | number | `0` | 最大ファイルサイズ(KB、0 = 制限なし) | | `dpi` | number (72-1200) | `300` | 出力 DPI | | `customWidthMm` | number | - | カスタム幅(mm、国別仕様を上書き) | | `customHeightMm` | number | - | カスタム高さ(mm、国別仕様を上書き) | | `zoom` | number (0.5-3) | `1` | ズーム倍率 | | `adjustX` | number | `0` | 水平方向の位置調整 | | `adjustY` | number | `0` | 垂直方向の位置調整 | | `landmarks` | object | (必須) | フェーズ 1 のランドマーク | | `imageWidth` | number | (必須) | フェーズ 1 の画像幅 | | `imageHeight` | number | (必須) | フェーズ 1 の画像高さ | ## オブジェクト消去(インペインティング) {#object-erasing-inpainting} **ツールルート:** `erase-object`\ **モデル:** ONNX Runtime を介した LaMa マスクは base64 ではなく、**2 つ目のファイルパート**(フィールド名 `mask`)として送信されます。マスク内の白いピクセルが消去する領域を示します。`format` と `quality` の設定はトップレベルのフォームフィールドとして送信されます。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `file` | file | (必須) | ソース画像(マルチパート) | | `mask` | file | (必須) | マスク画像(マルチパート、フィールド名 `mask`、白 = 消去) | | `format` | string | `"auto"` | 出力形式: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | 出力品質 | NVIDIA GPU が利用可能な場合は CUDA で高速化されます。 ## AI キャンバス拡張 {#ai-canvas-expand} **ツールルート:** `ai-canvas-expand`\ **モデル:** LaMa ベースのアウトペインティング 画像のキャンバスを任意の方向に拡張し、新しい領域を既存の画像に合わせた AI 生成コンテンツで埋めます。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | 上方向に拡張するピクセル数 | | `extendRight` | integer | `0` | 右方向に拡張するピクセル数 | | `extendBottom` | integer | `0` | 下方向に拡張するピクセル数 | | `extendLeft` | integer | `0` | 左方向に拡張するピクセル数 | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | 品質ティア | | `format` | string | `"auto"` | 出力形式: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | 出力品質 | 少なくとも 1 つの拡張方向が 0 より大きくなければなりません。 ## スマートクロップ {#smart-crop} **ツールルート:** `smart-crop`\ **モデル:** MediaPipe 顔検出(face モードのみ) | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | クロップ戦略: `subject`, `face`, `trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | subject モードの戦略 | | `width` | integer | - | 出力幅 | | `height` | integer | - | 出力高さ | | `padding` | integer (0-50) | `0` | 被写体周りのパディング割合 | | `facePreset` | string | `"head-shoulders"` | `mode=face` の場合のプリセット構図 | | `sensitivity` | number (0-1) | `0.5` | 顔検出のしきい値 | | `threshold` | integer (0-255) | `30` | 背景検出のしきい値(trim モード) | | `padToSquare` | boolean | `false` | トリミング結果を正方形にパディング | | `padColor` | string | `"#ffffff"` | 正方形パディングの背景色 | | `targetSize` | integer | - | パディング後の出力の目標サイズ(ピクセル) | | `quality` | integer (1-100) | - | 出力品質 | レガシーの `mode` 値 `attention` と `content` は受け付けられ、それぞれ `subject` と `trim` にマッピングされます。 **顔プリセット:** | プリセット | 最適な用途 | |--------|---------| | `closeup` | ヘッドショット | | `head-shoulders` | プロフィール写真 | | `upper-body` | LinkedIn / フォーマル | | `half-body` | 上半身全体 | ## 音声の文字起こし {#transcribe-audio} **ツールルート:** `transcribe-audio`\ **モデル:** faster-whisper 音声をテキストに変換します。プレーンテキスト、SRT、VTT の出力形式に対応しています。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 言語: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | 出力形式 | ## 自動字幕 {#auto-subtitles} **ツールルート:** `auto-subtitles`\ **モデル:** faster-whisper(動画から音声を抽出してから文字起こし) 動画の音声トラックから字幕ファイルを生成します。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 言語: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | 出力字幕形式 | ## PNG 透過修正 {#png-transparency-fixer} **ツールルート:** `transparency-fixer`\ **モデル:** BiRefNet HR マッティング(2048x2048 解像度) 背景が除去されたものの、フリンジ、ハロー、半透明のアーティファクトが残った「見せかけの透過」PNG を修正します。BiRefNet の高解像度マッティングモデルを使用してクリーンなアルファチャンネルを生成し、その後、設定可能なデフリンジ処理を適用してエッジに沿った色の混入を除去します。 **OOM フォールバックチェーン:** BiRefNet HR マッティングが利用可能なメモリを超過した場合、ツールは自動的に `birefnet-general` にフォールバックし、さらに `u2net` にフォールバックします。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | 色の混入を除去するエッジデフリンジの強度 | | `outputFormat` | `"png"` | `"webp"` | `"png"` | 出力画像形式 | | `removeWatermark` | boolean | `false` | ウォーターマーク除去の前処理(メディアンフィルター)を適用 | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## AI 機能をオプションで備えたツール {#tools-with-optional-ai-capabilities} 以下のツールは Python サイドカーツールではありませんが、特定のオプションが有効な場合に AI 機能を使用します。 ### 画像補正 {#image-enhancement} **ツールルート:** `image-enhancement`\ **エンジン:** 解析ベース(Sharp のヒストグラムと統計) 画像を解析し、露出、コントラスト、ホワイトバランス、彩度、シャープネス、ノイズに対して自動補正を適用します。シーン別のモードに対応しています。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | 補正を調整するシーンモード | | `intensity` | number (0-100) | `50` | 全体的な補正の強度 | | `corrections.exposure` | boolean | `true` | 露出補正を適用 | | `corrections.contrast` | boolean | `true` | コントラスト補正を適用 | | `corrections.whiteBalance` | boolean | `true` | ホワイトバランス補正を適用 | | `corrections.saturation` | boolean | `true` | 彩度補正を適用 | | `corrections.sharpness` | boolean | `true` | シャープネス補正を適用 | | `corrections.denoise` | boolean | `true` | ノイズ除去を適用 | | `deepEnhance` | boolean | `false` | SCUNet による AI ノイズ除去を有効化(`upscale-enhance` バンドルが必要) | 適用せずに検出された補正内容を返す追加の解析エンドポイントが `POST /api/v1/tools/image/image-enhancement/analyze` で利用できます。 ### コンテンツを考慮したリサイズ(シームカービング) {#content-aware-resize-seam-carving} **ツールルート:** `content-aware-resize`\ **エンジン:** Go の `caire` バイナリ(Python ではないため GPU の恩恵なし) 低エネルギーのシームを除去することで画像をインテリジェントにリサイズし、重要なコンテンツを保持します。 | パラメータ | 型 | デフォルト | 説明 | |-----------|------|---------|-------------| | `width` | number | - | 目標幅 | | `height` | number | - | 目標高さ | | `protectFaces` | boolean | `false` | 検出された顔の領域を保護(`face-detection` バンドルが必要) | | `blurRadius` | number (0-20) | `4` | エネルギー計算のための事前ぼかし | | `sobelThreshold` | number (1-20) | `2` | エッジ感度のしきい値 | | `square` | boolean | `false` | 正方形出力を強制 | --- --- url: https://docs.snapotter.com/zh-CN/tools/image/colorize.md description: 使用 DDColor AI 模型自动为黑白或灰度照片上色。 --- # AI 上色 {#ai-colorization} 使用 AI(DDColor 模型,以 OpenCV DNN 作为回退方案)将黑白或灰度照片转换为全彩。 ## API 端点 {#api-endpoint} `POST /api/v1/tools/image/colorize` **处理方式:** 异步(返回 202,通过 SSE 轮询 `/api/v1/jobs/{jobId}/progress` 获取状态) **模型包:** `object-eraser-colorize`(1-2 GB) ## 参数 {#parameters} | 参数 | 类型 | 必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | file | file | 是 | - | 图片文件(multipart) | | intensity | number | 否 | `1.0` | 颜色强度(0-1)。较低的值会产生更柔和的上色效果 | | model | string | 否 | `"auto"` | 使用的模型:`auto`、`ddcolor`、`opencv` | ## 请求示例 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## 响应 {#response} ### 初始响应(202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### 进度(SSE 位于 `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### 最终结果(通过 SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## 注意事项 {#notes} * 需要安装 `object-eraser-colorize` 模型包(1-2 GB)。 * DDColor 产生更高质量的结果但较慢;OpenCV DNN 更快,质量略低。`auto` 在可用时使用 DDColor,并以 OpenCV 作为回退方案。 * `intensity` 参数在原始灰度与 AI 上色结果之间进行混合。使用 1.0 获得全彩效果,较低的值可获得部分去饱和的复古外观。 * 输出格式会自动与输入格式一致。 * 对于无法在浏览器中预览的输出格式,会在主输出旁一并生成 WebP 预览。 * 通过自动解码支持 HEIC/HEIF、RAW、TGA、PSD、EXR 和 HDR 输入格式。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/colorize.md description: 使用 DDColor AI 模型自動為黑白或灰階照片上色。 --- # AI 上色 {#ai-colorization} 使用 AI(DDColor 模型,並以 OpenCV DNN 作為後備)將黑白或灰階照片轉換為全彩。 ## API 端點 {#api-endpoint} `POST /api/v1/tools/image/colorize` **處理方式:** 非同步(回傳 202,透過 SSE 輪詢 `/api/v1/jobs/{jobId}/progress` 取得狀態) **模型套件:** `object-eraser-colorize`(1-2 GB) ## 參數 {#parameters} | 參數 | 類型 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | file | file | 是 | - | 圖片檔案(multipart) | | intensity | number | 否 | `1.0` | 色彩強度(0-1)。數值越低,上色越細膩 | | model | string | 否 | `"auto"` | 要使用的模型:`auto`、`ddcolor`、`opencv` | ## 範例請求 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## 回應 {#response} ### 初始回應(202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### 進度(SSE,位於 `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### 最終結果(透過 SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## 備註 {#notes} * 需要安裝 `object-eraser-colorize` 模型套件(1-2 GB)。 * DDColor 產生的結果品質較高但較慢;OpenCV DNN 較快但品質略低。`auto` 會在 DDColor 可用時使用它,並以 OpenCV 作為後備。 * `intensity` 參數會在原始灰階與 AI 上色結果之間混合。使用 1.0 表示全彩,較低的數值則呈現部分去飽和的復古效果。 * 輸出格式會自動與輸入格式相符。 * 對於瀏覽器無法預覽的輸出格式,會在主要輸出旁一併產生 WebP 預覽。 * 透過自動解碼支援 HEIC/HEIF、RAW、TGA、PSD、EXR 與 HDR 輸入格式。 --- --- url: https://docs.snapotter.com/zh-CN/api/ai.md description: AI 引擎参考,涵盖所有本地 ML 工具。抠图、放大、OCR、人脸检测、照片修复等。 --- # AI 引擎参考 {#ai-engine-reference} `@snapotter/ai` 包协调本机工具和 Python 运行时以进行本地 ML 操作。 大多数 ML 工具使用持久的 Python sidecar 来实现快速热启动。 OCR 是故意分开的: `fast` 调用本机 Tesseract 二进制文件, 而 `balanced` 和 `best` 使用专用的持久性 JSONL dispatcher,固定到 `/data/ai/v3` 下的活动不可变 RapidOCR 代。 每个请求都包含一个 generation lease。 在升级期间,SnapOtter 在激活之前在候选者上运行 smoke test,自动切换到新的 dispatcher,然后在 garbage collection 之前耗尽旧代。 NVIDIA CUDA 由支持它的运行时自动检测和使用。 OCR 在每个主机上使用 CPU,包括具有 NVIDIA GPU 的系统,避免 CUDA 和该工具的驱动程序耦合。 目前不支持通过 VA-API、Quick Sync 或 OpenCL 使用 Intel/AMD 集成显卡加速 AI 推理。将 `/dev/dri` 映射到容器中并不会加速这些 Python 边车工具,除非有支持 CUDA 的 NVIDIA GPU 可用。 19 个 Python 边车 AI 工具,覆盖四种模态(图像、音频、视频、文档),另有 2 个具备可选 AI 能力的工具。所有模型均在本地运行,首次下载模型后无需联网。 ::: info 韩语 OCR 兼容性 快速 OCR 支持 `auto`、`en`、`de`、`es`、`fr`、`zh` 和 `ja`,但不支持韩语 (`ko`)。韩语需要精确 OCR 包以及 `balanced` 或 `best`。该包可在官方 Linux amd64 和 arm64 容器上运行;即使是 NVIDIA 主机,OCR 仍使用 CPU。不受支持的系统会返回明确的兼容性错误,绝不会静默回退到 `fast`。韩语与 `fast` 或旧版 `tesseract` 别名的组合会在入队前以 `FEATURE_INCOMPATIBLE` 和 `fast-korean-unsupported` 拒绝。 ::: ## 架构 {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` 一个独立的 "docs" 调度器配置用文档处理脚本(`doc_pagecount`、`doc_health`、`doc_flatten`、`doc_redact`、`doc_text`、`doc_to_word`、`doc_metadata`、`doc_html_pdf`)替换了 AI 白名单,并跳过繁重的 ML 导入。 **超时:** 默认 300 秒;OCR 和 BiRefNet 抠图为 600 秒。 ## 功能包 {#feature-bundles} AI 模型按共享依赖栈打包,而不是每个工具一个归档。当多个工具使用同一模型系列、Python wheel 或原生库时,一个功能包可以启用多个工具。这样可以让发布用的 Docker 镜像更小,并避免重复存储相同的抠图、人脸检测、OCR、修复和语音模型副本。 Docker 镜像随附应用程序以及通用运行时。大型模型归档会按需下载到常驻的 `/data/ai` 卷中,然后供每个需要它的工具复用。如果某个包因为另一个工具需要而已经安装,那么启用一个新的依赖工具时不会再次下载该包。 大多数人工智能工具都需要一个或多个功能包才能运行。 管理 UI 通过 `POST /api/v1/admin/tools/:toolId/features/install` 工具安装这些包,它解析完整的捆绑包列表,跳过已安装的捆绑包,并仅对缺少的下载进行排队。 例如,在新实例队列 `background-removal` 和 `face-detection` 上启用 Passport Photo; 在已安装后台删除后启用它仅排队 `face-detection`。 OCR 是例外,因为 `fast` 不需要包装; 通过 UI 或 `POST /api/v1/admin/features/ocr/install` 安装其可选的精确运行时。 | 功能包 | 大小 | 共享依赖组 | 使用它的工具 | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet 抠图 | remove-background、passport-photo、transparency-fixer、background-replace、blur-background | | `face-detection` | 200-300 MB | MediaPipe 人脸检测与关键点 | blur-faces、red-eye-removal、smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa 图像修复/外扩与 DDColor | erase-object、colorize、ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN、GFPGAN / CodeFormer、降噪 | upscale、enhance-faces、noise-removal | | `photo-restoration` | 4-5 GB | 划痕修复与修复流水线 | restore-photo | | `ocr` | ~208-234 MiB 下载 / ~409-488 MiB 安装 | 可选 RapidOCR 3.9.1、ONNX Runtime 1.20.1 和固定 PP-OCR 型号 | ocr、ocr-pdf(仅限 `balanced` 和 `best`) | | `transcription` | ~600 MB | faster-whisper 语音转文本模型 | transcribe-audio、auto-subtitles | 具有跨包依赖的工具: | 工具 | 所需功能包 | 原因 | |------|------------------|-----| | `passport-photo` | `background-removal`、`face-detection` | 先移除背景,然后使用人脸关键点将裁剪对齐到护照和证件照规则。 | | `enhance-faces` | `upscale-enhance`、`face-detection` | 在对选定的人脸区域运行 GFPGAN 或 CodeFormer 增强之前先检测人脸。 | 仅当安装了工具所需的所有捆绑包(OCR 除外)后,该工具才可用:其内置 `fast` 层在没有可选 OCR 包的情况下仍然可用。 部分安装是有效的,并且是增量处理的:已安装的捆绑包被重用,丢失的捆绑包显示为下载,排队安装一次运行一个,因此共享的 Python 环境不会同时修改。 ### 准确的 OCR 运行时安装{#accurate-ocr-runtime-installation} 准确的 OCR 包是官方 Linux amd64 或 Linux arm64 容器的特定于平台的运行时。 amd64 构建使用 Python 3.12; arm64 版本使用 Python 3.11。 两个版本都通过 ONNX Runtime 的 `CPUExecutionProvider` 运行 RapidOCR,因此同一包可在仅 CPU 和 NVIDIA Docker 主机上运行。 准确的运行时需要至少 4 GiB 的有效内存:配置的容器 cgroup 限制,否则为主机内存。 低于该签名兼容性最低值的系统在下载前会被拒绝。 此要求不适用于内置 Fast OCR。 Bare-metal 构建被拒绝,因为它们的 libc 和 Python ABI 无法安全推断; 当主机提供 Tesseract 和 Ghostscript 时,快速 OCR 保持可用。 可选工件大约压缩 208-234 MiB 并提取 409-488 MiB,具体取决于架构。 签名索引绑定安装程序强制执行的精确压缩和提取字节计数。 内置 Tesseract 在官方镜像上增加了约25个 MiB,并且不需要`/data/ai`中的文件。 在线安装会获取已签名的版本索引以及当前平台的精确内容寻址工件。 SnapOtter 在原子激活新一代之前验证 Ed25519 索引签名、工件大小、SHA-256 摘要、模型摘要、路径、文件模式和暂存 smoke test。 失败的安装会使之前的健康生成保持活动状态。 对于气隙安装,请使用名为 `index` 和 `archive` 的多部分字段将版本的 `ocr-runtime-index.json` 和匹配的 OCR 运行时存档上传到 `POST /api/v1/admin/features/import`。 离线导入应用与在线安装相同的签名、哈希、提取、兼容性和冒烟测试检查; 没有可信签名索引的存档将被拒绝。 *** ## 抠图 {#background-removal} **工具路由:** `remove-background`\ **模型:** 采用 BiRefNet(默认)或 U2-Net 变体的 rembg | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `model` | string | - | 模型变体(可选覆盖) | | `backgroundType` | string | `"transparent"` | 其一:`transparent`、`color`、`gradient`、`blur`、`image` | | `backgroundColor` | string | - | 纯色背景的十六进制颜色 | | `gradientColor1` | string | - | 第一个渐变颜色 | | `gradientColor2` | string | - | 第二个渐变颜色 | | `gradientAngle` | number | - | 渐变角度(度) | | `blurEnabled` | boolean | - | 启用背景模糊效果 | | `blurIntensity` | number (0-100) | - | 模糊强度 | | `shadowEnabled` | boolean | - | 为主体启用投影 | | `shadowOpacity` | number (0-100) | - | 阴影不透明度 | | `outputFormat` | string | - | 输出格式:`png`、`webp` 或 `avif` | | `edgeRefine` | integer (0-3) | - | 边缘细化级别 | | `decontaminate` | boolean | - | 移除边缘的颜色溢出 | ## 背景替换 {#background-replace} **工具路由:** `background-replace`\ **模型:** rembg / BiRefNet(与 remove-background 共享) 移除背景并将其替换为纯色或渐变。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | 背景模式 | | `color` | string | `"#ffffff"` | 背景十六进制颜色(当 `backgroundType` 为 `color` 时) | | `gradientColor1` | string | - | 第一个渐变十六进制颜色 | | `gradientColor2` | string | - | 第二个渐变十六进制颜色 | | `gradientAngle` | integer (0-360) | `180` | 渐变角度(度) | | `feather` | integer (0-20) | `0` | 边缘羽化半径 | | `format` | `"png"` | `"webp"` | `"png"` | 输出格式 | ## 背景模糊 {#blur-background} **工具路由:** `blur-background`\ **模型:** rembg / BiRefNet(与 remove-background 共享) 在保持主体清晰的同时模糊背景。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | 模糊强度 | | `feather` | integer (0-20) | `0` | 边缘羽化半径 | | `format` | `"png"` | `"webp"` | `"png"` | 输出格式 | ## 图像放大 {#image-upscaling} **工具路由:** `upscale`\ **模型:** RealESRGAN(不可用时回退到 Lanczos) | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `scale` | number | `2` | 放大倍数 | | `model` | string | `"auto"` | 模型变体 | | `faceEnhance` | boolean | `false` | 应用 GFPGAN 人脸增强处理 | | `denoise` | number | `0` | 降噪强度 | | `format` | string | `"auto"` | 输出格式覆盖 | | `quality` | number | `95` | 输出质量(1-100) | ## OCR / 文本提取 {#ocr-text-extraction} **工具路由:** `ocr`\ **型号:** Tesseract (`fast`); RapidOCR 与 PP-OCRv6 小型号(`balanced`);具有校准变体评分的 PP-OCRv6 中型模型 (`best`) | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 动态的 | 省略 `quality` 和 `engine` 时,SnapOtter 会按 `best`、`balanced`、`fast` 的顺序选择可用的最高质量层。韩语绝不会选择 `fast`;它会使用 `best`,其次是 `balanced`,否则返回精确运行时的安装或兼容性错误。 | | `language` | string | `"auto"` | 语言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko` | | `enhance` | 布尔值 | 取决于层级 | 提高局部对比度。快速直接应用;仅当校准得分提高 OCR 时,准确的等级才会保留变体。默认为“最佳” | | `engine` | 细绳 | - | 已弃用的兼容性别名。将 `tesseract` 映射到 `fast`,并将旧版 `paddleocr` 值映射到 `balanced`;它不加载 PaddlePaddle | 返回提取的文本以及来源元数据:引擎、请求的和实际的质量、设备、提供商、降级状态、警告和准确的运行时/模型版本(如果适用)。 明确的质量要求永远不会退回到另一层。 如果 `balanced` 或 `best` 不可用,则 API 返回 `FEATURE_NOT_INSTALLED` 或 `FEATURE_INCOMPATIBLE`,而不是静默运行 `fast`。 ## PDF OCR {#pdf-ocr} **工具路由:** `ocr-pdf`\ **模型:** 与图像 OCR 相同的档次体系 使用 AI 驱动的 OCR 逐页从扫描的 PDF 文档中提取文本。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 动态的 | 省略 `quality` 和 `engine` 时,SnapOtter 会按 `best`、`balanced`、`fast` 的顺序选择可用的最高质量层。韩语绝不会选择 `fast`;它会使用 `best`,其次是 `balanced`,否则返回精确运行时的安装或兼容性错误。 | | `language` | string | `"auto"` | 语言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko` | | `pages` | string | `"all"` | 页面选择:`"all"`、`"1-3"`、`"1,3,5"` | | `enhance` | 布尔值 | 取决于层级 | 提高局部对比度。快速直接应用;仅当校准得分提高 OCR 时,准确的等级才会保留变体。默认为“最佳” | | `engine` | 细绳 | - | 已弃用的兼容性别名。将 `tesseract` 映射到 `fast`,并将旧版 `paddleocr` 值映射到 `balanced`;它不加载 PaddlePaddle | 同样的不降级规则适用于 PDF OCR。 PDF 页面在识别前会进行光栅化处理,一次请求最多可以选择50个页面。 ## 人脸 / PII 模糊 {#face-pii-blur} **工具路由:** `blur-faces`\ **模型:** MediaPipe 人脸检测 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | 高斯模糊半径 | | `sensitivity` | number (0-1) | `0.5` | 检测置信度阈值 | ## 人脸增强 {#face-enhancement} **工具路由:** `enhance-faces`\ **模型:** GFPGAN、CodeFormer | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | 增强模型 | | `strength` | number (0-1) | `0.8` | 增强强度 | | `sensitivity` | number (0-1) | `0.5` | 人脸检测阈值 | | `onlyCenterFace` | boolean | `false` | 仅增强最居中的人脸 | ## AI 上色 {#ai-colorization} **工具路由:** `colorize`\ **模型:** DDColor(回退到 OpenCV DNN) 将黑白或灰度照片转换为全彩。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | 色彩饱和度强度 | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | 模型变体 | ## 噪点去除 {#noise-removal} **工具路由:** `noise-removal`\ **模型:** SCUNet(分档降噪流水线) | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | 处理档次 | | `strength` | number (0-100) | `50` | 降噪强度 | | `detailPreservation` | number (0-100) | `50` | 保留多少细节;数值越高保留的纹理越多 | | `colorNoise` | number (0-100) | `30` | 彩色噪点抑制强度 | | `format` | string | `"original"` | 输出格式:`original`、`png`、`jpeg`、`webp`、`avif`、`jxl` | | `quality` | number (1-100) | `90` | 输出编码质量 | ## 红眼消除 {#red-eye-removal} **工具路由:** `red-eye-removal` 检测人脸关键点,定位眼部区域,并校正红色通道过饱和。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | 红色像素检测阈值 | | `strength` | number (0-100) | `70` | 校正强度 | | `format` | string | - | 输出格式覆盖(可选) | | `quality` | number (1-100) | `90` | 输出质量 | ## 照片修复 {#photo-restoration} **工具路由:** `restore-photo` 针对老旧或受损照片的多步流水线:划痕/撕裂检测与修复、人脸增强、降噪,以及可选的上色。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | 检测并修复划痕、撕裂 | | `faceEnhancement` | boolean | `true` | 应用人脸增强处理 | | `fidelity` | number (0-1) | `0.7` | 人脸增强强度(越高越保守) | | `denoise` | boolean | `true` | 应用降噪处理 | | `denoiseStrength` | number (0-100) | `25` | 降噪强度 | | `colorize` | boolean | `false` | 修复后进行上色 | | `colorizeStrength` | number (0-100) | `85` | 上色强度 | ## 护照照片 {#passport-photo} **工具路由:** `passport-photo`\ **模型:** MediaPipe 人脸关键点 + BiRefNet 抠图 两阶段工作流:分析(检测人脸 + 移除背景),然后生成(裁剪、缩放、平铺)。支持横跨 6 个地区的 37+ 个国家/地区。 ### 阶段 1:分析 {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` 接受一个图像文件(multipart)。返回人脸关键点数据、一张 base64 预览图,以及图像尺寸。 ### 阶段 2:生成 {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` 接受一个 JSON 主体,其中包含阶段 1 的结果加上生成设置: | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `jobId` | string | (必填) | 来自阶段 1 的作业 ID | | `filename` | string | (必填) | 来自阶段 1 的原始文件名 | | `countryCode` | string | (必填) | ISO 国家/地区代码(例如 `US`、`GB`、`IN`) | | `documentType` | string | `"passport"` | 证件类型 | | `bgColor` | string | `"#FFFFFF"` | 背景颜色十六进制 | | `printLayout` | string | `"none"` | 打印排版:`none`、`4x6`、`a4`、`letter` | | `maxFileSizeKb` | number | `0` | 最大文件大小(KB)(0 = 无限制) | | `dpi` | number (72-1200) | `300` | 输出 DPI | | `customWidthMm` | number | - | 自定义宽度(毫米)(覆盖国家/地区规格) | | `customHeightMm` | number | - | 自定义高度(毫米)(覆盖国家/地区规格) | | `zoom` | number (0.5-3) | `1` | 缩放系数 | | `adjustX` | number | `0` | 水平位置调整 | | `adjustY` | number | `0` | 垂直位置调整 | | `landmarks` | object | (必填) | 来自阶段 1 的关键点 | | `imageWidth` | number | (必填) | 来自阶段 1 的图像宽度 | | `imageHeight` | number | (必填) | 来自阶段 1 的图像高度 | ## 对象擦除(图像修复) {#object-erasing-inpainting} **工具路由:** `erase-object`\ **模型:** 通过 ONNX Runtime 运行的 LaMa 蒙版作为**第二个文件部分**发送(字段名 `mask`),而不是作为 base64。蒙版中的白色像素表示要擦除的区域。`format` 和 `quality` 设置作为顶层表单字段发送。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `file` | file | (必填) | 源图像(multipart) | | `mask` | file | (必填) | 蒙版图像(multipart,字段名 `mask`,白色 = 擦除) | | `format` | string | `"auto"` | 输出格式:`auto`、`png`、`jpg`、`jpeg`、`webp`、`tiff`、`gif`、`avif`、`heic`、`heif`、`jxl` | | `quality` | integer (1-100) | `95` | 输出质量 | 当有 NVIDIA GPU 可用时启用 CUDA 加速。 ## AI 画布扩展 {#ai-canvas-expand} **工具路由:** `ai-canvas-expand`\ **模型:** 基于 LaMa 的外扩 向任意方向扩展图像画布,并用与现有图像相匹配的 AI 生成内容填充新增区域。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | 顶部扩展的像素数 | | `extendRight` | integer | `0` | 右侧扩展的像素数 | | `extendBottom` | integer | `0` | 底部扩展的像素数 | | `extendLeft` | integer | `0` | 左侧扩展的像素数 | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | 质量档次 | | `format` | string | `"auto"` | 输出格式:`auto`、`png`、`jpg`、`jpeg`、`webp`、`tiff`、`gif`、`avif`、`heic`、`heif`、`jxl` | | `quality` | integer (1-100) | `95` | 输出质量 | 至少有一个扩展方向必须大于 0。 ## 智能裁剪 {#smart-crop} **工具路由:** `smart-crop`\ **模型:** MediaPipe 人脸检测(仅人脸模式) | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | 裁剪策略:`subject`、`face`、`trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | 主体模式的策略 | | `width` | integer | - | 输出宽度 | | `height` | integer | - | 输出高度 | | `padding` | integer (0-50) | `0` | 主体周围的内边距百分比 | | `facePreset` | string | `"head-shoulders"` | 当 `mode=face` 时的预设取景 | | `sensitivity` | number (0-1) | `0.5` | 人脸检测阈值 | | `threshold` | integer (0-255) | `30` | 背景检测阈值(trim 模式) | | `padToSquare` | boolean | `false` | 将裁剪结果补齐为正方形 | | `padColor` | string | `"#ffffff"` | 正方形补齐的背景颜色 | | `targetSize` | integer | - | 补齐输出的目标尺寸(像素) | | `quality` | integer (1-100) | - | 输出质量 | 旧版 `mode` 值 `attention` 和 `content` 仍被接受,并分别映射到 `subject` 和 `trim`。 **人脸预设:** | 预设 | 最适合 | |--------|---------| | `closeup` | 头像特写 | | `head-shoulders` | 个人资料照片 | | `upper-body` | LinkedIn / 正式照 | | `half-body` | 完整上半身 | ## 音频转写 {#transcribe-audio} **工具路由:** `transcribe-audio`\ **模型:** faster-whisper 将语音转换为文本。支持纯文本、SRT 和 VTT 输出格式。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 语言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko`、`id`、`th`、`vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | 输出格式 | ## 自动字幕 {#auto-subtitles} **工具路由:** `auto-subtitles`\ **模型:** faster-whisper(从视频中提取音频,然后转写) 从视频的音轨生成字幕文件。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 语言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko`、`id`、`th`、`vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | 输出字幕格式 | ## PNG 透明度修复 {#png-transparency-fixer} **工具路由:** `transparency-fixer`\ **模型:** BiRefNet HR-matting(2048x2048 分辨率) 修复"伪透明"PNG,即背景已被移除但残留了毛边、光晕或半透明杂影。使用 BiRefNet 的高分辨率抠图模型生成干净的 alpha 通道,然后应用可配置的去边处理以移除边缘的颜色污染。 **OOM 回退链:** 如果 BiRefNet HR-matting 超出可用内存,工具会自动回退到 `birefnet-general`,然后回退到 `u2net`。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | 边缘去边强度,用于移除颜色污染 | | `outputFormat` | `"png"` | `"webp"` | `"png"` | 输出图像格式 | | `removeWatermark` | boolean | `false` | 应用水印移除预处理(中值滤波) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## 具备可选 AI 能力的工具 {#tools-with-optional-ai-capabilities} 以下工具并非 Python 边车工具,但在启用某些选项时会使用 AI 功能。 ### 图像增强 {#image-enhancement} **工具路由:** `image-enhancement`\ **引擎:** 基于分析(Sharp 直方图与统计) 分析图像并对曝光、对比度、白平衡、饱和度、锐度和噪点应用自动校正。支持特定场景模式。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | 用于微调校正的场景模式 | | `intensity` | number (0-100) | `50` | 整体校正强度 | | `corrections.exposure` | boolean | `true` | 应用曝光校正 | | `corrections.contrast` | boolean | `true` | 应用对比度校正 | | `corrections.whiteBalance` | boolean | `true` | 应用白平衡校正 | | `corrections.saturation` | boolean | `true` | 应用饱和度校正 | | `corrections.sharpness` | boolean | `true` | 应用锐度校正 | | `corrections.denoise` | boolean | `true` | 应用降噪 | | `deepEnhance` | boolean | `false` | 通过 SCUNet 启用 AI 噪点去除(需要 `upscale-enhance` 功能包) | 在 `POST /api/v1/tools/image/image-enhancement/analyze` 处还提供一个额外的分析端点,它返回检测到的校正而不实际应用它们。 ### 内容感知缩放(接缝裁剪) {#content-aware-resize-seam-carving} **工具路由:** `content-aware-resize`\ **引擎:** Go `caire` 二进制文件(非 Python,无 GPU 收益) 通过移除低能量接缝智能地缩放图像,保留重要内容。 | 参数 | 类型 | 默认值 | 说明 | |-----------|------|---------|-------------| | `width` | number | - | 目标宽度 | | `height` | number | - | 目标高度 | | `protectFaces` | boolean | `false` | 保护检测到的人脸区域(需要 `face-detection` 功能包) | | `blurRadius` | number (0-20) | `4` | 用于能量计算的预模糊 | | `sobelThreshold` | number (1-20) | `2` | 边缘敏感度阈值 | | `square` | boolean | `false` | 强制正方形输出 | --- --- url: https://docs.snapotter.com/zh-TW/api/ai.md description: AI 引擎參考,涵蓋所有本機 ML 工具。去背、放大、OCR、人臉偵測、相片修復等。 --- # AI 引擎參考 {#ai-engine-reference} `@snapotter/ai` 套件協調本機工具和 Python 運行時以進行本機 ML 操作。 大多數 ML 工具使用持久的 Python sidecar 來實現快速熱啟動。 OCR 是故意分開的: `fast` 呼叫本機 Tesseract 二進位文件, 儘管 `balanced` 和 `best` 使用專用的持久化 JSONL dispatcher 固定到活動的不可變的 RapidOCR 新一代 `/data/ai/v3`。 每個請求都包含一個 generation lease。 在升級期間,SnapOtter 在啟動之前在候選者上運行 smoke test,自動切換到新的 dispatcher,然後在 garbage collection 之前耗盡舊代。 NVIDIA CUDA 由支援它的運行時自動檢測和使用。 OCR 在每個主機上使用 CPU,包括具有 NVIDIA GPU 的系統,避免 CUDA 和該工具的驅動程式耦合。 目前不支援透過 VA-API、Quick Sync 或 OpenCL 進行 Intel/AMD iGPU 的 AI 推論加速。除非有支援 CUDA 的 NVIDIA GPU 可用,否則將 `/dev/dri` 對映進容器並不會加速這些 Python sidecar 工具。 19 個 Python sidecar AI 工具,橫跨四種模態(image、audio、video、document),另有 2 個具備選用 AI 功能的工具。所有模型都在本機執行,初次下載模型後即不需要網際網路。 ::: info 韓語 OCR 相容性 快速 OCR 支援 `auto`、`en`、`de`、`es`、`fr`、`zh` 和 `ja`,但不支援韓語 (`ko`)。韓語需要精確 OCR 套件以及 `balanced` 或 `best`。此套件可在官方 Linux amd64 和 arm64 容器上執行;即使是 NVIDIA 主機,OCR 仍使用 CPU。不受支援的系統會傳回明確的相容性錯誤,絕不會靜默回退至 `fast`。韓語搭配 `fast` 或舊版 `tesseract` 別名時,會在排入佇列前以 `FEATURE_INCOMPATIBLE` 和 `fast-korean-unsupported` 拒絕。 ::: ## 架構 {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` 另有一個獨立的「docs」dispatcher 設定檔,以文件處理指令碼(`doc_pagecount`、`doc_health`、`doc_flatten`、`doc_redact`、`doc_text`、`doc_to_word`、`doc_metadata`、`doc_html_pdf`)取代 AI 允許清單,並略過大型 ML 匯入。 **逾時:** 預設 300 秒;OCR 與 BiRefNet 去背則為 600 秒。 ## 功能套件包 {#feature-bundles} AI 模型是依共用相依堆疊來封裝,而非每個工具一個封存檔。當多個工具使用相同的模型家族、Python wheel 或原生函式庫時,一個功能套件包可同時啟用這些工具。這讓發行的 Docker 映像更小,並避免重複儲存相同的背景去背、人臉偵測、OCR、修復與語音模型。 Docker 映像隨附應用程式加上共用執行環境。大型模型封存檔會在需要時下載到常駐的 `/data/ai` 磁碟區,之後由所有需要它的工具重複使用。如果某個套件包已因另一個工具的需要而安裝,啟用一個新的相依工具並不會再次下載該套件包。 大多數人工智慧工具都需要一個或多個功能包才能運作。 管理 UI 透過 `POST /api/v1/admin/tools/:toolId/features/install` 工具安裝這些包,它解析完整的捆綁包列表,跳過已安裝的捆綁包,並僅對缺少的下載進行排隊。 例如,在新實例佇列 `background-removal` 和 `face-detection` 上啟用 Passport Photo; 在已安裝背景刪除後啟用它僅排隊 `face-detection`。 OCR 是例外,因為 `fast` 不需要包裝; 透過 UI 或 `POST /api/v1/admin/features/ocr/install` 安裝其選購的精確執行時間。 | 套件包 | 大小 | 共用相依群組 | 使用它的工具 | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet 背景去背 | remove-background、passport-photo、transparency-fixer、background-replace、blur-background | | `face-detection` | 200-300 MB | MediaPipe 人臉偵測與特徵點 | blur-faces、red-eye-removal、smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa 影像修補/外延與 DDColor | erase-object、colorize、ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN、GFPGAN / CodeFormer、去雜訊 | upscale、enhance-faces、noise-removal | | `photo-restoration` | 4-5 GB | 刮痕修復與修復流程 | restore-photo | | `ocr` | ~208-234 MiB 下載 / ~409-488 MiB 安裝 | 選配 RapidOCR 3.9.1、ONNX Runtime 1.20.1 和固定 PP-OCR 型號 | ocr、ocr-pdf(僅限 `balanced` 和 `best`) | | `transcription` | ~600 MB | faster-whisper 語音轉文字模型 | transcribe-audio、auto-subtitles | 具有跨套件包相依性的工具: | 工具 | 必要套件包 | 原因 | |------|------------------|-----| | `passport-photo` | `background-removal`、`face-detection` | 先移除背景,再用人臉特徵點依護照與身分證照片規則框住裁切範圍。 | | `enhance-faces` | `upscale-enhance`、`face-detection` | 在對選定的人臉區域執行 GFPGAN 或 CodeFormer 增強之前,先偵測人臉。 | 只有在安裝了工具所需的所有捆綁包(OCR 除外)後,工具才可用:其內建 `fast` 層在沒有選購 OCR 包的情況下仍然可用。 部分安裝是有效的,並且是增量處理的:已安裝的捆綁包被重用,丟失的捆綁包顯示為下載,排隊安裝一次運行一個,因此共享的 Python 環境不會同時修改。 ### 準確的 OCR 運行時安裝{#accurate-ocr-runtime-installation} 準確的 OCR 套件是官方 Linux amd64 或 Linux arm64 容器的特定於平台的運行時。 amd64 建置使用 Python 3.12; arm64 版本使用 Python 3.11。 兩個版本都透過 ONNX Runtime 的 `CPUExecutionProvider` 運行 RapidOCR, 因此,相同的套件適用於僅 CPU 和 NVIDIA Docker 主機。 準確的運行時需要至少 4 GiB 的有效記憶體:配置的容器 cgroup 限制,否則為主機記憶體。 低於該簽章相容性最低值的系統在下載前會被拒絕。 此要求不適用於內建 Fast OCR。 Bare-metal 建置被拒絕,因為它們的 libc 和 Python ABI 無法安全推斷; 當主機提供 Tesseract 和 Ghostscript 時,快速 OCR 保持可用。 選用工件大約壓縮 208-234 MiB 並提取 409-488 MiB,具體取決於架構。 簽章索引綁定安裝程式強制執行的精確壓縮和提取位元組計數。 內建 Tesseract 在官方鏡像上增加了約25個 MiB,並且不需要`/data/ai`中的檔案。 線上安裝會取得已簽署的版本索引以及目前平台的精確內容尋址工件。 SnapOtter 在原子啟動新世代之前驗證 Ed25519 索引簽章、工件大小、SHA-256 摘要、模型摘要、路徑、檔案模式和暫存 smoke test。 失敗的安裝會使先前的健康生成保持活動狀態。 對於氣隙安裝,請使用名為 `index` 和 `archive` 的多部分欄位將版本的 `ocr-runtime-index.json` 和相符的 OCR 執行時間存檔上傳到 `POST /api/v1/admin/features/import`。 離線導入應用與線上安裝相同的簽名、哈希、提取、相容性和冒煙測試檢查; 沒有可信任簽名索引的檔案將被拒絕。 *** ## 去背 {#background-removal} **工具路由:** `remove-background`\ **模型:** rembg 搭配 BiRefNet(預設)或 U2-Net 變體 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `model` | string | - | 模型變體(選用覆寫) | | `backgroundType` | string | `"transparent"` | 其一:`transparent`、`color`、`gradient`、`blur`、`image` | | `backgroundColor` | string | - | 純色背景的十六進位色碼 | | `gradientColor1` | string | - | 第一個漸層顏色 | | `gradientColor2` | string | - | 第二個漸層顏色 | | `gradientAngle` | number | - | 漸層角度(以度為單位) | | `blurEnabled` | boolean | - | 啟用背景模糊效果 | | `blurIntensity` | number (0-100) | - | 模糊強度 | | `shadowEnabled` | boolean | - | 為主體啟用陰影 | | `shadowOpacity` | number (0-100) | - | 陰影不透明度 | | `outputFormat` | string | - | 輸出格式:`png`、`webp` 或 `avif` | | `edgeRefine` | integer (0-3) | - | 邊緣細化等級 | | `decontaminate` | boolean | - | 移除邊緣的顏色滲色 | ## 背景替換 {#background-replace} **工具路由:** `background-replace`\ **模型:** rembg / BiRefNet(與 remove-background 共用) 移除背景並以純色或漸層取代。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | 背景模式 | | `color` | string | `"#ffffff"` | 背景十六進位色碼(當 `backgroundType` 為 `color` 時) | | `gradientColor1` | string | - | 第一個漸層十六進位色碼 | | `gradientColor2` | string | - | 第二個漸層十六進位色碼 | | `gradientAngle` | integer (0-360) | `180` | 漸層角度(以度為單位) | | `feather` | integer (0-20) | `0` | 邊緣羽化半徑 | | `format` | `"png"` | `"webp"` | `"png"` | 輸出格式 | ## 模糊背景 {#blur-background} **工具路由:** `blur-background`\ **模型:** rembg / BiRefNet(與 remove-background 共用) 在保持主體清晰的同時模糊背景。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | 模糊強度 | | `feather` | integer (0-20) | `0` | 邊緣羽化半徑 | | `format` | `"png"` | `"webp"` | `"png"` | 輸出格式 | ## 影像放大 {#image-upscaling} **工具路由:** `upscale`\ **模型:** RealESRGAN(不可用時以 Lanczos 備援) | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `scale` | number | `2` | 放大倍率 | | `model` | string | `"auto"` | 模型變體 | | `faceEnhance` | boolean | `false` | 套用 GFPGAN 人臉增強處理 | | `denoise` | number | `0` | 去雜訊強度 | | `format` | string | `"auto"` | 輸出格式覆寫 | | `quality` | number | `95` | 輸出品質(1-100) | ## OCR / 文字擷取 {#ocr-text-extraction} **工具路由:** `ocr`\ **型號:** Tesseract (`fast`); RapidOCR 和 PP-OCRv6 小型型號(`balanced`); PP-OCRv6 具有校準變數評分的中等模型(`best`) | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 動態的 | 省略 `quality` 和 `engine` 時,SnapOtter 會依 `best`、`balanced`、`fast` 的順序選擇可用的最高品質層。韓語絕不會選擇 `fast`;它會使用 `best`,其次是 `balanced`,否則傳回精確執行階段的安裝或相容性錯誤。 | | `language` | string | `"auto"` | 語言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko` | | `enhance` | 布林值 | 取決於層級 | 提高局部對比。快速直接應用;僅當校準得分提高 OCR 時,準確的等級才會保留變體。預設為“最佳” | | `engine` | 細繩 | - | 已棄用的兼容性別名。將 `tesseract` 對應到 `fast`,並將舊版 `paddleocr` 值對應到 `balanced`;它不載入 PaddlePaddle | 傳回提取的文字以及來源元資料:引擎、請求的和實際的品質、設備、提供者、降級狀態、警告和準確的運行時/模型版本(如果適用)。 明確的品質要求永遠不會退回到另一層。 如果 `balanced` 或 `best` 不可用,則 API 傳回 `FEATURE_NOT_INSTALLED` 或 `FEATURE_INCOMPATIBLE`,而不是靜默執行 `fast`。 ## PDF OCR {#pdf-ocr} **工具路由:** `ocr-pdf`\ **模型:** 與影像 OCR 相同的層級系統 使用 AI 驅動的 OCR,逐頁從掃描的 PDF 文件擷取文字。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | 動態的 | 省略 `quality` 和 `engine` 時,SnapOtter 會依 `best`、`balanced`、`fast` 的順序選擇可用的最高品質層。韓語絕不會選擇 `fast`;它會使用 `best`,其次是 `balanced`,否則傳回精確執行階段的安裝或相容性錯誤。 | | `language` | string | `"auto"` | 語言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko` | | `pages` | string | `"all"` | 頁面選取:`"all"`、`"1-3"`、`"1,3,5"` | | `enhance` | 布林值 | 取決於層級 | 提高局部對比。快速直接應用;僅當校準得分提高 OCR 時,準確的等級才會保留變體。預設為“最佳” | | `engine` | 細繩 | - | 已棄用的兼容性別名。將 `tesseract` 對應到 `fast`,並將舊版 `paddleocr` 值對應到 `balanced`;它不載入 PaddlePaddle | 同樣的不降級規則適用於 PDF OCR。 PDF 頁面在辨識前會進行光柵化處理,一次要求最多可以選擇50個頁面。 ## 人臉 / PII 模糊 {#face-pii-blur} **工具路由:** `blur-faces`\ **模型:** MediaPipe 人臉偵測 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | 高斯模糊半徑 | | `sensitivity` | number (0-1) | `0.5` | 偵測信賴度門檻 | ## 人臉增強 {#face-enhancement} **工具路由:** `enhance-faces`\ **模型:** GFPGAN、CodeFormer | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | 增強模型 | | `strength` | number (0-1) | `0.8` | 增強強度 | | `sensitivity` | number (0-1) | `0.5` | 人臉偵測門檻 | | `onlyCenterFace` | boolean | `false` | 只增強最靠近中央的人臉 | ## AI 上色 {#ai-colorization} **工具路由:** `colorize`\ **模型:** DDColor(以 OpenCV DNN 備援) 將黑白或灰階相片轉換為全彩。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | 色彩飽和度強度 | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | 模型變體 | ## 去雜訊 {#noise-removal} **工具路由:** `noise-removal`\ **模型:** SCUNet(分層去雜訊流程) | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | 處理層級 | | `strength` | number (0-100) | `50` | 去雜訊強度 | | `detailPreservation` | number (0-100) | `50` | 要保留多少細節;數值越高保留越多紋理 | | `colorNoise` | number (0-100) | `30` | 色彩雜訊降低強度 | | `format` | string | `"original"` | 輸出格式:`original`、`png`、`jpeg`、`webp`、`avif`、`jxl` | | `quality` | number (1-100) | `90` | 輸出編碼品質 | ## 紅眼移除 {#red-eye-removal} **工具路由:** `red-eye-removal` 偵測人臉特徵點、定位眼睛區域,並修正紅色通道的過飽和。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | 紅色像素偵測門檻 | | `strength` | number (0-100) | `70` | 修正強度 | | `format` | string | - | 輸出格式覆寫(選用) | | `quality` | number (1-100) | `90` | 輸出品質 | ## 相片修復 {#photo-restoration} **工具路由:** `restore-photo` 針對老舊或受損相片的多步驟流程:刮痕/撕裂偵測與修復、人臉增強、去雜訊,以及選用的上色。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | 偵測並修復刮痕、撕裂 | | `faceEnhancement` | boolean | `true` | 套用人臉增強處理 | | `fidelity` | number (0-1) | `0.7` | 人臉增強強度(越高越保守) | | `denoise` | boolean | `true` | 套用去雜訊處理 | | `denoiseStrength` | number (0-100) | `25` | 去雜訊強度 | | `colorize` | boolean | `false` | 修復後進行上色 | | `colorizeStrength` | number (0-100) | `85` | 上色強度 | ## 證件照 {#passport-photo} **工具路由:** `passport-photo`\ **模型:** MediaPipe 人臉特徵點 + BiRefNet 去背 兩階段工作流程:分析(偵測人臉 + 移除背景),接著產生(裁切、調整大小、平舖)。支援橫跨 6 個地區的 37+ 個國家。 ### 階段 1:分析 {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` 接受一個影像檔(multipart)。傳回人臉特徵點資料、一張 base64 預覽,以及影像尺寸。 ### 階段 2:產生 {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` 接受一個 JSON 主體,內含階段 1 的結果加上產生設定: | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `jobId` | string | (必填) | 來自階段 1 的 Job ID | | `filename` | string | (必填) | 來自階段 1 的原始檔名 | | `countryCode` | string | (必填) | ISO 國家代碼(例如 `US`、`GB`、`IN`) | | `documentType` | string | `"passport"` | 文件類型 | | `bgColor` | string | `"#FFFFFF"` | 背景顏色十六進位色碼 | | `printLayout` | string | `"none"` | 列印版面配置:`none`、`4x6`、`a4`、`letter` | | `maxFileSizeKb` | number | `0` | 檔案大小上限(KB)(0 = 無限制) | | `dpi` | number (72-1200) | `300` | 輸出 DPI | | `customWidthMm` | number | - | 自訂寬度(mm)(覆寫國家規格) | | `customHeightMm` | number | - | 自訂高度(mm)(覆寫國家規格) | | `zoom` | number (0.5-3) | `1` | 縮放倍率 | | `adjustX` | number | `0` | 水平位置調整 | | `adjustY` | number | `0` | 垂直位置調整 | | `landmarks` | object | (必填) | 來自階段 1 的特徵點 | | `imageWidth` | number | (必填) | 來自階段 1 的影像寬度 | | `imageHeight` | number | (必填) | 來自階段 1 的影像高度 | ## 物件擦除(影像修補) {#object-erasing-inpainting} **工具路由:** `erase-object`\ **模型:** 透過 ONNX Runtime 的 LaMa 遮罩會以**第二個檔案部分**(欄位名稱 `mask`)傳送,而非以 base64。遮罩中的白色像素表示要擦除的區域。`format` 與 `quality` 設定會以頂層表單欄位傳送。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `file` | file | (必填) | 來源影像(multipart) | | `mask` | file | (必填) | 遮罩影像(multipart,欄位名稱 `mask`,白色 = 擦除) | | `format` | string | `"auto"` | 輸出格式:`auto`、`png`、`jpg`、`jpeg`、`webp`、`tiff`、`gif`、`avif`、`heic`、`heif`、`jxl` | | `quality` | integer (1-100) | `95` | 輸出品質 | 當有 NVIDIA GPU 可用時以 CUDA 加速。 ## AI 畫布擴展 {#ai-canvas-expand} **工具路由:** `ai-canvas-expand`\ **模型:** 以 LaMa 為基礎的外延 朝任何方向擴展影像的畫布,並以與現有影像相符的 AI 生成內容填滿新增區域。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | 上方要延伸的像素數 | | `extendRight` | integer | `0` | 右方要延伸的像素數 | | `extendBottom` | integer | `0` | 下方要延伸的像素數 | | `extendLeft` | integer | `0` | 左方要延伸的像素數 | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | 品質層級 | | `format` | string | `"auto"` | 輸出格式:`auto`、`png`、`jpg`、`jpeg`、`webp`、`tiff`、`gif`、`avif`、`heic`、`heif`、`jxl` | | `quality` | integer (1-100) | `95` | 輸出品質 | 至少要有一個延伸方向大於 0。 ## 智慧裁切 {#smart-crop} **工具路由:** `smart-crop`\ **模型:** MediaPipe 人臉偵測(僅 face 模式) | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | 裁切策略:`subject`、`face`、`trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | subject 模式的策略 | | `width` | integer | - | 輸出寬度 | | `height` | integer | - | 輸出高度 | | `padding` | integer (0-50) | `0` | 主體周圍的留白百分比 | | `facePreset` | string | `"head-shoulders"` | 當 `mode=face` 時的預設框取 | | `sensitivity` | number (0-1) | `0.5` | 人臉偵測門檻 | | `threshold` | integer (0-255) | `30` | 背景偵測門檻(trim 模式) | | `padToSquare` | boolean | `false` | 將修剪後的結果補齊為正方形 | | `padColor` | string | `"#ffffff"` | 正方形補齊的背景顏色 | | `targetSize` | integer | - | 補齊輸出的目標尺寸(像素) | | `quality` | integer (1-100) | - | 輸出品質 | 舊版 `mode` 值 `attention` 與 `content` 仍被接受,並分別對映為 `subject` 與 `trim`。 **人臉預設:** | 預設 | 最適用於 | |--------|---------| | `closeup` | 大頭照 | | `head-shoulders` | 個人檔案相片 | | `upper-body` | LinkedIn / 正式 | | `half-body` | 完整上半身 | ## 音訊轉錄 {#transcribe-audio} **工具路由:** `transcribe-audio`\ **模型:** faster-whisper 將語音轉換為文字。支援純文字、SRT 與 VTT 輸出格式。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 語言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko`、`id`、`th`、`vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | 輸出格式 | ## 自動字幕 {#auto-subtitles} **工具路由:** `auto-subtitles`\ **模型:** faster-whisper(先從影片擷取音訊,再進行轉錄) 從影片的音軌產生字幕檔。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `language` | string | `"auto"` | 語言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko`、`id`、`th`、`vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | 輸出字幕格式 | ## PNG 透明度修復 {#png-transparency-fixer} **工具路由:** `transparency-fixer`\ **模型:** BiRefNet HR-matting(2048x2048 解析度) 修復「假透明」的 PNG,也就是背景已被移除但留下毛邊、光暈或半透明瑕疵的情況。使用 BiRefNet 的高解析度去背模型產生乾淨的 alpha 通道,接著套用可設定的去毛邊處理,以移除邊緣沿線的顏色汙染。 **OOM 備援鏈:** 若 BiRefNet HR-matting 超出可用記憶體,工具會自動退回 `birefnet-general`,然後退回 `u2net`。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | 用於移除顏色汙染的邊緣去毛邊強度 | | `outputFormat` | `"png"` | `"webp"` | `"png"` | 輸出影像格式 | | `removeWatermark` | boolean | `false` | 套用浮水印移除前處理(中值濾波) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## 具備選用 AI 功能的工具 {#tools-with-optional-ai-capabilities} 以下工具並非 Python sidecar 工具,但在啟用特定選項時會使用 AI 功能。 ### 影像增強 {#image-enhancement} **工具路由:** `image-enhancement`\ **引擎:** 以分析為基礎(Sharp 直方圖與統計) 分析影像並自動修正曝光、對比、白平衡、飽和度、銳利度與雜訊。支援特定場景模式。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | 用於調校修正的場景模式 | | `intensity` | number (0-100) | `50` | 整體修正強度 | | `corrections.exposure` | boolean | `true` | 套用曝光修正 | | `corrections.contrast` | boolean | `true` | 套用對比修正 | | `corrections.whiteBalance` | boolean | `true` | 套用白平衡修正 | | `corrections.saturation` | boolean | `true` | 套用飽和度修正 | | `corrections.sharpness` | boolean | `true` | 套用銳利度修正 | | `corrections.denoise` | boolean | `true` | 套用去雜訊 | | `deepEnhance` | boolean | `false` | 透過 SCUNet 啟用 AI 去雜訊(需要 `upscale-enhance` 套件包) | 另有一個分析端點位於 `POST /api/v1/tools/image/image-enhancement/analyze`,它會傳回偵測到的修正而不加以套用。 ### 內容感知調整大小(接縫裁減) {#content-aware-resize-seam-carving} **工具路由:** `content-aware-resize`\ **引擎:** Go `caire` 二進位檔(非 Python,無 GPU 效益) 透過移除低能量接縫來智慧調整影像大小,保留重要內容。 | 參數 | 型別 | 預設值 | 說明 | |-----------|------|---------|-------------| | `width` | number | - | 目標寬度 | | `height` | number | - | 目標高度 | | `protectFaces` | boolean | `false` | 保護偵測到的人臉區域(需要 `face-detection` 套件包) | | `blurRadius` | number (0-20) | `4` | 能量計算的預先模糊 | | `sobelThreshold` | number (1-20) | `2` | 邊緣敏感度門檻 | | `square` | boolean | `false` | 強制正方形輸出 | --- --- url: https://docs.snapotter.com/nl/tools/image/ai-canvas-expand.md description: >- Breid een afbeeldingscanvas uit met AI-outpainting, verleng het in elke richting en vul nieuwe gebieden om bij het origineel aan te sluiten. --- # AI-canvas uitbreiden {#ai-canvas-expand} Breid het canvas van een afbeelding uit met AI-gestuurde invulling (outpainting). Verlengt de afbeelding in elke richting en vult de nieuwe gebieden met AI-gegenereerde content die aansluit op de bestaande afbeelding. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Verwerking:** Asynchroon (retourneert 202, poll `/api/v1/jobs/{jobId}/progress` voor de status via SSE) **Modelbundel:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Afbeeldingsbestand (multipart) | | extendTop | integer | Nee | `0` | Pixels om bovenaan uit te breiden | | extendRight | integer | Nee | `0` | Pixels om rechts uit te breiden | | extendBottom | integer | Nee | `0` | Pixels om onderaan uit te breiden | | extendLeft | integer | Nee | `0` | Pixels om links uit te breiden | | tier | string | Nee | `"balanced"` | Kwaliteitsniveau: `fast`, `balanced`, `high` | | format | string | Nee | `"auto"` | Uitvoerformaat: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | Nee | `95` | Uitvoerkwaliteit (1-100) | Ten minste één uitbreidingsrichting moet groter zijn dan 0. ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Antwoord {#response} ### Initieel antwoord (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Voortgang (SSE op `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Eindresultaat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Opmerkingen {#notes} * Vereist dat de modelbundel `object-eraser-colorize` is geïnstalleerd (1-2 GB). * Gebruikt op LaMa gebaseerde outpainting om content voor de uitgebreide gebieden te genereren. * De parameter `tier` ruilt snelheid in voor kwaliteit: `fast` levert snel resultaten op met mogelijke artefacten, `high` duurt langer maar levert vloeiendere, samenhangender invullingen op. * Uitbreidingswaarden zijn in pixels. De uiteindelijke afmetingen van de afbeelding worden: originele breedte + extendLeft + extendRight bij originele hoogte + extendTop + extendBottom. * Voor uitvoerformaten die niet in de browser kunnen worden bekeken (HEIC, JXL, TIFF) wordt naast de hoofduitvoer een WebP-voorbeeld gegenereerd. * Ondersteunt de invoerformaten HEIC/HEIF, RAW, TGA, PSD, EXR en HDR via automatische decodering. --- --- url: https://docs.snapotter.com/nl/api/ai.md description: >- AI-engine-referentie met alle lokale ML-tools. Achtergrondverwijdering, upscaling, OCR, gezichtsdetectie, fotorestauratie en meer. --- # AI-engine-referentie {#ai-engine-reference} Het `@snapotter/ai`-pakket coördineert native tools en Python-runtimes voor lokale ML-bewerkingen. De meeste ML-tools gebruiken een persistente Python sidecar voor snelle warme starts. OCR is opzettelijk gescheiden: `fast` roept het oorspronkelijke Tesseract binaire bestand aan, terwijl `balanced` en `best` een speciale persistente JSONL dispatcher gebruiken die is vastgemaakt aan de actieve onveranderlijke RapidOCR-generatie onder `/data/ai/v3`. Elk verzoek bevat een generation lease. Tijdens een upgrade voert SnapOtter een smoke test uit op de kandidaat vóór activering, schakelt atomair over naar de nieuwe dispatcher en leegt vervolgens de oude generatie vóór garbage collection. NVIDIA CUDA wordt automatisch gedetecteerd en gebruikt door runtimes die dit ondersteunen. OCR gebruikt CPU op elke host, inclusief systemen met NVIDIA GPU's, waardoor CUDA en driverkoppeling voor deze tool worden vermeden. Intel/AMD iGPU-versnelling via VA-API, Quick Sync of OpenCL wordt vandaag niet ondersteund voor AI-inferentie. Het toewijzen van `/dev/dri` aan een container versnelt deze Python-sidecar-tools niet, tenzij er een CUDA-compatibele NVIDIA-GPU beschikbaar is. 19 Python-sidecar-AI-tools verdeeld over vier modaliteiten (afbeelding, audio, video, document), plus 2 tools met optionele AI-mogelijkheden. Alle modellen draaien lokaal: na de eerste modeldownload is er geen internet vereist. ::: info Compatibiliteit voor Koreaanse OCR Snelle OCR ondersteunt `auto`, `en`, `de`, `es`, `fr`, `zh` en `ja`, maar geen Koreaans (`ko`). Koreaans vereist het nauwkeurige OCR-pakket en `balanced` of `best`. Het pakket werkt in officiële Linux amd64- en arm64-containers, ook op NVIDIA-hosts waar OCR op de CPU blijft draaien. Niet-ondersteunde systemen krijgen een expliciete compatibiliteitsfout en vallen nooit stil terug op `fast`. Koreaans met `fast` of de oude alias `tesseract` wordt vóór het in de wachtrij plaatsen geweigerd met `FEATURE_INCOMPATIBLE` en `fast-korean-unsupported`. ::: ## Architectuur {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` Een apart "docs"-dispatcher-profiel vervangt de AI-allowlist door scripts voor documentverwerking (`doc_pagecount`, `doc_health`, `doc_flatten`, `doc_redact`, `doc_text`, `doc_to_word`, `doc_metadata`, `doc_html_pdf`) en slaat zware ML-imports over. **Time-outs:** 300 s standaard; OCR en BiRefNet-achtergrondverwijdering krijgen 600 s. ## Feature-bundels {#feature-bundles} AI-modellen worden per gedeelde dependency-stack gebundeld, niet één archief per tool. Een feature-bundel kan meerdere tools inschakelen wanneer ze dezelfde modelfamilie, Python-wheels of native libraries gebruiken. Dit houdt de release-Docker-image kleiner en voorkomt het opslaan van dubbele kopieën van dezelfde achtergrondmatting-, gezichtsdetectie-, OCR-, restauratie- en spraakmodellen. De Docker-image levert de applicatie plus de gedeelde runtime. Grote modelarchieven worden op aanvraag gedownload naar het persistente `/data/ai`-volume en vervolgens hergebruikt door elke tool die ze nodig heeft. Als een bundel al geïnstalleerd is omdat een andere tool deze nodig had, downloadt het inschakelen van een nieuwe afhankelijke tool die bundel niet opnieuw. De meeste AI-tools hebben een of meer functiebundels nodig voordat ze kunnen worden uitgevoerd. De beheerdersinterface installeert deze per tool via `POST /api/v1/admin/tools/:toolId/features/install`, die de volledige bundellijst oplost, bundels overslaat die al zijn geïnstalleerd en alleen de ontbrekende downloads in de wachtrij plaatst. Als u bijvoorbeeld Passport Photo inschakelt op een nieuw exemplaar, staan ​​de wachtrijen `background-removal` en `face-detection` in; inschakelen nadat Achtergrondverwijdering al is geïnstalleerd, alleen wachtrijen `face-detection`. OCR is de uitzondering omdat `fast` geen pakket nodig heeft; installeer de optionele nauwkeurige runtime via de gebruikersinterface of `POST /api/v1/admin/features/ocr/install`. | Bundel | Grootte | Gedeelde dependency-groep | Tools die het gebruiken | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | rembg / BiRefNet-achtergrondmatting | remove-background, passport-photo, transparency-fixer, background-replace, blur-background | | `face-detection` | 200-300 MB | MediaPipe-gezichtsdetectie en -landmarks | blur-faces, red-eye-removal, smart-crop | | `object-eraser-colorize` | 1-2 GB | LaMa inpainting/outpainting en DDColor | erase-object, colorize, ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN, GFPGAN / CodeFormer, denoising | upscale, enhance-faces, noise-removal | | `photo-restoration` | 4-5 GB | krasreparatie- en restauratiepijplijn | restore-photo | | `ocr` | ~208-234 MiB downloaden / ~409-488 MiB geïnstalleerd | Optionele RapidOCR 3.9.1-, ONNX Runtime 1.20.1- en vastgezette PP-OCR-modellen | ocr, ocr-pdf (alleen `balanced` en `best`) | | `transcription` | ~600 MB | faster-whisper spraak-naar-tekst-modellen | transcribe-audio, auto-subtitles | Tools met bundeloverschrijdende afhankelijkheden: | Tool | Vereiste bundels | Waarom | |------|------------------|-----| | `passport-photo` | `background-removal`, `face-detection` | Verwijdert de achtergrond en gebruikt vervolgens gezichtslandmarks om de uitsnede te kaderen volgens de regels voor pasfoto's en ID-foto's. | | `enhance-faces` | `upscale-enhance`, `face-detection` | Detecteert gezichten voordat GFPGAN- of CodeFormer-verbetering op de geselecteerde gezichtsregio's wordt uitgevoerd. | Een tool is alleen beschikbaar als alle vereiste bundels zijn geïnstalleerd, behalve OCR: de ingebouwde `fast`-laag blijft beschikbaar zonder het optionele OCR-pakket. Gedeeltelijke installaties zijn geldig en worden stapsgewijs afgehandeld: geïnstalleerde bundels worden hergebruikt, ontbrekende bundels worden weergegeven als downloads en installaties in de wachtrij worden één voor één uitgevoerd, zodat de gedeelde Python-omgeving niet tegelijkertijd wordt gewijzigd. ### Nauwkeurige OCR runtime-installatie {#accurate-ocr-runtime-installation} Het nauwkeurige OCR-pakket is een platformspecifieke runtime voor de officiële Linux amd64 of Linux arm64-container. De amd64-build maakt gebruik van Python 3.12; de arm64-build maakt gebruik van Python 3.11. Beide builds draaien RapidOCR via ONNX Runtime's `CPUExecutionProvider`, dus hetzelfde pakket werkt alleen op CPU- en NVIDIA Docker-hosts. De nauwkeurige runtime vereist minimaal 4 GiB effectief geheugen: de geconfigureerde container cgroup-limiet, anders hostgeheugen. Een systeem onder het ondertekende compatibiliteitsminimum wordt vóór het downloaden afgewezen. Deze vereiste geldt niet voor ingebouwde Fast OCR. Bare-metal-builds worden afgewezen omdat hun libc en Python ABI niet veilig kunnen worden afgeleid; Snelle OCR blijft beschikbaar wanneer de host Tesseract en Ghostscript biedt. Het optionele artefact is ongeveer 208-234 MiB gecomprimeerd en 409-488 MiB geëxtraheerd, afhankelijk van de architectuur. De ondertekende index bindt de exacte gecomprimeerde en geëxtraheerde bytetellingen die door het installatieprogramma worden afgedwongen. Ingebouwde Tesseract voegt ongeveer 25 MiB toe aan de officiële image en heeft geen bestanden nodig in `/data/ai`. Online installatie haalt een ondertekende release-index en het exacte op de inhoud geadresseerde artefact voor het huidige platform op. SnapOtter verifieert de Ed25519-indexhandtekening, artefactgrootte, SHA-256-samenvatting, modelsamenvattingen, paden, bestandsmodi en geënsceneerde smoke test voordat de nieuwe generatie atomair wordt geactiveerd. Bij een mislukte installatie blijft de vorige gezonde generatie actief. Voor air-gapped installatie uploadt u zowel de `ocr-runtime-index.json` van de release als het bijbehorende OCR runtime-archief naar `POST /api/v1/admin/features/import` met behulp van meerdelige velden genaamd `index` en `archive`. Bij offline importeren worden dezelfde handtekening-, hash-, extractie-, compatibiliteits- en rooktestcontroles toegepast als bij online installatie; een archief zonder de vertrouwde ondertekende index wordt afgewezen. *** ## Achtergrondverwijdering {#background-removal} **Toolroute:** `remove-background`\ **Model:** rembg met BiRefNet (standaard) of U2-Net-varianten | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `model` | string | - | Modelvariant (optionele override) | | `backgroundType` | string | `"transparent"` | Een van: `transparent`, `color`, `gradient`, `blur`, `image` | | `backgroundColor` | string | - | Hex-kleur voor effen achtergrond | | `gradientColor1` | string | - | Eerste verloopkleur | | `gradientColor2` | string | - | Tweede verloopkleur | | `gradientAngle` | number | - | Verloophoek in graden | | `blurEnabled` | boolean | - | Achtergrondvervaging inschakelen | | `blurIntensity` | number (0-100) | - | Vervagingsintensiteit | | `shadowEnabled` | boolean | - | Slagschaduw op onderwerp inschakelen | | `shadowOpacity` | number (0-100) | - | Schaduwdekking | | `outputFormat` | string | - | Uitvoerformaat: `png`, `webp`, of `avif` | | `edgeRefine` | integer (0-3) | - | Niveau van randverfijning | | `decontaminate` | boolean | - | Kleurdoorloop van randen verwijderen | ## Achtergrond vervangen {#background-replace} **Toolroute:** `background-replace`\ **Model:** rembg / BiRefNet (gedeeld met remove-background) Verwijdert de achtergrond en vervangt deze door een effen kleur of verloop. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | Achtergrondmodus | | `color` | string | `"#ffffff"` | Hex-achtergrondkleur (wanneer `backgroundType` `color` is) | | `gradientColor1` | string | - | Eerste hex-verloopkleur | | `gradientColor2` | string | - | Tweede hex-verloopkleur | | `gradientAngle` | integer (0-360) | `180` | Verloophoek in graden | | `feather` | integer (0-20) | `0` | Straal van randvervaging | | `format` | `"png"` | `"webp"` | `"png"` | Uitvoerformaat | ## Achtergrond vervagen {#blur-background} **Toolroute:** `blur-background`\ **Model:** rembg / BiRefNet (gedeeld met remove-background) Vervaagt de achtergrond terwijl het onderwerp scherp blijft. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | Vervagingsintensiteit | | `feather` | integer (0-20) | `0` | Straal van randvervaging | | `format` | `"png"` | `"webp"` | `"png"` | Uitvoerformaat | ## Afbeelding upscalen {#image-upscaling} **Toolroute:** `upscale`\ **Model:** RealESRGAN (met Lanczos-fallback wanneer niet beschikbaar) | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `scale` | number | `2` | Upscale-factor | | `model` | string | `"auto"` | Modelvariant | | `faceEnhance` | boolean | `false` | GFPGAN-gezichtsverbeteringspas toepassen | | `denoise` | number | `0` | Denoising-sterkte | | `format` | string | `"auto"` | Override van uitvoerformaat | | `quality` | number | `95` | Uitvoerkwaliteit (1-100) | ## OCR / Tekstextractie {#ocr-text-extraction} **Toolroute:** `ocr`\ **Modellen:** Tesseract (`fast`); RapidOCR met PP-OCRv6 kleine modellen (`balanced`); PP-OCRv6 middelgrote modellen met gekalibreerde variantscore (`best`) | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dynamisch | Als `quality` en `engine` zijn weggelaten, kiest SnapOtter de beste beschikbare laag in deze volgorde: `best`, `balanced`, `fast`. Voor Koreaans wordt `fast` nooit gekozen; het gebruikt `best`, daarna `balanced`, of geeft een installatie- of compatibiliteitsfout voor de nauwkeurige runtime terug. | | `language` | string | `"auto"` | Taal: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `enhance` | Booleaans | Niveau-afhankelijk | Verbeter het lokale contrast. Snel past het direct toe; nauwkeurige niveaus behouden de variant alleen als de gekalibreerde score OCR verbetert. Standaard ingeschakeld voor Beste | | `engine` | snaar | - | Verouderde compatibiliteitsalias. Wijst `tesseract` toe aan `fast` en de oude `paddleocr`-waarde aan `balanced`; PaddlePaddle wordt niet geladen | Retourneert geëxtraheerde tekst plus metagegevens over de herkomst: engine, gevraagde en werkelijke kwaliteit, apparaat, provider, degradatiestatus, waarschuwingen en nauwkeurige runtime-/modelversies, indien van toepassing. Expliciete kwaliteitsverzoeken vallen nooit terug naar een ander niveau. Als `balanced` of `best` niet beschikbaar is, retourneert API `FEATURE_NOT_INSTALLED` of `FEATURE_INCOMPATIBLE` in plaats van `fast` stil uit te voeren. ## PDF-OCR {#pdf-ocr} **Toolroute:** `ocr-pdf`\ **Modellen:** Hetzelfde niveausysteem als afbeeldings-OCR Extraheert tekst uit gescande PDF-documenten met AI-gestuurde OCR, pagina voor pagina. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dynamisch | Als `quality` en `engine` zijn weggelaten, kiest SnapOtter de beste beschikbare laag in deze volgorde: `best`, `balanced`, `fast`. Voor Koreaans wordt `fast` nooit gekozen; het gebruikt `best`, daarna `balanced`, of geeft een installatie- of compatibiliteitsfout voor de nauwkeurige runtime terug. | | `language` | string | `"auto"` | Taal: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `pages` | string | `"all"` | Paginaselectie: `"all"`, `"1-3"`, `"1,3,5"` | | `enhance` | Booleaans | Niveau-afhankelijk | Verbeter het lokale contrast. Snel past het direct toe; nauwkeurige niveaus behouden de variant alleen als de gekalibreerde score OCR verbetert. Standaard ingeschakeld voor Beste | | `engine` | snaar | - | Verouderde compatibiliteitsalias. Wijst `tesseract` toe aan `fast` en de oude `paddleocr`-waarde aan `balanced`; PaddlePaddle wordt niet geladen | Dezelfde regel zonder downgrade is van toepassing op PDF OCR. PDF-pagina's worden vóór herkenning gerasterd, en één verzoek kan maximaal 50 pagina's selecteren. ## Gezicht / PII vervagen {#face-pii-blur} **Toolroute:** `blur-faces`\ **Model:** MediaPipe-gezichtsdetectie | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | Straal van gaussische vervaging | | `sensitivity` | number (0-1) | `0.5` | Drempel voor detectiebetrouwbaarheid | ## Gezichtsverbetering {#face-enhancement} **Toolroute:** `enhance-faces`\ **Modellen:** GFPGAN, CodeFormer | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | Verbeteringsmodel | | `strength` | number (0-1) | `0.8` | Verbeteringssterkte | | `sensitivity` | number (0-1) | `0.5` | Gezichtsdetectiedrempel | | `onlyCenterFace` | boolean | `false` | Alleen het meest centrale gezicht verbeteren | ## AI-inkleuring {#ai-colorization} **Toolroute:** `colorize`\ **Model:** DDColor (met OpenCV DNN-fallback) Zet zwart-wit- of grijswaardenfoto's om naar volledige kleur. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | Sterkte van kleurverzadiging | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | Modelvariant | ## Ruisverwijdering {#noise-removal} **Toolroute:** `noise-removal`\ **Model:** SCUNet (getrapte denoising-pijplijn) | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | Verwerkingsniveau | | `strength` | number (0-100) | `50` | Denoising-sterkte | | `detailPreservation` | number (0-100) | `50` | Hoeveel detail behouden blijft; hoger behoudt meer textuur | | `colorNoise` | number (0-100) | `30` | Sterkte van kleurruisreductie | | `format` | string | `"original"` | Uitvoerformaat: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | `quality` | number (1-100) | `90` | Kwaliteit van uitvoercodering | ## Rode-ogenverwijdering {#red-eye-removal} **Toolroute:** `red-eye-removal` Detecteert gezichtslandmarks, lokaliseert oogregio's en corrigeert oververzadiging van het rode kanaal. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | Detectiedrempel voor rode pixels | | `strength` | number (0-100) | `70` | Correctiesterkte | | `format` | string | - | Override van uitvoerformaat (optioneel) | | `quality` | number (1-100) | `90` | Uitvoerkwaliteit | ## Fotorestauratie {#photo-restoration} **Toolroute:** `restore-photo` Meerstaps-pijplijn voor oude of beschadigde foto's: detectie en reparatie van krassen/scheuren, gezichtsverbetering, denoising en optionele inkleuring. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | Krassen en scheuren detecteren en repareren | | `faceEnhancement` | boolean | `true` | Gezichtsverbeteringspas toepassen | | `fidelity` | number (0-1) | `0.7` | Sterkte van gezichtsverbetering (hoger = behoudender) | | `denoise` | boolean | `true` | Denoising-pas toepassen | | `denoiseStrength` | number (0-100) | `25` | Denoising-sterkte | | `colorize` | boolean | `false` | Inkleuren na restauratie | | `colorizeStrength` | number (0-100) | `85` | Inkleurintensiteit | ## Pasfoto {#passport-photo} **Toolroute:** `passport-photo`\ **Modellen:** MediaPipe-gezichtslandmarks + BiRefNet-achtergrondverwijdering Workflow in twee fasen: analyseren (gezicht detecteren + achtergrond verwijderen) en vervolgens genereren (uitsnijden, formaat wijzigen, tegelen). Ondersteunt meer dan 37 landen in 6 regio's. ### Fase 1: Analyseren {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` Accepteert een afbeeldingsbestand (multipart). Retourneert gezichtslandmark-gegevens, een base64-voorbeeld en afbeeldingsafmetingen. ### Fase 2: Genereren {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` Accepteert een JSON-body met de resultaten van fase 1 plus generatie-instellingen: | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `jobId` | string | (vereist) | Job-ID uit fase 1 | | `filename` | string | (vereist) | Oorspronkelijke bestandsnaam uit fase 1 | | `countryCode` | string | (vereist) | ISO-landcode (bijv. `US`, `GB`, `IN`) | | `documentType` | string | `"passport"` | Documenttype | | `bgColor` | string | `"#FFFFFF"` | Hex-achtergrondkleur | | `printLayout` | string | `"none"` | Afdruklay-out: `none`, `4x6`, `a4`, `letter` | | `maxFileSizeKb` | number | `0` | Max. bestandsgrootte in KB (0 = geen limiet) | | `dpi` | number (72-1200) | `300` | Uitvoer-DPI | | `customWidthMm` | number | - | Aangepaste breedte in mm (overschrijft landspecificatie) | | `customHeightMm` | number | - | Aangepaste hoogte in mm (overschrijft landspecificatie) | | `zoom` | number (0.5-3) | `1` | Zoomfactor | | `adjustX` | number | `0` | Horizontale positieaanpassing | | `adjustY` | number | `0` | Verticale positieaanpassing | | `landmarks` | object | (vereist) | Landmarks uit fase 1 | | `imageWidth` | number | (vereist) | Afbeeldingsbreedte uit fase 1 | | `imageHeight` | number | (vereist) | Afbeeldingshoogte uit fase 1 | ## Objecten wissen (Inpainting) {#object-erasing-inpainting} **Toolroute:** `erase-object`\ **Model:** LaMa via ONNX Runtime Het masker wordt verzonden als een **tweede bestandsdeel** (fieldname `mask`), niet als base64. Witte pixels in het masker geven gebieden aan die gewist moeten worden. De instellingen `format` en `quality` worden verzonden als velden op het hoogste niveau van het formulier. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `file` | file | (vereist) | Bronafbeelding (multipart) | | `mask` | file | (vereist) | Maskerafbeelding (multipart, fieldname `mask`, wit = wissen) | | `format` | string | `"auto"` | Uitvoerformaat: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Uitvoerkwaliteit | CUDA-versneld wanneer een NVIDIA-GPU beschikbaar is. ## AI-canvas uitbreiden {#ai-canvas-expand} **Toolroute:** `ai-canvas-expand`\ **Model:** LaMa-gebaseerde outpainting Breidt het canvas van een afbeelding in elke richting uit en vult nieuwe gebieden met door AI gegenereerde inhoud die aansluit op de bestaande afbeelding. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | Aantal pixels om bovenaan uit te breiden | | `extendRight` | integer | `0` | Aantal pixels om rechts uit te breiden | | `extendBottom` | integer | `0` | Aantal pixels om onderaan uit te breiden | | `extendLeft` | integer | `0` | Aantal pixels om links uit te breiden | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | Kwaliteitsniveau | | `format` | string | `"auto"` | Uitvoerformaat: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Uitvoerkwaliteit | Ten minste één uitbreidingsrichting moet groter zijn dan 0. ## Slim uitsnijden {#smart-crop} **Toolroute:** `smart-crop`\ **Model:** MediaPipe-gezichtsdetectie (alleen gezichtsmodus) | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | Uitsnijstrategie: `subject`, `face`, `trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | Strategie voor onderwerpmodus | | `width` | integer | - | Uitvoerbreedte | | `height` | integer | - | Uitvoerhoogte | | `padding` | integer (0-50) | `0` | Percentage opvulling rond onderwerp | | `facePreset` | string | `"head-shoulders"` | Vaste kadering wanneer `mode=face` | | `sensitivity` | number (0-1) | `0.5` | Gezichtsdetectiedrempel | | `threshold` | integer (0-255) | `30` | Achtergronddetectiedrempel (trimmodus) | | `padToSquare` | boolean | `false` | Getrimd resultaat opvullen tot een vierkant | | `padColor` | string | `"#ffffff"` | Achtergrondkleur voor vierkante opvulling | | `targetSize` | integer | - | Doelgrootte voor opgevulde uitvoer (pixels) | | `quality` | integer (1-100) | - | Uitvoerkwaliteit | Verouderde `mode`-waarden `attention` en `content` worden geaccepteerd en respectievelijk toegewezen aan `subject` en `trim`. **Gezichtspresets:** | Preset | Best voor | |--------|---------| | `closeup` | Portretfoto's | | `head-shoulders` | Profielfoto's | | `upper-body` | LinkedIn / formeel | | `half-body` | Volledig bovenlichaam | ## Audio transcriberen {#transcribe-audio} **Toolroute:** `transcribe-audio`\ **Model:** faster-whisper Zet spraak om naar tekst. Ondersteunt platte tekst, SRT en VTT als uitvoerformaten. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Taal: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | Uitvoerformaat | ## Automatische ondertiteling {#auto-subtitles} **Toolroute:** `auto-subtitles`\ **Model:** faster-whisper (extraheert audio uit video en transcribeert vervolgens) Genereert ondertitelbestanden op basis van het audiospoor van een video. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Taal: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | Uitvoerformaat voor ondertitels | ## PNG-transparantiehersteller {#png-transparency-fixer} **Toolroute:** `transparency-fixer`\ **Model:** BiRefNet HR-matting (2048x2048-resolutie) Herstelt "nep-transparante" PNG's waarbij de achtergrond werd verwijderd maar fringing, halo's of semi-transparante artefacten achterbleven. Gebruikt het hoge-resolutie-mattingmodel van BiRefNet om een schoon alfakanaal te produceren en past vervolgens configureerbare defringe-verwerking toe om kleurverontreiniging langs randen te verwijderen. **OOM-fallbackketen:** Als BiRefNet HR-matting het beschikbare geheugen overschrijdt, valt de tool automatisch terug op `birefnet-general` en vervolgens op `u2net`. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | Sterkte van rand-defringe om kleurverontreiniging te verwijderen | | `outputFormat` | `"png"` | `"webp"` | `"png"` | Uitvoerformaat voor afbeelding | | `removeWatermark` | boolean | `false` | Voorbewerking voor watermerkverwijdering toepassen (mediaanfilter) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## Tools met optionele AI-mogelijkheden {#tools-with-optional-ai-capabilities} De volgende tools zijn geen Python-sidecar-tools, maar gebruiken AI-functies wanneer bepaalde opties zijn ingeschakeld. ### Afbeeldingsverbetering {#image-enhancement} **Toolroute:** `image-enhancement`\ **Engine:** Analysegebaseerd (Sharp-histogram en -statistieken) Analyseert de afbeelding en past automatische correcties toe voor belichting, contrast, witbalans, verzadiging, scherpte en ruis. Ondersteunt scènespecifieke modi. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | Scènemodus voor het afstemmen van correcties | | `intensity` | number (0-100) | `50` | Algehele correctiesterkte | | `corrections.exposure` | boolean | `true` | Belichtingscorrectie toepassen | | `corrections.contrast` | boolean | `true` | Contrastcorrectie toepassen | | `corrections.whiteBalance` | boolean | `true` | Witbalanscorrectie toepassen | | `corrections.saturation` | boolean | `true` | Verzadigingscorrectie toepassen | | `corrections.sharpness` | boolean | `true` | Scherptecorrectie toepassen | | `corrections.denoise` | boolean | `true` | Denoising toepassen | | `deepEnhance` | boolean | `false` | AI-ruisverwijdering via SCUNet inschakelen (vereist `upscale-enhance`-bundel) | Er is een aanvullend analyse-endpoint beschikbaar op `POST /api/v1/tools/image/image-enhancement/analyze` dat de gedetecteerde correcties retourneert zonder ze toe te passen. ### Inhoudsbewuste vergroting/verkleining (Seam Carving) {#content-aware-resize-seam-carving} **Toolroute:** `content-aware-resize`\ **Engine:** Go `caire`-binary (geen Python: geen GPU-voordeel) Wijzigt op intelligente wijze het formaat van afbeeldingen door naden met lage energie te verwijderen, met behoud van belangrijke inhoud. | Parameter | Type | Standaard | Beschrijving | |-----------|------|---------|-------------| | `width` | number | - | Doelbreedte | | `height` | number | - | Doelhoogte | | `protectFaces` | boolean | `false` | Gedetecteerde gezichtsregio's beschermen (vereist `face-detection`-bundel) | | `blurRadius` | number (0-20) | `4` | Voorvervaging voor energieberekening | | `sobelThreshold` | number (1-20) | `2` | Drempel voor randgevoeligheid | | `square` | boolean | `false` | Vierkante uitvoer forceren | --- --- url: https://docs.snapotter.com/sv/tools/image/colorize.md description: >- Färglägg svartvita foton eller gråskalefoton automatiskt med AI-modellen DDColor. --- # AI-färgläggning {#ai-colorization} Omvandla svartvita foton eller gråskalefoton till fullfärg med AI (DDColor-modellen med OpenCV DNN som reserv). ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/colorize` **Bearbetning:** Asynkron (returnerar 202, hämta status via SSE på `/api/v1/jobs/{jobId}/progress`) **Modellpaket:** `object-eraser-colorize` (1-2 GB) ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bildfil (multipart) | | intensity | number | Nej | `1.0` | Färgintensitet (0-1). Lägre värden ger mer subtil färgläggning | | model | string | Nej | `"auto"` | Modell att använda: `auto`, `ddcolor`, `opencv` | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Svar {#response} ### Inledande svar (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Förlopp (SSE på `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Slutresultat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Anteckningar {#notes} * Kräver att modellpaketet `object-eraser-colorize` är installerat (1-2 GB). * DDColor ger resultat av högre kvalitet men är långsammare; OpenCV DNN är snabbare med något lägre kvalitet. `auto` använder DDColor när det är tillgängligt med OpenCV som reserv. * Parametern `intensity` blandar mellan den ursprungliga gråskalan och det AI-färglagda resultatet. Använd 1.0 för fullfärg, lägre värden för ett delvis avmättat vintageutseende. * Utdataformatet matchar indataformatet automatiskt. * För utdataformat som inte kan förhandsgranskas i webbläsaren genereras en WebP-förhandsgranskning vid sidan av huvudutdatan. * Stöder indataformaten HEIC/HEIF, RAW, TGA, PSD, EXR och HDR via automatisk avkodning. --- --- url: https://docs.snapotter.com/nl/tools/image/colorize.md description: >- Kleur zwart-witfoto's of grijstintfoto's automatisch in met het DDColor-AI-model. --- # AI-inkleuring {#ai-colorization} Zet zwart-witfoto's of grijstintfoto's om naar volledige kleur met AI (DDColor-model met OpenCV DNN als terugval). ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/colorize` **Verwerking:** Asynchroon (geeft 202 terug, poll `/api/v1/jobs/{jobId}/progress` voor de status via SSE) **Modelbundel:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Afbeeldingsbestand (multipart) | | intensity | number | Nee | `1.0` | Kleurintensiteit (0-1). Lagere waarden geven subtielere inkleuring | | model | string | Nee | `"auto"` | Te gebruiken model: `auto`, `ddcolor`, `opencv` | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Antwoord {#response} ### Eerste antwoord (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Voortgang (SSE op `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Eindresultaat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Opmerkingen {#notes} * Vereist dat de modelbundel `object-eraser-colorize` is geïnstalleerd (1-2 GB). * DDColor levert resultaten van hogere kwaliteit maar is trager; OpenCV DNN is sneller met een iets lagere kwaliteit. `auto` gebruikt DDColor indien beschikbaar, met OpenCV als terugval. * De parameter `intensity` mengt tussen het originele grijstintbeeld en het door AI ingekleurde resultaat. Gebruik 1.0 voor volledige kleur en lagere waarden voor een gedeeltelijk ontzadigde vintage look. * Het uitvoerformaat komt automatisch overeen met het invoerformaat. * Voor uitvoerformaten die niet in de browser kunnen worden bekeken, wordt naast de hoofduitvoer een WebP-voorbeeld gegenereerd. * Ondersteunt de invoerformaten HEIC/HEIF, RAW, TGA, PSD, EXR en HDR via automatische decodering. --- --- url: https://docs.snapotter.com/sv/tools/image/ai-canvas-expand.md description: >- Utöka en bilds arbetsyta med AI-outpainting, förläng den i valfri riktning och fyll nya områden så att de matchar originalet. --- # AI-utökning av arbetsyta {#ai-canvas-expand} Utöka en bilds arbetsyta med AI-driven ifyllnad (outpainting). Förlänger bilden i valfri riktning och fyller de nya områdena med AI-genererat innehåll som matchar den befintliga bilden. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Bearbetning:** Asynkron (returnerar 202, hämta status genom att polla `/api/v1/jobs/{jobId}/progress` via SSE) **Modellpaket:** `object-eraser-colorize` (1-2 GB) ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | fil | Ja | - | Bildfil (multipart) | | extendTop | heltal | Nej | `0` | Pixlar att förlänga upptill | | extendRight | heltal | Nej | `0` | Pixlar att förlänga till höger | | extendBottom | heltal | Nej | `0` | Pixlar att förlänga nedtill | | extendLeft | heltal | Nej | `0` | Pixlar att förlänga till vänster | | tier | sträng | Nej | `"balanced"` | Kvalitetsnivå: `fast`, `balanced`, `high` | | format | sträng | Nej | `"auto"` | Utdataformat: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | heltal | Nej | `95` | Utdatakvalitet (1-100) | Minst en förlängningsriktning måste vara större än 0. ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Svar {#response} ### Första svaret (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Förlopp (SSE på `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Slutresultat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Anteckningar {#notes} * Kräver att modellpaketet `object-eraser-colorize` är installerat (1-2 GB). * Använder LaMa-baserad outpainting för att generera innehåll för de utökade områdena. * Parametern `tier` byter hastighet mot kvalitet: `fast` ger resultat snabbt med potentiella artefakter, `high` tar längre tid men ger jämnare, mer sammanhängande ifyllnad. * Förlängningsvärdena anges i pixlar. De slutliga bildmåtten blir: ursprunglig bredd + extendLeft + extendRight gånger ursprunglig höjd + extendTop + extendBottom. * För utdataformat som inte kan förhandsvisas i webbläsare (HEIC, JXL, TIFF) genereras en WebP-förhandsvisning tillsammans med huvudutdata. * Stöder indataformaten HEIC/HEIF, RAW, TGA, PSD, EXR och HDR via automatisk avkodning. --- --- url: https://docs.snapotter.com/ru/tools/image/ai-canvas-expand.md description: >- Расширение холста изображения с помощью AI-аутпейнтинга, растягивая его в любом направлении и заполняя новые области в соответствии с оригиналом. --- # AI-расширение холста {#ai-canvas-expand} Расширьте холст изображения с помощью заполнения на основе AI (аутпейнтинг). Растягивает изображение в любом направлении и заполняет новые области сгенерированным AI содержимым, соответствующим существующему изображению. ## Конечная точка API {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Обработка:** асинхронная (возвращает 202, опрашивайте `/api/v1/jobs/{jobId}/progress` для получения статуса через SSE) **Пакет модели:** `object-eraser-colorize` (1–2 ГБ) ## Параметры {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | file | file | Да | - | Файл изображения (multipart) | | extendTop | integer | Нет | `0` | Пикселей для расширения сверху | | extendRight | integer | Нет | `0` | Пикселей для расширения справа | | extendBottom | integer | Нет | `0` | Пикселей для расширения снизу | | extendLeft | integer | Нет | `0` | Пикселей для расширения слева | | tier | string | Нет | `"balanced"` | Уровень качества: `fast`, `balanced`, `high` | | format | string | Нет | `"auto"` | Выходной формат: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | Нет | `95` | Качество вывода (1–100) | Хотя бы одно направление расширения должно быть больше 0. ## Пример запроса {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Ответ {#response} ### Первоначальный ответ (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Прогресс (SSE по адресу `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Итоговый результат (через SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Примечания {#notes} * Требует установки пакета модели `object-eraser-colorize` (1–2 ГБ). * Использует аутпейнтинг на основе LaMa для генерации содержимого расширенных областей. * Параметр `tier` обменивает скорость на качество: `fast` быстро выдаёт результаты с возможными артефактами, `high` занимает больше времени, но даёт более плавное и связное заполнение. * Значения расширения указываются в пикселях. Итоговые размеры изображения будут: исходная ширина + extendLeft + extendRight на исходную высоту + extendTop + extendBottom. * Для выходных форматов, не поддерживающих предпросмотр в браузере (HEIC, JXL, TIFF), рядом с основным выводом создаётся предпросмотр WebP. * Поддерживает входные форматы HEIC/HEIF, RAW, TGA, PSD, EXR и HDR через автоматическое декодирование. --- --- url: https://docs.snapotter.com/ja/tools/image/colorize.md description: DDColor AIモデルで、白黒またはグレースケール写真を自動でカラー化します。 --- # AIカラー化 {#ai-colorization} AI(OpenCV DNNフォールバック付きのDDColorモデル)を使って、白黒またはグレースケール写真をフルカラーに変換します。 ## API エンドポイント {#api-endpoint} `POST /api/v1/tools/image/colorize` **処理:** 非同期(202を返し、SSE経由でステータスを取得するには `/api/v1/jobs/{jobId}/progress` をポーリング) **モデルバンドル:** `object-eraser-colorize`(1〜2 GB) ## パラメータ {#parameters} | パラメータ | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | file | file | はい | - | 画像ファイル(multipart) | | intensity | number | いいえ | `1.0` | 色の強度(0〜1)。値が低いほどカラー化が控えめになります | | model | string | いいえ | `"auto"` | 使用するモデル: `auto`、`ddcolor`、`opencv` | ## リクエスト例 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## レスポンス {#response} ### 初回レスポンス(202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### 進捗(`/api/v1/jobs/{jobId}/progress` でのSSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### 最終結果(SSE経由) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## 補足 {#notes} * `object-eraser-colorize` モデルバンドル(1〜2 GB)のインストールが必要です。 * DDColorはより高品質な結果を生成しますが低速です。OpenCV DNNは高速でわずかに品質が劣ります。`auto` は利用可能な場合にDDColorを使用し、OpenCVをフォールバックとします。 * `intensity` パラメータは元のグレースケールとAIカラー化結果の間をブレンドします。フルカラーには1.0を、部分的に彩度を落としたビンテージ風の見た目には低い値を使用します。 * 出力形式は入力形式に自動で一致します。 * ブラウザでプレビューできない出力形式の場合、メイン出力と併せてWebPプレビューが生成されます。 * HEIC/HEIF、RAW、TGA、PSD、EXR、HDR の入力形式に自動デコードで対応します。 --- --- url: https://docs.snapotter.com/es/tools/image/adjust-colors.md description: >- Ajusta el brillo, el contraste, la saturación, la temperatura, el tono y los canales, y aplica efectos de color. --- # Ajustar colores {#adjust-colors} Herramienta integral de ajuste de color que combina brillo, contraste, exposición, saturación, temperatura, matiz, rotación de tono, niveles por canal y efectos de un clic (escala de grises, sepia, invertir) en un único endpoint. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` Acepta datos de formulario multipart con un archivo de imagen y un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | brightness | number | No | `0` | Ajuste de brillo (-100 a 100) | | contrast | number | No | `0` | Ajuste de contraste (-100 a 100) | | exposure | number | No | `0` | Exposición / gamma de tonos medios (-100 a 100) | | saturation | number | No | `0` | Saturación de color (-100 a 100) | | temperature | number | No | `0` | Balance de blancos: frío/azul a cálido/naranja (-100 a 100) | | tint | number | No | `0` | Cambio de matiz: verde a magenta (-100 a 100) | | hue | number | No | `0` | Rotación de tono en grados (-180 a 180) | | sharpness | number | No | `0` | Intensidad de enfoque (0 a 100) | | red | number | No | `100` | Nivel del canal rojo (0 a 200, 100 = sin cambios) | | green | number | No | `100` | Nivel del canal verde (0 a 200, 100 = sin cambios) | | blue | number | No | `100` | Nivel del canal azul (0 a 200, 100 = sin cambios) | | effect | string | No | `"none"` | Efecto de color: `none`, `grayscale`, `sepia`, `invert` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` Aplica un aspecto vintage cálido: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Notes {#notes} * Todos los parámetros toman por defecto valores neutros, de modo que puedes ajustar solo lo que necesites. * Los ajustes se aplican en este orden: brillo, contraste, exposición, saturación/tono, temperatura/matiz, enfoque, canales, efectos. * La temperatura usa una matriz de recombinación de color de 3x3 sobre los ejes azul-naranja y verde-magenta. * La exposición se corresponde con la función gamma de Sharp (los valores positivos aclaran los tonos medios y los negativos los oscurecen). * Este endpoint también responde en las rutas heredadas `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels` y `/api/v1/tools/image/color-effects`. Todas usan el mismo esquema. * El formato de salida coincide con el de entrada. Las entradas HEIC, RAW, PSD y SVG se decodifican automáticamente antes del procesamiento. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/adjust-colors.md description: >- Ajuste brilho, contraste, saturação, temperatura, matiz, canais e aplique efeitos de cor. --- # Ajustar Cores {#adjust-colors} Ferramenta abrangente de ajuste de cores que combina brilho, contraste, exposição, saturação, temperatura, tonalidade, rotação de matiz, níveis por canal e efeitos de um clique (escala de cinza, sépia, inverter) em um único endpoint. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | brightness | number | Não | `0` | Ajuste de brilho (-100 a 100) | | contrast | number | Não | `0` | Ajuste de contraste (-100 a 100) | | exposure | number | Não | `0` | Exposição / gama dos tons médios (-100 a 100) | | saturation | number | Não | `0` | Saturação de cor (-100 a 100) | | temperature | number | Não | `0` | Balanço de branco: frio/azul a quente/laranja (-100 a 100) | | tint | number | Não | `0` | Deslocamento de tonalidade: verde a magenta (-100 a 100) | | hue | number | Não | `0` | Rotação de matiz em graus (-180 a 180) | | sharpness | number | Não | `0` | Intensidade da nitidez (0 a 100) | | red | number | Não | `100` | Nível do canal vermelho (0 a 200, 100 = inalterado) | | green | number | Não | `100` | Nível do canal verde (0 a 200, 100 = inalterado) | | blue | number | Não | `100` | Nível do canal azul (0 a 200, 100 = inalterado) | | effect | string | Não | `"none"` | Efeito de cor: `none`, `grayscale`, `sepia`, `invert` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` Aplique um visual vintage quente: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Observações {#notes} * Todos os parâmetros têm valores neutros como padrão, para que você ajuste apenas o que precisar. * Os ajustes são aplicados nesta ordem: brilho, contraste, exposição, saturação/matiz, temperatura/tonalidade, nitidez, canais, efeitos. * A temperatura usa uma matriz 3x3 de recombinação de cores nos eixos azul-laranja e verde-magenta. * A exposição é mapeada para a função gama do Sharp (valores positivos clareiam os tons médios, negativos os escurecem). * Este endpoint também responde nos caminhos legados `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels` e `/api/v1/tools/image/color-effects`. Todos usam o mesmo esquema. * O formato de saída corresponde ao formato de entrada. Entradas HEIC, RAW, PSD e SVG são decodificadas automaticamente antes do processamento. --- --- url: https://docs.snapotter.com/pt-BR/tools/audio/volume-adjust.md description: Aumente ou diminua o volume do áudio por um ganho fixo em decibéis. --- # Ajustar Volume {#volume-adjust} Aumente ou diminua o volume de um arquivo de áudio aplicando um ganho fixo em decibéis. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/audio/volume-adjust` Aceita dados de formulário multipart com um arquivo de áudio e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | gainDb | number | Não | `3` | Ajuste de volume em decibéis (-30 a 30) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/volume-adjust \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"gainDb": 6}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notas {#notes} * Valores positivos aumentam o volume; valores negativos o diminuem. * Ganhos positivos grandes podem causar clipping. Use normalize-audio para nivelamento de volume seguro. * A saída geralmente mantém o contêiner de entrada. Entradas AAC são gravadas como M4A, e entradas somente de decodificação sem suporte recorrem a MP3. --- --- url: https://docs.snapotter.com/es/tools/audio/volume-adjust.md description: Aumenta o reduce el volumen del audio con una ganancia fija en decibelios. --- # Ajustar volumen {#volume-adjust} Aumenta o reduce el volumen de un archivo de audio aplicando una ganancia fija en decibelios. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/volume-adjust` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | gainDb | number | No | `3` | Ajuste de volumen en decibelios (-30 a 30) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/volume-adjust \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"gainDb": 6}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notas {#notes} * Los valores positivos aumentan el volumen; los negativos lo reducen. * Las ganancias positivas grandes pueden causar recorte (clipping). Usa normalize-audio para una nivelación segura de la sonoridad. * La salida suele mantener el contenedor de entrada. La entrada AAC se escribe como M4A, y las entradas de solo decodificación no compatibles recurren a MP3. --- --- url: https://docs.snapotter.com/fr/tools/image/adjust-colors.md description: >- Ajuste la luminosité, le contraste, la saturation, la température, la teinte, les canaux et applique des effets de couleur. --- # Ajuster les couleurs {#adjust-colors} Outil complet d'ajustement des couleurs combinant luminosité, contraste, exposition, saturation, température, tonalité, rotation de teinte, niveaux par canal et effets en un clic (niveaux de gris, sépia, inversion) dans un seul point de terminaison. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` Accepte des données de formulaire multipart contenant un fichier image et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | brightness | nombre | Non | `0` | Ajustement de la luminosité (-100 à 100) | | contrast | nombre | Non | `0` | Ajustement du contraste (-100 à 100) | | exposure | nombre | Non | `0` | Exposition / gamma des tons moyens (-100 à 100) | | saturation | nombre | Non | `0` | Saturation des couleurs (-100 à 100) | | temperature | nombre | Non | `0` | Balance des blancs : froid/bleu à chaud/orange (-100 à 100) | | tint | nombre | Non | `0` | Décalage de tonalité : vert à magenta (-100 à 100) | | hue | nombre | Non | `0` | Rotation de teinte en degrés (-180 à 180) | | sharpness | nombre | Non | `0` | Force de la netteté (0 à 100) | | red | nombre | Non | `100` | Niveau du canal rouge (0 à 200, 100 = inchangé) | | green | nombre | Non | `100` | Niveau du canal vert (0 à 200, 100 = inchangé) | | blue | nombre | Non | `100` | Niveau du canal bleu (0 à 200, 100 = inchangé) | | effect | chaîne | Non | `"none"` | Effet de couleur : `none`, `grayscale`, `sepia`, `invert` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` Appliquer un rendu vintage chaleureux : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Remarques {#notes} * Tous les paramètres ont pour valeur par défaut des valeurs neutres, de sorte que vous n'ajustez que ce dont vous avez besoin. * Les ajustements sont appliqués dans cet ordre : luminosité, contraste, exposition, saturation/teinte, température/tonalité, netteté, canaux, effets. * La température utilise une matrice de recombinaison des couleurs 3x3 sur les axes bleu-orange et vert-magenta. * L'exposition correspond à la fonction gamma de Sharp (une valeur positive éclaircit les tons moyens, une valeur négative les assombrit). * Ce point de terminaison répond également aux anciens chemins `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels` et `/api/v1/tools/image/color-effects`. Tous utilisent le même schéma. * Le format de sortie correspond au format d'entrée. Les entrées HEIC, RAW, PSD et SVG sont automatiquement décodées avant le traitement. --- --- url: https://docs.snapotter.com/tr/tools/image/smart-crop.md description: >- Sharp ve AI yüz algılama kullanarak görüntüleri akıllıca çerçeveleyen özne, yüz ve entropi farkındalıklı kırpma. --- # Akıllı Kırpma {#smart-crop} Akıllı özne farkındalıklı, yüz farkındalıklı veya kırpma tabanlı kesme. Akıllı çerçeveleme için Sharp'ın dikkat/entropi stratejilerini ve AI yüz algılamayı kullanır. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/smart-crop` **İşleme:** Eşzamansız (202 döner, durum için SSE aracılığıyla `/api/v1/jobs/{jobId}/progress` üzerinden sorgulanır) **Model paketi:** `face-detection` (200-300 MB) - yalnızca `face` modu için gereklidir ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | file | Evet | - | Görüntü dosyası (multipart) | | mode | string | Hayır | `"subject"` | Kırpma modu: `subject`, `face`, `trim`. (Eski değerler `attention` ve `content`, `subject` ve `trim` değerlerine eşlenir) | | strategy | string | Hayır | `"attention"` | Özne modu için strateji: `attention` veya `entropy` | | width | integer | Hayır | - | Piksel cinsinden hedef genişlik | | height | integer | Hayır | - | Piksel cinsinden hedef yükseklik | | padding | integer | Hayır | `0` | Özne çevresindeki dolgu yüzdesi (0-50) | | facePreset | string | Hayır | `"head-shoulders"` | Yüz çerçeveleme ön ayarı: `closeup`, `head-shoulders`, `upper-body`, `half-body` | | sensitivity | number | Hayır | `0.5` | Yüz algılama duyarlılığı (0-1) | | threshold | integer | Hayır | `30` | Arka plan algılama için kırpma modu eşiği (0-255) | | padToSquare | boolean | Hayır | `false` | Kırpılmış sonucu bir kareye dolgu ile tamamla | | padColor | string | Hayır | `"#ffffff"` | Dolgu için arka plan rengi | | targetSize | integer | Hayır | - | Dolgulu çıktı için hedef boyut (piksel) | | quality | integer | Hayır | - | Çıktı kalitesi (1-100) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/smart-crop \ -F "file=@portrait.jpg" \ -F 'settings={"mode":"face","width":1080,"height":1080,"facePreset":"head-shoulders"}' ``` ## Yanıt {#response} ### İlk Yanıt (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### İlerleme (`/api/v1/jobs/{jobId}/progress` üzerinde SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","percent":50} ``` ### Nihai Sonuç (SSE aracılığıyla) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_smartcrop.jpg", "originalSize": 500000, "processedSize": 320000 } } ``` ## Modlar {#modes} ### Özne Modu {#subject-mode} Görsel olarak en ilgi çekici bölgeyi bulmak için Sharp'ın dikkat veya entropi stratejisini kullanır ve etrafında kırpar. ### Yüz Modu {#face-mode} AI kullanarak yüzleri algılar, ardından belirtilen `facePreset` kullanarak kırpmayı algılanan yüzlerin etrafında çerçeveler. Hiçbir yüz algılanmazsa özne moduna (dikkat stratejisi) geri döner. ### Kırpma Modu {#trim-mode} Görüntüden düzgün kenarlıkları/arka planı kaldırır. İsteğe bağlı olarak sonucu belirtilen bir arka plan rengi ve hedef boyutla bir kareye dolgu ile tamamlar. ## Notlar {#notes} * Bu araç `executionHint: "long"` ile `createToolRoute` fabrikasını kullanır, bu nedenle SSE ilerlemesiyle 202 döner. * Yüz modu `face-detection` model paketini gerektirir (200-300 MB). * Özne ve kırpma modları herhangi bir AI model paketi olmadan çalışır. * `facePreset` değeri, kırpmanın algılanan yüzleri ne kadar sıkı çerçevelediğini belirler: `closeup` en sıkı, `half-body` en geniş olanıdır. * Genişlik/yükseklik belirtilmezse varsayılan olarak 1080x1080 kullanılır. --- --- url: https://docs.snapotter.com/pl/guide/upgrading.md --- # Aktualizacja z 1.x do 2.0 {#upgrading-from-1-x-to-2-0} SnapOtter 1.x przechowywał wszystko w pojedynczym pliku SQLite i działał jako jeden kontener. SnapOtter 2.0 używa PostgreSQL i Redis. Ten przewodnik prowadzi przez przeniesienie instalacji 1.x do 2.0 bez utraty danych. W skrócie: użyj ponownie istniejącego woluminu `/data`, a 2.0 automatycznie zaimportuje Twoją bazę danych 1.x przy pierwszym uruchomieniu. Twoi użytkownicy, zapisane pliki, ustawienia, klucze API i potoki zostaną przeniesione. Stara baza danych nigdy nie jest modyfikowana, więc zawsze możesz cofnąć zmiany. ::: tip Uwaga dla naszych użytkowników 1.x Wielu z Was zaufało SnapOtter od pierwszego dnia, a Wasze opinie ukształtowały to wydanie. 2.0 zmienia wiele pod maską, a ten przewodnik istnieje po to, by przenosiny nie kosztowały Was niczego, na czym Wam zależy. Wasze konta, pliki, ustawienia, klucze API i potoki są przenoszone, a Wasza stara baza danych nigdy nie jest ruszana. Dziękujemy, że aktualizujecie razem z nami. ::: ## Zanim zaczniesz: wykonaj kopię zapasową całego woluminu `/data` {#before-you-start-back-up-the-whole-data-volume} Zrób to najpierw, za każdym razem. Wykonaj kopię zapasową **całego** woluminu `/data`, a nie tylko pliku `snapotter.db`. Oto dlaczego to ma znaczenie. 1.x uruchamia SQLite w trybie WAL, więc zatrzymany kontener 1.x rutynowo pozostawia większość zatwierdzonych danych w `snapotter.db-wal`, obok niemal pustego `snapotter.db`. Skopiowanie tylko `snapotter.db` przechwytuje pustą bazę danych i po cichu traci wszystko. Wolumin przenosi razem `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm` oraz Twój katalog `files/`, i muszą one wędrować jako komplet. ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## Najpierw zaktualizuj do 1.17.2 {#upgrade-to-1-17-2-first} Zaktualizuj swoją instalację 1.x do najnowszego wydania 1.x (1.17.2), zanim przejdziesz do 2.0. Dzięki temu 1.x uruchomi własne końcowe migracje schematu, tak że 2.0 importuje ze znanego, kompletnego schematu. Aktualizacja ze starszej wersji 1.x bezpośrednio do 2.0 nie jest obsługiwana. ## Sprawdź nazwę swojego woluminu {#check-your-volume-name} Importer widzi Twoje dane tylko wtedy, gdy stos 2.0 montuje ten sam wolumin, którego używała Twoja instalacja 1.x. Nazwy woluminów Docker rozróżniają wielkość liter, a starsze fragmenty README używały małych liter `snapotter-data`, podczas gdy pliki Compose używają `SnapOtter-data`. Potwierdź, którą masz: ```bash docker volume ls | grep -i snapotter ``` Użyj dokładnie tej nazwy w swojej konfiguracji 2.0. ## Ścieżka A: pojedynczy kontener (najszybsza) {#path-a-single-container-quickest} Jeśli uruchamiasz SnapOtter jednym `docker run`, rób to nadal. 2.0 uruchamia wbudowany PostgreSQL i Redis wewnątrz kontenera, gdy nie ustawisz `DATABASE_URL` ani `REDIS_URL`, oraz automatycznie wykrywa i importuje `/data/snapotter.db` przy pierwszym uruchomieniu. ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` Obserwuj logi w poszukiwaniu wiersza w rodzaju: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` To wszystko. Zaloguj się przy użyciu swoich dotychczasowych danych uwierzytelniających. ## Ścieżka B: Compose (zalecana dla produkcji) {#path-b-compose-recommended-for-production} Stos Compose w 2.0 uruchamia trzy usługi (aplikacja, Postgres, Redis). Użyj ponownie woluminu `/data` z 1.x dla usługi aplikacji. Aplikacja automatycznie wykrywa `/data/snapotter.db` i importuje go do Postgres przy pierwszym uruchomieniu. ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` Jeśli wolisz jawnie wskazać starą bazę danych, ustaw `SQLITE_MIGRATE_PATH=/data/snapotter.db`. Jawna ścieżka zawsze ma pierwszeństwo przed automatycznym wykrywaniem. ## Najpierw podejrzyj import (opcjonalnie) {#preview-the-import-first-optional} Aby zobaczyć dokładnie, co zostałoby zaimportowane, bez zapisywania czegokolwiek, uruchom próbny przebieg wobec pliku bazy danych: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` Wypisuje liczbę wierszy na tabelę, ile plików biblioteki zapisanych plików znaleziono na dysku oraz wszelkie statusy zadań, które znormalizuje. Nie potrzebuje działającego Postgres. ## Co jest przenoszone, a co nie {#what-carries-over-and-what-does-not} Przenoszone: * Użytkownicy i możliwość logowania. Skróty haseł pozostają niezmienione, więc ta sama nazwa użytkownika i hasło działają. * Zespoły, ustawienia (w tym tożsamość Twojej instancji), role, klucze API (nadal działają) i zapisane potoki. * Rekordy historii zadań. * Twoja biblioteka zapisanych plików, zarówno rekordy, jak i faktyczne pliki, ponieważ `/data/files` jest zachowywany na woluminie. Nieprzenoszone: * Sesje logowania. Wszyscy logują się raz po aktualizacji. Dane uwierzytelniające pozostają niezmienione, więc to pojedyncze ponowne logowanie, nic więcej. * Pliki wejściowe i wyjściowe starych zadań przetwarzania. Znajdowały się one w tymczasowej przestrzeni roboczej i zniknęły z założenia. Rekordy historii zadań pozostają. * Flagi zgody na analitykę per użytkownik z 1.x, które nie mają odpowiednika w 2.0 (analityka w 2.0 to ustawienie na poziomie instancji). ## Wyłączanie importu {#turning-the-import-off} Jeśli celowo chcesz świeżą bazę danych, mimo że na woluminie obecny jest `snapotter.db`, ustaw `SQLITE_MIGRATE_PATH=off`. ## Jeśli masz już dane w instancji 2.0 {#if-you-already-have-data-in-the-2-0-instance} Importer uruchamia się tylko do pustej bazy danych. Jeśli uruchomiłeś 2.0 od zera (tworząc dane), a później zamontowałeś stary `snapotter.db`, 2.0 go wykryje, ale nie zaimportuje, ponieważ scalanie dwóch zestawów danych może kolidować na identyfikatorach. Zobaczysz ostrzeżenie w logach. Aby zaimportować dane 1.x, potrzebujesz pustej instancji: * Jeśli instancja 2.0 zawiera tylko domyślnego administratora (tak naprawdę jej nie używałeś), zatrzymaj stos, usuń wolumin Postgres (`SnapOtter-pgdata`) i uruchom ponownie z obecnym starym `/data`. Zaimportuje się czysto. To wymazuje tylko jednorazowe dane Postgres, a nie Twoją bazę danych 1.x. * Jeśli instancja 2.0 zawiera prawdziwe dane, które chcesz zachować, dwóch zestawów danych nie da się automatycznie scalić. Wyeksportuj to, czego potrzebujesz, i zaimportuj dane 1.x do osobnego, świeżego wdrożenia. ## Cofanie zmian {#rolling-back} Aktualizacja nigdy nie modyfikuje ani nie usuwa Twojego `snapotter.db` z 1.x. Jeśli musisz wrócić do 1.x, wdróż ponownie obraz 1.x wobec tego samego woluminu. Wszystko, co utworzyłeś w 2.0 po aktualizacji, znajduje się w Postgres i nie będzie w bazie danych 1.x, więc cofnij zmiany bezzwłocznie, jeśli masz to zrobić. --- --- url: https://docs.snapotter.com/pt-BR/tools/audio/pitch-shift.md description: Aumente ou reduza o tom do áudio em semitons sem alterar a velocidade. --- # Alteração de Tom {#pitch-shift} Aumente ou reduza o tom de um arquivo de áudio em uma quantidade de semitons sem alterar sua velocidade de reprodução. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/audio/pitch-shift` Aceita dados de formulário multipart com um arquivo de áudio e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | semitones | integer | Não | `3` | Semitons a deslocar (-12 a 12). Deve ser diferente de zero. | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/pitch-shift \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"semitones": -5}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notas {#notes} * Valores positivos elevam o tom; valores negativos o reduzem. * Um deslocamento de 12 semitons equivale a uma oitava acima; -12 equivale a uma oitava abaixo. * A duração da reprodução permanece a mesma, independentemente da quantidade de deslocamento. * A saída normalmente mantém o contêiner de entrada. Entrada AAC é gravada como M4A, e entradas apenas de decodificação não suportadas recorrem a MP3. --- --- url: https://docs.snapotter.com/pt-BR/guide/low-resource.md --- # Ambientes com Poucos Recursos {#low-resource-setups} O SnapOtter roda bem em hardware modesto: um Raspberry Pi 4 ou 5, um notebook antigo ou um VPS de 2 GB. Esta página é o guia prático para essas máquinas: o que esperar, uma configuração pronta para copiar e colar com limites sensatos e quais features pular. Os dados completos de benchmark por trás desses números estão em [Requisitos de Hardware](/pt-BR/guide/deployment#hardware-requirements). Antes de tudo, duas restrições rígidas: * **Apenas 64 bits.** A imagem é construída para `linux/amd64` e `linux/arm64`. ARM de 32 bits (`armv7`/`armhf`) não é suportado, então os Pis de primeira geração e a família Pi Zero ficam de fora. * **Piso de memória de 2 GB.** Com 512 MB a stack nem inicia, e 1 GB falha em lotes com vários arquivos. 2 GB com 2 núcleos é a menor configuração que funciona com folga. ## O que roda bem em hardware modesto {#what-runs-well} Toda ferramenta sem IA funciona em uma máquina de 2 GB / 2 núcleos: as seções de Imagem e Arquivos inteiras, as ferramentas de PDF e as operações de vídeo e áudio por stream-copy (cortar, silenciar, remux de contêiner). A maioria termina em menos de um segundo. Duas cargas de trabalho são as exceções: * **Recodificação de vídeo** (converter entre codecs) é limitada pela CPU. Um clipe 1080p que leva ~40 s em uma CPU de desktop rápida pode levar vários minutos em uma CPU da classe do Pi. As operações de stream-copy continuam instantâneas. * **Ferramentas de IA** precisam de RAM (4 GB recomendados) e disco (os bundles maiores têm 4-5 GB cada), e as pesadas (upscale, restauração de fotos, remoção de fundo) não são práticas em CPUs da classe do Pi. IA leve, como detecção de rosto e OCR, é utilizável se você tiver memória para isso. Nenhuma das duas é instalada ou fica rodando a menos que você a use: sem bundles de IA instalados, o aplicativo fica ocioso em torno de 360 MB, e os bundles de IA só são baixados quando um admin os habilita. ## Passo a passo para Raspberry Pi / notebook antigo {#walkthrough} Esta é a instalação padrão com Compose de [Primeiros Passos](/pt-BR/guide/getting-started), mais limites de recursos e tetos conservadores. Ela pressupõe um sistema operacional de 64 bits (em um Pi: Raspberry Pi OS 64-bit ou Ubuntu Server arm64). ```yaml services: snapotter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - ./snapotter-data:/data environment: - DATABASE_URL=postgres://snapotter:snapotter@db:5432/snapotter - REDIS_URL=redis://redis:6379 # Small-box profile: see the table below for what each cap does. - CONCURRENT_JOBS=1 - MAX_WORKER_THREADS=2 - MAX_BATCH_SIZE=5 - MAX_UPLOAD_SIZE_MB=100 - MAX_MEGAPIXELS=50 - MAX_VIDEO_DURATION_S=300 deploy: resources: limits: cpus: "2" memory: 2G depends_on: - db - redis restart: unless-stopped db: image: postgres:17-alpine environment: - POSTGRES_USER=snapotter - POSTGRES_PASSWORD=snapotter # Altere isso para implantações não locais - POSTGRES_DB=snapotter volumes: - ./postgres-data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:8-alpine command: redis-server --maxmemory 256mb --maxmemory-policy noeviction restart: unless-stopped ``` Observações para máquinas da classe do Pi: * **Prefira um SSD USB a um cartão SD** para o volume de dados e o Postgres. As áreas de trabalho dos jobs fazem IO de disco de verdade, e cartões SD são lentos e se desgastam rápido. * **O contêiner único tudo-em-um também funciona aqui** (Postgres e Redis embutidos quando `DATABASE_URL`/`REDIS_URL` não estão definidos), e em um host com pouca memória você deve reduzir o teto do Redis embutido com `REDIS_MAXMEMORY` (veja [Configuração](/pt-BR/guide/configuration)). O Compose dá um controle mais fino por serviço, e é por isso que este passo a passo o utiliza. * **Adicione swap em dispositivos de 2 GB.** Isso evita que um pico ocasional (um PDF grande, um lote que você esqueceu de limitar) termine em um kill por falta de memória. zram é a opção amigável ao cartão SD. * A imagem arm64 é apenas CPU; não há CUDA em placas ARM. ## Os ajustes disponíveis {#tuning-knobs} Todos os limites são variáveis de ambiente, documentadas por completo em [Configuração](/pt-BR/guide/configuration). `0` significa ilimitado ou automático. Os que importam em hardware modesto: | Variável | Sugestão para máquinas pequenas | O que protege | |---|---|---| | `CONCURRENT_JOBS` | `1` | Quantos jobs rodam em paralelo. A detecção automática usa o número de núcleos de CPU menos um, o que funciona bem em máquinas grandes e é agressivo demais em uma máquina de 2 núcleos sob pressão de memória. | | `MAX_WORKER_THREADS` | `2` | Pool de threads de processamento de imagem. | | `MAX_BATCH_SIZE` | `5` | É nos lotes que máquinas de 1-2 GB ficam sem memória primeiro. | | `MAX_UPLOAD_SIZE_MB` | `100` | Impede que um único arquivo enorme ocupe toda a área de trabalho. | | `MAX_MEGAPIXELS` | `50` | Decodificar uma imagem de 100+ MP custa RAM independentemente do tamanho do arquivo. | | `MAX_VIDEO_DURATION_S` | `300` | Transcodificações longas monopolizam uma CPU pequena por minutos ou horas. | | `PROCESSING_TIMEOUT_S` | `600` | Teto rígido para que um job descontrolado acabe liberando a máquina. | Esses limites se aplicam ao que o servidor aceita, então defina-os de acordo com o que você realmente usa, e não com o menor valor possível. Se você nunca mexe com vídeo, um limite em `MAX_VIDEO_DURATION_S` não custa nada; se você digitaliza documentos todos os dias, não limite `MAX_PDF_PAGES`. ## O que pular {#what-to-skip} * **Bundles de IA pesados.** Upscale, restauração de fotos e remoção de fundo pedem uma GPU ou uma CPU rápida com muitos núcleos, e cada bundle custa 4-5 GB de disco. Em uma máquina pequena, simplesmente não os instale; ferramentas cujo bundle está ausente mostram um aviso de instalação em vez de rodar. * **Recodificação de vídeo como carga de trabalho rotineira.** Transcodificações ocasionais são aceitáveis (só são lentas); uma fila constante de transcodificação pede núcleos de CPU, não um Pi. * **Ferramentas não usadas em geral.** Um admin pode desligar ferramentas individuais em Configurações, o que as remove da interface e deixa de registrar suas rotas de API. Isso por si só não economiza memória, mas evita que uma instância pequena compartilhada seja usada justamente para a carga de trabalho que o hardware não aguenta. Se mais tarde você mover a instância para um hardware maior, remova os limites (defina-os de volta para `0`) e o mesmo volume de dados vai junto. --- --- url: https://docs.snapotter.com/fr/tools/image/image-enhancement.md description: >- Amélioration automatique en un clic qui analyse une image et corrige l'exposition, le contraste, la balance des blancs, la saturation et la netteté. --- # Amélioration d'image {#image-enhancement} Amélioration automatique en un clic avec analyse intelligente. Analyse l'image et applique des corrections d'exposition, de contraste, de balance des blancs, de saturation, de netteté et de débruitage. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **Traitement :** Synchrone (utilise la factory `createToolRoute`, renvoie le résultat directement) **Ensemble de modèles :** Aucun requis pour l'amélioration de base. L'ensemble `upscale-enhance` (5 à 6 Go) n'est utilisé que lorsque `deepEnhance` est activé (pour la suppression de bruit par IA via SCUNet). ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | file | file | Oui | - | Fichier image (multipart) | | mode | string | Non | `"auto"` | Mode d'amélioration : `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | Non | `50` | Intensité globale de l'amélioration (0-100) | | corrections | object | Non | toutes `true` | Corrections sélectives à appliquer (voir ci-dessous) | | deepEnhance | boolean | Non | `false` | Activer la suppression de bruit par IA (nécessite l'outil `noise-removal` installé) | ### Objet Corrections {#corrections-object} | Champ | Type | Par défaut | Description | |-------|------|---------|-------------| | exposure | boolean | `true` | Corriger automatiquement l'exposition | | contrast | boolean | `true` | Corriger automatiquement le contraste | | whiteBalance | boolean | `true` | Corriger automatiquement la balance des blancs | | saturation | boolean | `true` | Corriger automatiquement la saturation | | sharpness | boolean | `true` | Renforcer automatiquement la netteté | | denoise | boolean | `true` | Débruitage léger | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Réponse (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Point de terminaison Analyze {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Analyse une image et renvoie des recommandations de correction sans les appliquer. ### Paramètres {#parameters-1} | Paramètre | Type | Requis | Description | |-----------|------|----------|-------------| | file | file | Oui | Fichier image (multipart) | ### Exemple de requête {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Réponse (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Notes {#notes} * Cet outil utilise la factory synchrone `createToolRoute`, il renvoie donc une réponse standard (pas de 202 asynchrone). * Le paramètre `mode` ajuste la pondération des corrections (par exemple, le mode portrait est plus doux sur les tons chair, le mode paysage renforce la saturation). * Lorsque `deepEnhance` est activé et que l'outil `noise-removal` (SCUNet) est installé, une passe de débruitage par IA supplémentaire est appliquée après les corrections standard. * Le point de terminaison Analyze est utile pour prévisualiser les corrections qui seraient appliquées avant de valider. * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR via un décodage automatique. --- --- url: https://docs.snapotter.com/fr/tools/image/enhance-faces.md description: >- Restaurez et affinez les visages flous ou de faible qualité dans les images avec les modèles d'IA GFPGAN et CodeFormer. --- # Amélioration des visages {#face-enhancement} Restaurez et améliorez les visages dans les images à l'aide de modèles d'IA (GFPGAN/CodeFormer). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Traitement :** asynchrone (renvoie 202, interrogez `/api/v1/jobs/{jobId}/progress` pour le statut via SSE) **Bundles de modèles :** `upscale-enhance` (5-6 Go) et `face-detection` (200-300 Mo) ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | file | file | Oui | - | Fichier image (multipart) | | model | string | Non | `"auto"` | Modèle à utiliser : `auto`, `gfpgan`, `codeformer` | | strength | number | Non | `0.8` | Force de l'amélioration (0-1). Les valeurs plus élevées produisent une amélioration plus forte | | onlyCenterFace | boolean | Non | `false` | N'améliorer que le visage le plus central/proéminent | | sensitivity | number | Non | `0.5` | Sensibilité de la détection des visages (0-1) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Notes {#notes} * Nécessite à la fois le bundle de modèle `upscale-enhance` (5-6 Go) et le bundle de modèle `face-detection` (200-300 Mo). * GFPGAN produit une amélioration plus agressive ; CodeFormer préserve mieux l'identité. `auto` sélectionne le meilleur modèle pour l'entrée. * La sortie est toujours au format PNG pour une qualité maximale. * Un aperçu WebP est généré en parallèle de la sortie pleine résolution pour un affichage plus rapide côté frontal. * Le paramètre `strength` mélange le visage amélioré avec l'original. Utilisez des valeurs plus basses (0.3-0.5) pour des améliorations subtiles, des valeurs plus élevées (0.7-1.0) pour une restauration plus forte. * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR par décodage automatique. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/upscale.md description: >- Amplia imagens de 2x a 4x com super-resolução por IA Real-ESRGAN, preservando detalhes finos. --- # Ampliação de Imagem (Upscaling) {#image-upscaling} Aprimoramento por super-resolução com IA usando Real-ESRGAN. Amplia imagens de 2x a 4x preservando os detalhes. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/upscale` **Processamento:** Assíncrono (retorna 202, consulte `/api/v1/jobs/{jobId}/progress` para obter o status via SSE) **Pacote de modelo:** `upscale-enhance` (5-6 GB) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | scale | number | Não | `2` | Fator de ampliação (por exemplo, 2, 3, 4) | | model | string | Não | `"auto"` | Modelo a usar (por exemplo, `auto`, nomes específicos de modelos) | | faceEnhance | boolean | Não | `false` | Aplica aprimoramento de rosto durante a ampliação | | denoise | number | Não | `0` | Intensidade da redução de ruído (0 = desativado) | | format | string | Não | `"auto"` | Formato de saída: `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | Não | `95` | Qualidade de saída (1-100) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Resposta {#response} ### Resposta Inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progresso (SSE em `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Resultado Final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Notas {#notes} * Requer que o pacote de modelo `upscale-enhance` esteja instalado (5-6 GB). * Usa Real-ESRGAN quando disponível; recai para interpolação Lanczos se o modelo de IA estiver indisponível. * A opção `faceEnhance` aplica a restauração de rosto GFPGAN durante a ampliação para melhor qualidade dos rostos. * Para formatos de saída que não podem ser pré-visualizados no navegador (HEIC, JXL, TIFF), uma pré-visualização WebP é gerada junto com a saída principal. * Suporta os formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR via decodificação automática. --- --- url: https://docs.snapotter.com/es/tools/image/upscale.md description: >- Amplía imágenes de 2x a 4x con la superresolución por IA Real-ESRGAN conservando el detalle fino. --- # Ampliación de imágenes {#image-upscaling} Mejora por superresolución con IA usando Real-ESRGAN. Amplía imágenes de 2x a 4x conservando el detalle. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/upscale` **Procesamiento:** Asíncrono (devuelve 202, sondea `/api/v1/jobs/{jobId}/progress` para conocer el estado mediante SSE) **Paquete de modelos:** `upscale-enhance` (5-6 GB) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | scale | number | No | `2` | Factor de ampliación (por ejemplo, 2, 3, 4) | | model | string | No | `"auto"` | Modelo a usar (por ejemplo, `auto`, nombres de modelos específicos) | | faceEnhance | boolean | No | `false` | Aplica mejora de caras durante la ampliación | | denoise | number | No | `0` | Intensidad de reducción de ruido (0 = desactivado) | | format | string | No | `"auto"` | Formato de salida: `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | No | `95` | Calidad de salida (1-100) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Respuesta {#response} ### Respuesta inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progreso (SSE en `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Resultado final (mediante SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Notas {#notes} * Requiere que el paquete de modelos `upscale-enhance` esté instalado (5-6 GB). * Usa Real-ESRGAN cuando está disponible; recurre a la interpolación Lanczos si el modelo de IA no está disponible. * La opción `faceEnhance` aplica la restauración de caras GFPGAN durante la ampliación para una mejor calidad de las caras. * Para los formatos de salida no previsualizables en el navegador (HEIC, JXL, TIFF), se genera una vista previa WebP junto con la salida principal. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/es/tools/image/ai-canvas-expand.md description: >- Amplía el lienzo de una imagen con outpainting por IA, extendiéndola en cualquier dirección y rellenando las nuevas áreas para que coincidan con la original. --- # Ampliar lienzo con IA {#ai-canvas-expand} Amplía el lienzo de una imagen con relleno impulsado por IA (outpainting). Extiende la imagen en cualquier dirección y rellena las nuevas áreas con contenido generado por IA que coincide con la imagen existente. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Procesamiento:** Asíncrono (devuelve 202, consulta `/api/v1/jobs/{jobId}/progress` para conocer el estado mediante SSE) **Paquete de modelos:** `object-eraser-colorize` (1-2 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | extendTop | integer | No | `0` | Píxeles a extender por la parte superior | | extendRight | integer | No | `0` | Píxeles a extender por la derecha | | extendBottom | integer | No | `0` | Píxeles a extender por la parte inferior | | extendLeft | integer | No | `0` | Píxeles a extender por la izquierda | | tier | string | No | `"balanced"` | Nivel de calidad: `fast`, `balanced`, `high` | | format | string | No | `"auto"` | Formato de salida: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | Calidad de salida (1-100) | Al menos una dirección de extensión debe ser mayor que 0. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Notes {#notes} * Requiere que esté instalado el paquete de modelos `object-eraser-colorize` (1-2 GB). * Usa outpainting basado en LaMa para generar contenido en las regiones ampliadas. * El parámetro `tier` intercambia velocidad por calidad: `fast` produce resultados rápidamente con posibles artefactos, `high` tarda más pero produce rellenos más suaves y coherentes. * Los valores de extensión están en píxeles. Las dimensiones finales de la imagen serán: ancho original + extendLeft + extendRight por alto original + extendTop + extendBottom. * Para formatos de salida que no se pueden previsualizar en el navegador (HEIC, JXL, TIFF), se genera una previsualización WebP junto a la salida principal. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/sv/tools/image/resize.md description: Ändra storlek på bilder efter pixlar, procent eller med anpassningslägen. --- # Ändra bildstorlek {#resize} Ändra storlek på bilder genom att ange exakta pixeldimensioner, en procentuell skalfaktor eller ett anpassningsläge som styr hur bilden anpassas till måldimensionerna. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/resize` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | width | integer | Nej | - | Målbredd i pixlar (max 16383) | | height | integer | Nej | - | Målhöjd i pixlar (max 16383) | | fit | string | Nej | `"contain"` | Hur bilden anpassas till dimensionerna: `contain`, `cover`, `fill`, `inside`, `outside` | | withoutEnlargement | boolean | Nej | `false` | Förhindra uppskalning om bilden är mindre än målet | | percentage | number | Nej | - | Skala med procent (t.ex. 50 för halv storlek) | Minst en av `width`, `height` eller `percentage` måste anges. ### Anpassningslägen {#fit-modes} * **contain** - Ändra storlek för att rymmas inom dimensionerna, med bevarat bildförhållande (kan lämna tomt utrymme) * **cover** - Ändra storlek för att täcka dimensionerna, med bevarat bildförhållande (kan beskära) * **fill** - Sträck ut för att exakt matcha dimensionerna (ignorerar bildförhållande) * **inside** - Som `contain`, men skalar bara ned, aldrig upp * **outside** - Som `cover`, men skalar bara ned, aldrig upp ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"width": 800, "height": 600, "fit": "contain"}' ``` Ändra storlek med procent: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"percentage": 50}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 980000 } ``` ## Anteckningar {#notes} * Maximal dimension är 16383 pixlar på vardera axeln (Sharp/libvips-gräns). * Utdataformatet matchar indataformatet. HEIC-, RAW-, PSD- och SVG-indata avkodas automatiskt före bearbetning. * EXIF-orientering appliceras automatiskt före storleksändring. * Flaggan `withoutEnlargement` är användbar för batchbearbetning där vissa bilder redan kan vara mindre än målet. --- --- url: https://docs.snapotter.com/sv/tools/video/change-fps.md description: Ändra bildhastigheten för en video. --- # Ändra FPS {#change-fps} Ändra bildhastigheten för en video till ett målvärde mellan 1 och 120 fps. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/change-fps` Tar emot multipart-formulärdata med en videofil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | fps | number | Nej | `30` | Målbildhastighet (1-120) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Anteckningar {#notes} * Att sänka bildhastigheten släpper bildrutor och minskar filstorleken. Att öka den duplicerar bildrutor för att fylla luckan men tillför ingen verklig rörelsedetalj. * Vanliga målvärden: 24 (bio), 30 (webb/broadcast), 60 (jämn uppspelning). * Ljudspåret bevaras med sin ursprungliga samplingsfrekvens. --- --- url: https://docs.snapotter.com/sv/tools/video/resize-video.md description: Skala en video till en ny upplösning eller förinställd storlek. --- # Ändra storlek på video {#resize-video} Skala en video till en ny upplösning med anpassade pixeldimensioner eller en standardförinställning. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/resize-video` Tar emot multipart-formulärdata med en videofil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | width | integer | Nej | - | Målbredd i pixlar (16-7680) | | height | integer | Nej | - | Målhöjd i pixlar (16-4320) | | preset | string | Nej | `"custom"` | Upplösningsförinställning: `custom`, `2160p`, `1440p`, `1080p`, `720p`, `480p`, `360p` | När `preset` är `"custom"` måste minst en av `width` eller `height` anges. Den andra dimensionen skalas proportionellt. ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/resize-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"preset": "720p"}' ``` Ändra storlek till anpassade dimensioner: ```bash curl -X POST http://localhost:1349/api/v1/tools/video/resize-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 1280, "height": 720}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 25000000, "processedSize": 8500000 } ``` ## Anteckningar {#notes} * Förinställningsvärden mappar till standardhöjder (t.ex. `720p` = 1280x720, `1080p` = 1920x1080). Bredden skalas proportionellt från källans bildförhållande. * Dimensioner avrundas till jämna tal enligt kraven hos de flesta videocodecs. * Maximalt stödd upplösning är 7680x4320 (8K UHD). --- --- url: https://docs.snapotter.com/sv/changelog.md description: >- Versionsinformation och versionshistorik för SnapOtter. Se vad som är nytt, förbättrat och åtgärdat i varje version. --- # Ändringslogg {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 förvandlar bildverktyget till en komplett svit för filhantering: 200+ verktyg fördelade på fem modaliteter (Image, Video, Audio, PDF och Files), ombyggt på Postgres 17 och en Redis-baserad jobbkö, med en `docker run` som körs med ett enda kommando. Det här är en större version; läs Brytande ändringar innan du uppgraderar från 1.x. ### Nya funktioner {#new-features} * **Fyra nya verktygsmodaliteter**: Video, Audio, PDF och Files ansluter till Image och tar katalogen till 200+ verktyg. * **Beständiga bakgrundsjobb**: En Redis-baserad kö (BullMQ) kör varje verktyg som ett spårat jobb med live SSE-förlopp. * **Allt-i-ett-läge med en enda container**: En `docker run` startar en komplett instans med inbäddad Postgres och Redis. * **AI-paket på begäran**: Bakgrundsborttagning, OCR, transkribering, uppskalning, ansiktsigenkänning och -förbättring, objektradering, färgläggning och fotorestaurering installeras från gränssnittet. GPU-acceleration upptäcks per ramverk. * **Signera PDF**: Rita, skriv eller ladda upp en signatur och placera den på en PDF i webbläsaren. * **Automate**: En visuell pipelinebyggare som kedjar samman verktyg, med nio förbyggda mallar. * **83 konverteringsförinställningar med ett klick**: Dedikerade konverterare för JPG-till-PNG, MP4-till-GIF och liknande med luddig sökning. * **Lagerbaserad bildredigerare**: En Konva-driven redigerare på `/editor` med penslar, former, justeringar, filter och kurvor. * **Files-bibliotek**: Spara valfritt resultat och återanvänd det som indata till ett annat verktyg. * Fästa verktyg, zoom och panorering i arbetsytan, 21 språk och funktioner för företag (OIDC/SSO, SAML, SCIM, S3-lagring, behörigheter per verktyg, revisionsexport, distribuerad spårning). ### Förbättringar {#improvements} * Avbryt en pågående process. (#137) * RAW-avkodning i full upplösning via LibRaw, inklusive DNG. (#289) * Distributioner som inte körs som root och med främmande UID (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Korrekt identifiering av AI-installationer och ett härdat installationsflöde. (#214, #352) * Härdad integritet: ingen automatisk tredjepartstrafik utåt, plus ett valfritt strikt offline-läge. * Alltid tillgänglig feedbackknapp, även med analys avstängd. ### Felrättningar {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` inaktiverar hastighetsbegränsning för verktygsrutter igen. (#271) * Reparerade sökvägar för AI-virtualenv inuti Docker-avbildningen. (#390) * Kompatibilitet med sharp 0.35.2+. (#362) * Layoutfixar i bildredigeraren: linjaler, fyllnadsbeteende, sidopanel och storleksändring av arbetsytan. (#258, #259) * Slutförde den italienska översättningen. (#231, #206, #425) * Ljudnormalisering och loudnorm bevarar källans samplingsfrekvens. * SSRF-härdning: numerisk IPv6 CIDR-matchning och en breddad förhandsgranskning av URL:er. (#287) * Genererade PDF:er stämplas med SnapOtter som Producer. * mediapipe installeras på Python 3.13 och Debian 13. ### Brytande ändringar {#breaking-changes} 2.0 ersätter den inbäddade SQLite-databasen med Postgres 17 och lägger till Redis 8 för jobbkön. Dina 1.x-data migreras automatiskt vid första start, men containerstacken har ändrats, så säkerhetskopiera hela din `/data`-volym först (1.x kör SQLite i WAL-läge, så de committade data ligger vanligtvis i `snapotter.db-wal`). Välj sedan avbildningen med en enda container (inbäddad Postgres och Redis, endast root) eller Compose-stacken (app plus Postgres 17 och Redis 8). Se [migreringsguiden](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) och [uppgraderingsguiden](/sv/guide/upgrading). ### Uppgradering {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Eller med Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Fullständig diff på GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Nytt verktyg för HTML till bild, WCAG 2.2 AA-tillgänglighet, säkerhetshärdning från penetrationstestning och 5 kritiska Docker-fixar. ### Nya funktioner {#new-features-1} * **HTML till bild**: Fånga skärmbilder av URL:er eller rå HTML som PNG/JPEG/WebP. Helsidesfångster, anpassade visningsytor, mörkt läge. * **Docker \_FILE-hemlighetskonvention**: Montera känsliga miljövariabler som filer i stället för klartext. (#205) * **Företagslicensiering och S3-lagring**: Valfri kommersiell licensnyckel och S3-kompatibel objektlagring. * **Förbättringar av formredigeraren**: Genomskinlighet för fyllnad/kontur, RGBA-färgväljare, streckade linjestilar. * **Förbyggda release-arkiv**: Ladda ner tarballs från GitHub Releases för installationer utan Docker (Proxmox, bare metal, LXC). (#202) ### Förbättringar {#improvements-1} * **WCAG 2.2 AA-tillgänglighet**: Hoppa över navigering, fokusfällor, aria-live-regioner, stöd för reducerad rörelse, korrekta kontrastförhållanden. (#209) * **Mobilanpassning**: Responsiva inställningar, automatisk SSE-återanslutning vid byte av mobilflik. (#203, #204) * **Kvalitet på bakgrundsborttagning**: Kantutjämning, färgdekontaminering, val av utdataformat. * **Italiensk översättning**: ~145 nya strängar av @albanobattistella. (#206) * **API-dokumentation per verktyg**: 53 dokumentsidor med parametrar, exempel och svarsformat. * **Nedladdning av AI-modeller**: Återförsökslogik med exponentiell backoff för HuggingFace. (#201) ### Felrättningar {#bug-fixes-1} * Nya Docker-containrar var helt oanvändbara (hastighetsbegränsningen blockerade alla förfrågningar). * AI-verktyg för ansiktsigenkänning (blur-faces, red-eye-removal, enhance-faces, passport-photo) misslyckades på alla plattformar. * HEIC-filer trasiga på ARM (symbolmatchningsfel i libheif). * AI-paketen upscale och restore-photo misslyckades att installeras på ARM. * OCR använde fel CUDA-version på GPU-containrar. * Kringgående av SSRF-skydd via hex-IPv4-mappade IPv6-adresser. (Tack: @tonghuaroot) * HEIC-avkodning från iPhone med hjälpbilder. (#183, #199) * Real-ESRGAN CUDA OOM på 8GB-GPU:er. (#200) * 6 Sentry-fel i produktion och 7 QA-buggar. (#208) ### Säkerhet {#security} * 10 fynd från penetrationstest åtgärdade (XFF-kringgående, krascher vid felformaterad JSON, obegränsade pipelines, XSS i revisionslogg, TRACE-metod med mera). (#207) * SSRF-kringgående med hex-IPv6 blockerat. (Tack: @tonghuaroot) * Dockerfile-basavbildningar fästa via digest. ### Uppgradering {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Eller med Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Fullständig diff på GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Live-demo, landningssidor per verktyg och en omgång putsande fixar. ### Nya funktioner {#new-features-2} * **Live-demo** - [demo.snapotter.com](https://demo.snapotter.com) låter folk prova SnapOtter utan att installera något. * **Verktygsindexsida** - Bläddra bland alla 50+ verktyg på `/tools` med sökning och kategorifilter. * **50+ SEO-landningssidor** - Varje verktyg har nu en dedikerad landningssida med vanliga frågor, användningsfall och jämförelsetabeller. * **Bakgrundsförhandsgranskning** - Ett före-efter-reglage visar en rutig bakgrund bakom genomskinliga bilder. * **Generator för starka lösenord** - Knapp med ett klick i formuläret Lägg till medlemmar. ### Felrättningar {#bug-fixes-2} * Info-verktyget för HEIC/HEIF misslyckas inte längre (föravkodning tillagd). * Installation av AI-modellpaket visar bättre felmeddelanden och respekterar resursgränser. * Bibliotekets miniatyrbilder laddas korrekt (autentiseringshuvuden saknades). * Rullgardinsmenyer klipps inte längre i inställningstabellerna för People och Teams. * Procentandel för storleksjämförelse dold på verktyg som inte komprimerar. * Dubblerad länk till integritetspolicy borttagen. * Italiensk översättning tillagd för inställningar av AI-funktioner. * Omdöpta Lucide-ikoner uppdaterade (Wand2, Columns). ### Infrastruktur {#infrastructure} * OpenSSF Scorecard härdat från 4.3 till ~7.0. * CI-tester parallelliserade i 4 shards med förminskade fixturer. * 41 beroendeuppdateringar. ### Uppgradering {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Eller med Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Fullständig diff på GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Fem nya verktyg, en fullständig bildredigerare, SSO-inloggning, 20 språk. Borde nog ha varit tre separata versioner, men här är vi. ### Nya funktioner {#new-features-3} * **Bildredigerare** - Lager, penslar, former, justeringar, filter, kurvor, tangentbordsgenvägar. Körs i din webbläsare, bearbetar på din hårdvara. * **OIDC/SSO-autentisering** - Logga in med Google, GitHub, Okta eller valfri OpenID Connect-leverantör. Ställ in några få miljövariabler så använder ditt team sina befintliga konton. * **Meme-generator** - 100 inbyggda mallar med textrendering via opentype.js. Eller ladda upp din egen bild. * **Beautify** - Släpp in en skärmbild, få en polerad bild ut. Enhetsramar (macOS, Windows, webbläsare), skuggor, gradienter, förinställningar för sociala medier. * **Simulering av färgblindhet** - Förhandsgranska hur bilder ser ut med protanopi, deuteranopi, tritanopi och andra färgsynsavvikelser. * **PNG-genomskinlighetsfixare** - Upptäcker falskt genomskinliga PNG:er och åtgärdar dem med BiRefNet HR-matting. Valfri borttagning av vattenstämpel via LaMa-inpainting. * **AI-arbetsyteutökning** - Utöka bildgränser med AI-fyllning. Tre kvalitetsnivåer (snabb, balanserad, kvalitet) beroende på hur mycket GPU-tid du vill byta bort. * **20 språk** - Arabiska, kinesiska (förenklad/traditionell), tjeckiska, nederländska, franska, tyska, hindi, indonesiska, italienska, japanska, koreanska, polska, portugisiska, ryska, spanska, thailändska, turkiska, ukrainska, vietnamesiska. RTL fungerar för arabiska. * **URL-import** - Klistra in URL:er i släppzonen eller massimportera från en lista. Serversidig hämtning med SSRF-skydd. * **Flerfilsradering** - Rita raderingsmasker över flera bilder, bearbeta dem alla med ett klick. Penseldrag bevaras per bild. * **Pipeline-import/-export** - Spara verktygskedjor som JSON, dela dem med andra. * **17 nya kamera-RAW-format** via exiftool, plus QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ och APNG som indata. Nya utdatakodekar för BMP, ICO, JP2, QOI. Export till AVIF, TIFF, GIF, JXL och PSD återställd från en tidigare förlorad gren. ### Förbättringar {#improvements-2} * **Bildförbättring** - Ersatte den gamla pipelinen med CLAHE + normalise + gamma. En ny Deep Enhance-växel använder AI-modellen för mer aggressiva resultat. * **Restaurera foto** - Reptdetektering omskriven med 8-vinklad Otsu-filtrering. LaMa-inpainting körs nu i inbyggd upplösning. * **Exotiska format överallt** - OCR, bild-till-PDF, favicon-generator, komposition, hopfogning och vektorisering avkodar alla HEIC, RAW, PSD nu. * **Komprimera** - Toleransen för målstorlek strammades åt från 5% till 1%. Målstorlek är standardläget. Lade till stegknappar och enhetsväljare för KB/MB. * **Sentry-rensning** - 644 ej åtgärdbara händelser filtrerade. Verkliga fel hanteras nu korrekt. * **GPU-detektering** - Bättre diagnostik för containrar där CUDA finns men nvidia-smi inte gör det. * **Läge med autentisering avstängd** - En anonym användare seedas i databasen med admin-roll. API-nycklar, pipelines och användarfiler bryts inte längre av FK-begränsningar. * **2 705+ nya tester** över enhets-, integrations- och E2E-tester. ### Felrättningar {#bug-fixes-3} * Uppskalning på CPU får inte längre timeout på NAS-boxar och lågeffektshårdvara. * QR-kodslogotyp får inte längre förhandsgranskningen att försvinna permanent. * Beskärningsöverflöde åtgärdat för höga porträttbilder. * TIFF-alfafiler tvingar korrekt PNG-utdata i stället för att producera korruption. * HDR/EXR-avkodning konverterar till 8-bit före CLAHE, vilket åtgärdar avkodningsfel. * Indatabuffertar för ansiktslandmärken konverteras till PNG före Python-sidovagnen, vilket åtgärdar krascher. * Hitta dubbletter hanterar batchar med blandade format och nätverksfel. * Beautify-förhandsgranskning uppdateras i realtid. * Förloppsindikatorer för hopfogning och vektorisering. * SVGZ hanteras av SVG-till-raster. * Filnamn med icke-ASCII åtgärdade via procentkodat X-File-Results-huvud. ### Uppgradering {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Eller med Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Fullständig diff på GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Enhetlig Docker-avbildning med automatisk GPU-detektering. En avbildning hanterar både CPU- och GPU-arbetsbelastningar. Förenklad compose till en enda fil med loggrotation. Modellförnedladdningar inkluderar nu verifiering och ett röktest. *** ## v1.13.0 {#v1-13-0} Rollbaserad åtkomstkontroll (RBAC). 14 granulära behörigheter, tre inbyggda roller (admin, editor, user), stöd för anpassade roller. Behörighetskontroller på alla API-rutter. Frontend-flikar filtrerade efter användarbehörigheter. *** ## v1.12.0 {#v1-12-0} Verktyg för PDF till bild. Konvertera PDF-sidor till PNG, JPEG, WebP eller TIFF med anpassad DPI. Enhetlig Docker-avbildning med automatisk GPU-detektering. *** ## v1.11.0 {#v1-11-0} Autogenererad llms.txt via vitepress-plugin-llms för AI-vänlig dokumentation. *** ## v1.10.0 {#v1-10-0} Innehållsmedveten storleksändring (seam carving) med ansiktsskydd. Ändra storlek på bilder samtidigt som viktigt innehåll bevaras. *** ## v1.9.0 {#v1-9-0} Verktyg för hopfogning/kombination. Foga samman bilder sida vid sida, staplade vertikalt eller i ett anpassat rutnät. *** ## v1.8.0 {#v1-8-0} Verktyg för att redigera metadata. Visa och redigera EXIF-, IPTC- och XMP-metadata med ett granulärt gränssnitt för att ta bort/behålla. *** ## Äldre versioner {#older-releases} För den fullständiga ändringsloggen på commit-nivå inklusive patch-versioner, se [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/vi/tools/image/collage.md description: >- Ghép nhiều ảnh thành các bố cục ghép ảnh dạng lưới với hơn 25 mẫu, khoảng cách và bo góc điều chỉnh được, cùng thao tác di chuyển và phóng to theo từng ô. --- # Ảnh ghép và Lưới {#collage-grid} Ghép nhiều ảnh thành các bố cục ghép ảnh dạng lưới đẹp mắt với hơn 25 mẫu. Hỗ trợ bố cục từ 2 đến 9 ảnh với khoảng cách, bán kính bo góc, màu nền tùy chỉnh và điều khiển di chuyển/phóng to theo từng ô. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/collage` ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | templateId | string | Có | - | ID bố cục mẫu (ví dụ `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | Không | - | Mảng thiết lập theo từng ô với `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Có | - | Chỉ số của ảnh đặt vào ô này (bắt đầu từ 0) | | cells\[].panX | number | Không | 0 | Độ lệch di chuyển ngang (-100 đến 100) | | cells\[].panY | number | Không | 0 | Độ lệch di chuyển dọc (-100 đến 100) | | cells\[].zoom | number | Không | 1 | Mức phóng to (1 đến 10) | | cells\[].objectFit | string | Không | `"cover"` | Cách ảnh lấp đầy ô: `cover` hoặc `contain` | | gap | number | Không | 8 | Khoảng cách giữa các ô tính bằng pixel (0 đến 500) | | cornerRadius | number | Không | 0 | Bán kính bo góc cho mỗi ô tính bằng pixel (0 đến 500) | | backgroundColor | string | Không | `"#FFFFFF"` | Màu nền dạng hex hoặc `"transparent"` | | aspectRatio | string | Không | `"free"` | Tỷ lệ khung hình canvas: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | Không | `"png"` | Định dạng đầu ra: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Không | 90 | Chất lượng đầu ra (1 đến 100) | ## Các mẫu có sẵn {#available-templates} | ID mẫu | Số ảnh | Bố cục | |-------------|--------|--------| | `2-h-equal` | 2 | Hai cột bằng nhau | | `2-v-equal` | 2 | Hai hàng bằng nhau | | `2-h-left-large` | 2 | Trái 2/3, phải 1/3 | | `2-h-right-large` | 2 | Trái 1/3, phải 2/3 | | `3-left-large` | 3 | Lớn bên trái, hai ảnh xếp chồng bên phải | | `3-right-large` | 3 | Hai ảnh xếp chồng bên trái, lớn bên phải | | `3-top-large` | 3 | Lớn ở trên, hai cột ở dưới | | `3-h-equal` | 3 | Ba cột bằng nhau | | `3-v-equal` | 3 | Ba hàng bằng nhau | | `4-grid` | 4 | Lưới 2x2 | | `4-left-large` | 4 | Lớn bên trái, ba ảnh xếp chồng bên phải | | `4-top-large` | 4 | Lớn ở trên, ba cột ở dưới | | `4-bottom-large` | 4 | Ba cột ở trên, lớn ở dưới | | `5-top2-bottom3` | 5 | Hai ở trên, ba ở dưới | | `5-top3-bottom2` | 5 | Ba ở trên, hai ở dưới | | `5-left-large` | 5 | Lớn bên trái, bốn ảnh xếp chồng bên phải | | `5-center-large` | 5 | Lớn ở giữa, bốn góc | | `6-grid-2x3` | 6 | 2 cột x 3 hàng | | `6-grid-3x2` | 6 | 3 cột x 2 hàng | | `6-top-large` | 6 | Lớn ở trên, năm cột ở dưới | | `7-mosaic` | 7 | Bố cục khảm | | `8-mosaic` | 8 | Bố cục khảm | | `9-grid` | 9 | Lưới 3x3 | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Ghi chú {#notes} * Tải lên nhiều tệp ảnh trong yêu cầu multipart. Các ảnh được gán vào ô mẫu theo thứ tự tải lên. * Nếu tải lên nhiều ảnh hơn mức mẫu hỗ trợ, các ảnh dư sẽ bị bỏ qua. * Hỗ trợ định dạng đầu vào HEIC, RAW, PSD và SVG (được giải mã tự động). * Kích thước gốc của canvas là 2400px ở cạnh dài nhất, được co giãn theo tỷ lệ khung hình đã chọn. * Khi `aspectRatio` là `"free"`, canvas mặc định là 4:3 (2400x1800). * Giá trị `panX`/`panY` theo từng ô dịch chuyển khung cắt bên trong ô. Giá trị 100 dịch hoàn toàn về một cạnh, -100 về cạnh kia. * Màu nền `"transparent"` chỉ được giữ lại với định dạng đầu ra `png`, `webp` hoặc `avif`. --- --- url: https://docs.snapotter.com/vi/tools/image/lqip-placeholder.md description: Tạo một ảnh giữ chỗ chất lượng thấp cực nhỏ với data URI base64. --- # Ảnh giữ chỗ LQIP {#lqip-placeholder} Tạo một ảnh giữ chỗ chất lượng thấp cực nhỏ (LQIP) từ một ảnh nguồn. Trả về một tệp giữ chỗ nhỏ cùng với một data URI base64, thẻ HTML `` sẵn sàng dùng, và đoạn CSS `background-image` để nhúng ngay lập tức. ## Điểm cuối API {#api-endpoint} `POST /api/v1/tools/image/lqip-placeholder` Chấp nhận dữ liệu biểu mẫu multipart với một tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | width | integer | Không | `16` | Chiều rộng đích tính bằng pixel (4-64) | | blur | number | Không | `2` | Bán kính làm mờ cho chiến lược blur (0-20) | | strategy | string | Không | `"blur"` | Chiến lược giữ chỗ: `blur`, `pixelate`, hoặc `solid` | | format | string | Không | `"webp"` | Định dạng đầu ra: `webp`, `png`, hoặc `jpeg` | | quality | integer | Không | `50` | Chất lượng đầu ra (1-100) | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/lqip-placeholder \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"width": 20, "strategy": "blur", "format": "webp"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 280, "dataUri": "data:image/webp;base64,UklGR...", "width": 20, "height": 13, "bytes": 280, "strategy": "blur", "html": "", "css": "background-image:url('data:image/webp;base64,UklGR...');background-size:cover;background-position:center;" } ``` ## Ghi chú {#notes} * Trường `dataUri` chứa data URI hoàn chỉnh, sẵn sàng dùng trong các thuộc tính `src` hoặc CSS mà không cần yêu cầu bổ sung nào. * Các trường `html` và `css` cung cấp các đoạn sao-chép-dán cho các trường hợp dùng phổ biến. * Chiến lược `blur` tạo ra một thumbnail mềm, mờ. Chiến lược `pixelate` tạo ra một khảm ô vuông. Chiến lược `solid` trả về một màu trung bình duy nhất. * Kích thước giữ chỗ điển hình là 200-500 byte, khiến chúng phù hợp để nhúng trực tiếp trong HTML. * Chiều cao được tính tự động để giữ tỷ lệ khung hình của ảnh nguồn. * Đầu vào HEIC, RAW, PSD và SVG được giải mã tự động trước khi xử lý. --- --- url: https://docs.snapotter.com/vi/tools/image/image-to-base64.md description: Chuyển đổi ảnh thành data URI base64 để nhúng vào HTML, CSS và nhiều nơi khác. --- # Ảnh sang Base64 {#image-to-base64} Chuyển đổi một hoặc nhiều ảnh thành chuỗi được mã hóa base64 và data URI. Hỗ trợ chuyển đổi định dạng tùy chọn, kiểm soát chất lượng và thay đổi kích thước. Hữu ích để nhúng ảnh trực tiếp vào HTML, CSS, JSON hoặc mẫu email. ## Điểm cuối API {#api-endpoint} `POST /api/v1/tools/image/image-to-base64` Chấp nhận dữ liệu biểu mẫu multipart với một hoặc nhiều tệp ảnh và một trường JSON `settings` tùy chọn. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | outputFormat | string | Không | `"original"` | Chuyển đổi trước khi mã hóa: `original`, `jpeg`, `png`, `webp`, `avif`, `jxl` | | quality | number | Không | `80` | Chất lượng đầu ra cho các định dạng mất dữ liệu (1 đến 100) | | maxWidth | number | Không | `0` | Chiều rộng tối đa tính bằng pixel (0 = không thay đổi kích thước, sẽ không phóng to) | | maxHeight | number | Không | `0` | Chiều cao tối đa tính bằng pixel (0 = không thay đổi kích thước, sẽ không phóng to) | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon.png" \ -F 'settings={"outputFormat": "webp", "quality": 80, "maxWidth": 200}' ``` Nhiều tệp: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon1.png" \ -F "file=@icon2.png" \ -F "file=@icon3.png" \ -F 'settings={"outputFormat": "original"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "results": [ { "filename": "icon.png", "mimeType": "image/webp", "width": 200, "height": 200, "originalSize": 45000, "encodedSize": 28800, "overheadPercent": -36.0, "base64": "UklGRlYAAABXRUJQ...", "dataUri": "data:image/webp;base64,UklGRlYAAABXRUJQ..." } ], "errors": [] } ``` ## Trường phản hồi {#response-fields} | Trường | Kiểu | Mô tả | |-------|------|-------------| | results | array | Các ảnh đã chuyển đổi thành công | | errors | array | Các ảnh không xử lý được (kèm tên tệp và thông báo lỗi) | ### Đối tượng Result {#result-object} | Trường | Kiểu | Mô tả | |-------|------|-------------| | filename | string | Tên tệp gốc | | mimeType | string | Kiểu MIME của đầu ra được mã hóa | | width | number | Chiều rộng cuối cùng tính bằng pixel (sau bất kỳ thay đổi kích thước nào) | | height | number | Chiều cao cuối cùng tính bằng pixel (sau bất kỳ thay đổi kích thước nào) | | originalSize | number | Kích thước tệp gốc tính bằng byte | | encodedSize | number | Kích thước của chuỗi base64 tính bằng byte | | overheadPercent | number | Phần trăm chênh lệch kích thước so với bản gốc (dương = lớn hơn, âm = nhỏ hơn) | | base64 | string | Dữ liệu ảnh mã hóa base64 thô | | dataUri | string | Data URI hoàn chỉnh sẵn sàng dùng trong thuộc tính `src` | ## Ghi chú {#notes} * Mã hóa Base64 thường làm tăng kích thước khoảng 33% so với tệp nhị phân. Trường `overheadPercent` cho biết chênh lệch thực tế. * Khi `outputFormat` là `"original"`, các tệp HEIC/HEIF được chuyển sang JPEG (vì trình duyệt không thể hiển thị HEIC trong data URI). * Các tùy chọn `maxWidth` và `maxHeight` thay đổi kích thước bằng `fit: inside` với `withoutEnlargement`, nên các ảnh nhỏ hơn kích thước đã chỉ định sẽ không được phóng to. * Nhiều tệp có thể được xử lý trong một yêu cầu duy nhất. Mỗi tệp được xử lý độc lập, và các lỗi không ngăn các tệp khác thành công. * Các tệp SVG được truyền qua dưới dạng `image/svg+xml` mà không mã hóa lại (trừ khi yêu cầu chuyển đổi định dạng). * Đây là một điểm cuối chỉ đọc. Nó không tạo ra tệp có thể tải xuống hoặc một `jobId`. Dữ liệu base64 được trả về trực tiếp trong thân phản hồi. --- --- url: https://docs.snapotter.com/vi/tools/image/image-to-pdf.md description: >- Kết hợp một hoặc nhiều ảnh thành tài liệu PDF với các tùy chọn kích thước trang, hướng và dung lượng tệp đích. --- # Ảnh sang PDF {#image-to-pdf} Kết hợp một hoặc nhiều ảnh thành tài liệu PDF. Hỗ trợ nhiều kích thước trang, hướng, lề và tùy chọn nhắm dung lượng tệp qua điều chỉnh chất lượng. ## Điểm cuối API {#api-endpoint} `POST /api/v1/tools/image/image-to-pdf` Chấp nhận dữ liệu biểu mẫu multipart với một hoặc nhiều tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | pageSize | string | Không | `"A4"` | Kích thước trang: `A4`, `Letter`, `A3`, `A5` | | orientation | string | Không | `"portrait"` | Hướng trang: `portrait` hoặc `landscape` | | margin | number | Không | `20` | Lề trang tính bằng point (0-500) | | targetSize | object | Không | - | Ràng buộc dung lượng tệp đích (xem bên dưới) | | collate | boolean | Không | `true` | Kết hợp tất cả ảnh vào một PDF. Nếu `false`, tạo một PDF cho mỗi ảnh. | ### Đối tượng Target Size {#target-size-object} | Trường | Kiểu | Bắt buộc | Mô tả | |-------|------|----------|-------------| | value | number | Có | Giá trị kích thước đích | | unit | string | Có | Đơn vị: `KB` hoặc `MB` | Kích thước đích tối thiểu là 50 KB. ## Ví dụ yêu cầu {#example-request} PDF nhiều ảnh cơ bản: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page1.jpg" \ -F "file=@page2.jpg" \ -F "file=@page3.jpg" \ -F 'settings={"pageSize": "A4", "orientation": "portrait", "margin": 20}' ``` Với dung lượng tệp đích: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@scan1.jpg" \ -F "file=@scan2.jpg" \ -F 'settings={"pageSize": "Letter", "targetSize": {"value": 2, "unit": "MB"}}' ``` Một PDF cho mỗi ảnh: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F 'settings={"collate": false}' ``` ## Ví dụ phản hồi (Đã gộp) {#example-response-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 5000000, "processedSize": 1200000, "pages": 3 } ``` ## Ví dụ phản hồi (Không gộp) {#example-response-non-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.zip", "originalSize": 5000000, "processedSize": 2400000, "pages": 2, "collated": false } ``` ## Ví dụ phản hồi (Với dung lượng đích) {#example-response-with-target-size} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 10000000, "processedSize": 2000000, "pages": 5, "compression": { "targetRequested": 2097152, "targetMet": true, "jpegQuality": 72 } } ``` ## Ghi chú {#notes} * Ảnh được căn giữa trang và thu phóng để vừa trong lề trong khi giữ tỷ lệ khung hình. Ảnh không bao giờ được phóng to. * Khi `collate` là `false`, mỗi ảnh trở thành một tệp PDF riêng, và bản tải xuống là một kho lưu trữ ZIP chứa tất cả các PDF. * Tính năng dung lượng đích dùng tìm kiếm nhị phân lặp trên các mức chất lượng JPEG (10-95) để tìm chất lượng tốt nhất vừa với ngân sách. * Ảnh trong suốt được làm phẳng thành trắng trước khi nhúng vào PDF. * Các định dạng đầu vào được hỗ trợ: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW, PSD, SVG và nhiều định dạng khác. * Hướng EXIF được áp dụng tự động trước khi nhúng. --- --- url: https://docs.snapotter.com/vi/tools/image/vectorize.md description: >- Chuyển ảnh raster sang SVG với vector hóa đen trắng (potrace) và nhiều lớp toàn màu. --- # Ảnh sang SVG {#image-to-svg} Vector hóa ảnh raster thành SVG bằng các thuật toán tracing. Hỗ trợ tracing đen trắng (potrace) và vector hóa nhiều lớp toàn màu. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/vectorize` ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | colorMode | string | Không | `"bw"` | Chế độ tracing: `bw` (đen trắng) hoặc `color` (nhiều lớp màu) | | threshold | number | Không | 128 | Ngưỡng độ sáng cho chế độ B\&W (0 đến 255). Các pixel bên dưới ngưỡng trở thành đen. | | colorPrecision | number | Không | 6 | Độ chính xác lượng tử hóa màu cho chế độ màu (1 đến 16). Giá trị cao hơn tạo ra nhiều lớp màu riêng biệt hơn. | | layerDifference | number | Không | 6 | Chênh lệch màu tối thiểu giữa các lớp trong chế độ màu (1 đến 128) | | filterSpeckle | number | Không | 4 | Diện tích tối thiểu cho các hình được trace tính bằng pixel (1 đến 256). Xóa nhiễu/đốm. | | pathMode | string | Không | `"spline"` | Làm mượt đường: `none` (răng cưa), `polygon` (đoạn thẳng), `spline` (đường cong mượt) | | cornerThreshold | number | Không | 60 | Ngưỡng góc để phát hiện góc trong chế độ màu (0 đến 180 độ) | | invert | boolean | Không | `false` | Đảo ngược ảnh trước khi trace (hoán đổi đen/trắng) | ## Ví dụ Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@logo.png" \ -F 'settings={"colorMode":"bw","threshold":128,"filterSpeckle":4,"pathMode":"spline"}' ``` ### Vector hóa màu {#color-vectorization} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@illustration.png" \ -F 'settings={"colorMode":"color","colorPrecision":8,"layerDifference":6,"filterSpeckle":4}' ``` ## Ví dụ Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logo.svg", "originalSize": 45678, "processedSize": 12345 } ``` ## Ghi chú {#notes} * Đầu ra luôn là tệp SVG bất kể định dạng đầu vào. * Hỗ trợ các định dạng đầu vào HEIC, RAW, PSD, và SVG (tự động giải mã sang raster trước khi trace). * Chế độ B\&W dùng thuật toán potrace. Ảnh được chuyển sang grayscale trước, sau đó áp ngưỡng thành đen/trắng thuần trước khi trace. * Chế độ màu dùng cách tiếp cận nhiều lớp: ảnh được lượng tử hóa thành các lớp màu, mỗi lớp được trace riêng và xếp chồng trong đầu ra SVG. * Giá trị `filterSpeckle` thấp hơn giữ lại nhiều chi tiết hơn nhưng tạo ra tệp SVG lớn hơn với nhiều path hơn. * Thiết lập `pathMode` ảnh hưởng đáng kể đến kích thước tệp: `none` tạo ra nhiều path nhất, `spline` tạo ra đầu ra mượt nhất (và thường nhỏ nhất). * Để có kết quả tốt nhất với logo và biểu tượng, dùng chế độ B\&W với đầu vào tương phản cao rõ ràng. Đối với ảnh chụp hoặc minh họa, dùng chế độ màu với `colorPrecision` cao hơn. --- --- url: https://docs.snapotter.com/sv/tools/image/enhance-faces.md description: >- Återställ och skärp suddiga eller lågkvalitativa ansikten i bilder med AI-modellerna GFPGAN och CodeFormer. --- # Ansiktsförbättring {#face-enhancement} Återställ och förbättra ansikten i bilder med AI-modeller (GFPGAN/CodeFormer). ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Bearbetning:** Asynkron (returnerar 202, hämta status via SSE på `/api/v1/jobs/{jobId}/progress`) **Modellpaket:** `upscale-enhance` (5-6 GB) och `face-detection` (200-300 MB) ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bildfil (multipart) | | model | string | Nej | `"auto"` | Modell att använda: `auto`, `gfpgan`, `codeformer` | | strength | number | Nej | `0.8` | Förbättringsstyrka (0-1). Högre värden ger starkare förbättring | | onlyCenterFace | boolean | Nej | `false` | Förbättra endast det mest centrala/framträdande ansiktet | | sensitivity | number | Nej | `0.5` | Känslighet för ansiktsdetektering (0-1) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Svar {#response} ### Inledande svar (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Förlopp (SSE på `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Slutresultat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Anteckningar {#notes} * Kräver både modellpaketet `upscale-enhance` (5-6 GB) och modellpaketet `face-detection` (200-300 MB). * GFPGAN ger mer aggressiv förbättring; CodeFormer bevarar identiteten bättre. `auto` väljer den bästa modellen för indatan. * Utdatan är alltid i PNG-format för maximal kvalitet. * En WebP-förhandsgranskning genereras vid sidan av utdatan i full upplösning för snabbare visning i frontend. * Parametern `strength` blandar det förbättrade ansiktet med originalet. Använd lägre värden (0.3-0.5) för subtila förbättringar, högre värden (0.7-1.0) för starkare återställning. * Stöder indataformaten HEIC/HEIF, RAW, TGA, PSD, EXR och HDR via automatisk avkodning. --- --- url: https://docs.snapotter.com/sv/guide/users-roles.md description: >- Hantera användare, inbyggda och anpassade roller, behörigheter, API-nycklar, team, sessioner och granskningsloggen i SnapOtter. --- # Användare, roller och behörigheter {#users-roles-permissions} SnapOtter levereras med tre inbyggda roller, 17 detaljerade behörigheter och stöd för anpassade roller med valfri åtkomstkontroll per verktyg. Den här sidan täcker hela auktoriseringsmodellen, API-nyckelscoping, teamhantering och granskningsloggning. ::: tip Relaterade sidor [OIDC / SSO](/sv/guide/oidc) | [SAML SSO](/sv/guide/saml) | [SCIM-provisionering](/sv/guide/scim) | [Säkerhet och härdning](/sv/guide/security) ::: ## Användare {#users} ### Skapa användare {#creating-users} Administratörer kan skapa användare via administratörspanelen eller `POST /api/auth/register`-slutpunkten. Varje användare har ett användarnamn, en roll, en teamtilldelning och en valfri e-postadress. ### Standardadministratör {#default-admin} Vid första uppstart skapar SnapOtter ett standardadministratörskonto. Inloggningsuppgifterna kommer från miljövariabler: | Variabel | Standard | Beskrivning | |---|---|---| | `DEFAULT_USERNAME` | `admin` | Användarnamn för det initiala administratörskontot | | `DEFAULT_PASSWORD` | `admin` | Lösenord för det initiala administratörskontot | Standardadministratören måste byta lösenord vid första inloggningen. ### Autentiseringsleverantörer {#authentication-providers} Användare kan autentisera sig via flera metoder: * **Lokal** - användarnamn och lösenord lagrade i SnapOtter-databasen * **OIDC** - valfri OpenID Connect-leverantör (se [OIDC / SSO](/sv/guide/oidc)) * **SAML** - SAML 2.0-identitetsleverantörer (se [SAML SSO](/sv/guide/saml)) * **SCIM** - automatiserad provisionering från en identitetsleverantör (se [SCIM-provisionering](/sv/guide/scim)) ### Inaktivera autentisering {#disabling-authentication} Ange `AUTH_ENABLED=false` för att inaktivera autentisering helt. I det här läget används en syntetisk anonym användare med rollen `admin` för alla förfrågningar. Ingen inloggning krävs. ::: warning Att inaktivera autentisering ger full administratörsåtkomst till alla som kan nå instansen. Använd endast detta i betrodda miljöer. ::: ## Inbyggda roller {#built-in-roles} SnapOtter inkluderar tre inbyggda roller. De kan inte ändras eller raderas. ### Admin {#admin} Alla 17 behörigheter. Full kontroll över instansen. `tools:use` `files:own` `files:all` `apikeys:own` `apikeys:all` `pipelines:own` `pipelines:all` `settings:read` `settings:write` `users:manage` `teams:manage` `features:manage` `system:health` `audit:read` `compliance:manage` `webhooks:manage` `security:manage` ### Editor {#editor} 7 behörigheter. Kan använda alla verktyg och hantera alla filer och pipelines, men kan inte komma åt administratörsfunktioner. `tools:use` `files:own` `files:all` `apikeys:own` `pipelines:own` `pipelines:all` `settings:read` ### User {#user} 5 behörigheter. Kan använda verktyg och hantera sina egna resurser. `tools:use` `files:own` `apikeys:own` `pipelines:own` `settings:read` ## Behörighetsreferens {#permissions-reference} | Behörighet | Beskrivning | |---|---| | `tools:use` | Använd valfritt bearbetningsverktyg | | `files:own` | Visa och hantera egna filer | | `files:all` | Visa och hantera alla användares filer | | `apikeys:own` | Skapa och hantera egna API-nycklar | | `apikeys:all` | Visa alla användares API-nycklar | | `pipelines:own` | Skapa och hantera egna pipelines | | `pipelines:all` | Visa och hantera alla användares pipelines | | `settings:read` | Visa instansinställningar | | `settings:write` | Ändra instansinställningar | | `users:manage` | Skapa och hantera användarkonton inom aktörens behörighetsgräns | | `teams:manage` | Skapa, uppdatera och radera team | | `features:manage` | Installera och hantera AI-funktionsbuntar | | `system:health` | Åtkomst till health- och readiness-slutpunkter | | `audit:read` | Visa granskningsloggen och lista roller | | `compliance:manage` | Hantera GDPR-livscykel- och efterlevnadsfunktioner; destruktiva användaroperationer förblir auktoritetsbundna | | `webhooks:manage` | Konfigurera utgående webhooks | | `security:manage` | Hantera säkerhetsinställningar (IP-tillåtelselista, SSO-tvingande) | ## Anpassade roller {#custom-roles} Administratörer med behörigheten `security:manage` kan skapa anpassade roller via administratörspanelen eller roles-API:et. Att lista roller kräver `audit:read`. ### Skapa en anpassad roll {#creating-a-custom-role} ```bash curl -X POST http://localhost:1349/api/v1/roles \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "reviewer", "description": "Can use tools and view all files", "permissions": ["tools:use", "files:own", "files:all", "settings:read"] }' ``` Rollnamn måste vara 2-30 tecken, gemena alfanumeriska med bindestreck och understreck. ### Delegerade administrationsgränser {#delegated-administration-boundaries} Alla 17 behörigheter kan delegeras genom anpassade roller, men en administrativ behörighet gör inte den rollen likvärdig med den inbyggda `admin`-rollen. Användarmutationer godkända av `users:manage`, destruktiva operationer godkända av `compliance:manage` och anpassade rollhantering auktoriserad av `security:manage` begränsas av skådespelarens nuvarande auktoritet: * Inbyggda roller följer `admin` > `editor` > `user`; anpassade roller är under inbyggda roller. * Målets behörigheter måste innehållas av skådespelarens **effektiva** behörigheter. En scoped API-nyckel kan därför inte utöva behörigheter som utelämnas från dess scope. * En målrolls verktygsåtkomst ska innehållas av aktörens egen verktygsåtkomst. * Ett inaktiverat konto kontrolleras mot sin ursprungliga roll när den rollen registreras som `disabled:`. * Att ta bort en anpassad roll kräver också behörighet att tilldela den inbyggda `user` reserv; funktionshindrade medlemmar förblir inaktiverade som `disabled:user`. Globala autentiseringsuppgifter och konfiguration är strängare: utfärdande eller återkallande av SCIM-token och import av instanskonfiguration kräver den inbyggda `admin`-rollen med fullständig effektiv administratörsbehörighet. ### Behörigheter på verktygsnivå {#tool-level-permissions} Anpassade roller kan valfritt begränsa vilka verktyg användare får komma åt. Två lägen finns tillgängliga: | Läge | Beteende | Licenskrav | |---|---|---| | `category` | Begränsa per modalitet (bild, video, ljud, dokument, fil) | Inget (gratis) | | `tool` | Begränsa per enskilt verktygs-ID | Kräver enterprise-funktionen `per_tool_permissions` | När läget `tool` är satt men enterprise-funktionen inte är tillgänglig, degraderar SnapOtter graciöst och tillåter åtkomst till alla verktyg. ```json { "name": "image-only", "permissions": ["tools:use", "files:own"], "toolPermissions": { "mode": "category", "allowed": ["image"] } } ``` ### Radera en anpassad roll {#deleting-a-custom-role} När en anpassad roll raderas tilldelas alla användare som tilldelats den automatiskt om till rollen `user`. ## Team {#teams} Team grupperar användare för lagrings- och lagringshantering. Ett `Default`-team skapas vid första uppstart. | Fält | Typ | Beskrivning | |---|---|---| | `name` | string | Unikt teamnamn (1-50 tecken) | | `storageQuota` | number | Lagringsgräns per team i byte (fungerar utan enterprise) | | `retentionHours` | number | Radera utdata automatiskt efter så här många timmar (kräver `team_retention_overrides`, enterprise) | | `legalHold` | boolean | Förhindra automatisk radering av teammedlemmars filer (kräver `legal_hold`, enterprise) | ::: info Teamet `Default` kan inte raderas. Team som fortfarande har medlemmar kan inte raderas. Tilldela om medlemmar först. ::: ## API-nycklar {#api-keys} Användare kan generera API-nycklar för programmatisk åtkomst. Varje nyckel använder prefixet `si_` och visas endast en gång vid skapandet. ### Scopade behörigheter {#scoped-permissions} API-nycklar kan valfritt bära en `permissions`-array. När den är satt är de effektiva behörigheterna för en förfrågan **snittet** av användarens rollbehörigheter och nyckelns scopade behörigheter. Detta innebär att en API-nyckel aldrig kan eskalera bortom användarens egna behörigheter. ```bash curl -X POST http://localhost:1349/api/v1/api-keys \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "CI pipeline key", "permissions": ["tools:use", "files:own"], "expiresAt": "2027-01-01T00:00:00Z" }' ``` ### Utgång {#expiration} Nycklar accepterar en valfri `expiresAt`-tidsstämpel. Utgångna nycklar avvisas vid autentiseringstillfället. ## Granskningslogg {#audit-log} SnapOtter registrerar säkerhetsrelevanta händelser i en strukturerad granskningslogg som lagras i databastabellen `audit_log`. ### Visa granskningsloggen {#viewing-the-audit-log} ``` GET /api/v1/audit-log?page=1&limit=50&action=LOGIN_FAILED&from=2026-01-01T00:00:00Z&to=2026-12-31T23:59:59Z ``` Kräver behörigheten `audit:read`. Stöder paginering (`page`, `limit`) och filter (`action`, `ip`, `from`, `to`). ### Granskning av verktygsoperationer {#tool-operation-auditing} ::: warning `TOOL_EXECUTED`-händelser loggas **inte** som standard. De aktiveras via någon av två vägar: 1. Ange administratörsinställningen `auditToolOperations` till `true`. 2. Inneha en aktiv licens med funktionen `audit_export` (tillgänglig på både team- och enterprise-planer). Utan någon av dessa registreras inte enskilda verktygskörningar i granskningsloggen. ::: ### Exportera {#exporting} ``` GET /api/v1/enterprise/audit/export?format=csv&from=2026-01-01T00:00:00Z ``` Kräver behörigheten `audit:read` och enterprise-funktionen `audit_export` (tillgänglig på både team- och enterprise-planer). Stöder CSV- och JSON-format, filtrerat efter `action`, `actorId`, `targetType`, `targetId`, `from` och `to`. ### Manipuleringsbeständig signering {#tamper-resistant-signing} När det är aktiverat signeras varje granskningsloggpost med en HMAC härledd från `DATA_ENCRYPTION_KEY`. Detta kräver: 1. Att ange `DATA_ENCRYPTION_KEY` i din miljö. 2. Att aktivera administratörsinställningen `tamperResistantAudit`. 3. En enterprise-licens med funktionen `tamper_resistant_audit`. ### Lagring {#retention} Ange `AUDIT_RETENTION_DAYS` för att automatiskt rensa gamla poster. Standarden är `0`, vilket innebär att poster behålls på obestämd tid. ### Händelsereferens {#event-reference} | Händelse | Kategori | |---|---| | `LOGIN_SUCCESS`, `LOGIN_FAILED` | Autentisering | | `OIDC_LOGIN_SUCCESS`, `OIDC_LOGIN_FAILED` | Autentisering | | `SAML_LOGIN_SUCCESS`, `SAML_LOGIN_FAILED` | Autentisering | | `LOGOUT` | Autentisering | | `USER_CREATED`, `USER_UPDATED`, `USER_DELETED` | Användarhantering | | `PASSWORD_CHANGED`, `PASSWORD_RESET` | Användarhantering | | `MFA_ENROLLED`, `MFA_DISABLED`, `MFA_VERIFIED`, `MFA_VERIFY_FAILED` | MFA | | `MFA_CHALLENGE_ISSUED`, `MFA_RECOVERY_USED`, `MFA_RESET` | MFA | | `ROLE_CREATED`, `ROLE_UPDATED`, `ROLE_DELETED` | Roller | | `API_KEY_CREATED`, `API_KEY_DELETED` | API-nycklar | | `SETTINGS_UPDATED`, `IP_ALLOWLIST_UPDATED` | Inställningar | | `FILE_UPLOADED`, `FILE_DELETED` | Filer | | `TOOL_EXECUTED` | Verktyg (opt-in) | | `SCIM_USER_PROVISIONED`, `SCIM_USER_UPDATED`, `SCIM_USER_DEPROVISIONED` | SCIM | | `SCIM_GROUP_SYNCED` | SCIM | | `LEGAL_HOLD_APPLIED`, `LEGAL_HOLD_RELEASED` | Efterlevnad | | `GDPR_EXPORT_INITIATED`, `GDPR_USER_PURGED`, `GDPR_TEAM_PURGED` | Efterlevnad | | `CONFIG_EXPORTED`, `CONFIG_IMPORTED` | Konfiguration | ## Sessionshantering {#session-management} Sessioner är cookie-baserade, styrda av `SESSION_DURATION_HOURS` (standard: 168 timmar / 7 dagar). ### Rolländringar ogiltigförklarar sessioner {#role-changes-invalidate-sessions} När en administratör ändrar en användares roll raderas alla den användarens aktiva sessioner. Användaren måste logga in igen för att plocka upp sina nya behörigheter. ### Säkerhetsspärrar {#safety-guards} * **Skydd för sista administratören**: den sista kvarvarande administratören kan inte degraderas till en lägre roll. API:et returnerar ett fel om du försöker. * **Förhindrande av självradering**: administratörer kan inte radera sitt eget konto via API:et. --- --- url: https://docs.snapotter.com/id/guide/telemetry.md description: >- Data penggunaan anonim apa yang dikumpulkan SnapOtter, kapan dikirim, dan cara mematikan analitik produk untuk seluruh instance. --- # Apa yang dikumpulkan SnapOtter {#what-snapotter-collects} Analitik Produk Anonim aktif secara default dan diatur untuk seluruh instance oleh administrator. Matikan di Settings > System > Privacy. ## Peristiwa yang kami kirim (ketika diaktifkan) {#events-we-send-when-enabled} * tool\_used: id alat, status, durasi, kategori, apakah ini alat AI, kode error saat gagal. * pipeline\_executed: jumlah langkah, id alat, flag batch, jumlah file, durasi, status. * ai\_bundle\_action: id bundle, aksi, durasi. * Penggunaan frontend: halaman alat mana yang dibuka, file ditambahkan (hanya jumlah), alat dimulai, unduhan, penyimpanan, pencarian (hanya jumlah hasil), batch diproses. * Laporan crash: tipe error dan source stack dengan hanya basename file. ## Apa yang tidak pernah kami kumpulkan {#what-we-never-collect} * Nama atau path file * Isi file * Teks keluaran OCR * Metadata gambar (EXIF) * Teks dokumen yang diekstrak * Alamat IP atau identitas akun Anda ## Cara mematikannya {#turning-it-off} Admin: Settings > System > Privacy, matikan "Anonymous Product Analytics". Pengiriman langsung berhenti, untuk seluruh instance. Untuk membangun image yang tidak akan pernah mengirim, atur build arg `SNAPOTTER_ANALYTICS=off`. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/erase-object.md description: >- Remova objetos indesejados de imagens com inpainting por IA (LaMa), guiado por uma máscara da região a apagar. --- # Apagador de Objetos {#object-eraser} Remova objetos indesejados de imagens usando inpainting por IA (modelo LaMa). Aceita uma imagem e uma máscara indicando a região a apagar. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/erase-object` **Processamento:** Assíncrono (retorna 202, consulte `/api/v1/jobs/{jobId}/progress` para o status via SSE) **Pacote do modelo:** `object-eraser-colorize` (1-2 GB) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem de origem (multipart) | | mask | file | Sim | - | Imagem de máscara (branco = área a apagar, preto = manter). Deve ser enviada com o fieldname `mask` | | format | string | Não | `"auto"` | Formato de saída: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | Não | `95` | Qualidade de saída (1-100) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/erase-object \ -F "file=@photo.jpg" \ -F "mask=@mask.png" \ -F "format=png" \ -F "quality=95" ``` ## Resposta {#response} ### Resposta Inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progresso (SSE em `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Inpainting...","percent":70} ``` ### Resultado Final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_erased.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 245000, "processedSize": 230000 } } ``` ## Notas {#notes} * Requer que o pacote do modelo `object-eraser-colorize` esteja instalado (1-2 GB). * A máscara deve ter as mesmas dimensões da imagem de origem. Pixels brancos indicam áreas a apagar; a IA as preenche com conteúdo plausível. * Usa o LaMa (Large Mask Inpainting) para remoção de objetos de alta qualidade. * Para formatos de saída não pré-visualizáveis no navegador, uma pré-visualização WebP é gerada junto com a saída principal. * Suporta os formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR via decodificação automática. --- --- url: https://docs.snapotter.com/es/tools/pdf/flatten-pdf.md description: Incorpora formularios y anotaciones al contenido de la página. --- # Aplanar PDF {#flatten-pdf} Incorpora los campos de formulario interactivos y las anotaciones al contenido de la página, produciendo un PDF estático que se ve igual en todas partes. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Acepta datos de formulario multipart con un archivo PDF. ## Parameters {#parameters} Esta herramienta no tiene parámetros configurables. Sube un PDF y todos los formularios y anotaciones se aplanarán. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Formato de entrada aceptado: `.pdf`. * Esta es una herramienta rápida (síncrona) que devuelve el resultado directamente. * Los valores de los campos de formulario se conservan como texto estático en la salida. * Las anotaciones (comentarios, resaltados, notas adhesivas) pasan a formar parte del contenido de la página y ya no se pueden editar. --- --- url: https://docs.snapotter.com/fr/tools/pdf/flatten-pdf.md description: Intégrer les formulaires et annotations dans le contenu des pages. --- # Aplatir un PDF {#flatten-pdf} Intégrez les champs de formulaire interactifs et les annotations dans le contenu des pages, produisant un PDF statique qui s'affiche de la même façon partout. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Accepte des données de formulaire multipart avec un fichier PDF. ## Paramètres {#parameters} Cet outil n'a aucun paramètre configurable. Téléversez un PDF et tous les formulaires et annotations seront aplatis. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Remarques {#notes} * Format d'entrée accepté : `.pdf`. * Il s'agit d'un outil rapide (synchrone) qui renvoie le résultat directement. * Les valeurs des champs de formulaire sont conservées sous forme de texte statique dans la sortie. * Les annotations (commentaires, surlignages, notes autocollantes) deviennent partie intégrante du contenu de la page et ne peuvent plus être modifiées. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/sharpening.md description: >- Realce imagens usando os métodos adaptativo, máscara de nitidez (unsharp mask) ou passa-alta, com redução de ruído opcional. --- # Aplicar Nitidez na Imagem {#sharpening} Ferramenta avançada de nitidez com três métodos: adaptativo (inteligente, sensível a bordas), máscara de nitidez (unsharp mask, com raio/quantidade clássicos) e passa-alta (ênfase em textura). Inclui redução de ruído embutida para evitar artefatos de nitidez. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/sharpening` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | method | string | Não | `"adaptive"` | Algoritmo de nitidez: `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | Não | `1.0` | Adaptativo: sigma gaussiano (0.5 a 10) | | m1 | number | Não | `1.0` | Adaptativo: nitidez em áreas planas (0 a 10) | | m2 | number | Não | `3.0` | Adaptativo: nitidez em áreas irregulares (0 a 20) | | x1 | number | Não | `2.0` | Adaptativo: limiar plano/irregular (0 a 10) | | y2 | number | Não | `12` | Adaptativo: nitidez máxima em áreas planas (0 a 50) | | y3 | number | Não | `20` | Adaptativo: nitidez máxima em áreas irregulares (0 a 50) | | amount | number | Não | `100` | Máscara de nitidez: quantidade de nitidez (0 a 1000) | | radius | number | Não | `1.0` | Máscara de nitidez: raio de desfoque em pixels (0.1 a 5) | | threshold | number | Não | `0` | Máscara de nitidez: diferença mínima de brilho para aplicar nitidez (0 a 255) | | strength | number | Não | `50` | Passa-alta: intensidade do filtro (0 a 100) | | kernelSize | number | Não | `3` | Passa-alta: tamanho do kernel de convolução (3 ou 5) | | denoise | string | Não | `"off"` | Redução de ruído antes da nitidez: `off`, `light`, `medium`, `strong` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Máscara de nitidez com limiar para proteger áreas suaves: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Notas {#notes} * Apenas os parâmetros relevantes ao método escolhido são usados. Por exemplo, `amount`, `radius` e `threshold` são ignorados quando `method` é `adaptive`. * O método adaptativo usa a nitidez adaptativa embutida do Sharp, com comportamento configurável para regiões planas/irregulares. * A opção `denoise` aplica redução de ruído antes da nitidez para evitar a amplificação de ruído/granulação. * A nitidez passa-alta extrai detalhes finos subtraindo uma versão desfocada do original e, em seguida, mesclando de volta. * O formato de saída corresponde ao formato de entrada. Entradas HEIC, RAW, PSD e SVG são decodificadas automaticamente antes do processamento. --- --- url: https://docs.snapotter.com/it/tools/pdf/flatten-pdf.md description: Incorpora moduli e annotazioni nel contenuto della pagina. --- # Appiattisci PDF {#flatten-pdf} Incorpora i campi modulo interattivi e le annotazioni nel contenuto della pagina, producendo un PDF statico che appare identico ovunque. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Accetta dati di form multipart con un file PDF. ## Parameters {#parameters} Questo strumento non ha parametri configurabili. Carica un PDF e tutti i moduli e le annotazioni verranno appiattiti. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Formato di input accettato: `.pdf`. * Questo è uno strumento veloce (sincrono) che restituisce direttamente il risultato. * I valori dei campi modulo vengono conservati come testo statico nell'output. * Le annotazioni (commenti, evidenziazioni, note adesive) diventano parte del contenuto della pagina e non possono più essere modificate. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/image-enhancement.md description: >- Aprimoramento automático de um clique que analisa uma imagem e corrige exposição, contraste, balanço de branco, saturação e nitidez. --- # Aprimoramento de Imagem {#image-enhancement} Melhoria automática de um clique com análise inteligente. Analisa a imagem e aplica correções de exposição, contraste, balanço de branco, saturação, nitidez e redução de ruído. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **Processamento:** Síncrono (usa a fábrica `createToolRoute`, retorna o resultado diretamente) **Pacote de modelo:** Nenhum necessário para o aprimoramento básico. O pacote `upscale-enhance` (5-6 GB) é usado apenas quando `deepEnhance` está ativado (para remoção de ruído por IA via SCUNet). ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | mode | string | Não | `"auto"` | Modo de aprimoramento: `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | Não | `50` | Intensidade geral do aprimoramento (0-100) | | corrections | object | Não | todas `true` | Correções seletivas a aplicar (veja abaixo) | | deepEnhance | boolean | Não | `false` | Ativa a remoção de ruído com IA (requer a ferramenta `noise-removal` instalada) | ### Objeto de Correções {#corrections-object} | Campo | Tipo | Padrão | Descrição | |-------|------|---------|-------------| | exposure | boolean | `true` | Correção automática de exposição | | contrast | boolean | `true` | Correção automática de contraste | | whiteBalance | boolean | `true` | Correção automática de balanço de branco | | saturation | boolean | `true` | Correção automática de saturação | | sharpness | boolean | `true` | Nitidez automática | | denoise | boolean | `true` | Redução leve de ruído | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Resposta (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Endpoint de Análise {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Analisa uma imagem e retorna recomendações de correção sem aplicá-las. ### Parâmetros {#parameters-1} | Parâmetro | Tipo | Obrigatório | Descrição | |-----------|------|----------|-------------| | file | file | Sim | Arquivo de imagem (multipart) | ### Exemplo de Requisição {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Resposta (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Observações {#notes} * Esta ferramenta usa a fábrica síncrona `createToolRoute`, então retorna uma resposta padrão (não 202 assíncrona). * O parâmetro `mode` ajusta como as correções são ponderadas (por exemplo, o modo retrato é mais suave com tons de pele, o modo paisagem aumenta a saturação). * Quando `deepEnhance` está ativado e a ferramenta `noise-removal` (SCUNet) está instalada, uma passagem adicional de redução de ruído por IA é aplicada após as correções padrão. * O endpoint de análise é útil para pré-visualizar quais correções seriam aplicadas antes de confirmar. * Suporta formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR via decodificação automática. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/enhance-faces.md description: >- Restaure e nitidez rostos borrados ou de baixa qualidade em imagens com os modelos de IA GFPGAN e CodeFormer. --- # Aprimoramento de Rostos {#face-enhancement} Restaure e aprimore rostos em imagens usando modelos de IA (GFPGAN/CodeFormer). ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Processamento:** Assíncrono (retorna 202, consulte `/api/v1/jobs/{jobId}/progress` para o status via SSE) **Pacotes de modelo:** `upscale-enhance` (5-6 GB) e `face-detection` (200-300 MB) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | model | string | Não | `"auto"` | Modelo a usar: `auto`, `gfpgan`, `codeformer` | | strength | number | Não | `0.8` | Intensidade do aprimoramento (0-1). Valores maiores produzem um aprimoramento mais forte | | onlyCenterFace | boolean | Não | `false` | Aprimora apenas o rosto mais central/proeminente | | sensitivity | number | Não | `0.5` | Sensibilidade da detecção de rostos (0-1) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Resposta {#response} ### Resposta Inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progresso (SSE em `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Resultado Final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Notas {#notes} * Requer tanto o pacote do modelo `upscale-enhance` (5-6 GB) quanto o pacote do modelo `face-detection` (200-300 MB). * O GFPGAN produz um aprimoramento mais agressivo; o CodeFormer preserva melhor a identidade. `auto` seleciona o melhor modelo para a entrada. * A saída é sempre no formato PNG para a máxima qualidade. * Uma pré-visualização WebP é gerada junto com a saída em resolução completa para uma exibição mais rápida no frontend. * O parâmetro `strength` mescla o rosto aprimorado com o original. Use valores menores (0.3-0.5) para melhorias sutis, valores maiores (0.7-1.0) para uma restauração mais forte. * Suporta os formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR via decodificação automática. --- --- url: https://docs.snapotter.com/es/guide/scim.md description: >- Configura el aprovisionamiento SCIM 2.0 para sincronizar usuarios y grupos desde tu proveedor de identidad hacia SnapOtter. Cubre Okta, Azure AD / Entra ID e integraciones personalizadas. --- # Aprovisionamiento SCIM {#scim-provisioning} SnapOtter implementa SCIM 2.0 (System for Cross-domain Identity Management) para el aprovisionamiento automatizado de usuarios y grupos. Tu proveedor de identidad puede crear, actualizar, desactivar y reactivar cuentas de usuario y sincronizar la pertenencia a grupos automáticamente. ::: tip Función enterprise El aprovisionamiento SCIM requiere una licencia **enterprise** con la función `scim`. No está disponible en el plan team. Sin la función, todos los endpoints SCIM (excepto discovery) devuelven 403. ::: ## Requisitos previos {#prerequisites} * Una instancia de SnapOtter en ejecución accesible en una URL pública * Una clave de licencia enterprise con la función `scim` * Una cuenta SnapOtter `admin` integrada con su conjunto completo de permisos efectivos. Una función personalizada delegada o una clave API de administrador a la que le falta algún permiso de administrador no pueden generar ni revocar el token SCIM global. * Acceso de administrador a la configuración de aprovisionamiento de tu proveedor de identidad ## Inicio rápido {#quick-start} 1. Genera un token bearer de SCIM: ```bash curl -X POST https://photos.example.com/api/v1/enterprise/scim/token \ -H "Cookie: snapotter-session=YOUR_SESSION" \ -H "Content-Type: application/json" ``` La respuesta contiene el token. Guárdalo de inmediato; no se puede recuperar de nuevo. ```json { "token": "so_scim_v2_a1b2c3d4e5f6...", "message": "Save this token - it cannot be retrieved again" } ``` 2. En tu proveedor de identidad, configura el aprovisionamiento SCIM con: * **Base URL**: `https://photos.example.com/api/v1/scim/v2` * **Autenticación**: token bearer (pega el token del paso 1) ## Autenticación {#authentication} Los endpoints SCIM usan un token Bearer dedicado, independiente de las sesiones de usuario y de las claves de API. ### Generar un token {#generating-a-token} `POST /api/v1/enterprise/scim/token` genera un nuevo token SCIM. Debido a que el token puede aprovisionar y mutar usuarios en la instancia, este punto final requiere el rol `admin` integrado con el conjunto completo de permisos de administrador efectivo. Mantener a `users:manage` en una función personalizada no es suficiente. El token se devuelve en texto plano exactamente una vez. SnapOtter almacena solo un hash scrypt. Si pierdes el token, revócalo y genera uno nuevo. Solo hay un token SCIM activo a la vez. Generar un token nuevo reemplaza al anterior. ::: warning Reemisión de token después de la actualización Los tokens SCIM heredados y no versionados se rechazan. Después de actualizar a una versión que emite tokens `so_scim_v2_...`, genere un token nuevo y actualice su proveedor de identidad antes de reanudar el aprovisionamiento. ::: ### Revocar un token {#revoking-a-token} `DELETE /api/v1/enterprise/scim/token` revoca el token SCIM actual. Tiene los mismos requisitos de administración integrados que la generación de tokens. ### Limitación de tasa {#rate-limiting} Los endpoints SCIM están limitados a 1000 solicitudes por minuto por token. Superar este límite devuelve HTTP 429. ## Recursos admitidos {#supported-resources} | Recurso SCIM | Concepto de SnapOtter | Crear | Leer | Actualizar | Eliminar | |---|---|---|---|---|---| | User | Cuenta de usuario | Sí | Sí | Sí | Eliminación lógica | | Group | Equipo | Sí | Sí | Sí | Sí | ::: warning Los Groups de SCIM se corresponden con los **equipos** de SnapOtter, no con roles. SCIM no puede establecer el rol de un usuario. Todos los usuarios creados vía SCIM reciben el rol `user`. Para cambiar el rol de un usuario, usa la interfaz de administración de SnapOtter. ::: ## Operaciones de usuario {#user-operations} ### Crear usuario {#create-user} `POST /api/v1/scim/v2/Users` Crea una nueva cuenta de usuario con `authProvider` establecido en `scim` y el rol `user`. El usuario se asigna al equipo Default. Si `active` es `false`, el rol se establece en `disabled` en su lugar. Atributos obligatorios: `userName`. Opcionales: `externalId`, `emails`, `active` (por defecto `true`). ### Listar y filtrar usuarios {#list-and-filter-users} `GET /api/v1/scim/v2/Users` Devuelve una lista paginada de usuarios. Admite los parámetros de consulta `startIndex` y `count` (máximo 200 resultados por página). El filtrado admite solo `eq` (igual), sobre estos atributos: * `userName eq "jane"` * `externalId eq "ext-12345"` Otros operadores de filtro y atributos devuelven HTTP 400. ### Obtener usuario {#get-user} `GET /api/v1/scim/v2/Users/:id` Devuelve un único usuario por su ID de usuario de SnapOtter. ### Reemplazar usuario {#replace-user} `PUT /api/v1/scim/v2/Users/:id` Reemplaza los atributos del usuario. Admite `userName`, `externalId`, `emails` y `active`. Los cambios de nombre de usuario se comprueban en busca de conflictos (409 si otro usuario ya usa el nuevo nombre de usuario). ### Aplicar patch a un usuario {#patch-user} `PATCH /api/v1/scim/v2/Users/:id` Actualización parcial mediante SCIM PatchOp. Operaciones admitidas: | Operación | Rutas | |---|---| | `replace` | `active`, `userName`, `externalId`, `emails`, `emails[type eq "work"].value`, `name.formatted`, `displayName` | | `add` | Igual que `replace` | | `remove` | `externalId`, `emails` | Las rutas `name.formatted` y `displayName` se aceptan por compatibilidad, pero no tienen efecto persistente (SnapOtter no almacena un nombre para mostrar por separado). Las operaciones `replace` sin valor (donde el valor es un objeto sin un `path`) también se admiten, con las claves `userName`, `externalId`, `emails` y `active`. ### Desactivar usuario (eliminación lógica) {#deactivate-user-soft-delete} `DELETE /api/v1/scim/v2/Users/:id` SnapOtter no elimina usuarios de forma definitiva vía SCIM. En su lugar, DELETE realiza una desactivación lógica: 1. El rol del usuario se cambia de su valor actual (p. ej. `editor`) a `disabled:editor`, preservando el rol original. 2. Se borra la contraseña del usuario. 3. Se revocan todas las sesiones activas. 4. Se revocan todas las claves de API. El usuario ya no puede iniciar sesión ni usar ninguna clave de API. Sus datos (archivos, historial) se conservan. ### Reactivar usuario {#reactivate-user} Para reactivar un usuario previamente desactivado, envía una solicitud `PUT` o `PATCH` con `active: true`. SnapOtter restaura el rol original de antes de la desactivación (p. ej. `disabled:editor` vuelve a ser `editor`). Si no se puede determinar el rol original, se recurre a `user`. ::: details Ejemplo: desactivar y reactivar vía PATCH ```json // Deactivate { "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": false } ] } // Reactivate { "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": true } ] } ``` ::: ## Operaciones de grupo {#group-operations} Los Groups de SCIM se corresponden con los equipos de SnapOtter. Crear un grupo crea un equipo. La pertenencia al grupo controla a qué equipo pertenece un usuario. ### Crear grupo {#create-group} `POST /api/v1/scim/v2/Groups` Obligatorio: `displayName`. Opcional: `members` (array de `{ value: userId }`). ### Listar y filtrar grupos {#list-and-filter-groups} `GET /api/v1/scim/v2/Groups` El filtrado admite solo `displayName eq "..."`. Paginado con `startIndex` y `count` (máximo 200 resultados por página). ### Obtener grupo {#get-group} `GET /api/v1/scim/v2/Groups/:id` ### Reemplazar grupo {#replace-group} `PUT /api/v1/scim/v2/Groups/:id` Reemplaza el nombre del grupo y la lista completa de miembros. Los miembros existentes que no estén en la nueva lista se trasladan al equipo Default. ### Aplicar patch a un grupo {#patch-group} `PATCH /api/v1/scim/v2/Groups/:id` Admite estas operaciones: | Operación | Ruta | Efecto | |---|---|---| | `add` | `members` | Añade usuarios al equipo | | `remove` | `members[value eq "userId"]` | Traslada al usuario al equipo Default | | `replace` | `displayName` | Renombra el equipo | | `replace` | `members` | Reemplaza todos los miembros (los miembros eliminados pasan al equipo Default) | ### Eliminar grupo {#delete-group} `DELETE /api/v1/scim/v2/Groups/:id` Elimina el equipo. Todos los miembros del equipo eliminado se trasladan al equipo Default. Los usuarios no se desactivan ni se eliminan. ## Configuración del IdP {#idp-setup} ### Okta {#okta} 1. En la consola de administración de Okta, abre tu aplicación de SnapOtter (o crea una). 2. Ve a la pestaña **Provisioning** y haz clic en **Configure API Integration**. 3. Marca **Enable API Integration** e introduce: * **Base URL**: `https://photos.example.com/api/v1/scim/v2` * **API Token**: el token bearer de SCIM generado anteriormente 4. Haz clic en **Test API Credentials** y luego en **Save**. 5. En **Provisioning > To App**, habilita: * **Create Users** * **Update User Attributes** * **Deactivate Users** 6. En **Push Groups**, configura qué grupos de Okta sincronizar como equipos de SnapOtter. ### Azure AD / Entra ID {#azure-ad-entra-id} 1. En el portal de Azure, ve a tu aplicación empresarial de SnapOtter. 2. Ve a **Provisioning** y establece **Provisioning Mode** en **Automatic**. 3. En **Admin Credentials**, introduce: * **Tenant URL**: `https://photos.example.com/api/v1/scim/v2` * **Secret Token**: el token bearer de SCIM generado anteriormente 4. Haz clic en **Test Connection** y luego en **Save**. 5. En **Mappings**, configura las asignaciones de atributos de usuario y de grupo. Los valores por defecto suelen funcionar, pero verifica que `userName` se asigne a `userPrincipalName` o `mail` según prefieras. 6. Establece **Provisioning Status** en **On** y guarda. Azure aprovisiona usuarios y grupos en un ciclo de sincronización fijo (normalmente cada 40 minutos). ## Endpoints de discovery {#discovery-endpoints} Estos tres endpoints están disponibles sin autenticación y describen las capacidades del servidor SCIM: | Endpoint | Descripción | |---|---| | `GET /api/v1/scim/v2/ServiceProviderConfig` | Capacidades del servidor y funciones admitidas | | `GET /api/v1/scim/v2/Schemas` | Definiciones de esquema de User y Group | | `GET /api/v1/scim/v2/ResourceTypes` | Tipos de recurso disponibles (User, Group) | El `ServiceProviderConfig` anuncia estas capacidades: | Función | Admitida | |---|---| | Patch | Sí | | Bulk | No | | Filter | Sí (máx. 200 resultados, solo el operador `eq`) | | Change password | No | | Sort | No | | ETag | No | ## Limitaciones {#limitations} * **Filtrado**: solo se admite el operador `eq`. Los filtros complejos, los operadores `and`/`or`, `co` (contiene) y `sw` (empieza por) no están implementados. * **Operaciones bulk**: no se admiten. * **Sort y ETag**: no se admiten. * **Roles**: SCIM no puede asignar roles de SnapOtter. Todos los usuarios aprovisionados reciben el rol `user`. * **MAX\_USERS**: el límite de la variable de entorno `MAX_USERS` no se aplica en la creación de usuarios vía SCIM. Si necesitas limitar el número de usuarios, gestiona las asignaciones en tu IdP. * **Un solo token**: solo puede haber un token SCIM activo a la vez. Si varios IdP necesitan acceso SCIM, deben compartir el token. * **Los grupos son equipos**: los Groups de SCIM se corresponden con equipos, no con roles ni grupos de permisos. ## Solución de problemas {#troubleshooting} ### 403 "SCIM provisioning requires an enterprise license with the scim feature" {#\_403-scim-provisioning-requires-an-enterprise-license-with-the-scim-feature} Tu licencia no incluye la función `scim`, o no hay ninguna licencia configurada. SCIM requiere una licencia de plan enterprise. Verifica que `SNAPOTTER_LICENSE_KEY` esté establecido y que la licencia incluya la función `scim`. ### 401 "Bearer token required" {#\_401-bearer-token-required} La solicitud SCIM no incluía una cabecera `Authorization: Bearer `. Comprueba la configuración de aprovisionamiento de tu IdP. ### 401 "Invalid token" {#\_401-invalid-token} El token tiene un formato incorrecto, utiliza el formato no versionado retirado o no coincide con el hash almacenado. Genere un token `so_scim_v2_...` actual y actualícelo en la configuración de aprovisionamiento de su IdP. ### 401 "SCIM not configured" {#\_401-scim-not-configured} Aún no se ha generado ningún token SCIM. Usa el endpoint `POST /api/v1/enterprise/scim/token` para crear uno. ### 409 "User already exists" / "userName already taken" {#\_409-user-already-exists-username-already-taken} Ya existe un usuario con el mismo nombre de usuario. Esto puede ocurrir cuando un IdP reintenta una creación fallida. Comprueba si hay nombres de usuario duplicados en el panel de administración de SnapOtter. ### 429 "SCIM rate limit exceeded" {#\_429-scim-rate-limit-exceeded} El IdP está enviando más de 1000 solicitudes por minuto. Esto suele ocurrir durante una gran sincronización inicial. La mayoría de los IdP reintentan automáticamente cuando se reinicia la ventana de límite de tasa. Si el problema persiste, comprueba el intervalo de sincronización de aprovisionamiento de tu IdP. ### Usuarios desaprovisionados pero no eliminados de la interfaz {#users-deprovisioned-but-not-removed-from-the-ui} DELETE de SCIM es una desactivación lógica. Los usuarios desactivados siguen apareciendo en la lista de usuarios del administrador con un estado deshabilitado. Esto es intencionado para preservar sus datos. Su rol se muestra como `disabled:`. --- --- url: https://docs.snapotter.com/fr/guide/architecture.md description: >- Structure du monorepo, architecture des applications et des packages, cycle de vie des requêtes et empreinte de ressources de SnapOtter. --- # Architecture {#architecture} SnapOtter est un monorepo géré avec les espaces de travail pnpm et Turborepo. Il se déploie sous forme de pile Docker Compose à 3 conteneurs : l'image de l'application SnapOtter, PostgreSQL 17 et Redis 8. ## Structure du projet {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Packages {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} La bibliothèque principale de traitement d'images construite sur [Sharp](https://sharp.pixelplumbing.com/). Elle gère toutes les opérations sans IA : redimensionnement, rognage, rotation, retournement, conversion, compression, suppression des métadonnées et ajustements de couleur (luminosité, contraste, saturation, niveaux de gris, sépia, inversion, canaux de couleur). Ce package n'a aucune dépendance réseau et s'exécute entièrement en cours de processus. ### `@snapotter/ai` {#snapotter-ai} Une couche de pont qui appelle les environnements d'exécution natifs et Python ML. La plupart des outils Python utilisent un dispatcher persistant qui pré-importe des bibliothèques lourdes (PIL, NumPy, MediaPipe, rembg), de sorte que les appels ultérieurs ignorent la surcharge d'importation. OCR est isolé de cet environnement partagé mutable : `fast` invoque Tesseract natif, tandis que `balanced` et `best` utilisent un JSONL persistant dédié dispatcher épinglé à la génération RapidOCR/ONNX active et immuable. Chaque requête contient un generation lease. L'activation exécute d'abord un smoke test sur un candidat, puis passe atomiquement à son dispatcher. Le dispatcher précédent est drainé avant que sa génération ne soit récupérée. **Les modèles ne sont pas préchargés.** Chaque script d'outil charge les poids de son modèle depuis le disque au moment de la requête et les libère une fois la requête terminée. Consultez [Empreinte de ressources](#resource-footprint) pour le profil mémoire complet. Opérations prises en charge : suppression de l'arrière-plan (rembg/BiRefNet), mise à l'échelle (RealESRGAN), flou du visage (MediaPipe), amélioration du visage (GFPGAN/CodeFormer), effacement d'objets (LaMa ONNX), OCR (Tesseract et RapidOCR avec les modèles PP-OCR ONNX), colorisation (DDColor), suppression du bruit, suppression des yeux rouges, restauration de photos, génération de photos d'identité, correction de la transparence. (BiRefNet HR-matting) et redimensionnement sensible au contenu (binaire Go caire). Les scripts Python résident dans `packages/ai/python/`. De grands packs de modèles facultatifs sont installés à la demande dans le volume persistant `/data/ai`. Accurate OCR utilise des artefacts signés et spécifiques à la plate-forme ; le niveau Tesseract intégré ne nécessite aucun téléchargement de pack de modèles. ### `@snapotter/shared` {#snapotter-shared} Types TypeScript partagés, constantes (comme `APP_VERSION` et les définitions d'outils) et chaînes de traduction i18n utilisées à la fois par le frontend et le backend. ## Applications {#applications} ### API (`apps/api`) {#api-apps-api} Un serveur Fastify v5 exposant 243 routes d'outils réparties sur cinq modalités (image, vidéo, audio, PDF, fichier) qui gère : * Les téléversements de fichiers, la gestion de l'espace de travail temporaire et le stockage persistant des fichiers * Bibliothèque de fichiers utilisateur (table `user_files`) : une modification enregistrée est stockée par défaut comme un nouveau fichier indépendant, ou comme une version liée à son parent lorsque vous écrasez l'original. Elle enregistre les outils appliqués (`toolChain`) et obtient une vignette auto-générée pour la page Fichiers * L'exécution des outils (achemine chaque requête d'outil vers le moteur d'images ou le pont d'IA) * L'orchestration de pipelines (enchaînement séquentiel de plusieurs outils) * Le traitement par lots avec contrôle de la concurrence via les files d'attente de tâches BullMQ (pools : image, media, ai, docs, system) * L'authentification des utilisateurs, le RBAC (rôles admin/user avec un ensemble complet de permissions), la gestion des clés d'API et la limitation de débit * La gestion des équipes - CRUD réservé aux admins ; les utilisateurs sont affectés à une équipe via le champ `team` de leur profil * Les paramètres d'exécution - un magasin clé-valeur dans la table `settings` qui contrôle `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` et d'autres réglages opérationnels sans redéploiement * L'image de marque personnalisée et les préférences d'exécution via des paramètres stockés en base de données * La documentation Scalar/OpenAPI à `/api/docs` * La distribution du frontend compilé sous forme de SPA en production Dépendances clés : Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod pour la validation. Le serveur gère l'arrêt gracieux sur SIGTERM/SIGINT : il draine les connexions HTTP, arrête les workers BullMQ, arrête le dispatcher Python et ferme la connexion à la base de données. ### Web (`apps/web`) {#web-apps-web} Une application monopage React 19 construite avec Vite. Utilise Zustand pour la gestion de l'état, Tailwind CSS v4 pour le style et Lucide pour les icônes. Communique avec l'API via REST et SSE (pour le suivi de la progression). Les pages comprennent un espace de travail d'outils, une page Fichiers pour gérer les téléversements et résultats persistants, un constructeur d'automatisation/pipeline, et un panneau de paramètres d'administration. Le frontend compilé est distribué par le backend Fastify en production, il n'y a donc pas de serveur web distinct dans le conteneur Docker. ### Docs (`apps/docs`) {#docs-apps-docs} Ce site VitePress. Déployé automatiquement sur Cloudflare Pages à chaque push sur `main`. ## Cheminement d'une requête {#how-a-request-flows} 1. L'utilisateur choisit un outil dans l'interface web et téléverse un fichier. 2. Le frontend envoie une requête POST multipart à `/api/v1/tools/:section/:toolId` avec le fichier et les paramètres. 3. La route de l'API valide l'entrée avec Zod, puis lance le traitement. 4. Pour les outils standards, la tâche est mise en file d'attente dans le pool BullMQ approprié (image, media ou docs selon la modalité). Le worker BullMQ en cours de processus oriente automatiquement l'image d'après les métadonnées EXIF, exécute la fonction de traitement de l'outil et renvoie le résultat. 5. Pour la plupart des outils d'IA, le pont TypeScript envoie une requête au Python dispatcher persistant. OCR rapide appelle à la place Tesseract, et OCR précis démarre l'exécutable épinglé à partir de la génération OCR immuable active. Le niveau OCR demandé est fixé lors de l’entrée et n’est jamais modifié silencieusement pendant l’exécution. 6. La progression de la tâche est persistée dans la table `jobs` de PostgreSQL afin que l'état survive aux redémarrages du conteneur. Les mises à jour en temps réel sont livrées via SSE à `/api/v1/jobs/:jobId/progress`. 7. L'API renvoie un `jobId` et une `downloadUrl`. L'utilisateur télécharge le fichier traité depuis `/api/v1/download/:jobId/:filename`. Pour les pipelines, l'API alimente l'étape suivante avec la sortie de chaque étape, en les exécutant séquentiellement. Pour le traitement par lots, l'API utilise des flux BullMQ avec des tâches enfants par étape et renvoie un fichier ZIP contenant tous les fichiers traités. ## Empreinte de ressources {#resource-footprint} SnapOtter est conçu pour une faible utilisation de mémoire au repos. Rien n'est préchargé ni maintenu chaud au démarrage. ### Au repos {#at-idle} Le processus Node.js/Fastify, PostgreSQL et Redis sont en cours d'exécution. La RAM typique au repos est de **~200 à 300 Mo** répartie sur les trois conteneurs (processus Node.js, Postgres et Redis). Aucun processus Python, aucun poids de modèle en mémoire. ### Ce qui démarre, et quand {#what-starts-and-when} | Composant | Démarre quand | Mémoire pendant l'activité | |-----------|-------------|---------------------| | Serveur Fastify + Postgres + Redis | Démarrage du conteneur | ~200 à 300 Mo au total | | Workers BullMQ | Démarrage du conteneur (en cours de processus) | Un worker par pool (image, media, ai, docs, system) | | Dispatcher Python | Première requête d'outil d'IA | Interpréteur Python + bibliothèques pré-importées (PIL, NumPy, MediaPipe, rembg) - aucun poids de modèle | | Poids des modèles d'IA | Pendant la requête de l'outil concerné | Chargés depuis le disque, libérés à la fin de la requête | ### Chargement des modèles {#model-loading} Tous les fichiers de poids des modèles (totalisant plusieurs Go) résident en permanence sur le disque dans `/opt/models/`. Chaque script d'outil d'IA charge en mémoire uniquement son ou ses modèles pour la durée d'une requête, puis les libère. Certains scripts appellent explicitement `del model` et `torch.cuda.empty_cache()` après l'inférence pour garantir la restitution immédiate de la mémoire. Il n'y a pas de cache de modèles entre les requêtes. Exécuter le même outil d'IA de manière consécutive recharge le modèle à chaque fois. Cela maintient la mémoire au repos proche de zéro au prix d'un délai de chargement du modèle à chaque requête d'IA. ### Démarrage à froid de la première requête d'IA {#first-ai-request-cold-start} Le dispatcher Python n'est pas en cours d'exécution au démarrage du conteneur. La première requête d'IA déclenche deux choses en parallèle : le dispatcher commence à se préchauffer en arrière-plan, et la requête elle-même se rabat sur le lancement ponctuel d'un sous-processus Python. Une fois que le dispatcher signale qu'il est prêt, toutes les requêtes d'IA suivantes l'utilisent directement et évitent le coût du lancement d'un sous-processus. --- --- url: https://docs.snapotter.com/hi/guide/architecture.md description: >- SnapOtter की मोनोरेपो संरचना, ऐप और पैकेज आर्किटेक्चर, अनुरोध जीवनचक्र, और संसाधन फ़ुटप्रिंट। --- # Architecture {#architecture} SnapOtter एक मोनोरेपो है जिसे pnpm workspaces और Turborepo के साथ प्रबंधित किया जाता है। यह एक 3-कंटेनर Docker Compose स्टैक के रूप में परिनियोजित होता है: SnapOtter ऐप इमेज, PostgreSQL 17, और Redis 8। ## Project structure {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Packages {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} [Sharp](https://sharp.pixelplumbing.com/) पर बनी मुख्य इमेज प्रोसेसिंग लाइब्रेरी। यह सभी नॉन-AI ऑपरेशन संभालती है: resize, crop, rotate, flip, convert, compress, strip metadata, और रंग समायोजन (brightness, contrast, saturation, grayscale, sepia, invert, color channels)। इस पैकेज की कोई नेटवर्क डिपेंडेंसी नहीं है और यह पूरी तरह इन-प्रोसेस चलता है। ### `@snapotter/ai` {#snapotter-ai} एक ब्रिज परत जो मूल और Python ML रनटाइम को कॉल करती है। अधिकांश Python उपकरण एक सतत dispatcher का उपयोग करते हैं जो भारी पुस्तकालयों (PIL, NumPy, MediaPipe, rembg) को पूर्व-आयात करता है ताकि बाद की कॉलें आयात ओवरहेड को छोड़ दें। OCR उस परिवर्तनशील साझा वातावरण से अलग है: `fast` मूल Tesseract को आमंत्रित करता है, जबकि `balanced` और `best` सक्रिय अपरिवर्तनीय RapidOCR/ONNX पीढ़ी पर पिन किए गए एक समर्पित लगातार JSONL dispatcher का उपयोग करते हैं। प्रत्येक अनुरोध में एक generation lease होता है। सक्रियण पहले एक उम्मीदवार पर smoke test चलाता है, फिर परमाणु रूप से इसके dispatcher पर स्विच करता है। पूर्ववर्ती dispatcher कचरा एकत्रित होने से पहले ही नष्ट हो जाता है। **मॉडल पहले से लोड नहीं होते।** प्रत्येक टूल स्क्रिप्ट अनुरोध के समय डिस्क से अपने मॉडल वेट लोड करती है और अनुरोध समाप्त होने पर उन्हें त्याग देती है। पूर्ण मेमोरी प्रोफ़ाइल के लिए [Resource footprint](#resource-footprint) देखें। समर्थित ऑपरेशन: बैकग्राउंड रिमूवल (rembg/BiRefNet), अपस्केलिंग (RealESRGAN), फेस ब्लर (मीडियापाइप), फेस एन्हांसमेंट (GFPGAN/CodeFormer), ऑब्जेक्ट इरेजिंग (LaMa ONNX), OCR (Tesseract और RapidOCR PP-OCR ONNX मॉडल के साथ), रंगीकरण (DDColor), शोर निष्कासन, लाल आँख हटाना, फोटो बहाली, पासपोर्ट फोटो जनरेशन, पारदर्शिता फिक्सिंग (BiRefNet HR-मैटिंग), और सामग्री-जागरूक आकार बदलना (गो केयर बाइनरी)। Python स्क्रिप्ट `packages/ai/python/` में रहती हैं। बड़े वैकल्पिक मॉडल पैक लगातार `/data/ai` वॉल्यूम में मांग पर स्थापित किए जाते हैं। सटीक OCR हस्ताक्षरित, प्लेटफ़ॉर्म-विशिष्ट कलाकृतियों का उपयोग करता है; अंतर्निहित Tesseract टियर को किसी मॉडल-पैक डाउनलोड की आवश्यकता नहीं है। ### `@snapotter/shared` {#snapotter-shared} साझा TypeScript प्रकार, स्थिरांक (जैसे `APP_VERSION` और टूल परिभाषाएँ), और i18n अनुवाद स्ट्रिंग्स जो फ़्रंटएंड और बैकएंड दोनों द्वारा उपयोग की जाती हैं। ## Applications {#applications} ### API (`apps/api`) {#api-apps-api} एक Fastify v5 सर्वर जो पाँच मोडैलिटी (image, video, audio, PDF, file) में 243 टूल रूट प्रकट करता है, जो निम्न को संभालता है: * फ़ाइल अपलोड, अस्थायी वर्कस्पेस प्रबंधन, और स्थायी फ़ाइल स्टोरेज * उपयोगकर्ता फ़ाइल लाइब्रेरी (`user_files` तालिका): सहेजा गया संपादन डिफ़ॉल्ट रूप से एक स्वतंत्र नई फ़ाइल के रूप में संग्रहीत होता है, या जब आप मूल को अधिलेखित करते हैं तो एक पैरेंट-लिंक्ड संस्करण के रूप में। यह रिकॉर्ड करता है कि कौन-से टूल लागू किए गए थे (`toolChain`) और Files पेज के लिए स्वतः-जनरेट किया गया थंबनेल प्राप्त करता है * टूल निष्पादन (प्रत्येक टूल अनुरोध को इमेज इंजन या AI ब्रिज पर रूट करता है) * पाइपलाइन ऑर्केस्ट्रेशन (कई टूल को क्रमिक रूप से श्रृंखलाबद्ध करना) * BullMQ जॉब क्यू के माध्यम से समवर्तीता नियंत्रण के साथ बैच प्रोसेसिंग (पूल: image, media, ai, docs, system) * उपयोगकर्ता प्रमाणीकरण, RBAC (पूर्ण अनुमति सेट के साथ admin/user भूमिकाएँ), API कुंजी प्रबंधन, और रेट लिमिटिंग * Teams प्रबंधन - केवल-admin CRUD; उपयोगकर्ताओं को उनके प्रोफ़ाइल पर `team` फ़ील्ड के माध्यम से एक टीम को सौंपा जाता है * रनटाइम सेटिंग्स - `settings` तालिका में एक key-value स्टोर जो पुनः परिनियोजन के बिना `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit`, और अन्य परिचालन नियंत्रण संभालता है * डेटाबेस-समर्थित सेटिंग्स के माध्यम से कस्टम ब्रांडिंग और रनटाइम प्राथमिकताएँ * `/api/docs` पर Scalar/OpenAPI दस्तावेज़ीकरण * प्रोडक्शन में निर्मित फ़्रंटएंड को एक SPA के रूप में सर्व करना मुख्य डिपेंडेंसी: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, सत्यापन के लिए Zod। सर्वर SIGTERM/SIGINT पर सुशोभित शटडाउन संभालता है: यह HTTP कनेक्शन को खाली करता है, BullMQ वर्कर को रोकता है, Python डिस्पैचर को बंद करता है, और डेटाबेस कनेक्शन बंद करता है। ### Web (`apps/web`) {#web-apps-web} Vite के साथ बनाया गया एक React 19 सिंगल-पेज ऐप। स्टेट प्रबंधन के लिए Zustand, स्टाइलिंग के लिए Tailwind CSS v4, और आइकन के लिए Lucide का उपयोग करता है। REST और SSE (प्रगति ट्रैकिंग के लिए) पर API के साथ संवाद करता है। पेजों में एक टूल वर्कस्पेस, स्थायी अपलोड और परिणामों के प्रबंधन के लिए एक Files पेज, एक ऑटोमेशन/पाइपलाइन बिल्डर, और एक admin सेटिंग्स पैनल शामिल हैं। निर्मित फ़्रंटएंड प्रोडक्शन में Fastify बैकएंड द्वारा सर्व किया जाता है, इसलिए Docker कंटेनर में कोई अलग वेब सर्वर नहीं है। ### Docs (`apps/docs`) {#docs-apps-docs} यह VitePress साइट। `main` पर पुश होने पर स्वचालित रूप से Cloudflare Pages पर परिनियोजित। ## How a request flows {#how-a-request-flows} 1. उपयोगकर्ता वेब UI में एक टूल चुनता है और एक फ़ाइल अपलोड करता है। 2. फ़्रंटएंड फ़ाइल और सेटिंग्स के साथ `/api/v1/tools/:section/:toolId` पर एक multipart POST भेजता है। 3. API रूट इनपुट को Zod के साथ सत्यापित करता है, फिर प्रोसेसिंग डिस्पैच करता है। 4. मानक टूल के लिए, जॉब को उपयुक्त BullMQ पूल (मोडैलिटी के आधार पर image, media, या docs) में क्यू में डाला जाता है। इन-प्रोसेस BullMQ वर्कर EXIF मेटाडेटा के आधार पर इमेज को स्वतः-ओरिएंट करता है, टूल के प्रोसेस फ़ंक्शन को चलाता है, और परिणाम लौटाता है। 5. अधिकांश AI टूल के लिए, TypeScript ब्रिज लगातार Python dispatcher को एक अनुरोध भेजता है। तेज़ OCR इसके बजाय Tesseract को आमंत्रित करता है, और सटीक OCR सक्रिय अपरिवर्तनीय OCR पीढ़ी से पिन किए गए निष्पादन योग्य को प्रारंभ करता है। अनुरोधित OCR टियर प्रवेश पर तय किया गया है और निष्पादन के दौरान इसे कभी भी चुपचाप नहीं बदला जाता है। 6. जॉब प्रगति PostgreSQL में `jobs` तालिका में बनी रहती है ताकि स्टेट कंटेनर पुनरारंभ के दौरान बना रहे। वास्तविक समय अपडेट `/api/v1/jobs/:jobId/progress` पर SSE के माध्यम से वितरित किए जाते हैं। 7. API एक `jobId` और `downloadUrl` लौटाता है। उपयोगकर्ता `/api/v1/download/:jobId/:filename` से प्रोसेस की गई फ़ाइल डाउनलोड करता है। पाइपलाइनों के लिए, API प्रत्येक चरण के आउटपुट को अगले के इनपुट के रूप में फ़ीड करता है, उन्हें क्रमिक रूप से चलाता है। बैच प्रोसेसिंग के लिए, API प्रति-चरण चाइल्ड जॉब के साथ BullMQ फ़्लो का उपयोग करता है और सभी प्रोसेस की गई फ़ाइलों के साथ एक ZIP फ़ाइल लौटाता है। ## Resource footprint {#resource-footprint} SnapOtter को कम निष्क्रिय मेमोरी उपयोग के लिए डिज़ाइन किया गया है। स्टार्टअप पर कुछ भी पहले से लोड या गर्म नहीं रखा जाता। ### At idle {#at-idle} Node.js/Fastify प्रक्रिया, PostgreSQL, और Redis चल रहे हैं। सामान्य निष्क्रिय RAM तीनों कंटेनरों में **~200-300 MB** है (Node.js प्रक्रिया, Postgres, और Redis)। कोई Python प्रक्रिया नहीं, मेमोरी में कोई मॉडल वेट नहीं। ### What starts, and when {#what-starts-and-when} | घटक | कब शुरू होता है | सक्रिय रहते समय मेमोरी | |-----------|-------------|---------------------| | Fastify सर्वर + Postgres + Redis | कंटेनर शुरू | कुल ~200-300 MB | | BullMQ वर्कर | कंटेनर शुरू (इन-प्रोसेस) | प्रति पूल एक वर्कर (image, media, ai, docs, system) | | Python डिस्पैचर | पहला AI टूल अनुरोध | Python इंटरप्रेटर + पूर्व-इम्पोर्ट की गई लाइब्रेरी (PIL, NumPy, MediaPipe, rembg) - कोई मॉडल वेट नहीं | | AI मॉडल वेट | विशिष्ट टूल के अनुरोध के दौरान | डिस्क से लोड, अनुरोध समाप्त होने पर मुक्त | ### Model loading {#model-loading} सभी मॉडल वेट फ़ाइलें (कुल मिलाकर कई GB) हर समय `/opt/models/` में डिस्क पर रहती हैं। प्रत्येक AI टूल स्क्रिप्ट केवल अपने स्वयं के मॉडल को एक अनुरोध की अवधि के लिए मेमोरी में लोड करती है, फिर उन्हें रिलीज़ कर देती है। कुछ स्क्रिप्ट इंफ़रेंस के बाद स्पष्ट रूप से `del model` और `torch.cuda.empty_cache()` को कॉल करती हैं ताकि यह सुनिश्चित हो सके कि मेमोरी तुरंत वापस दी जाए। अनुरोधों के बीच कोई मॉडल कैश नहीं है। एक ही AI टूल को लगातार चलाने से हर बार मॉडल फिर से लोड होता है। यह हर AI अनुरोध पर एक मॉडल-लोड विलंब की कीमत पर निष्क्रिय मेमोरी को शून्य के करीब रखता है। ### First AI request cold start {#first-ai-request-cold-start} जब कंटेनर शुरू होता है तो Python डिस्पैचर नहीं चल रहा होता। पहला AI अनुरोध समानांतर में दो चीज़ें ट्रिगर करता है: डिस्पैचर बैकग्राउंड में गर्म होना शुरू होता है, और अनुरोध स्वयं एक बार की Python सबप्रोसेस स्पॉन पर वापस लौट आता है। एक बार डिस्पैचर तैयार होने का संकेत देता है, तो बाद के सभी AI अनुरोध सीधे इसका उपयोग करते हैं और सबप्रोसेस स्पॉन लागत को छोड़ देते हैं। --- --- url: https://docs.snapotter.com/th/guide/architecture.md description: >- โครงสร้าง monorepo, สถาปัตยกรรมของแอปและแพ็กเกจ, วงจรชีวิตของคำขอ และรอยเท้าทรัพยากรของ SnapOtter --- # Architecture {#architecture} SnapOtter เป็น monorepo ที่จัดการด้วย pnpm workspaces และ Turborepo ปรับใช้เป็นสแตก Docker Compose 3 คอนเทนเนอร์: อิมเมจแอป SnapOtter, PostgreSQL 17 และ Redis 8 ## Project structure {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Packages {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} ไลบรารีประมวลผลรูปภาพหลักที่สร้างบน [Sharp](https://sharp.pixelplumbing.com/) จัดการการดำเนินการที่ไม่ใช่ AI ทั้งหมด: ปรับขนาด, ครอบตัด, หมุน, พลิก, แปลง, บีบอัด, ลบเมทาดาทา และปรับสี (ความสว่าง, ความเปรียบต่าง, ความอิ่มตัว, ขาวดำ, ซีเปีย, กลับสี, ช่องสี) แพ็กเกจนี้ไม่มี dependency ของเครือข่ายและทำงานภายในกระบวนการทั้งหมด ### `@snapotter/ai` {#snapotter-ai} เลเยอร์บริดจ์ที่เรียกเนทีฟและรันไทม์ Python ML เครื่องมือ Python ส่วนใหญ่ใช้ dispatcher แบบถาวรที่นำเข้าไลบรารีขนาดใหญ่ล่วงหน้า (PIL, NumPy, MediaPipe, rembg) ดังนั้นการโทรครั้งต่อไปจะข้ามค่าใช้จ่ายในการนำเข้า OCR ถูกแยกออกจากสภาพแวดล้อมที่ใช้ร่วมกันที่ไม่แน่นอน: `fast` เรียกใช้ Tesseract ดั้งเดิม ในขณะที่ `balanced` และ `best` ใช้ JSONL dispatcher ถาวรโดยเฉพาะที่ปักหมุดไว้กับรุ่น RapidOCR/ONNX ที่ไม่เปลี่ยนรูปแบบที่ใช้งานอยู่ แต่ละคำขอจะมี generation lease การเปิดใช้งานจะรัน smoke test บนตัวเลือกแรก จากนั้นจึงสลับไปที่ dispatcher แบบอะตอมมิก dispatcher รุ่นก่อนหน้าจะระบายออกก่อนที่จะมีการรวบรวมขยะ **โมเดลไม่ได้ถูกโหลดล่วงหน้า** สคริปต์ของแต่ละเครื่องมือโหลดน้ำหนักโมเดลจากดิสก์ ณ เวลาที่ขอ และทิ้งเมื่อคำขอเสร็จสิ้น ดู [Resource footprint](#resource-footprint) สำหรับโปรไฟล์หน่วยความจำทั้งหมด การดำเนินการที่รองรับ: การลบพื้นหลัง (rembg/BiRefNet), การลดขนาด (RealESRGAN), การเบลอใบหน้า (MediaPipe), การปรับปรุงใบหน้า (GFPGAN/CodeFormer), การลบวัตถุ (LaMa ONNX), OCR (Tesseract และ RapidOCR พร้อมรุ่น PP-OCR ONNX), การปรับสี (DDColor), การกำจัดสัญญาณรบกวน, การลบตาแดง, การฟื้นฟูภาพถ่าย, การสร้างภาพถ่ายหนังสือเดินทาง การแก้ไขความโปร่งใส (BiRefNet HR-matting) และการปรับขนาดการรับรู้เนื้อหา (Go caire binary) สคริปต์ Python ใช้งานจริงใน `packages/ai/python/` แพ็กแบบจำลองเสริมขนาดใหญ่ได้รับการติดตั้งตามความต้องการในไดรฟ์ข้อมูล `/data/ai` แบบถาวร OCR ที่แม่นยำใช้สิ่งประดิษฐ์เฉพาะแพลตฟอร์มที่มีการลงนาม ระดับ Tesseract ในตัวไม่จำเป็นต้องดาวน์โหลดแพ็คโมเดล ### `@snapotter/shared` {#snapotter-shared} ประเภท TypeScript ที่ใช้ร่วมกัน, ค่าคงที่ (เช่น `APP_VERSION` และการกำหนดเครื่องมือ) และสตริงการแปล i18n ที่ใช้ทั้งส่วนหน้าและส่วนหลัง ## Applications {#applications} ### API (`apps/api`) {#api-apps-api} เซิร์ฟเวอร์ Fastify v5 ที่เปิดเผยเส้นทางเครื่องมือ 243 เส้นทางครอบคลุมห้ารูปแบบ (image, video, audio, PDF, file) ที่จัดการ: * การอัปโหลดไฟล์, การจัดการพื้นที่ทำงานชั่วคราว และที่จัดเก็บไฟล์แบบถาวร * คลังไฟล์ผู้ใช้ (ตาราง `user_files`): โดยค่าเริ่มต้น การแก้ไขที่บันทึกไว้จะถูกจัดเก็บเป็นไฟล์ใหม่อิสระ หรือเป็นเวอร์ชันที่เชื่อมโยงกับแถวแม่เมื่อคุณเขียนทับไฟล์ต้นฉบับ โดยจะบันทึกว่าใช้เครื่องมือใดบ้าง (`toolChain`) และได้ภาพขนาดย่อที่สร้างอัตโนมัติสำหรับหน้า Files * การเรียกใช้เครื่องมือ (กำหนดเส้นทางคำขอเครื่องมือแต่ละรายการไปยังเอนจินรูปภาพหรือบริดจ์ AI) * การประสานงานไปป์ไลน์ (เชื่อมโยงเครื่องมือหลายตัวตามลำดับ) * การประมวลผลเป็นชุดพร้อมการควบคุมการทำงานพร้อมกันผ่านคิวงาน BullMQ (pool: image, media, ai, docs, system) * การยืนยันตัวตนผู้ใช้, RBAC (บทบาท admin/user พร้อมชุดสิทธิ์เต็ม), การจัดการคีย์ API และการจำกัดอัตรา * การจัดการทีม - CRUD เฉพาะ admin ผู้ใช้ถูกกำหนดให้อยู่ในทีมผ่านฟิลด์ `team` บนโปรไฟล์ของพวกเขา * การตั้งค่ารันไทม์ - ที่จัดเก็บแบบคีย์-ค่าในตาราง `settings` ที่ควบคุม `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` และปุ่มปรับการทำงานอื่น ๆ โดยไม่ต้องปรับใช้ใหม่ * การสร้างแบรนด์กำหนดเองและการตั้งค่ารันไทม์ผ่านการตั้งค่าที่รองรับด้วยฐานข้อมูล * เอกสาร Scalar/OpenAPI ที่ `/api/docs` * การเสิร์ฟส่วนหน้าที่สร้างแล้วเป็น SPA ในการใช้งานจริง Dependency หลัก: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod สำหรับการตรวจสอบ เซิร์ฟเวอร์จัดการการปิดตัวอย่างสง่างามเมื่อได้รับ SIGTERM/SIGINT: มันระบายการเชื่อมต่อ HTTP, หยุด worker ของ BullMQ, ปิด Python dispatcher และปิดการเชื่อมต่อฐานข้อมูล ### Web (`apps/web`) {#web-apps-web} แอปหน้าเดียว React 19 ที่สร้างด้วย Vite ใช้ Zustand สำหรับการจัดการสถานะ, Tailwind CSS v4 สำหรับการจัดสไตล์ และ Lucide สำหรับไอคอน สื่อสารกับ API ผ่าน REST และ SSE (สำหรับการติดตามความคืบหน้า) หน้าต่าง ๆ รวมถึงพื้นที่ทำงานเครื่องมือ, หน้า Files สำหรับจัดการการอัปโหลดและผลลัพธ์แบบถาวร, ตัวสร้างระบบอัตโนมัติ/ไปป์ไลน์ และแผงการตั้งค่าผู้ดูแลระบบ ส่วนหน้าที่สร้างแล้วถูกเสิร์ฟโดยส่วนหลัง Fastify ในการใช้งานจริง จึงไม่มีเว็บเซิร์ฟเวอร์แยกต่างหากในคอนเทนเนอร์ Docker ### Docs (`apps/docs`) {#docs-apps-docs} ไซต์ VitePress นี้ ปรับใช้ไปยัง Cloudflare Pages โดยอัตโนมัติเมื่อ push ไปยัง `main` ## How a request flows {#how-a-request-flows} 1. ผู้ใช้เลือกเครื่องมือใน UI เว็บและอัปโหลดไฟล์ 2. ส่วนหน้าส่ง multipart POST ไปยัง `/api/v1/tools/:section/:toolId` พร้อมไฟล์และการตั้งค่า 3. เส้นทาง API ตรวจสอบอินพุตด้วย Zod จากนั้นส่งต่อการประมวลผล 4. สำหรับเครื่องมือมาตรฐาน งานจะถูกจัดคิวไปยัง BullMQ pool ที่เหมาะสม (image, media หรือ docs ตามรูปแบบ) worker BullMQ ในกระบวนการจะปรับทิศทางภาพอัตโนมัติตามเมทาดาทา EXIF, รันฟังก์ชันการประมวลผลของเครื่องมือ และส่งคืนผลลัพธ์ 5. สำหรับเครื่องมือ AI ส่วนใหญ่ สะพาน TypeScript จะส่งคำขอไปยัง Python dispatcher แบบถาวร Fast OCR จะเรียกใช้ Tesseract แทน และ OCR ที่แม่นยำจะเริ่มต้นการดำเนินการที่ปักหมุดไว้จากรุ่น OCR ที่ไม่เปลี่ยนรูปแบบที่ใช้งานอยู่ ระดับ OCR ที่ร้องขอได้รับการแก้ไขที่ทางเข้าและจะไม่มีการเปลี่ยนแปลงอย่างเงียบๆ ในระหว่างการดำเนินการ 6. ความคืบหน้าของงานจะถูกบันทึกลงในตาราง `jobs` ใน PostgreSQL เพื่อให้สถานะอยู่รอดจากการรีสตาร์ตคอนเทนเนอร์ การอัปเดตแบบเรียลไทม์ถูกส่งผ่าน SSE ที่ `/api/v1/jobs/:jobId/progress` 7. API ส่งคืน `jobId` และ `downloadUrl` ผู้ใช้ดาวน์โหลดไฟล์ที่ประมวลผลแล้วจาก `/api/v1/download/:jobId/:filename` สำหรับไปป์ไลน์ API จะป้อนเอาต์พุตของแต่ละขั้นตอนเป็นอินพุตให้ขั้นตอนถัดไป โดยรันตามลำดับ สำหรับการประมวลผลเป็นชุด API ใช้ BullMQ flow พร้อม child job ต่อขั้นตอน และส่งคืนไฟล์ ZIP พร้อมไฟล์ที่ประมวลผลแล้วทั้งหมด ## Resource footprint {#resource-footprint} SnapOtter ออกแบบมาเพื่อการใช้หน่วยความจำขณะว่างต่ำ ไม่มีสิ่งใดถูกโหลดล่วงหน้าหรืออุ่นไว้ตอนเริ่มต้น ### At idle {#at-idle} กระบวนการ Node.js/Fastify, PostgreSQL และ Redis กำลังทำงาน RAM ขณะว่างโดยทั่วไปอยู่ที่ **~200-300 MB** รวมทั้งสามคอนเทนเนอร์ (กระบวนการ Node.js, Postgres และ Redis) ไม่มีกระบวนการ Python ไม่มีน้ำหนักโมเดลในหน่วยความจำ ### What starts, and when {#what-starts-and-when} | Component | Starts when | Memory while active | |-----------|-------------|---------------------| | เซิร์ฟเวอร์ Fastify + Postgres + Redis | เมื่อคอนเทนเนอร์เริ่ม | ~200-300 MB รวม | | worker BullMQ | เมื่อคอนเทนเนอร์เริ่ม (ในกระบวนการ) | หนึ่ง worker ต่อ pool (image, media, ai, docs, system) | | Python dispatcher | คำขอเครื่องมือ AI ครั้งแรก | ตัวแปล Python + ไลบรารีที่นำเข้าล่วงหน้า (PIL, NumPy, MediaPipe, rembg) - ไม่มีน้ำหนักโมเดล | | น้ำหนักโมเดล AI | ระหว่างคำขอของเครื่องมือนั้น ๆ | โหลดจากดิสก์ ปล่อยเมื่อคำขอเสร็จสิ้น | ### Model loading {#model-loading} ไฟล์น้ำหนักโมเดลทั้งหมด (รวมหลาย GB) อยู่บนดิสก์ใน `/opt/models/` ตลอดเวลา สคริปต์เครื่องมือ AI แต่ละตัวโหลดเฉพาะโมเดลของตัวเองเข้าหน่วยความจำตลอดระยะเวลาของคำขอ แล้วปล่อยออก บางสคริปต์เรียก `del model` และ `torch.cuda.empty_cache()` อย่างชัดเจนหลังการอนุมานเพื่อให้แน่ใจว่าหน่วยความจำถูกคืนทันที ไม่มีแคชโมเดลระหว่างคำขอ การรันเครื่องมือ AI เดียวกันติดต่อกันจะโหลดโมเดลใหม่ทุกครั้ง สิ่งนี้ทำให้หน่วยความจำขณะว่างเข้าใกล้ศูนย์ โดยแลกกับความล่าช้าในการโหลดโมเดลในทุกคำขอ AI ### First AI request cold start {#first-ai-request-cold-start} Python dispatcher ไม่ทำงานเมื่อคอนเทนเนอร์เริ่มต้น คำขอ AI ครั้งแรกกระตุ้นสองสิ่งพร้อมกัน: dispatcher เริ่มอุ่นเครื่องในเบื้องหลัง และคำขอนั้นเองจะย้อนกลับไปสร้าง Python subprocess แบบครั้งเดียว เมื่อ dispatcher ส่งสัญญาณว่าพร้อม คำขอ AI ที่ตามมาทั้งหมดจะใช้มันโดยตรงและข้ามค่าใช้จ่ายในการสร้าง subprocess --- --- url: https://docs.snapotter.com/nl/guide/architecture.md description: >- Monorepo-structuur, app- en package-architectuur, request-levenscyclus en resourcegebruik van SnapOtter. --- # Architectuur {#architecture} SnapOtter is een monorepo beheerd met pnpm-workspaces en Turborepo. Het wordt uitgerold als een Docker Compose-stack met 3 containers: de SnapOtter-app-image, PostgreSQL 17 en Redis 8. ## Projectstructuur {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Packages {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} De kernbibliotheek voor beeldverwerking, gebouwd op [Sharp](https://sharp.pixelplumbing.com/). Deze handelt alle niet-AI-bewerkingen af: vergroten/verkleinen, bijsnijden, roteren, spiegelen, converteren, comprimeren, metadata verwijderen en kleuraanpassingen (helderheid, contrast, verzadiging, grijstinten, sepia, inverteren, kleurkanalen). Dit package heeft geen netwerkafhankelijkheden en draait volledig in-process. ### `@snapotter/ai` {#snapotter-ai} Een bruglaag die native en Python ML runtimes aanroept. De meeste Python-tools gebruiken een persistente dispatcher die zware bibliotheken (PIL, NumPy, MediaPipe, rembg) vooraf importeert, zodat daaropvolgende oproepen de importoverhead overslaan. OCR is geïsoleerd van die veranderlijke gedeelde omgeving: `fast` roept native Tesseract op, terwijl `balanced` en `best` een speciale persistente JSONL dispatcher gebruiken die is vastgemaakt aan de actieve onveranderlijke RapidOCR/ONNX-generatie. Elk verzoek bevat een generation lease. Bij activering wordt eerst een smoke test op een kandidaat uitgevoerd en vervolgens atomair overgeschakeld naar de dispatcher. De eerdere dispatcher loopt leeg voordat het afval wordt opgehaald. **Modellen worden niet vooraf geladen.** Elk toolscript laadt zijn modelgewichten bij het verzoek van schijf en verwijdert ze zodra het verzoek klaar is. Zie [Resourcegebruik](#resource-footprint) voor het volledige geheugenprofiel. Ondersteunde bewerkingen: achtergrondverwijdering (rembg/BiRefNet), opschaling (RealESRGAN), gezichtsvervaging (MediaPipe), gezichtsverbetering (GFPGAN/CodeFormer), object wissen (LaMa ONNX), OCR (Tesseract en RapidOCR met PP-OCR ONNX-modellen), inkleuring (DDColor), ruisverwijdering, verwijdering van rode ogen, fotoherstel, pasfoto generatie, transparantiefixatie (BiRefNet HR-matting) en inhoudsbewust formaat wijzigen (Go caire binary). Python-scripts zijn live in `packages/ai/python/`. Grote optionele modelpakketten worden op aanvraag geïnstalleerd in het permanente `/data/ai`-volume. Nauwkeurige OCR maakt gebruik van ondertekende, platformspecifieke artefacten; Voor de ingebouwde Tesseract-laag is geen download van een modelpakket vereist. ### `@snapotter/shared` {#snapotter-shared} Gedeelde TypeScript-types, constanten (zoals `APP_VERSION` en tooldefinities) en i18n-vertaalstrings die door zowel de frontend als de backend worden gebruikt. ## Applicaties {#applications} ### API (`apps/api`) {#api-apps-api} Een Fastify v5-server die 243 toolroutes over vijf modaliteiten (image, video, audio, PDF, file) blootstelt en het volgende afhandelt: * Bestandsuploads, beheer van tijdelijke werkruimte en persistente bestandsopslag * Gebruikersbibliotheek voor bestanden (`user_files`-tabel): een opgeslagen bewerking wordt standaard opgeslagen als een onafhankelijk nieuw bestand, of als een aan de bovenliggende rij gekoppelde versie wanneer je het origineel overschrijft. Ze registreert welke tools zijn toegepast (`toolChain`) en krijgt een automatisch gegenereerde miniatuur voor de Files-pagina * Tooluitvoering (routeert elk toolverzoek naar de image-engine of AI-brug) * Pijplijnorkestratie (meerdere tools sequentieel aan elkaar koppelen) * Batchverwerking met concurrentiebeheer via BullMQ-taakwachtrijen (pools: image, media, ai, docs, system) * Gebruikersauthenticatie, RBAC (admin/user-rollen met een volledige set permissies), beheer van API-sleutels en rate limiting * Teambeheer - alleen voor admins, CRUD; gebruikers worden aan een team toegewezen via het `team`-veld op hun profiel * Runtime-instellingen - een key-value store in de `settings`-tabel die `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` en andere operationele knoppen aanstuurt zonder opnieuw uit te rollen * Aangepaste branding en runtime-voorkeuren via database-ondersteunde instellingen * Scalar/OpenAPI-documentatie op `/api/docs` * De gebouwde frontend als SPA serveren in productie Belangrijkste dependencies: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod voor validatie. De server handelt een nette afsluiting af bij SIGTERM/SIGINT: hij drainert HTTP-verbindingen, stopt BullMQ-workers, sluit de Python-dispatcher af en sluit de databaseverbinding. ### Web (`apps/web`) {#web-apps-web} Een single-page app in React 19, gebouwd met Vite. Gebruikt Zustand voor statebeheer, Tailwind CSS v4 voor styling en Lucide voor iconen. Communiceert met de API via REST en SSE (voor voortgangsregistratie). Pagina's omvatten een toolwerkruimte, een Files-pagina voor het beheren van persistente uploads en resultaten, een automatiserings-/pijplijnbouwer en een admin-instellingenpaneel. De gebouwde frontend wordt in productie geserveerd door de Fastify-backend, dus er is geen aparte webserver in de Docker-container. ### Docs (`apps/docs`) {#docs-apps-docs} Deze VitePress-site. Wordt automatisch uitgerold naar Cloudflare Pages bij een push naar `main`. ## Hoe een verzoek verloopt {#how-a-request-flows} 1. De gebruiker kiest een tool in de web-UI en uploadt een bestand. 2. De frontend stuurt een multipart POST naar `/api/v1/tools/:section/:toolId` met het bestand en de instellingen. 3. De API-route valideert de invoer met Zod en start vervolgens de verwerking. 4. Voor standaardtools wordt de taak in de juiste BullMQ-pool geplaatst (image, media of docs op basis van modaliteit). De in-process BullMQ-worker oriënteert de afbeelding automatisch op basis van EXIF-metadata, voert de procesfunctie van de tool uit en geeft het resultaat terug. 5. Voor de meeste AI-tools stuurt de TypeScript-bridge een verzoek naar de persistente Python dispatcher. Snelle OCR roept in plaats daarvan Tesseract aan, en nauwkeurige OCR start het vastgezette uitvoerbare bestand vanaf de actieve onveranderlijke OCR-generatie. De aangevraagde OCR-laag wordt vastgesteld bij binnenkomst en wordt tijdens de uitvoering nooit stilzwijgend gewijzigd. 6. Taakvoortgang wordt vastgelegd in de `jobs`-tabel in PostgreSQL, zodat de state herstarts van de container overleeft. Realtime-updates worden geleverd via SSE op `/api/v1/jobs/:jobId/progress`. 7. De API retourneert een `jobId` en `downloadUrl`. De gebruiker downloadt het verwerkte bestand vanaf `/api/v1/download/:jobId/:filename`. Voor pijplijnen voert de API de uitvoer van elke stap als invoer aan de volgende, en draait ze sequentieel. Voor batchverwerking gebruikt de API BullMQ-flows met per-stap onderliggende taken en retourneert een ZIP-bestand met alle verwerkte bestanden. ## Resourcegebruik {#resource-footprint} SnapOtter is ontworpen voor laag geheugengebruik bij inactiviteit. Er wordt bij het opstarten niets vooraf geladen of warm gehouden. ### Bij inactiviteit {#at-idle} Het Node.js/Fastify-proces, PostgreSQL en Redis draaien. Typisch RAM-gebruik bij inactiviteit is **~200-300 MB** verdeeld over alle drie de containers (Node.js-proces, Postgres en Redis). Geen Python-proces, geen modelgewichten in het geheugen. ### Wat er start, en wanneer {#what-starts-and-when} | Component | Start wanneer | Geheugen tijdens actief zijn | |-----------|-------------|---------------------| | Fastify-server + Postgres + Redis | Bij het starten van de container | ~200-300 MB totaal | | BullMQ-workers | Bij het starten van de container (in-process) | Eén worker per pool (image, media, ai, docs, system) | | Python-dispatcher | Bij het eerste AI-toolverzoek | Python-interpreter + vooraf geïmporteerde bibliotheken (PIL, NumPy, MediaPipe, rembg) - geen modelgewichten | | AI-modelgewichten | Tijdens het verzoek van de specifieke tool | Van schijf geladen, vrijgegeven wanneer het verzoek klaar is | ### Modellen laden {#model-loading} Alle modelgewichtbestanden (samen enkele GB) staan te allen tijde op schijf in `/opt/models/`. Elk AI-toolscript laadt alleen zijn eigen model(len) in het geheugen voor de duur van een verzoek en geeft ze daarna vrij. Sommige scripts roepen expliciet `del model` en `torch.cuda.empty_cache()` aan na de inferentie om ervoor te zorgen dat het geheugen onmiddellijk wordt teruggegeven. Er is geen modelcache tussen verzoeken. Dezelfde AI-tool achter elkaar draaien laadt het model telkens opnieuw. Dit houdt het geheugengebruik bij inactiviteit vrijwel op nul, ten koste van een laadvertraging voor het model bij elk AI-verzoek. ### Cold start bij het eerste AI-verzoek {#first-ai-request-cold-start} De Python-dispatcher draait niet wanneer de container start. Het eerste AI-verzoek zet twee dingen parallel in gang: de dispatcher begint op de achtergrond op te warmen, en het verzoek zelf valt terug op het opstarten van een eenmalige Python-subprocess. Zodra de dispatcher aangeeft klaar te zijn, gebruiken alle volgende AI-verzoeken deze rechtstreeks en slaan ze de kosten van het opstarten van een subprocess over. --- --- url: https://docs.snapotter.com/de/guide/architecture.md description: >- Monorepo-Struktur, App- und Paketarchitektur, Request-Lebenszyklus und Ressourcen-Footprint von SnapOtter. --- # Architektur {#architecture} SnapOtter ist ein Monorepo, das mit pnpm-Workspaces und Turborepo verwaltet wird. Es wird als 3-Container-Docker-Compose-Stack ausgeliefert: das SnapOtter-App-Image, PostgreSQL 17 und Redis 8. ## Projektstruktur {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Pakete {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} Die zentrale Bildverarbeitungsbibliothek, aufgebaut auf [Sharp](https://sharp.pixelplumbing.com/). Sie übernimmt alle Nicht-KI-Operationen: Skalieren, Zuschneiden, Drehen, Spiegeln, Konvertieren, Komprimieren, Metadaten entfernen und Farbanpassungen (Helligkeit, Kontrast, Sättigung, Graustufen, Sepia, Invertieren, Farbkanäle). Dieses Paket hat keine Netzwerkabhängigkeiten und läuft vollständig im Prozess. ### `@snapotter/ai` {#snapotter-ai} Eine Brückenschicht, die native und Python ML-Laufzeiten aufruft. Die meisten Python-Tools verwenden ein persistentes dispatcher, das umfangreiche Bibliotheken (PIL, NumPy, MediaPipe, rembg) vorimportiert, sodass nachfolgende Aufrufe den Importaufwand überspringen. OCR ist von dieser veränderlichen gemeinsamen Umgebung isoliert: `fast` ruft natives Tesseract auf, während `balanced` und `best` ein dediziertes persistentes JSONL dispatcher verwenden, das an die aktive unveränderliche RapidOCR/ONNX-Generation angeheftet ist. Jede Anfrage enthält einen generation lease. Bei der Aktivierung wird zunächst ein smoke test für einen Kandidaten ausgeführt und dann atomar zu seinem dispatcher gewechselt. Der vorherige dispatcher wird entleert, bevor seine Generierung in die Speicherbereinigung aufgenommen wird. **Modelle werden nicht vorgeladen.** Jedes Werkzeug-Skript lädt seine Modellgewichte zur Anfragezeit von der Festplatte und verwirft sie, sobald die Anfrage abgeschlossen ist. Siehe [Ressourcen-Footprint](#resource-footprint) für das vollständige Speicherprofil. Unterstützte Vorgänge: Hintergrundentfernung (rembg/BiRefNet), Hochskalierung (RealESRGAN), Gesichtsunschärfe (MediaPipe), Gesichtsverbesserung (GFPGAN/CodeFormer), Objektlöschung (LaMa ONNX), OCR (Tesseract und RapidOCR mit PP-OCR ONNX-Modellen), Kolorierung (DDColor), Rauschentfernung, Rote-Augen-Entfernung, Fotowiederherstellung, Passfoto Generierung, Transparenzkorrektur (BiRefNet HR-Matting) und inhaltsbezogene Größenänderung (Go Caire Binary). Python-Skripte leben in `packages/ai/python/`. Große optionale Modellpakete werden bei Bedarf im persistenten `/data/ai`-Volume installiert. Accurate OCR verwendet signierte, plattformspezifische Artefakte; Für die integrierte Tesseract-Stufe ist kein Download des Modellpakets erforderlich. ### `@snapotter/shared` {#snapotter-shared} Gemeinsam genutzte TypeScript-Typen, Konstanten (wie `APP_VERSION` und Werkzeugdefinitionen) und i18n-Übersetzungsstrings, die sowohl vom Frontend als auch vom Backend verwendet werden. ## Anwendungen {#applications} ### API (`apps/api`) {#api-apps-api} Ein Fastify-v5-Server, der 243 Werkzeug-Routen über fünf Modalitäten (image, video, audio, PDF, file) bereitstellt und Folgendes übernimmt: * Datei-Uploads, Verwaltung des temporären Arbeitsbereichs und persistenter Dateispeicher * Benutzer-Dateibibliothek (`user_files`-Tabelle): Ein gespeicherter Edit wird standardmäßig als eigenständige neue Datei abgelegt, oder als übergeordnet verknüpfte Version, wenn du das Original überschreibst. Sie erfasst, welche Werkzeuge angewendet wurden (`toolChain`), und erhält ein automatisch generiertes Thumbnail für die Files-Seite * Werkzeugausführung (leitet jede Werkzeuganfrage an die Image-Engine oder die KI-Brücke weiter) * Pipeline-Orchestrierung (das sequenzielle Verketten mehrerer Werkzeuge) * Stapelverarbeitung mit Nebenläufigkeitssteuerung über BullMQ-Job-Warteschlangen (Pools: image, media, ai, docs, system) * Benutzerauthentifizierung, RBAC (admin-/user-Rollen mit einem vollständigen Berechtigungssatz), API-Schlüsselverwaltung und Ratenbegrenzung * Teamverwaltung - Admin-only-CRUD; Benutzer werden über das Feld `team` in ihrem Profil einem Team zugewiesen * Laufzeiteinstellungen - ein Schlüssel-Wert-Speicher in der `settings`-Tabelle, der `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` und andere betriebliche Stellschrauben ohne erneutes Deployment steuert * Benutzerdefiniertes Branding und Laufzeiteinstellungen über datenbankgestützte Settings * Scalar-/OpenAPI-Dokumentation unter `/api/docs` * Auslieferung des gebauten Frontends als SPA in der Produktion Wichtige Abhängigkeiten: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod für die Validierung. Der Server behandelt das kontrollierte Herunterfahren bei SIGTERM/SIGINT: Er lässt HTTP-Verbindungen auslaufen, stoppt die BullMQ-Worker, fährt den Python-Dispatcher herunter und schließt die Datenbankverbindung. ### Web (`apps/web`) {#web-apps-web} Eine React-19-Single-Page-App, gebaut mit Vite. Nutzt Zustand für die Zustandsverwaltung, Tailwind CSS v4 für das Styling und Lucide für Icons. Kommuniziert mit der API über REST und SSE (für die Fortschrittsverfolgung). Zu den Seiten gehören ein Werkzeug-Arbeitsbereich, eine Files-Seite zur Verwaltung persistenter Uploads und Ergebnisse, ein Automatisierungs-/Pipeline-Builder und ein Admin-Einstellungspanel. Das gebaute Frontend wird in der Produktion vom Fastify-Backend ausgeliefert, sodass es im Docker-Container keinen separaten Webserver gibt. ### Docs (`apps/docs`) {#docs-apps-docs} Diese VitePress-Site. Wird bei jedem Push auf `main` automatisch auf Cloudflare Pages bereitgestellt. ## Wie eine Anfrage abläuft {#how-a-request-flows} 1. Der Benutzer wählt in der Web-UI ein Werkzeug aus und lädt eine Datei hoch. 2. Das Frontend sendet einen Multipart-POST an `/api/v1/tools/:section/:toolId` mit der Datei und den Einstellungen. 3. Die API-Route validiert die Eingabe mit Zod und stellt dann die Verarbeitung zu. 4. Bei Standardwerkzeugen wird der Job in den passenden BullMQ-Pool eingereiht (image, media oder docs je nach Modalität). Der In-Prozess-BullMQ-Worker richtet das Bild anhand der EXIF-Metadaten automatisch aus, führt die Prozessfunktion des Werkzeugs aus und gibt das Ergebnis zurück. 5. Bei den meisten KI-Tools sendet die TypeScript-Brücke eine Anfrage an den persistenten Python dispatcher. Schnelles OCR ruft stattdessen Tesseract auf, und genaues OCR startet die angeheftete ausführbare Datei aus der aktiven unveränderlichen OCR-Generation. Die angeforderte OCR-Stufe ist beim Eingang festgelegt und wird während der Ausführung nie stillschweigend geändert. 6. Der Job-Fortschritt wird in der `jobs`-Tabelle in PostgreSQL persistiert, sodass der Zustand Container-Neustarts überdauert. Echtzeit-Updates werden über SSE unter `/api/v1/jobs/:jobId/progress` geliefert. 7. Die API gibt ein `jobId` und ein `downloadUrl` zurück. Der Benutzer lädt die verarbeitete Datei von `/api/v1/download/:jobId/:filename` herunter. Bei Pipelines führt die API die Ausgabe jedes Schritts als Eingabe an den nächsten weiter und führt sie sequenziell aus. Bei der Stapelverarbeitung nutzt die API BullMQ-Flows mit Kind-Jobs pro Schritt und gibt eine ZIP-Datei mit allen verarbeiteten Dateien zurück. ## Ressourcen-Footprint {#resource-footprint} SnapOtter ist auf geringen Speicherverbrauch im Leerlauf ausgelegt. Beim Start wird nichts vorgeladen oder warmgehalten. ### Im Leerlauf {#at-idle} Der Node.js-/Fastify-Prozess, PostgreSQL und Redis laufen. Der typische Leerlauf-RAM beträgt **~200-300 MB** über alle drei Container hinweg (Node.js-Prozess, Postgres und Redis). Kein Python-Prozess, keine Modellgewichte im Speicher. ### Was startet, und wann {#what-starts-and-when} | Komponente | Startet bei | Speicher während aktiv | |-----------|-------------|---------------------| | Fastify-Server + Postgres + Redis | Containerstart | ~200-300 MB gesamt | | BullMQ-Worker | Containerstart (im Prozess) | Ein Worker pro Pool (image, media, ai, docs, system) | | Python-Dispatcher | Erste KI-Werkzeuganfrage | Python-Interpreter + vorab importierte Bibliotheken (PIL, NumPy, MediaPipe, rembg) - keine Modellgewichte | | KI-Modellgewichte | Während der Anfrage des jeweiligen Werkzeugs | Von der Festplatte geladen, nach Abschluss der Anfrage freigegeben | ### Modellladen {#model-loading} Alle Modellgewichtsdateien (insgesamt mehrere GB) liegen jederzeit auf der Festplatte in `/opt/models/`. Jedes KI-Werkzeug-Skript lädt nur seine eigenen Modelle für die Dauer einer Anfrage in den Speicher und gibt sie dann frei. Einige Skripte rufen nach der Inferenz explizit `del model` und `torch.cuda.empty_cache()` auf, um sicherzustellen, dass der Speicher sofort zurückgegeben wird. Es gibt keinen Modell-Cache zwischen Anfragen. Führt man dasselbe KI-Werkzeug direkt hintereinander aus, wird das Modell jedes Mal neu geladen. Das hält den Leerlaufspeicher nahe null, auf Kosten einer Modellladeverzögerung bei jeder KI-Anfrage. ### Kaltstart bei der ersten KI-Anfrage {#first-ai-request-cold-start} Der Python-Dispatcher läuft nicht, wenn der Container startet. Die erste KI-Anfrage löst zwei Dinge parallel aus: Der Dispatcher beginnt im Hintergrund aufzuwärmen, und die Anfrage selbst weicht auf einen einmaligen Python-Subprozess-Start aus. Sobald der Dispatcher bereit signalisiert, nutzen alle nachfolgenden KI-Anfragen ihn direkt und sparen sich die Kosten des Subprozess-Starts. --- --- url: https://docs.snapotter.com/pl/guide/architecture.md description: >- Struktura monorepozytorium, architektura aplikacji i pakietów, cykl życia żądania oraz zapotrzebowanie na zasoby w SnapOtter. --- # Architektura {#architecture} SnapOtter jest monorepozytorium zarządzanym za pomocą przestrzeni roboczych pnpm i Turborepo. Wdraża się jako 3-kontenerowy stos Docker Compose: obraz aplikacji SnapOtter, PostgreSQL 17 i Redis 8. ## Struktura projektu {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Pakiety {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} Podstawowa biblioteka przetwarzania obrazów zbudowana na [Sharp](https://sharp.pixelplumbing.com/). Obsługuje wszystkie operacje niezwiązane z AI: zmianę rozmiaru, kadrowanie, obrót, odbicie, konwersję, kompresję, usuwanie metadanych oraz korekty kolorów (jasność, kontrast, nasycenie, skala szarości, sepia, inwersja, kanały kolorów). Ten pakiet nie ma zależności sieciowych i działa w całości w procesie. ### `@snapotter/ai` {#snapotter-ai} Warstwa pomostowa wywołująca środowiska wykonawcze natywne i Python ML. Większość narzędzi Python używa trwałego dispatcher, który wstępnie importuje duże biblioteki (PIL, NumPy, MediaPipe, rembg), więc kolejne wywołania pomijają obciążenie związane z importem. OCR jest izolowany od tego zmiennego środowiska współdzielonego: `fast` wywołuje natywny Tesseract, podczas gdy `balanced` i `best` używają dedykowanego, trwałego JSONL dispatcher przypiętego do aktywnej, niezmiennej generacji RapidOCR/ONNX. Każde żądanie zawiera generation lease. Aktywacja najpierw uruchamia smoke test na kandydacie, a następnie atomowo przełącza się na jego dispatcher. Poprzednie dispatcher drenuje, zanim zostanie wygenerowane, i zostanie usunięte. **Modele nie są wstępnie ładowane.** Każdy skrypt narzędzia ładuje swoje wagi modelu z dysku w momencie żądania i odrzuca je po zakończeniu żądania. Zobacz [Zapotrzebowanie na zasoby](#resource-footprint), aby poznać pełny profil pamięci. Obsługiwane operacje: usuwanie tła (rembg/BiRefNet), skalowanie (RealESRGAN), rozmycie twarzy (MediaPipe), ulepszanie twarzy (GFPGAN/CodeFormer), usuwanie obiektów (LaMa ONNX), OCR (Tesseract i RapidOCR z modelami PP-OCR ONNX), kolorowanie (DDColor), usuwanie szumu, efekt czerwonych oczu usuwanie, przywracanie zdjęć, generowanie zdjęć paszportowych, utrwalanie przezroczystości (matowanie BiRefNet HR) i zmiana rozmiaru z uwzględnieniem zawartości (Go Caire binary). Skrypty Python są dostępne w `packages/ai/python/`. Duże opcjonalne pakiety modeli są instalowane na żądanie w trwałym woluminie `/data/ai`. Dokładny OCR wykorzystuje podpisane artefakty specyficzne dla platformy; wbudowana warstwa Tesseract nie wymaga pobierania pakietu modeli. ### `@snapotter/shared` {#snapotter-shared} Współdzielone typy TypeScript, stałe (takie jak `APP_VERSION` i definicje narzędzi) oraz ciągi tłumaczeń i18n używane zarówno przez frontend, jak i backend. ## Aplikacje {#applications} ### API (`apps/api`) {#api-apps-api} Serwer Fastify v5 udostępniający 243 tras narzędzi w pięciu modalnościach (image, video, audio, PDF, file), który obsługuje: * Przesyłanie plików, zarządzanie tymczasową przestrzenią roboczą oraz trwałe przechowywanie plików * Bibliotekę plików użytkownika (tabela `user_files`): zapisana edycja jest domyślnie przechowywana jako niezależny nowy plik albo jako wersja powiązana z rodzicem, gdy nadpisujesz oryginał. Zapisuje, które narzędzia zostały zastosowane (`toolChain`), i otrzymuje automatycznie generowaną miniaturę dla strony Files * Wykonywanie narzędzi (kieruje każde żądanie narzędzia do silnika obrazów lub mostu AI) * Orkiestrację potoków (sekwencyjne łączenie wielu narzędzi w łańcuch) * Przetwarzanie wsadowe z kontrolą współbieżności za pomocą kolejek zadań BullMQ (pule: image, media, ai, docs, system) * Uwierzytelnianie użytkowników, RBAC (role admin/user z pełnym zestawem uprawnień), zarządzanie kluczami API oraz ograniczanie liczby żądań * Zarządzanie zespołami - CRUD tylko dla administratorów; użytkownicy są przypisywani do zespołu za pomocą pola `team` w swoim profilu * Ustawienia w czasie działania - magazyn klucz-wartość w tabeli `settings`, który steruje `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` i innymi operacyjnymi pokrętłami bez ponownego wdrażania * Niestandardowy branding i preferencje w czasie działania poprzez ustawienia oparte na bazie danych * Dokumentację Scalar/OpenAPI pod adresem `/api/docs` * Serwowanie zbudowanego frontendu jako SPA w środowisku produkcyjnym Kluczowe zależności: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod do walidacji. Serwer obsługuje płynne zamykanie na sygnał SIGTERM/SIGINT: opróżnia połączenia HTTP, zatrzymuje procesy robocze BullMQ, wyłącza dyspozytora Pythona i zamyka połączenie z bazą danych. ### Web (`apps/web`) {#web-apps-web} Jednostronicowa aplikacja React 19 zbudowana za pomocą Vite. Używa Zustand do zarządzania stanem, Tailwind CSS v4 do stylizacji oraz Lucide do ikon. Komunikuje się z API przez REST i SSE (do śledzenia postępu). Strony obejmują przestrzeń roboczą narzędzia, stronę Files do zarządzania trwałymi przesłaniami i wynikami, kreator automatyzacji/potoków oraz panel ustawień administratora. Zbudowany frontend jest serwowany przez backend Fastify w środowisku produkcyjnym, więc w kontenerze Docker nie ma osobnego serwera WWW. ### Docs (`apps/docs`) {#docs-apps-docs} Ta witryna VitePress. Wdrażana automatycznie do Cloudflare Pages przy wypchnięciu do `main`. ## Jak przebiega żądanie {#how-a-request-flows} 1. Użytkownik wybiera narzędzie w interfejsie WWW i przesyła plik. 2. Frontend wysyła wieloczęściowe żądanie POST do `/api/v1/tools/:section/:toolId` z plikiem i ustawieniami. 3. Trasa API waliduje dane wejściowe za pomocą Zod, a następnie rozdziela przetwarzanie. 4. W przypadku standardowych narzędzi zadanie jest kolejkowane do odpowiedniej puli BullMQ (image, media lub docs w zależności od modalności). Proces roboczy BullMQ działający w procesie automatycznie orientuje obraz na podstawie metadanych EXIF, uruchamia funkcję przetwarzającą narzędzia i zwraca wynik. 5. W przypadku większości narzędzi AI most TypeScript wysyła żądanie do trwałego Python dispatcher. Zamiast tego szybki OCR wywołuje Tesseract, a dokładny OCR uruchamia przypięty plik wykonywalny z aktywnej, niezmiennej generacji OCR. Żądany poziom OCR jest ustalany na wejściu i nigdy nie jest zmieniany w trybie cichym podczas wykonywania. 6. Postęp zadania jest utrwalany w tabeli `jobs` w PostgreSQL, więc stan przetrwa ponowne uruchomienia kontenera. Aktualizacje w czasie rzeczywistym są dostarczane przez SSE pod adresem `/api/v1/jobs/:jobId/progress`. 7. API zwraca `jobId` i `downloadUrl`. Użytkownik pobiera przetworzony plik z `/api/v1/download/:jobId/:filename`. W przypadku potoków API podaje wynik każdego kroku jako dane wejściowe do następnego, uruchamiając je sekwencyjnie. W przypadku przetwarzania wsadowego API używa przepływów BullMQ z zadaniami podrzędnymi dla poszczególnych kroków i zwraca plik ZIP ze wszystkimi przetworzonymi plikami. ## Zapotrzebowanie na zasoby {#resource-footprint} SnapOtter został zaprojektowany z myślą o niskim zużyciu pamięci w stanie spoczynku. Nic nie jest wstępnie ładowane ani utrzymywane w gotowości przy starcie. ### W stanie spoczynku {#at-idle} Proces Node.js/Fastify, PostgreSQL i Redis są uruchomione. Typowa pamięć RAM w stanie spoczynku wynosi **~200-300 MB** we wszystkich trzech kontenerach (proces Node.js, Postgres i Redis). Brak procesu Pythona, brak wag modeli w pamięci. ### Co się uruchamia i kiedy {#what-starts-and-when} | Komponent | Uruchamia się, gdy | Pamięć w trakcie działania | |-----------|-------------|---------------------| | Serwer Fastify + Postgres + Redis | Uruchomienie kontenera | ~200-300 MB łącznie | | Procesy robocze BullMQ | Uruchomienie kontenera (w procesie) | Jeden proces roboczy na pulę (image, media, ai, docs, system) | | Dyspozytor Pythona | Pierwsze żądanie narzędzia AI | Interpreter Pythona + wstępnie zaimportowane biblioteki (PIL, NumPy, MediaPipe, rembg) - bez wag modeli | | Wagi modeli AI | W trakcie żądania konkretnego narzędzia | Ładowane z dysku, zwalniane po zakończeniu żądania | ### Ładowanie modeli {#model-loading} Wszystkie pliki wag modeli (łącznie kilka GB) znajdują się na dysku w `/opt/models/` przez cały czas. Każdy skrypt narzędzia AI ładuje do pamięci tylko własne modele na czas trwania żądania, po czym je zwalnia. Niektóre skrypty jawnie wywołują `del model` i `torch.cuda.empty_cache()` po inferencji, aby zapewnić natychmiastowy zwrot pamięci. Między żądaniami nie ma pamięci podręcznej modeli. Uruchamianie tego samego narzędzia AI jedno po drugim ładuje model za każdym razem. Utrzymuje to pamięć w stanie spoczynku bliską zeru kosztem opóźnienia związanego z ładowaniem modelu przy każdym żądaniu AI. ### Zimny start pierwszego żądania AI {#first-ai-request-cold-start} Dyspozytor Pythona nie jest uruchomiony, gdy kontener startuje. Pierwsze żądanie AI wyzwala równolegle dwie rzeczy: dyspozytor zaczyna się rozgrzewać w tle, a samo żądanie awaryjnie korzysta z jednorazowego uruchomienia podprocesu Pythona. Gdy dyspozytor zasygnalizuje gotowość, wszystkie kolejne żądania AI używają go bezpośrednio i pomijają koszt uruchamiania podprocesu. --- --- url: https://docs.snapotter.com/it/guide/architecture.md description: >- Struttura del monorepo, architettura di app e pacchetti, ciclo di vita di una richiesta e impronta sulle risorse di SnapOtter. --- # Architettura {#architecture} SnapOtter è un monorepo gestito con i workspace pnpm e Turborepo. Viene distribuito come stack Docker Compose a 3 container: l'immagine dell'app SnapOtter, PostgreSQL 17 e Redis 8. ## Struttura del progetto {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Pacchetti {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} La libreria core di elaborazione delle immagini costruita su [Sharp](https://sharp.pixelplumbing.com/). Gestisce tutte le operazioni non-AI: ridimensiona, ritaglia, ruota, capovolgi, converti, comprimi, rimuovi i metadati e regola i colori (luminosità, contrasto, saturazione, scala di grigi, seppia, inversione, canali di colore). Questo pacchetto non ha dipendenze di rete e gira interamente in-process. ### `@snapotter/ai` {#snapotter-ai} Un livello bridge che chiama runtime nativi e Python ML. La maggior parte degli strumenti Python utilizzano un dispatcher persistente che preimporta librerie pesanti (PIL, NumPy, MediaPipe, rembg) in modo che le chiamate successive saltino il sovraccarico dell'importazione. OCR è isolato da quell'ambiente condiviso mutevole: `fast` richiama Tesseract nativo, mentre `balanced` e `best` utilizzano un JSONL dispatcher persistente dedicato aggiunto alla generazione attiva immutabile RapidOCR/ONNX. Ogni richiesta contiene un generation lease. L'attivazione esegue prima un smoke test su un candidato, quindi passa atomicamente al suo dispatcher. Il precedente dispatcher viene scaricato prima che la sua generazione venga sottoposta a garbage collection. **I modelli non sono precaricati.** Ogni script dello strumento carica i pesi del proprio modello dal disco al momento della richiesta e li scarta quando la richiesta termina. Consulta [Impronta sulle risorse](#resource-footprint) per il profilo di memoria completo. Operazioni supportate: rimozione dello sfondo (rembg/BiRefNet), upscaling (RealESRGAN), sfocatura del volto (MediaPipe), miglioramento del volto (GFPGAN/CodeFormer), cancellazione degli oggetti (LaMa ONNX), OCR (Tesseract e RapidOCR con modelli PP-OCR ONNX), colorazione (DDColor), rimozione del rumore, rimozione degli occhi rossi, restauro di foto, foto tessera generazione, correzione della trasparenza (BiRefNet HR-matting) e ridimensionamento in base al contenuto (Go caire binario). Gli script Python risiedono in `packages/ai/python/`. I pacchetti di modelli opzionali di grandi dimensioni vengono installati su richiesta nel volume `/data/ai` persistente. OCR accurato utilizza artefatti firmati specifici della piattaforma; il livello Tesseract integrato non richiede il download del pacchetto di modelli. ### `@snapotter/shared` {#snapotter-shared} Tipi TypeScript condivisi, costanti (come `APP_VERSION` e le definizioni degli strumenti) e stringhe di traduzione i18n usate sia dal frontend sia dal backend. ## Applicazioni {#applications} ### API (`apps/api`) {#api-apps-api} Un server Fastify v5 che espone 243 route di strumenti su cinque modalità (immagine, video, audio, PDF, file) e gestisce: * Upload di file, gestione dello spazio di lavoro temporaneo e archiviazione persistente dei file * Libreria di file utente (tabella `user_files`): per impostazione predefinita, una modifica salvata viene archiviata come nuovo file indipendente, oppure come versione collegata al genitore quando sovrascrivi l'originale. Registra quali strumenti sono stati applicati (`toolChain`) e ottiene una miniatura auto-generata per la pagina File * Esecuzione degli strumenti (instrada ogni richiesta di strumento all'image engine o all'AI bridge) * Orchestrazione delle pipeline (concatenamento sequenziale di più strumenti) * Elaborazione in batch con controllo della concorrenza tramite le code di lavori BullMQ (pool: image, media, ai, docs, system) * Autenticazione utente, RBAC (ruoli admin/user con un set completo di permessi), gestione delle chiavi API e rate limiting * Gestione dei team - CRUD solo per admin; gli utenti vengono assegnati a un team tramite il campo `team` sul loro profilo * Impostazioni di runtime - un archivio chiave-valore nella tabella `settings` che controlla `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` e altre manopole operative senza ridistribuire * Branding personalizzato e preferenze di runtime tramite impostazioni supportate dal database * Documentazione Scalar/OpenAPI su `/api/docs` * Servire il frontend compilato come SPA in produzione Dipendenze principali: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod per la validazione. Il server gestisce lo spegnimento controllato su SIGTERM/SIGINT: drena le connessioni HTTP, ferma i worker BullMQ, spegne il dispatcher Python e chiude la connessione al database. ### Web (`apps/web`) {#web-apps-web} Una single-page app React 19 costruita con Vite. Usa Zustand per la gestione dello stato, Tailwind CSS v4 per lo stile e Lucide per le icone. Comunica con l'API tramite REST e SSE (per il tracciamento dell'avanzamento). Le pagine includono uno spazio di lavoro per gli strumenti, una pagina File per gestire upload e risultati persistenti, un costruttore di automazione/pipeline e un pannello di impostazioni admin. Il frontend compilato viene servito dal backend Fastify in produzione, quindi non c'è un server web separato nel container Docker. ### Docs (`apps/docs`) {#docs-apps-docs} Questo sito VitePress. Distribuito su Cloudflare Pages automaticamente al push su `main`. ## Come scorre una richiesta {#how-a-request-flows} 1. L'utente sceglie uno strumento nell'interfaccia web e carica un file. 2. Il frontend invia un POST multipart a `/api/v1/tools/:section/:toolId` con il file e le impostazioni. 3. La route API valida l'input con Zod, poi avvia l'elaborazione. 4. Per gli strumenti standard, il lavoro viene accodato al pool BullMQ appropriato (image, media o docs in base alla modalità). Il worker BullMQ in-process orienta automaticamente l'immagine in base ai metadati EXIF, esegue la funzione di elaborazione dello strumento e restituisce il risultato. 5. Per la maggior parte degli strumenti IA, il bridge TypeScript invia una richiesta al persistente Python dispatcher. OCR veloce richiama invece Tesseract e OCR accurato avvia l'eseguibile bloccato dalla generazione OCR immutabile attiva. Il livello OCR richiesto è fisso in ingresso e non viene mai modificato automaticamente durante l'esecuzione. 6. L'avanzamento del lavoro viene persistito nella tabella `jobs` in PostgreSQL così che lo stato sopravviva ai riavvii del container. Gli aggiornamenti in tempo reale vengono consegnati via SSE su `/api/v1/jobs/:jobId/progress`. 7. L'API restituisce un `jobId` e un `downloadUrl`. L'utente scarica il file elaborato da `/api/v1/download/:jobId/:filename`. Per le pipeline, l'API passa l'output di ogni passaggio come input al successivo, eseguendoli in sequenza. Per l'elaborazione in batch, l'API usa i flow BullMQ con lavori figlio per ogni passaggio e restituisce un file ZIP con tutti i file elaborati. ## Impronta sulle risorse {#resource-footprint} SnapOtter è progettato per un basso utilizzo di memoria a riposo. Nulla viene precaricato o tenuto caldo all'avvio. ### A riposo {#at-idle} Il processo Node.js/Fastify, PostgreSQL e Redis sono in esecuzione. La RAM tipica a riposo è di **~200-300 MB** tra tutti e tre i container (processo Node.js, Postgres e Redis). Nessun processo Python, nessun peso di modello in memoria. ### Cosa si avvia, e quando {#what-starts-and-when} | Componente | Si avvia quando | Memoria mentre è attivo | |-----------|-------------|---------------------| | Server Fastify + Postgres + Redis | Avvio del container | ~200-300 MB in totale | | Worker BullMQ | Avvio del container (in-process) | Un worker per pool (image, media, ai, docs, system) | | Dispatcher Python | Prima richiesta di uno strumento AI | Interprete Python + librerie pre-importate (PIL, NumPy, MediaPipe, rembg) - nessun peso di modello | | Pesi dei modelli AI | Durante la richiesta dello specifico strumento | Caricati dal disco, liberati al termine della richiesta | ### Caricamento dei modelli {#model-loading} Tutti i file dei pesi dei modelli (per un totale di diversi GB) risiedono sul disco in `/opt/models/` in ogni momento. Ogni script dello strumento AI carica in memoria solo il proprio modello o i propri modelli per la durata di una richiesta, poi li rilascia. Alcuni script chiamano esplicitamente `del model` e `torch.cuda.empty_cache()` dopo l'inferenza per assicurarsi che la memoria venga restituita immediatamente. Non esiste una cache dei modelli tra le richieste. Eseguire lo stesso strumento AI in successione ricarica il modello ogni volta. Questo mantiene la memoria a riposo prossima allo zero al costo di un ritardo di caricamento del modello a ogni richiesta AI. ### Cold start della prima richiesta AI {#first-ai-request-cold-start} Il dispatcher Python non è in esecuzione all'avvio del container. La prima richiesta AI innesca due cose in parallelo: il dispatcher inizia a scaldarsi in background e la richiesta stessa ripiega sull'avvio una tantum di un sottoprocesso Python. Una volta che il dispatcher segnala di essere pronto, tutte le richieste AI successive lo usano direttamente e saltano il costo di avvio del sottoprocesso. --- --- url: https://docs.snapotter.com/tr/tools/image/background-replace.md description: AI kullanarak görsel arka planını düz bir renk veya gradyanla değiştirin. --- # Arka Plan Değiştirme {#background-replace} Bir görselin arka planını düz bir renk veya gradyanla değiştirin. AI modeli özneyi algılar, özgün arka planı kaldırır ve özneyi seçtiğiniz arka plan üzerine yerleştirir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/background-replace` Bir görsel dosyası ve bir JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | backgroundType | dize | Hayır | `"color"` | Arka plan modu: `color` veya `gradient` | | color | dize | Hayır | `"#ffffff"` | Arka plan onaltılık rengi (backgroundType `color` olduğunda) | | gradientColor1 | dize | Hayır | - | Birinci gradyan onaltılık rengi | | gradientColor2 | dize | Hayır | - | İkinci gradyan onaltılık rengi | | gradientAngle | tam sayı | Hayır | `180` | Derece cinsinden gradyan açısı (0-360) | | feather | tam sayı | Hayır | `0` | Kenar yumuşatma yarıçapı (0-20) | | format | dize | Hayır | `"png"` | Çıktı biçimi: `png` veya `webp` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` İlerlemeyi SSE üzerinden `GET /api/v1/jobs/{jobId}/progress` adresinden takip edin. İş tamamlandığında, SSE akışı indirme URL'sini içeren bir `completed` olayı yayar. ## Notlar {#notes} * Bu, `202 Accepted` döndüren ve eşzamansız işleyen AI destekli bir araçtır. İlerleme güncellemelerini ve nihai sonucu almak için SSE uç noktasına bağlanın. * **background-removal** özellik paketinin yüklü olmasını gerektirir. Paket mevcut değilse `501` döndürür. * HEIC, RAW, PSD ve SVG girişleri işlenmeden önce otomatik olarak çözülür. * Öznenin çevresindeki saydamlığı korumak için çıktı varsayılan olarak PNG'dir. --- --- url: https://docs.snapotter.com/tr/tools/image/blur-background.md description: AI kullanarak özneyi keskin tutarken arka planı bulanıklaştırın. --- # Arka Planı Bulanıklaştır {#blur-background} Bir görselin arka planını, özneyi keskin tutarken bulanıklaştırın. AI modeli özneyi ayırır, özgün arka plana bir bulanıklık uygular ve keskin özneyi üzerine yerleştirir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/blur-background` Bir görsel dosyası ve bir JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | intensity | tam sayı | Hayır | `50` | Bulanıklık yoğunluğu (1-100) | | feather | tam sayı | Hayır | `0` | Kenar yumuşatma yarıçapı (0-20) | | format | dize | Hayır | `"png"` | Çıktı biçimi: `png` veya `webp` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` İlerlemeyi SSE üzerinden `GET /api/v1/jobs/{jobId}/progress` adresinden takip edin. İş tamamlandığında, SSE akışı indirme URL'sini içeren bir `completed` olayı yayar. ## Notlar {#notes} * Bu, `202 Accepted` döndüren ve eşzamansız işleyen AI destekli bir araçtır. İlerleme güncellemelerini ve nihai sonucu almak için SSE uç noktasına bağlanın. * **background-removal** özellik paketinin yüklü olmasını gerektirir. Paket mevcut değilse `501` döndürür. * Daha yüksek yoğunluk değerleri daha güçlü bir bulanıklık efekti üretir. 80'in üzerindeki değerler belirgin, bokeh benzeri bir ayrım oluşturur. * HEIC, RAW, PSD ve SVG girişleri işlenmeden önce otomatik olarak çözülür. --- --- url: https://docs.snapotter.com/tr/tools/image/remove-background.md description: >- İsteğe bağlı efektlerle (bulanıklık, gölge, gradyan, özel arka plan) yapay zeka destekli arka plan kaldırma. --- # Arka Planı Kaldır {#remove-background} İsteğe bağlı efektlerle (bulanıklık, gölge, gradyan, özel arka plan) yapay zeka destekli arka plan kaldırma. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/remove-background` **İşleme:** Eşzamansız (202 döndürür, durum için SSE aracılığıyla `/api/v1/jobs/{jobId}/progress` sorgulayın) **Model paketi:** `background-removal` (4-5 GB) ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | file | Evet | - | Görsel dosyası (çok parçalı) | | model | string | Hayır | - | Kullanılacak yapay zeka model çeşidi | | backgroundType | string | Hayır | `"transparent"` | Şunlardan biri: `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | Hayır | - | Düz arka plan için hex rengi | | gradientColor1 | string | Hayır | - | Birinci gradyan rengi | | gradientColor2 | string | Hayır | - | İkinci gradyan rengi | | gradientAngle | number | Hayır | - | Derece cinsinden gradyan açısı | | blurEnabled | boolean | Hayır | - | Arka plan bulanıklık efektini etkinleştir | | blurIntensity | number | Hayır | - | Bulanıklık yoğunluğu (0-100) | | shadowEnabled | boolean | Hayır | - | Özne üzerinde açılır gölgeyi etkinleştir | | shadowOpacity | number | Hayır | - | Gölge opaklığı (0-100) | | outputFormat | string | Hayır | - | Çıktı biçimi: `png`, `webp` veya `avif` | | edgeRefine | integer | Hayır | - | Kenar iyileştirme seviyesi (0-3) | | decontaminate | boolean | Hayır | - | Kenarlardan renk taşmasını kaldır | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType":"transparent","edgeRefine":2,"outputFormat":"png"}' ``` ## Yanıt {#response} ### İlk Yanıt (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### İlerleme (`/api/v1/jobs/{jobId}/progress` konumunda SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing background...","percent":50} ``` ### Nihai Sonuç (SSE aracılığıyla) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_mask.png", "maskUrl": "/api/v1/download/{jobId}/photo_mask.png", "originalUrl": "/api/v1/download/{jobId}/photo_original.png", "originalSize": 245000, "processedSize": 180000, "filename": "photo.jpg", "model": "rembg" } } ``` ## Efektler Uç Noktası (Aşama 2) {#effects-endpoint-phase-2} `POST /api/v1/tools/image/remove-background/effects` Yapay zeka modelini yeniden çalıştırmadan arka plan efektlerini yeniden uygular. Aşama 1'den önbelleğe alınmış maskeyi ve orijinali kullanır. ### Parametreler {#parameters-1} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | settings | JSON | Evet | - | Efekt ayarlarını içeren JSON (aşağıya bakın) | | backgroundImage | file | Hayır | - | Özel arka plan görseli (backgroundType `image` olduğunda) | #### Ayarlar JSON alanları {#settings-json-fields} | Alan | Tür | Zorunlu | Açıklama | |-------|------|----------|-------------| | jobId | string | Evet | Aşama 1'den iş kimliği | | filename | string | Evet | Aşama 1'den orijinal dosya adı | | backgroundType | string | Hayır | `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | Hayır | Düz arka plan için hex rengi | | gradientColor1 | string | Hayır | Birinci gradyan rengi | | gradientColor2 | string | Hayır | İkinci gradyan rengi | | gradientAngle | number | Hayır | Derece cinsinden gradyan açısı | | blurEnabled | boolean | Hayır | Arka plan bulanıklığını etkinleştir | | blurIntensity | number | Hayır | Bulanıklık yoğunluğu (0-100) | | shadowEnabled | boolean | Hayır | Açılır gölgeyi etkinleştir | | shadowOpacity | number | Hayır | Gölge opaklığı (0-100) | | outputFormat | string | Hayır | `png`, `webp` veya `avif` | ### Örnek İstek {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background/effects \ -F 'settings={"jobId":"a1b2c3d4-...","filename":"photo.jpg","backgroundType":"color","backgroundColor":"#FF5500","outputFormat":"png"}' ``` ### Yanıt (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_nobg.png", "processedSize": 195000 } ``` ## Notlar {#notes} * `background-removal` model paketinin kurulu olmasını gerektirir (4-5 GB). * Aşama 1, saydam maskeyi ve orijinal görseli önbelleğe alır; böylece Aşama 2 (efektler) yapay zeka modelini yeniden çalıştırmadan farklı arka planları anında yeniden uygulayabilir. * HEIC/HEIF, RAW, TGA, PSD, EXR ve HDR girdi biçimlerini otomatik çözme yoluyla destekler. * EXIF döndürmesi işlemden önce otomatik olarak düzeltilir. --- --- url: https://docs.snapotter.com/sv/guide/architecture.md description: >- Monorepo-struktur, app- och paketarkitektur, förfrågningslivscykel och resursavtryck för SnapOtter. --- # Arkitektur {#architecture} SnapOtter är ett monorepo som hanteras med pnpm workspaces och Turborepo. Det distribueras som en Docker Compose-stack med 3 containrar: SnapOtter-appavbildningen, PostgreSQL 17 och Redis 8. ## Projektstruktur {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Paket {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} Kärnbiblioteket för bildbehandling byggt på [Sharp](https://sharp.pixelplumbing.com/). Det hanterar alla icke-AI-operationer: storleksändring, beskärning, rotation, spegling, konvertering, komprimering, borttagning av metadata och färgjusteringar (ljusstyrka, kontrast, mättnad, gråskala, sepia, invertering, färgkanaler). Detta paket har inga nätverksberoenden och körs helt in-process. ### `@snapotter/ai` {#snapotter-ai} Ett brygglager som anropar native och Python ML körtider. De flesta Python-verktyg använder en beständig dispatcher som förimporterar tunga bibliotek (PIL, NumPy, MediaPipe, rembg) så att efterföljande anrop hoppar över importkostnader. OCR är isolerad från den föränderliga delade miljön: `fast` anropar inbyggd Tesseract, medan `balanced` och `best` använder en dedikerad beständig JSONL dispatcher som är fäst vid den aktiva oföränderliga RapidOCR/ONNX-generationen. Varje begäran innehåller en generation lease. Aktivering kör först en smoke test på en kandidat och växlar sedan atomärt till dess dispatcher. Den tidigare dispatcher dräneras innan den genereras sopsamlas. **Modeller är inte förinlästa.** Varje verktygsskript laddar sina modellvikter från disk vid förfrågningstillfället och kasserar dem när förfrågan är klar. Se [Resursavtryck](#resource-footprint) för den fullständiga minnesprofilen. Operationer som stöds: bakgrundsborttagning (rembg/BiRefNet), uppskalning (RealESRGAN), ansiktsoskärpa (MediaPipe), ansiktsförbättring (GFPGAN/CodeFormer), objektradering (LaMa ONNX), OCR (Tesseract och RapidOCR med PP-OCR ONNX-modeller), färgläggning (DDColor), bullerborttagning, borttagning av röda ögon, foto restaurering, generering av passfoto, transparensfixering (BiRefNet HR-matta), och innehållsmedveten storleksändring (Go caire binär). Python-skript live i `packages/ai/python/`. Stora valfria modellpaket installeras på begäran i den ihållande `/data/ai`-volymen. Exakt OCR använder signerade, plattformsspecifika artefakter; den inbyggda Tesseract-nivån kräver ingen nedladdning av modellpaket. ### `@snapotter/shared` {#snapotter-shared} Delade TypeScript-typer, konstanter (som `APP_VERSION` och verktygsdefinitioner) och i18n-översättningssträngar som används av både frontend och backend. ## Applikationer {#applications} ### API (`apps/api`) {#api-apps-api} En Fastify v5-server som exponerar 243 verktygsrutter över fem modaliteter (image, video, audio, PDF, file) och som hanterar: * Filuppladdningar, hantering av tillfällig arbetsyta och beständig fillagring * Användarens filbibliotek (`user_files`-tabellen): en sparad ändring lagras som standard som en oberoende ny fil, eller som en förälderlänkad version när du skriver över originalet. Det registrerar vilka verktyg som tillämpades (`toolChain`) och får en autogenererad miniatyrbild för Files-sidan * Verktygsexekvering (dirigerar varje verktygsförfrågan till bildmotorn eller AI-bryggan) * Pipeline-orkestrering (kedjar samman flera verktyg sekventiellt) * Batchbearbetning med samtidighetskontroll via BullMQ-jobbköer (pooler: image, media, ai, docs, system) * Användarautentisering, RBAC (admin/user-roller med en fullständig behörighetsuppsättning), hantering av API-nycklar och hastighetsbegränsning * Teamhantering - endast admin-CRUD; användare tilldelas ett team via `team`-fältet på sin profil * Körtidsinställningar - ett nyckel-värde-lager i `settings`-tabellen som styr `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` och andra driftsrattar utan att distribuera om * Anpassad varumärkesprofilering och körtidsinställningar via databasbaserade inställningar * Scalar/OpenAPI-dokumentation på `/api/docs` * Serverar den byggda frontenden som en SPA i produktion Viktiga beroenden: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod för validering. Servern hanterar smidig avstängning vid SIGTERM/SIGINT: den dränerar HTTP-anslutningar, stoppar BullMQ-workers, stänger av Python-dispatchern och stänger databasanslutningen. ### Web (`apps/web`) {#web-apps-web} En React 19 single-page-app byggd med Vite. Använder Zustand för tillståndshantering, Tailwind CSS v4 för styling och Lucide för ikoner. Kommunicerar med API:et över REST och SSE (för förloppsspårning). Sidorna inkluderar en verktygsarbetsyta, en Files-sida för hantering av beständiga uppladdningar och resultat, en automatisering/pipelinebyggare och en admininställningspanel. Den byggda frontenden serveras av Fastify-backenden i produktion, så det finns ingen separat webbserver i Docker-containern. ### Docs (`apps/docs`) {#docs-apps-docs} Denna VitePress-webbplats. Distribueras automatiskt till Cloudflare Pages vid push till `main`. ## Hur en förfrågan flödar {#how-a-request-flows} 1. Användaren väljer ett verktyg i webbgränssnittet och laddar upp en fil. 2. Frontenden skickar en multipart-POST till `/api/v1/tools/:section/:toolId` med filen och inställningarna. 3. API-rutten validerar indata med Zod och dirigerar sedan bearbetningen. 4. För standardverktyg köas jobbet till lämplig BullMQ-pool (image, media eller docs baserat på modalitet). Den in-process-körda BullMQ-workern orienterar bilden automatiskt baserat på EXIF-metadata, kör verktygets bearbetningsfunktion och returnerar resultatet. 5. För de flesta AI-verktyg skickar TypeScript-bryggan en begäran till den beständiga Python dispatcher. Snabb OCR anropar istället Tesseract, och exakt OCR startar den fästa körbara filen från den aktiva oföränderliga OCR-generationen. Den begärda OCR-nivån är fixerad vid inträde och ändras aldrig tyst under exekvering. 6. Jobbförlopp bevaras i `jobs`-tabellen i PostgreSQL så att tillståndet överlever containeromstarter. Realtidsuppdateringar levereras via SSE på `/api/v1/jobs/:jobId/progress`. 7. API:et returnerar en `jobId` och `downloadUrl`. Användaren laddar ner den bearbetade filen från `/api/v1/download/:jobId/:filename`. För pipelines matar API:et utdata från varje steg som indata till nästa och kör dem sekventiellt. För batchbearbetning använder API:et BullMQ-flöden med underjobb per steg och returnerar en ZIP-fil med alla bearbetade filer. ## Resursavtryck {#resource-footprint} SnapOtter är utformat för låg minnesanvändning i viloläge. Ingenting förinläses eller hålls varmt vid start. ### I viloläge {#at-idle} Node.js/Fastify-processen, PostgreSQL och Redis körs. Typiskt vilo-RAM är **~200-300 MB** över alla tre containrar (Node.js-processen, Postgres och Redis). Ingen Python-process, inga modellvikter i minnet. ### Vad som startar, och när {#what-starts-and-when} | Komponent | Startar när | Minne medan aktiv | |-----------|-------------|---------------------| | Fastify-server + Postgres + Redis | Containerstart | ~200-300 MB totalt | | BullMQ-workers | Containerstart (in-process) | En worker per pool (image, media, ai, docs, system) | | Python-dispatcher | Första AI-verktygsförfrågan | Python-tolk + förimporterade bibliotek (PIL, NumPy, MediaPipe, rembg) - inga modellvikter | | AI-modellvikter | Under det specifika verktygets förfrågan | Laddade från disk, frigjorda när förfrågan är klar | ### Modellinläsning {#model-loading} Alla modellviktsfiler (totalt flera GB) ligger på disk i `/opt/models/` hela tiden. Varje AI-verktygsskript laddar endast sin egen modell(er) i minnet under en förfrågans varaktighet och frigör dem sedan. Vissa skript anropar uttryckligen `del model` och `torch.cuda.empty_cache()` efter inferens för att säkerställa att minne returneras omedelbart. Det finns ingen modellcache mellan förfrågningar. Att köra samma AI-verktyg direkt efter varandra laddar om modellen varje gång. Detta håller vilominnet nära noll till priset av en modellinläsningsfördröjning vid varje AI-förfrågan. ### Kallstart vid första AI-förfrågan {#first-ai-request-cold-start} Python-dispatchern körs inte när containern startar. Den första AI-förfrågan utlöser två saker parallellt: dispatchern börjar värmas upp i bakgrunden, och själva förfrågan faller tillbaka på en engångsskapad Python-subprocess. När dispatchern signalerar redo använder alla efterföljande AI-förfrågningar den direkt och hoppar över kostnaden för subprocess-skapande. --- --- url: https://docs.snapotter.com/pl/tools/image/sprite-sheet.md description: Połącz wiele obrazów w jedną siatkę arkusza sprite'ów z metadanymi klatek. --- # Arkusz sprite'ów {#sprite-sheet} Połącz wiele obrazów w jedną siatkę arkusza sprite'ów. Każdy obraz jest skalowany, aby dopasować się do wymiarów pierwszego obrazu, i umieszczany w siatce. Zwraca obraz arkusza sprite'ów wraz z metadanymi współrzędnych dla każdej klatki. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/sprite-sheet` Przyjmuje dane formularza multipart z dwoma lub więcej plikami obrazów i polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | columns | integer | Nie | `4` | Liczba kolumn w siatce (1-16) | | padding | integer | Nie | `0` | Odstęp między komórkami w pikselach (0-64) | | background | string | Nie | `"#ffffff"` | Kolor tła w formacie hex | | format | string | Nie | `"png"` | Format wyjściowy: `png`, `webp` lub `jpeg` | | quality | integer | Nie | `90` | Jakość wyjściowa (1-100) | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sprite-sheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@frame1.png" \ -F "file=@frame2.png" \ -F "file=@frame3.png" \ -F "file=@frame4.png" \ -F 'settings={"columns": 2, "padding": 4, "format": "png"}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sprite-sheet.png", "originalSize": 120000, "processedSize": 95000, "frames": [ { "index": 0, "left": 0, "top": 0, "width": 128, "height": 128 }, { "index": 1, "left": 132, "top": 0, "width": 128, "height": 128 }, { "index": 2, "left": 0, "top": 132, "width": 128, "height": 128 }, { "index": 3, "left": 132, "top": 132, "width": 128, "height": 128 } ], "cols": 2, "rows": 2, "cellWidth": 128, "cellHeight": 128, "canvasWidth": 260, "canvasHeight": 260 } ``` ## Uwagi {#notes} * Przyjmuje od 2 do 64 obrazów. Wszystkie obrazy są skalowane, aby dopasować się do wymiarów pierwszego przesłanego obrazu. * Tablica `frames` podaje dokładne współrzędne pikselowe każdej klatki w wyniku, odpowiednie do definicji sprite'ów CSS lub map klatek silników gier. * Liczba wierszy jest obliczana automatycznie na podstawie liczby obrazów i wartości `columns`. * Użyj parametru `padding`, aby dodać odstęp między komórkami. Kolor `background` jest widoczny w obszarach odstępów oraz we wszelkich pustych końcowych komórkach. * Dane wejściowe HEIC, RAW, PSD i SVG są automatycznie dekodowane przed przetwarzaniem. --- --- url: https://docs.snapotter.com/es/guide/architecture.md description: >- Estructura del monorepo, arquitectura de aplicaciones y paquetes, ciclo de vida de las solicitudes y huella de recursos de SnapOtter. --- # Arquitectura {#architecture} SnapOtter es un monorepo gestionado con espacios de trabajo de pnpm y Turborepo. Se despliega como una pila de Docker Compose de 3 contenedores: la imagen de la app de SnapOtter, PostgreSQL 17 y Redis 8. ## Estructura del proyecto {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Paquetes {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} La biblioteca principal de procesamiento de imágenes construida sobre [Sharp](https://sharp.pixelplumbing.com/). Gestiona todas las operaciones que no son de IA: redimensionar, recortar, rotar, voltear, convertir, comprimir, eliminar metadatos y ajustes de color (brillo, contraste, saturación, escala de grises, sepia, invertir, canales de color). Este paquete no tiene dependencias de red y se ejecuta enteramente en el proceso. ### `@snapotter/ai` {#snapotter-ai} Una capa puente que llama a los tiempos de ejecución nativos y Python ML. La mayoría de las herramientas Python utilizan un dispatcher persistente que preimporta bibliotecas pesadas (PIL, NumPy, MediaPipe, rembg) para que las llamadas posteriores omitan la sobrecarga de importación. OCR está aislado de ese entorno compartido mutable: `fast` invoca Tesseract nativo, mientras que `balanced` y `best` utilizan un JSONL dispatcher persistente dedicado anclado a la generación activa e inmutable RapidOCR/ONNX. Cada solicitud contiene un generation lease. La activación primero ejecuta un smoke test en un candidato y luego cambia atómicamente a su dispatcher. Los drenajes dispatcher anteriores antes de su generación se recolectan como basura. **Los modelos no se precargan.** Cada script de herramienta carga sus pesos de modelo desde el disco en el momento de la solicitud y los descarta cuando la solicitud finaliza. Consulta [Huella de recursos](#resource-footprint) para ver el perfil de memoria completo. Operaciones soportadas: eliminación de fondo (rembg/BiRefNet), ampliación (RealESRGAN), desenfoque de cara (MediaPipe), mejora facial (GFPGAN/CodeFormer), borrado de objetos (LaMa ONNX), OCR (Tesseract y RapidOCR con modelos PP-OCR ONNX), coloración (DDColor), eliminación de ruido, eliminación de ojos rojos, restauración de fotografías, generación de fotos de pasaporte, fijación de transparencias (estera BiRefNet HR), y cambio de tamaño según el contenido (Go caire binario). Los scripts Python viven en `packages/ai/python/`. Se instalan grandes paquetes de modelos opcionales según demanda en el volumen persistente `/data/ai`. Accurate OCR utiliza artefactos firmados y específicos de la plataforma; el nivel Tesseract integrado no requiere la descarga del paquete de modelos. ### `@snapotter/shared` {#snapotter-shared} Tipos de TypeScript compartidos, constantes (como `APP_VERSION` y definiciones de herramientas) y cadenas de traducción i18n usadas tanto por el frontend como por el backend. ## Aplicaciones {#applications} ### API (`apps/api`) {#api-apps-api} Un servidor Fastify v5 que expone 243 rutas de herramientas en cinco modalidades (imagen, vídeo, audio, PDF, archivo) y que gestiona: * Subidas de archivos, gestión del espacio de trabajo temporal y almacenamiento persistente de archivos * Biblioteca de archivos de usuario (tabla `user_files`): una edición guardada se almacena de forma predeterminada como un nuevo archivo independiente, o como una versión enlazada a su padre cuando sobrescribes el original. Registra qué herramientas se aplicaron (`toolChain`) y obtiene una miniatura autogenerada para la página de Archivos * Ejecución de herramientas (dirige cada solicitud de herramienta al motor de imágenes o al puente de IA) * Orquestación de canalizaciones (encadenado de varias herramientas de forma secuencial) * Procesamiento por lotes con control de concurrencia mediante colas de tareas de BullMQ (pools: image, media, ai, docs, system) * Autenticación de usuarios, RBAC (roles de administrador/usuario con un conjunto completo de permisos), gestión de claves de API y limitación de tasa * Gestión de equipos - CRUD solo para administradores; los usuarios se asignan a un equipo mediante el campo `team` en su perfil * Ajustes de tiempo de ejecución - un almacén de clave-valor en la tabla `settings` que controla `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` y otras palancas operativas sin necesidad de redesplegar * Personalización de marca y preferencias de tiempo de ejecución mediante ajustes respaldados por la base de datos * Documentación Scalar/OpenAPI en `/api/docs` * Servir el frontend compilado como una SPA en producción Dependencias clave: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod para la validación. El servidor gestiona un apagado ordenado ante SIGTERM/SIGINT: drena las conexiones HTTP, detiene los workers de BullMQ, apaga el despachador de Python y cierra la conexión a la base de datos. ### Web (`apps/web`) {#web-apps-web} Una aplicación de página única de React 19 construida con Vite. Usa Zustand para la gestión de estado, Tailwind CSS v4 para el estilo y Lucide para los iconos. Se comunica con la API a través de REST y SSE (para el seguimiento del progreso). Las páginas incluyen un espacio de trabajo de herramientas, una página de Archivos para gestionar subidas y resultados persistentes, un constructor de automatización/canalizaciones y un panel de ajustes de administrador. El frontend compilado lo sirve el backend de Fastify en producción, por lo que no hay un servidor web separado en el contenedor de Docker. ### Docs (`apps/docs`) {#docs-apps-docs} Este sitio de VitePress. Se despliega en Cloudflare Pages automáticamente al hacer push a `main`. ## Cómo fluye una solicitud {#how-a-request-flows} 1. El usuario elige una herramienta en la interfaz web y sube un archivo. 2. El frontend envía un POST multiparte a `/api/v1/tools/:section/:toolId` con el archivo y los ajustes. 3. La ruta de la API valida la entrada con Zod y luego despacha el procesamiento. 4. Para las herramientas estándar, la tarea se encola en el pool de BullMQ adecuado (image, media o docs según la modalidad). El worker de BullMQ en el proceso autoorienta la imagen según los metadatos EXIF, ejecuta la función de procesamiento de la herramienta y devuelve el resultado. 5. Para la mayoría de las herramientas de IA, el puente TypeScript envía una solicitud al Python dispatcher persistente. En cambio, el OCR rápido invoca a Tesseract, y el OCR preciso inicia el ejecutable anclado desde la generación OCR activa e inmutable. El nivel OCR solicitado se fija en el ingreso y nunca se cambia silenciosamente durante la ejecución. 6. El progreso de la tarea se persiste en la tabla `jobs` de PostgreSQL para que el estado sobreviva a los reinicios del contenedor. Las actualizaciones en tiempo real se entregan mediante SSE en `/api/v1/jobs/:jobId/progress`. 7. La API devuelve un `jobId` y un `downloadUrl`. El usuario descarga el archivo procesado desde `/api/v1/download/:jobId/:filename`. Para las canalizaciones, la API alimenta la salida de cada paso como entrada del siguiente, ejecutándolos de forma secuencial. Para el procesamiento por lotes, la API usa flujos de BullMQ con tareas hijas por paso y devuelve un archivo ZIP con todos los archivos procesados. ## Huella de recursos {#resource-footprint} SnapOtter está diseñado para un bajo uso de memoria en reposo. Nada se precarga ni se mantiene en caliente al arrancar. ### En reposo {#at-idle} El proceso de Node.js/Fastify, PostgreSQL y Redis están en ejecución. La RAM típica en reposo es de **~200-300 MB** entre los tres contenedores (proceso de Node.js, Postgres y Redis). Sin proceso de Python, sin pesos de modelo en memoria. ### Qué se inicia, y cuándo {#what-starts-and-when} | Componente | Se inicia cuando | Memoria mientras está activo | |-----------|-------------|---------------------| | Servidor Fastify + Postgres + Redis | Arranque del contenedor | ~200-300 MB en total | | Workers de BullMQ | Arranque del contenedor (en el proceso) | Un worker por pool (image, media, ai, docs, system) | | Despachador de Python | Primera solicitud de herramienta de IA | Intérprete de Python + bibliotecas preimportadas (PIL, NumPy, MediaPipe, rembg) - sin pesos de modelo | | Pesos de modelos de IA | Durante la solicitud de la herramienta específica | Cargados desde el disco, liberados cuando la solicitud finaliza | ### Carga de modelos {#model-loading} Todos los archivos de pesos de los modelos (que suman varios GB) residen en el disco en `/opt/models/` en todo momento. Cada script de herramienta de IA carga en memoria solo su propio modelo (o modelos) durante la duración de una solicitud y luego los libera. Algunos scripts llaman explícitamente a `del model` y `torch.cuda.empty_cache()` tras la inferencia para asegurar que la memoria se devuelve de inmediato. No hay caché de modelos entre solicitudes. Ejecutar la misma herramienta de IA de forma consecutiva recarga el modelo cada vez. Esto mantiene la memoria en reposo cercana a cero a costa de un retraso de carga de modelo en cada solicitud de IA. ### Arranque en frío de la primera solicitud de IA {#first-ai-request-cold-start} El despachador de Python no está en ejecución cuando el contenedor arranca. La primera solicitud de IA desencadena dos cosas en paralelo: el despachador empieza a calentarse en segundo plano y la propia solicitud recurre al lanzamiento puntual de un subproceso de Python. Una vez que el despachador señala que está listo, todas las solicitudes de IA posteriores lo usan directamente y omiten el coste de lanzar el subproceso. --- --- url: https://docs.snapotter.com/pt-BR/guide/architecture.md description: >- Estrutura do monorepo, arquitetura de apps e pacotes, ciclo de vida das requisições e uso de recursos do SnapOtter. --- # Arquitetura {#architecture} O SnapOtter é um monorepo gerenciado com pnpm workspaces e Turborepo. Ele é implantado como uma pilha Docker Compose de 3 contêineres: a imagem do app SnapOtter, o PostgreSQL 17 e o Redis 8. ## Estrutura do projeto {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Pacotes {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} A biblioteca principal de processamento de imagem construída sobre o [Sharp](https://sharp.pixelplumbing.com/). Ela lida com todas as operações que não são de IA: redimensionar, recortar, girar, espelhar, converter, comprimir, remover metadados e ajustes de cor (brilho, contraste, saturação, escala de cinza, sépia, inversão, canais de cor). Este pacote não tem dependências de rede e roda inteiramente em processo. ### `@snapotter/ai` {#snapotter-ai} Uma camada de ponte que chama tempos de execução nativos e Python ML. A maioria das ferramentas Python usa um dispatcher persistente que pré-importa bibliotecas pesadas (PIL, NumPy, MediaPipe, rembg) para que as chamadas subsequentes ignorem a sobrecarga de importação. OCR é isolado desse ambiente compartilhado mutável: `fast` invoca Tesseract nativo, enquanto `balanced` e `best` usam um JSONL dispatcher persistente dedicado fixado na geração RapidOCR/ONNX ativa e imutável. Cada solicitação contém um generation lease. A ativação primeiro executa um smoke test em um candidato e depois alterna atomicamente para seu dispatcher. O dispatcher anterior é drenado antes que sua geração seja coletada como lixo. **Os modelos não são pré-carregados.** Cada script de ferramenta carrega os pesos do seu modelo do disco no momento da requisição e os descarta quando a requisição termina. Consulte [Uso de recursos](#resource-footprint) para o perfil de memória completo. Operações suportadas: remoção de fundo (rembg/BiRefNet), upscaling (RealESRGAN), desfoque de rosto (MediaPipe), aprimoramento de rosto (GFPGAN/CodeFormer), apagamento de objeto (LaMa ONNX), OCR (Tesseract e RapidOCR com modelos PP-OCR ONNX), colorização (DDColor), remoção de ruído, remoção de olhos vermelhos, restauração de fotos, foto de passaporte geração, correção de transparência (BiRefNet HR-matting) e redimensionamento com reconhecimento de conteúdo (Go caire binário). Os scripts Python residem em `packages/ai/python/`. Grandes pacotes de modelos opcionais são instalados sob demanda no volume `/data/ai` persistente. O OCR preciso usa artefatos assinados e específicos da plataforma; a camada Tesseract integrada não requer download de pacote de modelo. ### `@snapotter/shared` {#snapotter-shared} Tipos TypeScript compartilhados, constantes (como `APP_VERSION` e as definições de ferramentas) e strings de tradução i18n usadas tanto pelo frontend quanto pelo backend. ## Aplicações {#applications} ### API (`apps/api`) {#api-apps-api} Um servidor Fastify v5 que expõe 243 rotas de ferramentas em cinco modalidades (image, video, audio, PDF, file) e lida com: * Uploads de arquivos, gerenciamento de espaço de trabalho temporário e armazenamento persistente de arquivos * Biblioteca de arquivos do usuário (tabela `user_files`): uma edição salva é armazenada por padrão como um novo arquivo independente, ou como uma versão vinculada ao pai quando você sobrescreve o original. Ela registra quais ferramentas foram aplicadas (`toolChain`) e recebe uma miniatura gerada automaticamente para a página Files * Execução de ferramentas (roteia cada requisição de ferramenta para o motor de imagem ou para a ponte de IA) * Orquestração de pipelines (encadeamento de várias ferramentas em sequência) * Processamento em lote com controle de concorrência via filas de jobs do BullMQ (pools: image, media, ai, docs, system) * Autenticação de usuários, RBAC (funções admin/user com um conjunto completo de permissões), gerenciamento de chaves de API e limitação de taxa * Gerenciamento de equipes - CRUD apenas para admin; os usuários são atribuídos a uma equipe por meio do campo `team` no seu perfil * Configurações de runtime - um armazenamento chave-valor na tabela `settings` que controla `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit` e outros parâmetros operacionais sem reimplantar * Marca personalizada e preferências de runtime por meio de configurações respaldadas pelo banco de dados * Documentação Scalar/OpenAPI em `/api/docs` * Serviço do frontend compilado como uma SPA em produção Dependências principais: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod para validação. O servidor lida com o encerramento gracioso em SIGTERM/SIGINT: ele drena as conexões HTTP, para os workers do BullMQ, desliga o dispatcher Python e fecha a conexão com o banco de dados. ### Web (`apps/web`) {#web-apps-web} Um app de página única em React 19 construído com Vite. Usa Zustand para gerenciamento de estado, Tailwind CSS v4 para estilização e Lucide para ícones. Comunica-se com a API por REST e SSE (para acompanhamento de progresso). As páginas incluem um espaço de trabalho de ferramentas, uma página Files para gerenciar uploads e resultados persistentes, um construtor de automação/pipelines e um painel de configurações de admin. O frontend compilado é servido pelo backend Fastify em produção, portanto não há um servidor web separado no contêiner Docker. ### Docs (`apps/docs`) {#docs-apps-docs} Este site VitePress. Implantado no Cloudflare Pages automaticamente a cada push para `main`. ## Como uma requisição flui {#how-a-request-flows} 1. O usuário escolhe uma ferramenta na interface web e envia um arquivo. 2. O frontend envia um POST multipart para `/api/v1/tools/:section/:toolId` com o arquivo e as configurações. 3. A rota da API valida a entrada com o Zod e depois despacha o processamento. 4. Para ferramentas padrão, o job é enfileirado no pool BullMQ apropriado (image, media ou docs, conforme a modalidade). O worker BullMQ em processo orienta automaticamente a imagem com base nos metadados EXIF, executa a função de processamento da ferramenta e retorna o resultado. 5. Para a maioria das ferramentas de IA, a ponte TypeScript envia uma solicitação ao Python dispatcher persistente. Em vez disso, o OCR rápido invoca Tesseract, e o OCR preciso inicia o executável fixado a partir da geração OCR imutável ativa. A camada OCR solicitada é fixada na entrada e nunca é alterada silenciosamente durante a execução. 6. O progresso do job é persistido na tabela `jobs` no PostgreSQL, de modo que o estado sobrevive a reinícios do contêiner. As atualizações em tempo real são entregues via SSE em `/api/v1/jobs/:jobId/progress`. 7. A API retorna um `jobId` e um `downloadUrl`. O usuário baixa o arquivo processado de `/api/v1/download/:jobId/:filename`. Para pipelines, a API alimenta a saída de cada etapa como entrada da próxima, executando-as em sequência. Para o processamento em lote, a API usa flows do BullMQ com jobs filhos por etapa e retorna um arquivo ZIP com todos os arquivos processados. ## Uso de recursos {#resource-footprint} O SnapOtter foi projetado para baixo uso de memória em repouso. Nada é pré-carregado ou mantido aquecido na inicialização. ### Em repouso {#at-idle} O processo Node.js/Fastify, o PostgreSQL e o Redis estão em execução. A RAM típica em repouso é de **cerca de 200 a 300 MB** entre os três contêineres (processo Node.js, Postgres e Redis). Sem processo Python, sem pesos de modelo na memória. ### O que inicia, e quando {#what-starts-and-when} | Componente | Inicia quando | Memória enquanto ativo | |-----------|-------------|---------------------| | Servidor Fastify + Postgres + Redis | Início do contêiner | ~200-300 MB no total | | Workers do BullMQ | Início do contêiner (em processo) | Um worker por pool (image, media, ai, docs, system) | | Dispatcher Python | Primeira requisição de ferramenta de IA | Interpretador Python + bibliotecas pré-importadas (PIL, NumPy, MediaPipe, rembg) - sem pesos de modelo | | Pesos de modelo de IA | Durante a requisição da ferramenta específica | Carregados do disco, liberados quando a requisição termina | ### Carregamento de modelos {#model-loading} Todos os arquivos de pesos de modelo (somando vários GB) ficam no disco em `/opt/models/` o tempo todo. Cada script de ferramenta de IA carrega na memória apenas o(s) seu(s) próprio(s) modelo(s) durante uma requisição e depois os libera. Alguns scripts chamam explicitamente `del model` e `torch.cuda.empty_cache()` após a inferência para garantir que a memória seja devolvida imediatamente. Não há cache de modelo entre requisições. Executar a mesma ferramenta de IA em sequência recarrega o modelo a cada vez. Isso mantém a memória em repouso próxima de zero, ao custo de um atraso de carregamento do modelo em cada requisição de IA. ### Cold start da primeira requisição de IA {#first-ai-request-cold-start} O dispatcher Python não está em execução quando o contêiner inicia. A primeira requisição de IA dispara duas coisas em paralelo: o dispatcher começa a aquecer em segundo plano e a própria requisição recorre a gerar um subprocesso Python único e avulso. Assim que o dispatcher sinaliza que está pronto, todas as requisições de IA subsequentes o usam diretamente e evitam o custo de gerar subprocessos. --- --- url: https://docs.snapotter.com/id/guide/architecture.md description: >- Struktur monorepo, arsitektur aplikasi dan paket, siklus hidup permintaan, dan jejak sumber daya SnapOtter. --- # Arsitektur {#architecture} SnapOtter adalah monorepo yang dikelola dengan workspace pnpm dan Turborepo. Ia di-deploy sebagai stack Docker Compose 3 kontainer: image aplikasi SnapOtter, PostgreSQL 17, dan Redis 8. ## Struktur proyek {#project-structure} ``` snapotter/ ├── apps/ │ ├── api/ # Fastify backend │ ├── web/ # React + Vite frontend │ └── docs/ # This VitePress site ├── packages/ │ ├── image-engine/ # Sharp-based image operations │ ├── media-engine/ # FFmpeg spawn + progress parsing │ ├── doc-engine/ # qpdf, LibreOffice, ghostscript wrappers │ ├── ai/ # Python AI model bridge │ └── shared/ # Types, constants, i18n └── docker/ # Dockerfile and Compose config ``` ## Paket {#packages} ### `@snapotter/image-engine` {#snapotter-image-engine} Pustaka pemrosesan gambar inti yang dibangun di atas [Sharp](https://sharp.pixelplumbing.com/). Ia menangani semua operasi non-AI: resize, crop, rotate, flip, convert, compress, strip metadata, dan penyesuaian warna (kecerahan, kontras, saturasi, grayscale, sepia, invert, saluran warna). Paket ini tidak memiliki dependensi jaringan dan berjalan sepenuhnya dalam proses. ### `@snapotter/ai` {#snapotter-ai} Lapisan jembatan yang memanggil runtime asli dan Python ML. Sebagian besar alat Python menggunakan dispatcher persisten yang melakukan pra-impor pustaka berat (PIL, NumPy, MediaPipe, rembg) sehingga panggilan berikutnya melewati overhead impor. OCR diisolasi dari lingkungan bersama yang dapat diubah: `fast` memanggil Tesseract asli, sementara `balanced` dan `best` menggunakan JSONL dispatcher persisten khusus yang disematkan pada generasi RapidOCR/ONNX aktif yang tidak dapat diubah. Setiap permintaan memiliki generation lease. Aktivasi pertama-tama menjalankan smoke test pada kandidat, kemudian beralih secara atom ke dispatcher-nya. Saluran air dispatcher sebelumnya sebelum pembangkitannya dikumpulkan sampahnya. **Model tidak dimuat terlebih dahulu.** Setiap skrip tool memuat bobot modelnya dari disk pada waktu permintaan dan membuangnya saat permintaan selesai. Lihat [Jejak sumber daya](#resource-footprint) untuk profil memori lengkap. Operasi yang didukung: penghapusan latar belakang (rembg/BiRefNet), peningkatan (RealESRGAN), keburaman wajah (MediaPipe), penyempurnaan wajah (GFPGAN/CodeFormer), penghapusan objek (LaMa ONNX), OCR (Tesseract dan RapidOCR dengan model PP-OCR ONNX), pewarnaan (DDColor), penghilangan noise, penghilangan mata merah, restorasi foto, pembuatan foto paspor, perbaikan transparansi (BiRefNet HR-matting), dan pengubahan ukuran berdasarkan konten (Go caire biner). Skrip Python ada di `packages/ai/python/`. Paket model opsional berukuran besar dipasang sesuai permintaan ke dalam volume `/data/ai` yang persisten. OCR yang akurat menggunakan artefak khusus platform yang ditandatangani; tingkat Tesseract bawaan tidak memerlukan pengunduhan paket model. ### `@snapotter/shared` {#snapotter-shared} Tipe TypeScript bersama, konstanta (seperti `APP_VERSION` dan definisi tool), dan string terjemahan i18n yang digunakan oleh frontend dan backend. ## Aplikasi {#applications} ### API (`apps/api`) {#api-apps-api} Server Fastify v5 yang mengekspos 243 route tool di lima modalitas (image, video, audio, PDF, file) yang menangani: * Unggahan file, manajemen workspace sementara, dan penyimpanan file persisten * Pustaka file pengguna (tabel `user_files`): secara default, sebuah editan yang disimpan disimpan sebagai file baru yang independen, atau sebagai versi yang tertaut ke induk ketika Anda menimpa file asli. Ia mencatat tool mana yang diterapkan (`toolChain`) dan mendapatkan thumbnail yang dibuat otomatis untuk halaman Files * Eksekusi tool (mengarahkan setiap permintaan tool ke image engine atau AI bridge) * Orkestrasi pipeline (merangkai beberapa tool secara berurutan) * Pemrosesan batch dengan kontrol konkurensi melalui antrean job BullMQ (pool: image, media, ai, docs, system) * Autentikasi pengguna, RBAC (peran admin/user dengan set izin lengkap), manajemen kunci API, dan pembatasan laju * Manajemen Teams - CRUD hanya-admin; pengguna ditugaskan ke sebuah tim melalui field `team` di profil mereka * Pengaturan runtime - penyimpanan key-value di tabel `settings` yang mengontrol `disabledTools`, `enableExperimentalTools`, `loginAttemptLimit`, dan tombol operasional lainnya tanpa deploy ulang * Branding kustom dan preferensi runtime melalui pengaturan yang didukung basis data * Dokumentasi Scalar/OpenAPI di `/api/docs` * Menyajikan frontend yang telah dibangun sebagai SPA dalam produksi Dependensi utama: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, BullMQ, ioredis, Zod untuk validasi. Server menangani penghentian yang mulus pada SIGTERM/SIGINT: ia menguras koneksi HTTP, menghentikan worker BullMQ, mematikan dispatcher Python, dan menutup koneksi basis data. ### Web (`apps/web`) {#web-apps-web} Aplikasi single-page React 19 yang dibangun dengan Vite. Menggunakan Zustand untuk manajemen state, Tailwind CSS v4 untuk penataan, dan Lucide untuk ikon. Berkomunikasi dengan API melalui REST dan SSE (untuk pelacakan progres). Halaman mencakup workspace tool, halaman Files untuk mengelola unggahan dan hasil persisten, pembuat automasi/pipeline, dan panel pengaturan admin. Frontend yang telah dibangun disajikan oleh backend Fastify dalam produksi, jadi tidak ada server web terpisah di kontainer Docker. ### Docs (`apps/docs`) {#docs-apps-docs} Situs VitePress ini. Di-deploy ke Cloudflare Pages secara otomatis saat push ke `main`. ## Bagaimana sebuah permintaan mengalir {#how-a-request-flows} 1. Pengguna memilih sebuah tool di UI web dan mengunggah file. 2. Frontend mengirim POST multipart ke `/api/v1/tools/:section/:toolId` dengan file dan pengaturan. 3. Route API memvalidasi input dengan Zod, lalu mengirim pemrosesan. 4. Untuk tool standar, job dimasukkan ke antrean ke pool BullMQ yang sesuai (image, media, atau docs berdasarkan modalitas). Worker BullMQ dalam proses secara otomatis mengorientasikan gambar berdasarkan metadata EXIF, menjalankan fungsi proses tool, dan mengembalikan hasilnya. 5. Untuk sebagian besar alat AI, jembatan TypeScript mengirimkan permintaan ke Python dispatcher yang persisten. OCR yang cepat malah memanggil Tesseract, dan OCR yang akurat memulai eksekusi yang disematkan dari generasi OCR aktif yang tidak dapat diubah. Tingkat OCR yang diminta ditetapkan saat masuk dan tidak pernah diubah secara diam-diam selama eksekusi. 6. Progres job dipertahankan ke tabel `jobs` di PostgreSQL sehingga state bertahan saat kontainer dimulai ulang. Pembaruan waktu nyata dikirimkan melalui SSE di `/api/v1/jobs/:jobId/progress`. 7. API mengembalikan `jobId` dan `downloadUrl`. Pengguna mengunduh file yang telah diproses dari `/api/v1/download/:jobId/:filename`. Untuk pipeline, API memberi output setiap langkah sebagai input ke langkah berikutnya, menjalankannya secara berurutan. Untuk pemrosesan batch, API menggunakan flow BullMQ dengan child job per langkah dan mengembalikan file ZIP berisi semua file yang diproses. ## Jejak sumber daya {#resource-footprint} SnapOtter dirancang untuk penggunaan memori idle yang rendah. Tidak ada yang dimuat terlebih dahulu atau dijaga tetap hangat saat startup. ### Saat idle {#at-idle} Proses Node.js/Fastify, PostgreSQL, dan Redis berjalan. RAM idle tipikal adalah **~200-300 MB** di ketiga kontainer (proses Node.js, Postgres, dan Redis). Tidak ada proses Python, tidak ada bobot model di memori. ### Apa yang mulai, dan kapan {#what-starts-and-when} | Komponen | Mulai saat | Memori saat aktif | |-----------|-------------|---------------------| | Server Fastify + Postgres + Redis | Kontainer mulai | ~200-300 MB total | | Worker BullMQ | Kontainer mulai (dalam proses) | Satu worker per pool (image, media, ai, docs, system) | | Dispatcher Python | Permintaan tool AI pertama | Interpreter Python + pustaka yang diimpor terlebih dahulu (PIL, NumPy, MediaPipe, rembg) - tanpa bobot model | | Bobot model AI | Selama permintaan tool spesifik | Dimuat dari disk, dibebaskan saat permintaan selesai | ### Pemuatan model {#model-loading} Semua file bobot model (berjumlah beberapa GB) berada di disk di `/opt/models/` setiap saat. Setiap skrip tool AI hanya memuat model miliknya sendiri ke memori selama durasi permintaan, lalu melepaskannya. Beberapa skrip secara eksplisit memanggil `del model` dan `torch.cuda.empty_cache()` setelah inferensi untuk memastikan memori segera dikembalikan. Tidak ada cache model antar permintaan. Menjalankan tool AI yang sama berturut-turut memuat ulang model setiap kali. Ini menjaga memori idle mendekati nol dengan biaya penundaan pemuatan model pada setiap permintaan AI. ### Cold start permintaan AI pertama {#first-ai-request-cold-start} Dispatcher Python tidak berjalan saat kontainer dimulai. Permintaan AI pertama memicu dua hal secara paralel: dispatcher mulai memanas di latar belakang, dan permintaan itu sendiri mundur ke pemunculan subproses Python sekali pakai. Setelah dispatcher menandakan siap, semua permintaan AI berikutnya menggunakannya secara langsung dan melewati biaya pemunculan subproses. --- --- url: https://docs.snapotter.com/ar/tools/video/aspect-pad.md description: إضافة أشرطة بلون خالص لملاءمة نسبة أبعاد مستهدفة. --- # Aspect Pad {#aspect-pad} أضف أشرطة letterbox أو pillarbox بلون خالص لملاءمة مقطع فيديو ضمن نسبة أبعاد مستهدفة دون اقتصاص. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` يقبل بيانات نموذج multipart تحتوي على ملف فيديو وحقل `settings` بصيغة JSON. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | نسبة الأبعاد المستهدفة: `16:9` أو `9:16` أو `1:1` أو `4:3` أو `3:4` | | color | string | No | `"#000000"` | لون سداسي عشري لأشرطة الحشو (مثل `"#000000"` للأسود) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * إذا كان الفيديو يطابق بالفعل نسبة الأبعاد المستهدفة، يُعاد الملف دون تغيير. * استخدم `9:16` لصيغ وسائل التواصل الاجتماعي العمودية/الطولية (TikTok وReels وShorts). * للحشو المموّه بدلاً من اللون الخالص، استخدم أداة Blur Pad. --- --- url: https://docs.snapotter.com/hi/tools/video/aspect-pad.md description: लक्षित आस्पेक्ट रेशियो में फिट करने के लिए ठोस-रंग की पट्टियां जोड़ें। --- # Aspect Pad {#aspect-pad} बिना क्रॉप किए किसी वीडियो को एक लक्षित आस्पेक्ट रेशियो में फिट करने के लिए ठोस-रंग की लेटरबॉक्स या पिलरबॉक्स पट्टियां जोड़ें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | लक्षित आस्पेक्ट रेशियो: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | No | `"#000000"` | पैडिंग पट्टियों के लिए हेक्स रंग (उदा. काले के लिए `"#000000"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * यदि वीडियो पहले से ही लक्षित आस्पेक्ट रेशियो से मेल खाता है, तो फ़ाइल अपरिवर्तित लौटाई जाती है। * वर्टिकल/पोर्ट्रेट सोशल मीडिया फ़ॉर्मेट (TikTok, Reels, Shorts) के लिए `9:16` का उपयोग करें। * ठोस रंग के बजाय धुंधली पैडिंग के लिए, Blur Pad टूल का उपयोग करें। --- --- url: https://docs.snapotter.com/id/tools/video/aspect-pad.md description: Tambahkan bilah berwarna solid agar pas dengan rasio aspek target. --- # Aspect Pad {#aspect-pad} Tambahkan bilah letterbox atau pillarbox berwarna solid agar video pas dengan rasio aspek target tanpa memotong. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Menerima data form multipart berisi file video dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | Rasio aspek target: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | No | `"#000000"` | Warna hex untuk bilah padding (mis. `"#000000"` untuk hitam) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Jika video sudah cocok dengan rasio aspek target, file dikembalikan tanpa perubahan. * Gunakan `9:16` untuk format media sosial vertikal/potret (TikTok, Reels, Shorts). * Untuk padding buram alih-alih warna solid, gunakan alat Blur Pad. --- --- url: https://docs.snapotter.com/ja/tools/video/aspect-pad.md description: 目標のアスペクト比に合わせるため単色のバーを追加します。 --- # Aspect Pad {#aspect-pad} 単色のレターボックスまたはピラーボックスのバーを追加し、切り抜くことなく動画を目標のアスペクト比に合わせます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | 目標のアスペクト比: `16:9`、`9:16`、`1:1`、`4:3`、`3:4` | | color | string | No | `"#000000"` | パディングバーの Hex カラー(黒の場合は例として `"#000000"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * 動画がすでに目標のアスペクト比に一致している場合、ファイルは変更されずに返されます。 * 縦型・ポートレートのソーシャルメディア形式(TikTok、Reels、Shorts)には `9:16` を使用してください。 * 単色ではなくぼかしパディングにする場合は、Blur Pad ツールを使用してください。 --- --- url: https://docs.snapotter.com/ko/tools/video/aspect-pad.md description: 목표 화면비에 맞추기 위해 단색 막대를 추가합니다. --- # Aspect Pad {#aspect-pad} 크롭 없이 비디오를 목표 화면비에 맞추기 위해 단색 레터박스 또는 필러박스 막대를 추가합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` 비디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | 목표 화면비: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | No | `"#000000"` | 패딩 막대의 16진수 색상(예: 검은색은 `"#000000"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * 비디오가 이미 목표 화면비와 일치하면 파일이 변경 없이 반환됩니다. * 세로/인물 모드 소셜 미디어 형식(TikTok, Reels, Shorts)에는 `9:16`을(를) 사용하세요. * 단색 대신 흐림 패딩을 원하면 Blur Pad 도구를 사용하세요. --- --- url: https://docs.snapotter.com/nl/tools/video/aspect-pad.md description: Voeg balken in een effen kleur toe om aan een doelbeeldverhouding te voldoen. --- # Aspect Pad {#aspect-pad} Voeg letterbox- of pillarbox-balken in een effen kleur toe om een video in een doelbeeldverhouding te passen zonder bij te snijden. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Accepteert multipart-formuliergegevens met een videobestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | target | string | Nee | `"9:16"` | Doelbeeldverhouding: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | Nee | `"#000000"` | Hex-kleur voor de opvulbalken (bijv. `"#000000"` voor zwart) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Als de video al overeenkomt met de doelbeeldverhouding, wordt het bestand ongewijzigd teruggegeven. * Gebruik `9:16` voor verticale/portret-socialmedia-indelingen (TikTok, Reels, Shorts). * Gebruik voor vervaagde opvulling in plaats van een effen kleur het hulpmiddel Blur Pad. --- --- url: https://docs.snapotter.com/pl/tools/video/aspect-pad.md description: Dodaj jednolite kolorowe pasy, aby dopasować do docelowych proporcji obrazu. --- # Aspect Pad {#aspect-pad} Dodaj jednolite kolorowe pasy typu letterbox lub pillarbox, aby dopasować film do docelowych proporcji obrazu bez przycinania. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Przyjmuje dane formularza multipart z plikiem wideo oraz polem JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | Docelowe proporcje obrazu: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | No | `"#000000"` | Kolor szesnastkowy pasów wypełnienia (np. `"#000000"` dla czerni) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Jeśli film już odpowiada docelowym proporcjom obrazu, plik jest zwracany bez zmian. * Użyj `9:16` dla pionowych/portretowych formatów mediów społecznościowych (TikTok, Reels, Shorts). * Aby uzyskać rozmyte wypełnienie zamiast jednolitego koloru, użyj narzędzia Blur Pad. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/aspect-pad.md description: Adicione barras de cor sólida para se ajustar a uma proporção alvo. --- # Aspect Pad {#aspect-pad} Adicione barras letterbox ou pillarbox de cor sólida para ajustar um vídeo a uma proporção alvo sem recortar. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | target | string | Não | `"9:16"` | Proporção alvo: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | Não | `"#000000"` | Cor hexadecimal para as barras de preenchimento (por exemplo `"#000000"` para preto) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Se o vídeo já corresponder à proporção alvo, o arquivo é retornado sem alteração. * Use `9:16` para formatos verticais/retrato de mídias sociais (TikTok, Reels, Shorts). * Para preenchimento desfocado em vez de cor sólida, use a ferramenta Blur Pad. --- --- url: https://docs.snapotter.com/ru/tools/video/aspect-pad.md description: Добавление полос сплошного цвета для подгонки под целевое соотношение сторон. --- # Aspect Pad {#aspect-pad} Добавьте полосы сплошного цвета сверху/снизу (letterbox) или по бокам (pillarbox), чтобы вписать видео в целевое соотношение сторон без обрезки. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Принимает данные multipart form с видеофайлом и JSON-полем `settings`. ## Parameters {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | target | string | Нет | `"9:16"` | Целевое соотношение сторон: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | Нет | `"#000000"` | Hex-цвет для полос заполнения (например, `"#000000"` для чёрного) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Если видео уже соответствует целевому соотношению сторон, файл возвращается без изменений. * Используйте `9:16` для вертикальных/портретных форматов социальных сетей (TikTok, Reels, Shorts). * Для размытого заполнения вместо сплошного цвета используйте инструмент Blur Pad. --- --- url: https://docs.snapotter.com/sv/tools/video/aspect-pad.md description: Lägg till enfärgade fält för att passa ett målformat. --- # Aspect Pad {#aspect-pad} Lägg till enfärgade letterbox- eller pillarbox-fält för att få en video att passa in i ett målbildförhållande utan att beskära. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Tar emot multipart-formulärdata med en videofil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | target | string | Nej | `"9:16"` | Målbildförhållande: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | Nej | `"#000000"` | Hex-färg för utfyllnadsfälten (t.ex. `"#000000"` för svart) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Om videon redan matchar målbildförhållandet returneras filen oförändrad. * Använd `9:16` för vertikala/porträttformat för sociala medier (TikTok, Reels, Shorts). * För suddig utfyllnad istället för enfärgad, använd verktyget Blur Pad. --- --- url: https://docs.snapotter.com/th/tools/video/aspect-pad.md description: เพิ่มแถบสีทึบเพื่อให้พอดีกับอัตราส่วนภาพเป้าหมาย --- # Aspect Pad {#aspect-pad} เพิ่มแถบสีทึบแบบเลตเตอร์บ็อกซ์หรือพิลลาร์บ็อกซ์เพื่อให้วิดีโอพอดีกับอัตราส่วนภาพเป้าหมายโดยไม่ต้องครอป ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` รับข้อมูลแบบ multipart form data พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | อัตราส่วนภาพเป้าหมาย: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | No | `"#000000"` | สีฐานสิบหกสำหรับแถบเติมขอบ (เช่น `"#000000"` สำหรับสีดำ) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * หากวิดีโอตรงกับอัตราส่วนภาพเป้าหมายอยู่แล้ว ไฟล์จะถูกคืนกลับมาโดยไม่เปลี่ยนแปลง * ใช้ `9:16` สำหรับรูปแบบโซเชียลมีเดียแนวตั้ง (TikTok, Reels, Shorts) * หากต้องการแถบเติมขอบแบบเบลอแทนสีทึบ ให้ใช้เครื่องมือ Blur Pad --- --- url: https://docs.snapotter.com/uk/tools/video/aspect-pad.md description: >- Додавання суцільнокольорових смуг для відповідності цільовому співвідношенню сторін. --- # Aspect Pad {#aspect-pad} Додавайте суцільнокольорові смуги (леттербокс або пілларбокс), щоб вписати відео в цільове співвідношення сторін без обрізання. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Приймає багаточастинні (multipart) дані форми з відеофайлом та полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | Цільове співвідношення сторін: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | No | `"#000000"` | Шістнадцятковий колір для смуг заповнення (наприклад `"#000000"` для чорного) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Якщо відео вже відповідає цільовому співвідношенню сторін, файл повертається без змін. * Використовуйте `9:16` для вертикальних/портретних форматів соціальних мереж (TikTok, Reels, Shorts). * Для розмитого заповнення замість суцільного кольору використовуйте інструмент Blur Pad. --- --- url: https://docs.snapotter.com/vi/tools/video/aspect-pad.md description: Thêm các thanh màu đơn sắc để vừa với một tỷ lệ khung hình mục tiêu. --- # Aspect Pad {#aspect-pad} Thêm các thanh letterbox hoặc pillarbox màu đơn sắc để đưa một video vừa vào một tỷ lệ khung hình mục tiêu mà không cắt xén. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Chấp nhận dữ liệu biểu mẫu multipart với một tệp video và một trường JSON `settings`. ## Parameters {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | target | string | Không | `"9:16"` | Tỷ lệ khung hình mục tiêu: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | Không | `"#000000"` | Màu hex cho các thanh đệm (ví dụ `"#000000"` cho màu đen) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * Nếu video đã khớp với tỷ lệ khung hình mục tiêu, tệp được trả về không thay đổi. * Dùng `9:16` cho các định dạng mạng xã hội dọc/khổ đứng (TikTok, Reels, Shorts). * Để có đệm làm mờ thay vì màu đơn sắc, hãy dùng công cụ Blur Pad. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/aspect-pad.md description: 添加纯色条以适应目标宽高比。 --- # Aspect Pad {#aspect-pad} 添加纯色的信箱或邮筒式条框,使视频在不裁剪的情况下适应目标宽高比。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` 接受包含一个视频文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"9:16"` | 目标宽高比:`16:9`、`9:16`、`1:1`、`4:3`、`3:4` | | color | string | No | `"#000000"` | 填充条的十六进制颜色(例如 `"#000000"` 表示黑色) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notes {#notes} * 如果视频已经匹配目标宽高比,则文件将原样返回。 * 竖屏/纵向社交媒体格式(TikTok、Reels、Shorts)请使用 `9:16`。 * 若要使用模糊填充而不是纯色,请使用 Blur Pad 工具。 --- --- url: https://docs.snapotter.com/fr/tools/image/stitch.md description: >- Assemble des images côte à côte, empilées ou en grille, avec un contrôle de l'alignement, des espacements, des bordures et du mode de redimensionnement. --- # Assembler des images {#stitch-combine} Assemble plusieurs images côte à côte, empilées verticalement ou disposées en grille. Prend en charge l'alignement, l'espacement, la bordure, le rayon des coins et plusieurs modes de redimensionnement. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/stitch` ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | direction | string | Non | `"horizontal"` | Direction de la disposition : `horizontal`, `vertical`, `grid` | | gridColumns | integer | Non | 2 | Nombre de colonnes lorsque la direction est `grid` (2 à 100) | | resizeMode | string | Non | `"fit"` | Mode de redimensionnement des images : `fit`, `original`, `stretch`, `crop` | | alignment | string | Non | `"center"` | Alignement transversal : `start`, `center`, `end` | | gap | number | Non | 0 | Espacement entre les images en pixels (0 à 1000) | | border | number | Non | 0 | Largeur de la bordure extérieure en pixels (0 à 500) | | cornerRadius | number | Non | 0 | Rayon des coins appliqué à la sortie finale (0 à 500) | | backgroundColor | string | Non | `"#FFFFFF"` | Couleur d'arrière-plan/bordure en hexadécimal (par exemple `#FF0000`) | | format | string | Non | `"png"` | Format de sortie : `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Non | 90 | Qualité de sortie (1 à 100) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/stitch \ -F "file=@image1.png" \ -F "file=@image2.png" \ -F "file=@image3.png" \ -F 'settings={"direction":"horizontal","resizeMode":"fit","gap":10,"backgroundColor":"#FFFFFF","format":"png"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stitch.png", "originalSize": 1234567, "processedSize": 987654 } ``` ## Remarques {#notes} * Nécessite au moins 2 images. Téléversez plusieurs fichiers image dans la requête multipart. * Prend en charge les formats d'entrée HEIC, RAW, PSD et SVG (décodés automatiquement). * Modes de redimensionnement : * `fit` - Met les images à l'échelle pour correspondre à la plus petite dimension le long de l'axe d'assemblage. * `original` - Conserve les tailles d'origine (peut produire des bords irréguliers). * `stretch` - Force les images à correspondre à la plus petite dimension sans conserver le rapport d'aspect. * `crop` - Recadre les images en mode couverture pour correspondre à la plus petite dimension. * En mode `grid`, les cellules sont dimensionnées selon les dimensions médianes de toutes les images. * Le `cornerRadius` est appliqué à l'ensemble de la sortie finale, et non aux images individuelles. * La taille du canevas est limitée par la configuration serveur `MAX_CANVAS_PIXELS` afin d'éviter l'épuisement de la mémoire. --- --- url: https://docs.snapotter.com/pt-BR/guide/upgrading.md --- # Atualizando da 1.x para a 2.0 {#upgrading-from-1-x-to-2-0} O SnapOtter 1.x armazenava tudo em um único arquivo SQLite e rodava como um contêiner. O SnapOtter 2.0 usa PostgreSQL e Redis. Este guia orienta a migração de uma instalação 1.x para a 2.0 sem perder dados. Em resumo: reutilize seu volume `/data` existente, e a 2.0 importa seu banco de dados 1.x automaticamente na primeira inicialização. Seus usuários, arquivos salvos, configurações, chaves de API e pipelines são transferidos. O banco de dados antigo nunca é modificado, então você sempre pode reverter. ::: tip Um recado para nossos usuários da 1.x Muitos de vocês confiaram no SnapOtter desde o primeiro dia, e seu feedback moldou esta versão. A 2.0 muda bastante coisa nos bastidores, e este guia existe para que a migração não custe nada do que importa para você. Suas contas, arquivos, configurações, chaves de API e pipelines são transferidos, e seu banco de dados antigo nunca é tocado. Obrigado por atualizar conosco. ::: ## Antes de começar: faça backup de todo o volume `/data` {#before-you-start-back-up-the-whole-data-volume} Faça isso primeiro, sempre. Faça backup do volume `/data` **inteiro**, não apenas do arquivo `snapotter.db`. Eis por que isso importa. A 1.x roda o SQLite em modo WAL, então um contêiner 1.x parado costuma deixar a maior parte dos seus dados confirmados em `snapotter.db-wal` ao lado de um `snapotter.db` quase vazio. Copiar apenas `snapotter.db` captura um banco de dados vazio e perde tudo silenciosamente. O volume carrega `snapotter.db`, `snapotter.db-wal`, `snapotter.db-shm` e seu diretório `files/` juntos, e eles precisam viajar como um conjunto. ```bash # Adjust the volume name to match yours (see "Check your volume name" below). docker run --rm -v SnapOtter-data:/data -v "$PWD":/backup \ alpine tar czf /backup/snapotter-1x-data.tgz -C /data . ``` ## Atualize primeiro para a 1.17.2 {#upgrade-to-1-17-2-first} Atualize sua instalação 1.x para a última versão 1.x (1.17.2) antes de migrar para a 2.0. Isso permite que a 1.x execute suas próprias migrações finais de esquema, de forma que a 2.0 importe a partir de um esquema conhecido e completo. Atualizar de uma 1.x mais antiga direto para a 2.0 não é suportado. ## Verifique o nome do seu volume {#check-your-volume-name} O importador só enxerga seus dados se a stack 2.0 montar o mesmo volume que sua instalação 1.x usava. Os nomes de volume do Docker diferenciam maiúsculas de minúsculas, e trechos antigos do README usavam um `snapotter-data` em minúsculas enquanto os arquivos do Compose usam `SnapOtter-data`. Confirme qual você tem: ```bash docker volume ls | grep -i snapotter ``` Use esse nome exato na sua configuração da 2.0. ## Caminho A: contêiner único (mais rápido) {#path-a-single-container-quickest} Se você roda o SnapOtter com um único `docker run`, continue fazendo isso. A 2.0 inicializa um PostgreSQL e um Redis embutidos dentro do contêiner quando você não define `DATABASE_URL` nem `REDIS_URL`, e detecta e importa `/data/snapotter.db` automaticamente na primeira inicialização. ```bash docker run -d --name snapotter -p 1349:1349 \ -v SnapOtter-data:/data \ snapotter/snapotter:latest ``` Acompanhe os logs em busca de uma linha como: ``` Imported 1.x SQLite database: {"tables":{"users":2,"teams":1,...},"blobs":{"present":1,"missing":0}} ``` É isso. Faça login com suas credenciais existentes. ## Caminho B: Compose (recomendado para produção) {#path-b-compose-recommended-for-production} A stack Compose da 2.0 roda três serviços (app, Postgres, Redis). Reutilize seu volume `/data` da 1.x para o serviço do app. O app detecta `/data/snapotter.db` automaticamente e o importa para o Postgres na primeira inicialização. ```yaml services: SnapOtter: image: snapotter/snapotter:latest volumes: - SnapOtter-data:/data # your existing 1.x volume - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://:snapotter@redis:6379 # ... ``` Se você preferir apontar para o banco de dados antigo explicitamente, defina `SQLITE_MIGRATE_PATH=/data/snapotter.db`. Um caminho explícito sempre prevalece sobre a detecção automática. ## Visualize a importação antes (opcional) {#preview-the-import-first-optional} Para ver exatamente o que seria importado sem gravar nada, execute uma simulação (dry run) contra seu arquivo de banco de dados: ```bash pnpm --filter @snapotter/api migrate:sqlite -- /path/to/snapotter.db --dry-run ``` Ela imprime a contagem de linhas por tabela, quantos arquivos da biblioteca salva foram encontrados em disco e quaisquer status de job que serão normalizados. Não precisa de um Postgres em execução. ## O que é transferido e o que não é {#what-carries-over-and-what-does-not} Transferido: * Usuários e a capacidade de fazer login. Os hashes de senha permanecem inalterados, então o mesmo nome de usuário e senha funcionam. * Times, configurações (incluindo a identidade da sua instância), papéis, chaves de API (que continuam funcionando) e pipelines salvos. * Registros de histórico de jobs. * Sua biblioteca de arquivos salvos, tanto os registros quanto os arquivos em si, porque `/data/files` é preservado no volume. Não transferido: * Sessões de login. Todos entram uma vez após a atualização. As credenciais permanecem inalteradas, então é um único novo login, nada mais. * Os arquivos de entrada e saída de jobs de processamento antigos. Eles ficavam em um espaço de trabalho temporário e não existem mais, por design. Os registros de histórico de jobs permanecem. * Sinalizadores de consentimento de análise por usuário da 1.x, que não têm equivalente na 2.0 (a análise da 2.0 é uma configuração no nível da instância). ## Desligando a importação {#turning-the-import-off} Se você deliberadamente quiser um banco de dados novo mesmo com um `snapotter.db` presente no volume, defina `SQLITE_MIGRATE_PATH=off`. ## Se você já tem dados na instância 2.0 {#if-you-already-have-data-in-the-2-0-instance} O importador só roda em um banco de dados vazio. Se você iniciou a 2.0 do zero (criando dados) e depois montou um `snapotter.db` antigo, a 2.0 vai detectá-lo mas não vai importar, porque mesclar dois conjuntos de dados pode gerar colisões de IDs. Você verá um aviso nos logs. Para importar os dados da 1.x, você precisa de uma instância vazia: * Se a instância 2.0 contém apenas o admin padrão (você praticamente não a usou), pare a stack, remova o volume do Postgres (`SnapOtter-pgdata`) e inicialize novamente com o `/data` antigo presente. Ele importará sem problemas. Isso apaga apenas os dados descartáveis do Postgres, não o seu banco de dados 1.x. * Se a instância 2.0 contém dados reais que você quer manter, os dois conjuntos de dados não podem ser mesclados automaticamente. Exporte o que você precisa e importe os dados da 1.x em uma implantação nova e separada. ## Revertendo {#rolling-back} A atualização nunca modifica nem exclui seu `snapotter.db` da 1.x. Se você precisar voltar para a 1.x, reimplante a imagem 1.x contra o mesmo volume. Qualquer coisa criada na 2.0 após a atualização fica no Postgres e não estaria no banco de dados 1.x, então reverta logo se for fazer isso. --- --- url: https://docs.snapotter.com/id/tools/audio/volume-adjust.md description: Naikkan atau turunkan volume audio dengan gain tetap dalam desibel. --- # Atur Volume {#volume-adjust} Naikkan atau turunkan volume file audio dengan menerapkan gain tetap dalam desibel. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/volume-adjust` Menerima multipart form data berisi file audio dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | gainDb | number | No | `3` | Penyesuaian volume dalam desibel (-30 hingga 30) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/volume-adjust \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"gainDb": 6}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Nilai positif menaikkan volume; nilai negatif menurunkannya. * Gain positif yang besar dapat menyebabkan clipping. Gunakan normalize-audio untuk penyetaraan kenyaringan yang aman. * Output biasanya mempertahankan container input. Input AAC ditulis sebagai M4A, dan input decode-only yang tidak didukung dialihkan ke MP3. --- --- url: https://docs.snapotter.com/hi/tools/audio/audio-channels.md description: mono और stereo के बीच रूपांतरण करें या बाएँ और दाएँ चैनल स्वैप करें। --- # Audio Channels {#audio-channels} audio को mono और stereo लेआउट के बीच रूपांतरित करें, या किसी stereo फ़ाइल के बाएँ और दाएँ चैनल स्वैप करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` एक audio फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | Yes | - | चैनल ऑपरेशन: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Notes {#notes} * `stereo-to-mono` दोनों चैनलों को एक ही mono ट्रैक में मिला देता है। * `mono-to-stereo` mono चैनल को बाएँ और दाएँ दोनों में डुप्लिकेट कर देता है। * `swap` किसी stereo फ़ाइल के बाएँ और दाएँ चैनल आपस में बदल देता है। * आउटपुट आमतौर पर इनपुट container रखता है। AAC इनपुट M4A के रूप में लिखा जाता है, और असमर्थित डिकोड-ओनली इनपुट MP3 पर वापस चले जाते हैं। --- --- url: https://docs.snapotter.com/id/tools/audio/audio-channels.md description: Konversi antara mono dan stereo atau tukar saluran kiri dan kanan. --- # Audio Channels {#audio-channels} Konversi audio antara tata letak mono dan stereo, atau tukar saluran kiri dan kanan dari file stereo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Menerima data formulir multipart dengan file audio dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | mode | string | Ya | - | Operasi saluran: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Catatan {#notes} * `stereo-to-mono` mencampur kedua saluran menjadi satu trek mono. * `mono-to-stereo` menduplikasi saluran mono ke kiri dan kanan. * `swap` menukar saluran kiri dan kanan dari file stereo. * Output biasanya mempertahankan kontainer input. Input AAC ditulis sebagai M4A, dan input decode-only yang tidak didukung beralih ke MP3. --- --- url: https://docs.snapotter.com/ko/tools/audio/audio-channels.md description: 모노와 스테레오 간 변환하거나 좌우 채널을 서로 바꿉니다. --- # Audio Channels {#audio-channels} 오디오를 모노와 스테레오 레이아웃 간에 변환하거나, 스테레오 파일의 좌우 채널을 서로 바꿉니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` 오디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 파라미터 {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | Yes | - | 채널 작업: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## 참고 {#notes} * `stereo-to-mono`은 두 채널을 하나의 모노 트랙으로 믹싱합니다. * `mono-to-stereo`은 모노 채널을 좌우 양쪽으로 복제합니다. * `swap`은 스테레오 파일의 좌우 채널을 서로 바꿉니다. * 출력은 보통 입력 컨테이너를 유지합니다. AAC 입력은 M4A로 작성되며, 지원되지 않는 디코드 전용 입력은 MP3로 폴백됩니다. --- --- url: https://docs.snapotter.com/nl/tools/audio/audio-channels.md description: Converteer tussen mono en stereo of wissel het linker- en rechterkanaal om. --- # Audio Channels {#audio-channels} Converteer audio tussen mono- en stereolay-outs, of wissel het linker- en rechterkanaal van een stereobestand om. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Accepteert multipart-formuliergegevens met een audiobestand en een JSON `settings`-veld. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | mode | string | Ja | - | Kanaalbewerking: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Opmerkingen {#notes} * `stereo-to-mono` mixt beide kanalen tot één enkel monospoor. * `mono-to-stereo` dupliceert het monokanaal naar zowel links als rechts. * `swap` wisselt het linker- en rechterkanaal van een stereobestand om. * De uitvoer behoudt meestal de invoercontainer. AAC-invoer wordt geschreven als M4A, en niet-ondersteunde decode-only-invoer valt terug op MP3. --- --- url: https://docs.snapotter.com/sv/tools/audio/audio-channels.md description: Konvertera mellan mono och stereo eller byt plats på vänster och höger kanal. --- # Audio Channels {#audio-channels} Konvertera ljud mellan mono- och stereolayouter, eller byt plats på vänster och höger kanal i en stereofil. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Accepterar multipart-formulärdata med en ljudfil och ett JSON `settings`-fält. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | mode | string | Ja | - | Kanaloperation: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Anteckningar {#notes} * `stereo-to-mono` mixar båda kanalerna till ett enda monospår. * `mono-to-stereo` duplicerar monokanalen till både vänster och höger. * `swap` byter plats på vänster och höger kanal i en stereofil. * Utdata behåller vanligtvis inmatningens container. AAC-inmatning skrivs som M4A, och inmatningar som endast kan avkodas och inte stöds faller tillbaka till MP3. --- --- url: https://docs.snapotter.com/th/tools/audio/audio-channels.md description: แปลงระหว่างโมโนกับสเตอริโอ หรือสลับช่องสัญญาณซ้ายและขวา --- # Audio Channels {#audio-channels} แปลงเสียงระหว่างเลย์เอาต์โมโนกับสเตอริโอ หรือสลับช่องสัญญาณซ้ายและขวาของไฟล์สเตอริโอ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` รับข้อมูลฟอร์มแบบ multipart พร้อมไฟล์เสียงและฟิลด์ JSON `settings` ## พารามิเตอร์ {#parameters} | พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย | |-----------|------|----------|---------|-------------| | mode | string | ใช่ | - | การดำเนินการช่องสัญญาณ: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## ตัวอย่างคำขอ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## ตัวอย่างการตอบกลับ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## หมายเหตุ {#notes} * `stereo-to-mono` ผสมทั้งสองช่องสัญญาณเข้าเป็นแทร็กโมโนเดียว * `mono-to-stereo` ทำสำเนาช่องสัญญาณโมโนไปยังทั้งซ้ายและขวา * `swap` สลับช่องสัญญาณซ้ายและขวาของไฟล์สเตอริโอ * เอาต์พุตมักคงคอนเทนเนอร์อินพุตไว้ อินพุต AAC จะเขียนเป็น M4A และอินพุตแบบถอดรหัสอย่างเดียวที่ไม่รองรับจะถอยกลับเป็น MP3 --- --- url: https://docs.snapotter.com/tr/tools/audio/audio-channels.md description: Mono ve stereo arasında dönüştürün veya sol ve sağ kanalları değiştirin. --- # Audio Channels {#audio-channels} Sesi mono ve stereo düzenler arasında dönüştürün veya bir stereo dosyanın sol ve sağ kanallarını değiştirin. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Bir ses dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | mode | string | Evet | - | Kanal işlemi: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Notlar {#notes} * `stereo-to-mono` her iki kanalı tek bir mono parçaya karıştırır. * `mono-to-stereo` mono kanalı hem sola hem de sağa çoğaltır. * `swap` bir stereo dosyanın sol ve sağ kanallarını takas eder. * Çıktı genellikle girdi konteynerini korur. AAC girdisi M4A olarak yazılır ve desteklenmeyen yalnızca-çözümleme (decode-only) girdileri MP3'e geri döner. --- --- url: https://docs.snapotter.com/de/tools/audio/fade-audio.md description: Ein- und Ausblendeffekte zu Audio hinzufügen. --- # Audio ein-/ausblenden {#fade-audio} Füge Ein- und Ausblendeffekte am Anfang und Ende einer Audiodatei hinzu. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Akzeptiert Multipart-Formulardaten mit einer Audiodatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | fadeInS | number | Nein | `1` | Einblenddauer in Sekunden (0 bis 30) | | fadeOutS | number | Nein | `1` | Ausblenddauer in Sekunden (0 bis 30) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Hinweise {#notes} * Setze einen der Werte auf `0`, um diese Blendrichtung zu überspringen. Mindestens einer muss größer als 0 sein. * Die Blenddauer wird auf die Audiolänge begrenzt, wenn sie diese überschreitet. * Die Ausgabe behält üblicherweise den Eingabecontainer bei. AAC-Eingabe wird als M4A geschrieben, und nicht unterstützte Nur-Dekodier-Eingaben fallen auf MP3 zurück. --- --- url: https://docs.snapotter.com/de/tools/audio/convert-audio.md description: Audio zwischen den Formaten MP3, WAV, OGG, FLAC und M4A konvertieren. --- # Audio konvertieren {#convert-audio} Konvertiere Audiodateien zwischen gängigen Formaten wie MP3, WAV, OGG, FLAC und M4A, mit konfigurierbarer Ausgabe-Bitrate und Abtastrate. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Akzeptiert Multipart-Formulardaten mit einer Audiodatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Nein | `"mp3"` | Ausgabeformat: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Nein | `192` | Ausgabe-Bitrate in kbps (32 bis 320) | | sampleRate | integer | Nein | Quellrate | Ausgabe-Abtastrate in Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` oder `96000`. Weglassen, um die Quellrate beizubehalten | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Hinweise {#notes} * Zu den unterstützten Eingabeformaten gehören MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF und OPUS. * Die Bitrate gilt nur für verlustbehaftete Formate (MP3, OGG, M4A). Verlustfreie Formate wie WAV und FLAC ignorieren diese Einstellung. * Die MP3-Ausgabe unterstützt Abtastraten bis zu 48000 Hz. Die Option 96000 Hz gilt nur für WAV, OGG, FLAC und M4A. * Die MP3-Bitrate ist durch die Abtastrate begrenzt: höchstens 64 kbps bei 8000 Hz und 160 kbps bei 16000 oder 22050 Hz. Anfragen über der Obergrenze werden abgelehnt, statt stillschweigend gesenkt zu werden. * Der Ausgabedateiname behält den ursprünglichen Namen mit der neuen Erweiterung bei. --- --- url: https://docs.snapotter.com/hi/tools/audio/audio-metadata.md description: audio मेटाडेटा टैग (ID3) देखें, संपादित करें, या हटाएँ। --- # Audio Metadata {#audio-metadata} audio मेटाडेटा टैग जैसे title, artist, और album (ID3 और समान टैग फ़ॉर्मैट) देखें, संपादित करें, या हटाएँ। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` एक audio फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | strip | boolean | No | `false` | सभी मौजूदा मेटाडेटा टैग हटाएँ | | title | string | No | - | title टैग सेट करें (अधिकतम 500 अक्षर) | | artist | string | No | - | artist टैग सेट करें (अधिकतम 500 अक्षर) | | album | string | No | - | album टैग सेट करें (अधिकतम 500 अक्षर) | ## Example Request {#example-request} मेटाडेटा टैग संपादित करें: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` सभी मेटाडेटा हटाएँ: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## Notes {#notes} * रिस्पॉन्स में container फ़ॉर्मैट, duration, bitrate, और मौजूदा टैग के साथ एक `metadata` ऑब्जेक्ट शामिल होता है। * जब `strip` `true` होता है, तो सभी टैग फ़ील्ड नज़रअंदाज़ किए जाते हैं और हर मौजूदा टैग हटा दिया जाता है। * केवल आपके द्वारा प्रदान किए गए टैग ही अपडेट होते हैं; अनिर्दिष्ट टैग अपरिवर्तित रहते हैं। * आउटपुट फ़ॉर्मैट इनपुट फ़ॉर्मैट से मेल खाता है। --- --- url: https://docs.snapotter.com/id/tools/audio/audio-metadata.md description: Lihat, edit, atau hapus tag metadata audio (ID3). --- # Audio Metadata {#audio-metadata} Lihat, edit, atau hapus tag metadata audio seperti judul, artis, dan album (ID3 dan format tag serupa). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` Menerima data formulir multipart dengan file audio dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | strip | boolean | Tidak | `false` | Menghapus semua tag metadata yang ada | | title | string | Tidak | - | Setel tag judul (maks 500 karakter) | | artist | string | Tidak | - | Setel tag artis (maks 500 karakter) | | album | string | Tidak | - | Setel tag album (maks 500 karakter) | ## Contoh Permintaan {#example-request} Edit tag metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` Hapus semua metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## Catatan {#notes} * Respons menyertakan objek `metadata` dengan format kontainer, durasi, bitrate, dan tag saat ini. * Saat `strip` bernilai `true`, semua bidang tag diabaikan dan setiap tag yang ada dihapus. * Hanya tag yang Anda berikan yang diperbarui; tag yang tidak ditentukan tetap tidak berubah. * Format output cocok dengan format input. --- --- url: https://docs.snapotter.com/ko/tools/audio/audio-metadata.md description: 오디오 메타데이터 태그(ID3)를 조회, 편집 또는 제거합니다. --- # Audio Metadata {#audio-metadata} 제목, 아티스트, 앨범과 같은 오디오 메타데이터 태그(ID3 및 유사 태그 형식)를 조회, 편집 또는 제거합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` 오디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 파라미터 {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | strip | boolean | No | `false` | 기존 메타데이터 태그를 모두 제거 | | title | string | No | - | 제목 태그 설정(최대 500자) | | artist | string | No | - | 아티스트 태그 설정(최대 500자) | | album | string | No | - | 앨범 태그 설정(최대 500자) | ## 요청 예시 {#example-request} 메타데이터 태그 편집: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` 모든 메타데이터 제거: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## 참고 {#notes} * 응답에는 컨테이너 형식, 길이, 비트레이트, 현재 태그가 담긴 `metadata` 객체가 포함됩니다. * `strip`이 `true`이면 모든 태그 필드가 무시되고 기존 태그가 모두 제거됩니다. * 제공한 태그만 업데이트되며, 지정하지 않은 태그는 변경되지 않습니다. * 출력 형식은 입력 형식과 동일합니다. --- --- url: https://docs.snapotter.com/nl/tools/audio/audio-metadata.md description: Bekijk, bewerk of verwijder audio-metadatatags (ID3). --- # Audio Metadata {#audio-metadata} Bekijk, bewerk of verwijder audio-metadatatags zoals titel, artiest en album (ID3 en vergelijkbare tagformaten). ## API-endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` Accepteert multipart-formuliergegevens met een audiobestand en een JSON `settings`-veld. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | strip | boolean | Nee | `false` | Verwijder alle bestaande metadatatags | | title | string | Nee | - | Stel de titeltag in (max 500 tekens) | | artist | string | Nee | - | Stel de artiesttag in (max 500 tekens) | | album | string | Nee | - | Stel de albumtag in (max 500 tekens) | ## Voorbeeldverzoek {#example-request} Metadatatags bewerken: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` Alle metadata verwijderen: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## Opmerkingen {#notes} * De respons bevat een `metadata`-object met containerformaat, duur, bitrate en huidige tags. * Wanneer `strip` `true` is, worden alle tagvelden genegeerd en wordt elke bestaande tag verwijderd. * Alleen de tags die je opgeeft worden bijgewerkt; niet-opgegeven tags blijven ongewijzigd. * Het uitvoerformaat komt overeen met het invoerformaat. --- --- url: https://docs.snapotter.com/sv/tools/audio/audio-metadata.md description: Visa, redigera eller ta bort ljudmetadatataggar (ID3). --- # Audio Metadata {#audio-metadata} Visa, redigera eller ta bort ljudmetadatataggar som titel, artist och album (ID3 och liknande taggformat). ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` Accepterar multipart-formulärdata med en ljudfil och ett JSON `settings`-fält. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | strip | boolean | Nej | `false` | Ta bort alla befintliga metadatataggar | | title | string | Nej | - | Ange titeltaggen (max 500 tecken) | | artist | string | Nej | - | Ange artisttaggen (max 500 tecken) | | album | string | Nej | - | Ange albumtaggen (max 500 tecken) | ## Exempelförfrågan {#example-request} Redigera metadatataggar: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` Ta bort all metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## Anteckningar {#notes} * Svaret inkluderar ett `metadata`-objekt med containerformat, längd, bithastighet och aktuella taggar. * När `strip` är `true` ignoreras alla taggfält och varje befintlig tagg tas bort. * Endast de taggar du anger uppdateras; ospecificerade taggar förblir oförändrade. * Utdataformatet matchar inmatningsformatet. --- --- url: https://docs.snapotter.com/th/tools/audio/audio-metadata.md description: ดู แก้ไข หรือลบแท็กเมทาดาทาของเสียง (ID3) --- # Audio Metadata {#audio-metadata} ดู แก้ไข หรือลบแท็กเมทาดาทาของเสียง เช่น title, artist และ album (ID3 และรูปแบบแท็กที่คล้ายกัน) ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` รับข้อมูลฟอร์มแบบ multipart พร้อมไฟล์เสียงและฟิลด์ JSON `settings` ## พารามิเตอร์ {#parameters} | พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย | |-----------|------|----------|---------|-------------| | strip | boolean | ไม่ | `false` | ลบแท็กเมทาดาทาที่มีอยู่ทั้งหมด | | title | string | ไม่ | - | ตั้งค่าแท็ก title (สูงสุด 500 อักขระ) | | artist | string | ไม่ | - | ตั้งค่าแท็ก artist (สูงสุด 500 อักขระ) | | album | string | ไม่ | - | ตั้งค่าแท็ก album (สูงสุด 500 อักขระ) | ## ตัวอย่างคำขอ {#example-request} แก้ไขแท็กเมทาดาทา: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` ลบเมทาดาทาทั้งหมด: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## ตัวอย่างการตอบกลับ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## หมายเหตุ {#notes} * การตอบกลับมีออบเจ็กต์ `metadata` พร้อมรูปแบบคอนเทนเนอร์ ระยะเวลา บิตเรต และแท็กปัจจุบัน * เมื่อ `strip` เป็น `true` ฟิลด์แท็กทั้งหมดจะถูกเพิกเฉยและแท็กที่มีอยู่ทุกตัวจะถูกลบ * อัปเดตเฉพาะแท็กที่คุณระบุเท่านั้น แท็กที่ไม่ได้ระบุจะยังคงไม่เปลี่ยนแปลง * รูปแบบเอาต์พุตตรงกับรูปแบบอินพุต --- --- url: https://docs.snapotter.com/tr/tools/audio/audio-metadata.md description: Ses meta veri etiketlerini (ID3) görüntüleyin, düzenleyin veya kaldırın. --- # Audio Metadata {#audio-metadata} Başlık, sanatçı ve albüm gibi ses meta veri etiketlerini (ID3 ve benzeri etiket formatları) görüntüleyin, düzenleyin veya kaldırın. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` Bir ses dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | strip | boolean | Hayır | `false` | Mevcut tüm meta veri etiketlerini kaldır | | title | string | Hayır | - | Başlık etiketini ayarla (en fazla 500 karakter) | | artist | string | Hayır | - | Sanatçı etiketini ayarla (en fazla 500 karakter) | | album | string | Hayır | - | Albüm etiketini ayarla (en fazla 500 karakter) | ## Örnek İstek {#example-request} Meta veri etiketlerini düzenle: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` Tüm meta veriyi kaldır: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## Notlar {#notes} * Yanıt, konteyner formatı, süre, bit hızı ve mevcut etiketleri içeren bir `metadata` nesnesi içerir. * `strip` değeri `true` olduğunda, tüm etiket alanları yok sayılır ve mevcut her etiket kaldırılır. * Yalnızca sağladığınız etiketler güncellenir; belirtilmeyen etiketler değişmeden kalır. * Çıktı formatı girdi formatıyla eşleşir. --- --- url: https://docs.snapotter.com/de/tools/audio/normalize-audio.md description: Lautheit auf Broadcast-Standardpegel angleichen (EBU R128). --- # Audio normalisieren {#normalize-audio} Gleiche die Audiolautheit mit EBU-R128-Normalisierung (-16 LUFS) auf Broadcast-Standardpegel an. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/normalize-audio` Akzeptiert Multipart-Formulardaten mit einer Audiodatei und einem JSON-Feld `settings`. ## Parameter {#parameters} Dieses Werkzeug hat keine konfigurierbaren Parameter. Es wendet automatisch die EBU-R128-Lautheitsnormalisierung an. ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/normalize-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Hinweise {#notes} * Verwendet den EBU-R128-Lautheitsstandard mit Zielwert -16 LUFS. * Ideal für Podcasts, Hörbücher und Broadcast-Inhalte, bei denen gleichmäßige Lautheit wichtig ist. * Die Abtastrate der Quelle bleibt in der Ausgabe erhalten. * Die Ausgabe behält üblicherweise den Eingabecontainer bei. AAC-Eingabe wird als M4A geschrieben, und nicht unterstützte Nur-Dekodier-Eingaben fallen auf MP3 zurück. --- --- url: https://docs.snapotter.com/hi/tools/audio/audio-speed.md description: गुणक के साथ audio प्लेबैक को तेज़ या धीमा करें। --- # Audio Speed {#audio-speed} एक स्पीड गुणक लगाकर audio प्लेबैक को तेज़ या धीमा करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` एक audio फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | factor | number | No | `1.5` | स्पीड गुणक (0.25 से 4)। 1 से कम मान धीमा करते हैं; 1 से अधिक तेज़ करते हैं। | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## Notes {#notes} * `0.25` का factor एक-चौथाई स्पीड पर चलता है (4x लंबा)। `4` का factor चौगुनी स्पीड पर चलता है (4x छोटा)। * स्पीड बदलते समय pitch संरक्षित रहता है (टाइम-स्ट्रेच)। pitch को स्वतंत्र रूप से समायोजित करने के लिए pitch-shift का उपयोग करें। * आउटपुट आमतौर पर इनपुट container रखता है। AAC इनपुट M4A के रूप में लिखा जाता है, और असमर्थित डिकोड-ओनली इनपुट MP3 पर वापस चले जाते हैं। --- --- url: https://docs.snapotter.com/id/tools/audio/audio-speed.md description: Percepat atau perlambat pemutaran audio dengan pengali. --- # Audio Speed {#audio-speed} Percepat atau perlambat pemutaran audio dengan menerapkan pengali kecepatan. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` Menerima data formulir multipart dengan file audio dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | factor | number | Tidak | `1.5` | Pengali kecepatan (0.25 hingga 4). Nilai di bawah 1 memperlambat; di atas 1 mempercepat. | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## Catatan {#notes} * Faktor `0.25` memutar pada seperempat kecepatan (4x lebih panjang). Faktor `4` memutar pada empat kali kecepatan (4x lebih pendek). * Nada dipertahankan saat kecepatan berubah (time-stretch). Gunakan pitch-shift untuk menyesuaikan nada secara independen. * Output biasanya mempertahankan kontainer input. Input AAC ditulis sebagai M4A, dan input decode-only yang tidak didukung beralih ke MP3. --- --- url: https://docs.snapotter.com/ko/tools/audio/audio-speed.md description: 배율을 적용해 오디오 재생 속도를 빠르게 하거나 느리게 합니다. --- # Audio Speed {#audio-speed} 속도 배율을 적용해 오디오 재생을 빠르게 하거나 느리게 합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` 오디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 파라미터 {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | factor | number | No | `1.5` | 속도 배율(0.25 ~ 4). 1 미만은 느려지고, 1 초과는 빨라집니다. | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## 참고 {#notes} * `0.25` 배율은 1/4 속도로 재생됩니다(4배 길어짐). `4` 배율은 4배 속도로 재생됩니다(4배 짧아짐). * 속도가 바뀌는 동안 피치는 보존됩니다(타임 스트레치). 피치를 독립적으로 조정하려면 pitch-shift를 사용하세요. * 출력은 보통 입력 컨테이너를 유지합니다. AAC 입력은 M4A로 작성되며, 지원되지 않는 디코드 전용 입력은 MP3로 폴백됩니다. --- --- url: https://docs.snapotter.com/nl/tools/audio/audio-speed.md description: Versnel of vertraag audioweergave met een vermenigvuldiger. --- # Audio Speed {#audio-speed} Versnel of vertraag audioweergave door een snelheidsvermenigvuldiger toe te passen. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` Accepteert multipart-formuliergegevens met een audiobestand en een JSON `settings`-veld. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | factor | number | Nee | `1.5` | Snelheidsvermenigvuldiger (0,25 tot 4). Waarden onder 1 vertragen; boven 1 versnellen. | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## Opmerkingen {#notes} * Een factor van `0.25` speelt af op een kwart van de snelheid (4x langer). Een factor van `4` speelt af op viervoudige snelheid (4x korter). * De toonhoogte blijft behouden terwijl de snelheid verandert (time-stretch). Gebruik pitch-shift om de toonhoogte onafhankelijk aan te passen. * De uitvoer behoudt meestal de invoercontainer. AAC-invoer wordt geschreven als M4A, en niet-ondersteunde decode-only-invoer valt terug op MP3. --- --- url: https://docs.snapotter.com/sv/tools/audio/audio-speed.md description: Snabba upp eller sakta ner ljuduppspelning med en multiplikator. --- # Audio Speed {#audio-speed} Snabba upp eller sakta ner ljuduppspelning genom att tillämpa en hastighetsmultiplikator. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` Accepterar multipart-formulärdata med en ljudfil och ett JSON `settings`-fält. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | factor | number | Nej | `1.5` | Hastighetsmultiplikator (0.25 till 4). Värden under 1 saktar ner; över 1 snabbar upp. | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## Anteckningar {#notes} * En faktor på `0.25` spelar upp i kvartsfart (4x längre). En faktor på `4` spelar upp i fyrdubbel fart (4x kortare). * Tonhöjden bevaras medan hastigheten ändras (tidssträckning). Använd tonhöjdsskifte för att justera tonhöjden oberoende. * Utdata behåller vanligtvis inmatningens container. AAC-inmatning skrivs som M4A, och inmatningar som endast kan avkodas och inte stöds faller tillbaka till MP3. --- --- url: https://docs.snapotter.com/th/tools/audio/audio-speed.md description: เร่งหรือลดความเร็วในการเล่นเสียงด้วยตัวคูณ --- # Audio Speed {#audio-speed} เร่งหรือลดความเร็วในการเล่นเสียงโดยใช้ตัวคูณความเร็ว ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` รับข้อมูลฟอร์มแบบ multipart พร้อมไฟล์เสียงและฟิลด์ JSON `settings` ## พารามิเตอร์ {#parameters} | พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย | |-----------|------|----------|---------|-------------| | factor | number | ไม่ | `1.5` | ตัวคูณความเร็ว (0.25 ถึง 4) ค่าต่ำกว่า 1 ทำให้ช้าลง สูงกว่า 1 ทำให้เร็วขึ้น | ## ตัวอย่างคำขอ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## ตัวอย่างการตอบกลับ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## หมายเหตุ {#notes} * factor เท่ากับ `0.25` จะเล่นที่ความเร็วหนึ่งในสี่ (ยาวขึ้น 4 เท่า) factor เท่ากับ `4` จะเล่นที่ความเร็วสี่เท่า (สั้นลง 4 เท่า) * ระดับเสียงถูกรักษาไว้ในขณะที่ความเร็วเปลี่ยน (time-stretch) ใช้ pitch-shift เพื่อปรับระดับเสียงอย่างเป็นอิสระ * เอาต์พุตมักคงคอนเทนเนอร์อินพุตไว้ อินพุต AAC จะเขียนเป็น M4A และอินพุตแบบถอดรหัสอย่างเดียวที่ไม่รองรับจะถอยกลับเป็น MP3 --- --- url: https://docs.snapotter.com/tr/tools/audio/audio-speed.md description: Bir çarpanla ses oynatmayı hızlandırın veya yavaşlatın. --- # Audio Speed {#audio-speed} Bir hız çarpanı uygulayarak ses oynatmayı hızlandırın veya yavaşlatın. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` Bir ses dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | factor | number | Hayır | `1.5` | Hız çarpanı (0.25 ile 4 arası). 1'in altındaki değerler yavaşlatır; üstündekiler hızlandırır. | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## Notlar {#notes} * `0.25` çarpanı çeyrek hızda oynatır (4 kat daha uzun). `4` çarpanı dört kat hızda oynatır (4 kat daha kısa). * Hız değişirken perde (pitch) korunur (zaman esnetme). Perdeyi bağımsız olarak ayarlamak için perde kaydırmayı (pitch-shift) kullanın. * Çıktı genellikle girdi konteynerini korur. AAC girdisi M4A olarak yazılır ve desteklenmeyen yalnızca-çözümleme (decode-only) girdileri MP3'e geri döner. --- --- url: https://docs.snapotter.com/de/tools/audio/reverse-audio.md description: Eine Audiodatei umkehren, sodass sie rückwärts abgespielt wird. --- # Audio umkehren {#reverse-audio} Kehre eine Audiodatei um, sodass sie rückwärts abgespielt wird. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/reverse-audio` Akzeptiert Multipart-Formulardaten mit einer Audiodatei und einem JSON-Feld `settings`. ## Parameter {#parameters} Dieses Werkzeug hat keine konfigurierbaren Parameter. Die gesamte Audiodatei wird umgekehrt. ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/reverse-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Hinweise {#notes} * Die gesamte Audiospur wird von Ende zu Anfang umgekehrt. * Die Ausgabe behält üblicherweise den Eingabecontainer bei. AAC-Eingabe wird als M4A geschrieben, und nicht unterstützte Nur-Dekodier-Eingaben fallen auf MP3 zurück. --- --- url: https://docs.snapotter.com/de/tools/audio/merge-audio.md description: Mehrere Audiodateien zu einer sequenziellen Spur zusammenführen. --- # Audio zusammenführen {#merge-audio} Kombiniere zwei oder mehr Audiodateien zu einer einzigen sequenziellen Spur, aneinandergereiht in der Reihenfolge, in der sie hochgeladen werden. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/merge-audio` Akzeptiert Multipart-Formulardaten mit mehreren Audiodateien und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Nein | `"mp3"` | Ausgabeformat: `mp3`, `wav`, `flac`, `m4a` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/merge-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@intro.mp3" \ -F "file=@main.mp3" \ -F "file=@outro.mp3" \ -F 'settings={"format": "mp3"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.mp3", "originalSize": 9500000, "processedSize": 9200000 } ``` ## Hinweise {#notes} * Akzeptiert 2 bis 10 Audiodateien pro Anfrage. * Die Dateien werden in der Upload-Reihenfolge aneinandergereiht. * Alle Eingabedateien werden für ein nahtloses Zusammenfügen in das gewählte Ausgabeformat und die gewählte Abtastrate neu kodiert. * Gemischte Eingabeformate werden unterstützt (z. B. eine WAV- und eine MP3-Datei). --- --- url: https://docs.snapotter.com/de/tools/audio/audio-metadata.md description: Audio-Metadaten-Tags (ID3) ansehen, bearbeiten oder entfernen. --- # Audio-Metadaten {#audio-metadata} Sieh dir Audio-Metadaten-Tags wie Titel, Interpret und Album an, bearbeite oder entferne sie (ID3 und ähnliche Tag-Formate). ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/audio-metadata` Akzeptiert Multipart-Formulardaten mit einer Audiodatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | strip | boolean | Nein | `false` | Alle vorhandenen Metadaten-Tags entfernen | | title | string | Nein | - | Den Titel-Tag setzen (max. 500 Zeichen) | | artist | string | Nein | - | Den Interpret-Tag setzen (max. 500 Zeichen) | | album | string | Nein | - | Den Album-Tag setzen (max. 500 Zeichen) | ## Beispielanfrage {#example-request} Metadaten-Tags bearbeiten: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' ``` Alle Metadaten entfernen: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strip": true}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4480000, "metadata": { "container": "mp3", "durationS": 245.3, "bitrateKbps": 192, "tags": { "title": "My Song", "artist": "Artist Name", "album": "Album Name" } } } ``` ## Hinweise {#notes} * Die Antwort enthält ein `metadata`-Objekt mit Containerformat, Dauer, Bitrate und aktuellen Tags. * Wenn `strip` auf `true` steht, werden alle Tag-Felder ignoriert und jeder vorhandene Tag entfernt. * Nur die von dir angegebenen Tags werden aktualisiert; nicht angegebene Tags bleiben unverändert. * Das Ausgabeformat entspricht dem Eingabeformat. --- --- url: https://docs.snapotter.com/de/tools/audio/audio-speed.md description: Audiowiedergabe mit einem Multiplikator beschleunigen oder verlangsamen. --- # Audiogeschwindigkeit {#audio-speed} Beschleunige oder verlangsame die Audiowiedergabe durch Anwenden eines Geschwindigkeitsmultiplikators. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/audio-speed` Akzeptiert Multipart-Formulardaten mit einer Audiodatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | factor | number | Nein | `1.5` | Geschwindigkeitsmultiplikator (0,25 bis 4). Werte unter 1 verlangsamen; über 1 beschleunigen. | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-speed \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"factor": 2}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2250000 } ``` ## Hinweise {#notes} * Ein Faktor von `0.25` spielt mit Vierteltempo ab (4x länger). Ein Faktor von `4` spielt mit vierfachem Tempo ab (4x kürzer). * Die Tonhöhe bleibt erhalten, während sich die Geschwindigkeit ändert (Time-Stretch). Verwende Pitch-Shift, um die Tonhöhe unabhängig anzupassen. * Die Ausgabe behält üblicherweise den Eingabecontainer bei. AAC-Eingabe wird als M4A geschrieben, und nicht unterstützte Nur-Dekodier-Eingaben fallen auf MP3 zurück. --- --- url: https://docs.snapotter.com/de/tools/audio/audio-channels.md description: Zwischen Mono und Stereo konvertieren oder linken und rechten Kanal tauschen. --- # Audiokanäle {#audio-channels} Konvertiere Audio zwischen Mono- und Stereo-Layouts oder tausche den linken und rechten Kanal einer Stereodatei. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Akzeptiert Multipart-Formulardaten mit einer Audiodatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | mode | string | Ja | - | Kanaloperation: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Hinweise {#notes} * `stereo-to-mono` mischt beide Kanäle zu einer einzigen Mono-Spur. * `mono-to-stereo` dupliziert den Mono-Kanal auf links und rechts. * `swap` tauscht den linken und rechten Kanal einer Stereodatei. * Die Ausgabe behält üblicherweise den Eingabecontainer bei. AAC-Eingabe wird als M4A geschrieben, und nicht unterstützte Nur-Dekodier-Eingaben fallen auf MP3 zurück. --- --- url: https://docs.snapotter.com/it/tools/image/sharpening.md description: >- Aumenta la nitidezza delle immagini con metodi adattivo, maschera di contrasto o passa-alto, con riduzione del rumore opzionale. --- # Aumenta nitidezza immagine {#sharpening} Strumento avanzato per la nitidezza con tre metodi: adattivo (intelligente, sensibile ai bordi), maschera di contrasto (raggio/quantità classici) e passa-alto (enfasi sulla texture). Include una riduzione del rumore integrata per prevenire artefatti dovuti alla nitidezza. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/sharpening` Accetta dati di form multipart con un file immagine e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | method | string | No | `"adaptive"` | Algoritmo di nitidezza: `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | No | `1.0` | Adattivo: sigma gaussiana (da 0.5 a 10) | | m1 | number | No | `1.0` | Adattivo: nitidezza delle aree piatte (da 0 a 10) | | m2 | number | No | `3.0` | Adattivo: nitidezza delle aree frastagliate (da 0 a 20) | | x1 | number | No | `2.0` | Adattivo: soglia piatto/frastagliato (da 0 a 10) | | y2 | number | No | `12` | Adattivo: nitidezza massima delle aree piatte (da 0 a 50) | | y3 | number | No | `20` | Adattivo: nitidezza massima delle aree frastagliate (da 0 a 50) | | amount | number | No | `100` | Maschera di contrasto: quantità di nitidezza (da 0 a 1000) | | radius | number | No | `1.0` | Maschera di contrasto: raggio di sfocatura in pixel (da 0.1 a 5) | | threshold | number | No | `0` | Maschera di contrasto: differenza minima di luminosità per applicare la nitidezza (da 0 a 255) | | strength | number | No | `50` | Passa-alto: intensità del filtro (da 0 a 100) | | kernelSize | number | No | `3` | Passa-alto: dimensione del kernel di convoluzione (3 o 5) | | denoise | string | No | `"off"` | Riduzione del rumore prima della nitidezza: `off`, `light`, `medium`, `strong` | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Maschera di contrasto con soglia per proteggere le aree uniformi: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Note {#notes} * Vengono usati solo i parametri pertinenti al metodo scelto. Per esempio, `amount`, `radius` e `threshold` vengono ignorati quando `method` è `adaptive`. * Il metodo adattivo usa la nitidezza adattiva integrata di Sharp con comportamento configurabile per le aree piatte/frastagliate. * L'opzione `denoise` applica la riduzione del rumore prima della nitidezza per evitare l'amplificazione di rumore/grana. * La nitidezza passa-alto estrae i dettagli fini sottraendo una versione sfocata dall'originale, per poi riunire il risultato. * Il formato di output corrisponde al formato di input. Gli input HEIC, RAW, PSD e SVG vengono decodificati automaticamente prima dell'elaborazione. --- --- url: https://docs.snapotter.com/de/tools/files/epub-convert.md description: Konvertiert ein EPUB in PDF, DOCX, HTML oder Markdown. --- # Aus EPUB konvertieren {#convert-epub} Konvertiert ein EPUB-E-Book in PDF, Word (DOCX), HTML oder Markdown. Entfernte Ressourcen im Buch werden nicht abgerufen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Akzeptiert Multipart-Formulardaten mit einer EPUB-Datei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Ausgabeformat: `pdf`, `docx`, `html`, `md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} Gibt `202 Accepted` zurück. Verfolge den Fortschritt per SSE unter `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akzeptiertes Eingabeformat: `.epub`. * Entfernte, im EPUB eingebettete Ressourcen (externe Bilder, Schriftarten) werden aus Sicherheitsgründen nicht abgerufen. * Die Bildtreue in der konvertierten Ausgabe kann je nach EPUB-Struktur variieren. * Die Konvertierung wird von Pandoc auf dem Server durchgeführt. --- --- url: https://docs.snapotter.com/ar/tools/video/auto-subtitles.md description: توليد ملفات ترجمة من المسارات الصوتية للفيديو باستخدام الذكاء الاصطناعي. --- # Auto Subtitles {#auto-subtitles} ولّد ملفات ترجمة من المسار الصوتي لمقطع فيديو باستخدام التعرّف على الكلام المدعوم بالذكاء الاصطناعي (faster-whisper). يدعم الاكتشاف التلقائي و10 لغات صريحة. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` يقبل بيانات نموذج multipart تحتوي على ملف فيديو وحقل `settings` بصيغة JSON. هذه نقطة نهاية غير متزامنة - تُعيد `202 Accepted` فوراً ويُبثّ التقدّم عبر SSE على `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | لغة الكلام: `auto` أو `en` أو `de` أو `fr` أو `es` أو `zh` أو `ja` أو `ko` أو `id` أو `th` أو `vi` | | format | string | No | `"srt"` | صيغة ملف الترجمة الناتج: `srt` أو `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * هذه أداة ذكاء اصطناعي تتطلّب تثبيت حزمة ميزة **transcription**. إذا لم تكن الحزمة مثبّتة، يُعيد الـ API `501 Feature Not Installed` مع تعليمات لتثبيتها عبر واجهة المشرف. * يستخدم خيار اللغة `auto` اكتشاف اللغة المدمج في whisper. يؤدي تحديد اللغة صراحةً إلى تحسين الدقة والسرعة. * SRT هي أوسع صيغ ملفات الترجمة دعماً. وVTT (WebVTT) هي المعيار لمشغّلات فيديو الويب. * تتوفّر تحديثات التقدّم عبر SSE على `GET /api/v1/jobs/{jobId}/progress` حتى تكتمل المهمة. --- --- url: https://docs.snapotter.com/hi/tools/video/auto-subtitles.md description: AI का उपयोग करके वीडियो ऑडियो ट्रैक से सबटाइटल फ़ाइलें उत्पन्न करें। --- # Auto Subtitles {#auto-subtitles} AI-संचालित स्पीच रिकग्निशन (faster-whisper) का उपयोग करके किसी वीडियो के ऑडियो ट्रैक से सबटाइटल फ़ाइलें उत्पन्न करें। ऑटो-डिटेक्शन और 10 स्पष्ट भाषाओं का समर्थन करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। यह एक async एंडपॉइंट है - यह तुरंत `202 Accepted` लौटाता है और प्रगति `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से स्ट्रीम की जाती है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | स्पीच भाषा: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | No | `"srt"` | आउटपुट सबटाइटल फ़ॉर्मेट: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * यह एक AI टूल है जिसके लिए **transcription** फ़ीचर बंडल का इंस्टॉल होना आवश्यक है। यदि बंडल इंस्टॉल नहीं है, तो API इसे एडमिन UI के माध्यम से इंस्टॉल करने के निर्देशों के साथ `501 Feature Not Installed` लौटाता है। * `auto` भाषा विकल्प whisper की अंतर्निहित भाषा पहचान का उपयोग करता है। भाषा को स्पष्ट रूप से निर्दिष्ट करने से सटीकता और गति बेहतर होती है। * SRT सबसे व्यापक रूप से समर्थित सबटाइटल फ़ॉर्मेट है। VTT (WebVTT) वेब वीडियो प्लेयर के लिए मानक है। * जॉब पूरा होने तक `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति अपडेट उपलब्ध हैं। --- --- url: https://docs.snapotter.com/id/tools/video/auto-subtitles.md description: Hasilkan file subtitle dari trek audio video menggunakan AI. --- # Auto Subtitles {#auto-subtitles} Hasilkan file subtitle dari trek audio video menggunakan pengenalan suara bertenaga AI (faster-whisper). Mendukung deteksi otomatis dan 10 bahasa eksplisit. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Menerima data form multipart berisi file video dan sebuah field JSON `settings`. Ini adalah endpoint async - ia mengembalikan `202 Accepted` segera dan progres dialirkan melalui SSE di `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | Bahasa ucapan: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | No | `"srt"` | Format subtitle output: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Ini adalah alat AI yang membutuhkan feature bundle **transcription** untuk terpasang. Jika bundle tidak terpasang, API mengembalikan `501 Feature Not Installed` dengan instruksi untuk memasangnya melalui UI admin. * Opsi bahasa `auto` menggunakan deteksi bahasa bawaan whisper. Menentukan bahasa secara eksplisit meningkatkan akurasi dan kecepatan. * SRT adalah format subtitle yang paling banyak didukung. VTT (WebVTT) adalah standar untuk pemutar video web. * Pembaruan progres tersedia melalui SSE di `GET /api/v1/jobs/{jobId}/progress` hingga job selesai. --- --- url: https://docs.snapotter.com/ja/tools/video/auto-subtitles.md description: AI を使って動画の音声トラックから字幕ファイルを生成します。 --- # Auto Subtitles {#auto-subtitles} AI 搭載の音声認識(faster-whisper)を使って、動画の音声トラックから字幕ファイルを生成します。自動検出と 10 の明示的な言語に対応しています。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。これは非同期エンドポイントで、すぐに `202 Accepted` を返し、進捗は `GET /api/v1/jobs/{jobId}/progress` の SSE でストリーミングされます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | 音声の言語: `auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko`、`id`、`th`、`vi` | | format | string | No | `"srt"` | 出力する字幕形式: `srt`、`vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * これは **transcription** 機能バンドルのインストールが必要な AI ツールです。バンドルがインストールされていない場合、API は管理 UI 経由でインストールする手順とともに `501 Feature Not Installed` を返します。 * `auto` の言語オプションは whisper の組み込み言語検出を使用します。言語を明示的に指定すると精度と速度が向上します。 * SRT は最も広くサポートされている字幕形式です。VTT(WebVTT)は Web の動画プレーヤー向けの標準です。 * ジョブが完了するまで、進捗の更新は `GET /api/v1/jobs/{jobId}/progress` の SSE で確認できます。 --- --- url: https://docs.snapotter.com/ko/tools/video/auto-subtitles.md description: AI를 사용하여 비디오 오디오 트랙에서 자막 파일을 생성합니다. --- # Auto Subtitles {#auto-subtitles} AI 기반 음성 인식(faster-whisper)을 사용하여 비디오의 오디오 트랙에서 자막 파일을 생성합니다. 자동 감지와 10개의 명시적 언어를 지원합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` 비디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. 이는 비동기 엔드포인트로, 즉시 `202 Accepted`을(를) 반환하며 진행 상황은 `GET /api/v1/jobs/{jobId}/progress`의 SSE로 스트리밍됩니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | 음성 언어: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | No | `"srt"` | 출력 자막 형식: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 이 도구는 **transcription** 기능 번들이 설치되어 있어야 하는 AI 도구입니다. 번들이 설치되어 있지 않으면 API가 관리자 UI를 통해 설치하라는 안내와 함께 `501 Feature Not Installed`을(를) 반환합니다. * `auto` 언어 옵션은 whisper에 내장된 언어 감지를 사용합니다. 언어를 명시적으로 지정하면 정확도와 속도가 향상됩니다. * SRT는 가장 널리 지원되는 자막 형식입니다. VTT(WebVTT)는 웹 비디오 플레이어의 표준입니다. * 작업이 완료될 때까지 `GET /api/v1/jobs/{jobId}/progress`의 SSE로 진행 상황 업데이트를 확인할 수 있습니다. --- --- url: https://docs.snapotter.com/nl/tools/video/auto-subtitles.md description: Genereer ondertitelbestanden uit de audiotracks van video's met AI. --- # Auto Subtitles {#auto-subtitles} Genereer ondertitelbestanden uit de audiotrack van een video met AI-gedreven spraakherkenning (faster-whisper). Ondersteunt automatische detectie en 10 expliciete talen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Accepteert multipart-formuliergegevens met een videobestand en een JSON-veld `settings`. Dit is een asynchroon endpoint - het geeft `202 Accepted` direct terug en de voortgang wordt gestreamd via SSE op `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | language | string | Nee | `"auto"` | Spraaktaal: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | Nee | `"srt"` | Uitvoerformaat voor ondertitels: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Dit is een AI-hulpmiddel dat vereist dat de **transcription**-functiebundel is geïnstalleerd. Als de bundel niet is geïnstalleerd, geeft de API `501 Feature Not Installed` terug met instructies om deze via de admin-UI te installeren. * De taaloptie `auto` gebruikt de ingebouwde taaldetectie van whisper. Het expliciet opgeven van de taal verbetert de nauwkeurigheid en snelheid. * SRT is het meest breed ondersteunde ondertitelformaat. VTT (WebVTT) is de standaard voor webvideospelers. * Voortgangsupdates zijn beschikbaar via SSE op `GET /api/v1/jobs/{jobId}/progress` totdat de taak is voltooid. --- --- url: https://docs.snapotter.com/pl/tools/video/auto-subtitles.md description: Generuj pliki napisów ze ścieżek dźwiękowych filmów za pomocą AI. --- # Auto Subtitles {#auto-subtitles} Generuj pliki napisów ze ścieżki dźwiękowej filmu za pomocą rozpoznawania mowy opartego na AI (faster-whisper). Obsługuje automatyczne wykrywanie oraz 10 jawnie wskazanych języków. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Przyjmuje dane formularza multipart z plikiem wideo oraz polem JSON `settings`. To punkt końcowy asynchroniczny - zwraca natychmiast `202 Accepted`, a postęp jest strumieniowany przez SSE pod `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | Język mowy: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | No | `"srt"` | Format wyjściowy napisów: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * To narzędzie AI, które wymaga zainstalowania pakietu funkcji **transcription**. Jeśli pakiet nie jest zainstalowany, API zwraca `501 Feature Not Installed` z instrukcjami instalacji przez interfejs administratora. * Opcja języka `auto` używa wbudowanego wykrywania języka whisper. Jawne wskazanie języka poprawia dokładność i szybkość. * SRT jest najszerzej obsługiwanym formatem napisów. VTT (WebVTT) to standard dla internetowych odtwarzaczy wideo. * Aktualizacje postępu są dostępne przez SSE pod `GET /api/v1/jobs/{jobId}/progress` do momentu zakończenia zadania. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/auto-subtitles.md description: Gere arquivos de legenda a partir das faixas de áudio de vídeos usando IA. --- # Auto Subtitles {#auto-subtitles} Gere arquivos de legenda a partir da faixa de áudio de um vídeo usando reconhecimento de fala com tecnologia de IA (faster-whisper). Oferece suporte à detecção automática e a 10 idiomas explícitos. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. Este é um endpoint assíncrono - ele retorna `202 Accepted` imediatamente e o progresso é transmitido via SSE em `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | language | string | Não | `"auto"` | Idioma da fala: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | Não | `"srt"` | Formato de legenda de saída: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Esta é uma ferramenta de IA que requer que o pacote de recurso **transcription** esteja instalado. Se o pacote não estiver instalado, a API retorna `501 Feature Not Installed` com instruções para instalá-lo pela interface de administração. * A opção de idioma `auto` usa a detecção de idioma integrada do whisper. Especificar o idioma explicitamente melhora a precisão e a velocidade. * SRT é o formato de legenda com suporte mais amplo. VTT (WebVTT) é o padrão para reprodutores de vídeo web. * Atualizações de progresso ficam disponíveis via SSE em `GET /api/v1/jobs/{jobId}/progress` até o job ser concluído. --- --- url: https://docs.snapotter.com/ru/tools/video/auto-subtitles.md description: Генерация файлов субтитров из аудиодорожек видео с помощью ИИ. --- # Auto Subtitles {#auto-subtitles} Сгенерируйте файлы субтитров из аудиодорожки видео с помощью распознавания речи на базе ИИ (faster-whisper). Поддерживает автоопределение и 10 явных языков. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Принимает данные multipart form с видеофайлом и JSON-полем `settings`. Это асинхронный endpoint - он немедленно возвращает `202 Accepted`, а прогресс передаётся через SSE по адресу `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | language | string | Нет | `"auto"` | Язык речи: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | Нет | `"srt"` | Выходной формат субтитров: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Это инструмент ИИ, требующий установленного пакета функций **transcription**. Если пакет не установлен, API возвращает `501 Feature Not Installed` с инструкциями по его установке через интерфейс администратора. * Языковой параметр `auto` использует встроенное определение языка в whisper. Явное указание языка повышает точность и скорость. * SRT является наиболее широко поддерживаемым форматом субтитров. VTT (WebVTT) является стандартом для веб-плееров видео. * Обновления прогресса доступны через SSE по адресу `GET /api/v1/jobs/{jobId}/progress` до завершения задания. --- --- url: https://docs.snapotter.com/sv/tools/video/auto-subtitles.md description: Generera undertextfiler från videons ljudspår med AI. --- # Auto Subtitles {#auto-subtitles} Generera undertextfiler från en videos ljudspår med AI-driven taligenkänning (faster-whisper). Stöder automatisk igenkänning och 10 uttryckliga språk. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Tar emot multipart-formulärdata med en videofil och ett JSON-fält `settings`. Detta är en asynkron slutpunkt - den returnerar `202 Accepted` omedelbart och förloppet strömmas via SSE på `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | language | string | Nej | `"auto"` | Talat språk: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | Nej | `"srt"` | Utdataformat för undertext: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Detta är ett AI-verktyg som kräver att funktionspaketet **transcription** är installerat. Om paketet inte är installerat returnerar API:et `501 Feature Not Installed` med instruktioner om hur du installerar det via administratörsgränssnittet. * Språkalternativet `auto` använder whispers inbyggda språkigenkänning. Att ange språket uttryckligen förbättrar träffsäkerheten och hastigheten. * SRT är det bredast stödda undertextformatet. VTT (WebVTT) är standarden för webbvideospelare. * Förloppsuppdateringar finns tillgängliga via SSE på `GET /api/v1/jobs/{jobId}/progress` tills jobbet är klart. --- --- url: https://docs.snapotter.com/th/tools/video/auto-subtitles.md description: สร้างไฟล์คำบรรยายจากแทร็กเสียงของวิดีโอโดยใช้ AI --- # Auto Subtitles {#auto-subtitles} สร้างไฟล์คำบรรยายจากแทร็กเสียงของวิดีโอโดยใช้การรู้จำเสียงพูดที่ขับเคลื่อนด้วย AI (faster-whisper) รองรับการตรวจจับอัตโนมัติและ 10 ภาษาที่ระบุชัดเจน ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` รับข้อมูลแบบ multipart form data พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` นี่เป็นเอนด์พอยต์แบบอะซิงโครนัส คืนค่า `202 Accepted` ทันทีและสตรีมความคืบหน้าผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | ภาษาของเสียงพูด: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | No | `"srt"` | รูปแบบคำบรรยายผลลัพธ์: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * นี่เป็นเครื่องมือ AI ที่ต้องติดตั้งชุดฟีเจอร์ **transcription** หากยังไม่ได้ติดตั้งชุดฟีเจอร์ API จะคืนค่า `501 Feature Not Installed` พร้อมคำแนะนำในการติดตั้งผ่าน admin UI * ตัวเลือกภาษา `auto` ใช้การตรวจจับภาษาในตัวของ whisper การระบุภาษาชัดเจนจะช่วยเพิ่มความแม่นยำและความเร็ว * SRT เป็นรูปแบบคำบรรยายที่ได้รับการรองรับกว้างขวางที่สุด ส่วน VTT (WebVTT) เป็นมาตรฐานสำหรับโปรแกรมเล่นวิดีโอบนเว็บ * การอัปเดตความคืบหน้ามีให้ผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` จนกว่างานจะเสร็จสมบูรณ์ --- --- url: https://docs.snapotter.com/uk/tools/video/auto-subtitles.md description: Генерація файлів субтитрів з аудіодоріжок відео за допомогою ШІ. --- # Auto Subtitles {#auto-subtitles} Генеруйте файли субтитрів з аудіодоріжки відео за допомогою розпізнавання мовлення на основі ШІ (faster-whisper). Підтримує автовизначення та 10 явних мов. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Приймає багаточастинні (multipart) дані форми з відеофайлом та полем JSON `settings`. Це асинхронна кінцева точка - вона одразу повертає `202 Accepted`, а перебіг транслюється через SSE за адресою `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | Мова мовлення: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | No | `"srt"` | Вихідний формат субтитрів: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Це інструмент на основі ШІ, який потребує встановлення набору функцій **transcription**. Якщо набір не встановлено, API повертає `501 Feature Not Installed` з інструкціями щодо його встановлення через адмінінтерфейс. * Мовний варіант `auto` використовує вбудоване визначення мови whisper. Явне вказання мови підвищує точність та швидкість. * SRT є найбільш широко підтримуваним форматом субтитрів. VTT (WebVTT) є стандартом для вебплеєрів відео. * Оновлення перебігу доступні через SSE за адресою `GET /api/v1/jobs/{jobId}/progress` до завершення завдання. --- --- url: https://docs.snapotter.com/vi/tools/video/auto-subtitles.md description: Tạo tệp phụ đề từ bản âm thanh của video bằng AI. --- # Auto Subtitles {#auto-subtitles} Tạo tệp phụ đề từ bản âm thanh của một video bằng nhận dạng giọng nói hỗ trợ AI (faster-whisper). Hỗ trợ tự động phát hiện và 10 ngôn ngữ được chỉ định rõ ràng. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Chấp nhận dữ liệu biểu mẫu multipart với một tệp video và một trường JSON `settings`. Đây là một endpoint bất đồng bộ - nó trả về `202 Accepted` ngay lập tức và tiến độ được truyền qua SSE tại `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | language | string | Không | `"auto"` | Ngôn ngữ giọng nói: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | Không | `"srt"` | Định dạng phụ đề đầu ra: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Đây là một công cụ AI yêu cầu cài đặt gói tính năng **transcription**. Nếu gói chưa được cài đặt, API trả về `501 Feature Not Installed` cùng hướng dẫn cài đặt nó qua giao diện quản trị. * Tùy chọn ngôn ngữ `auto` dùng khả năng phát hiện ngôn ngữ tích hợp sẵn của whisper. Chỉ định ngôn ngữ rõ ràng cải thiện độ chính xác và tốc độ. * SRT là định dạng phụ đề được hỗ trợ rộng rãi nhất. VTT (WebVTT) là tiêu chuẩn cho các trình phát video web. * Cập nhật tiến độ có sẵn qua SSE tại `GET /api/v1/jobs/{jobId}/progress` cho đến khi công việc hoàn thành. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/auto-subtitles.md description: 使用 AI 从视频音轨生成字幕文件。 --- # Auto Subtitles {#auto-subtitles} 使用 AI 驱动的语音识别(faster-whisper)从视频的音轨生成字幕文件。支持自动检测和 10 种显式指定的语言。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` 接受包含一个视频文件和一个 JSON `settings` 字段的 multipart 表单数据。这是一个异步端点,它会立即返回 `202 Accepted`,进度通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 流式传输。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"auto"` | 语音语言:`auto`、`en`、`de`、`fr`、`es`、`zh`、`ja`、`ko`、`id`、`th`、`vi` | | format | string | No | `"srt"` | 输出字幕格式:`srt`、`vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 这是一个 AI 工具,需要安装 **transcription** 功能包。如果未安装该功能包,API 将返回 `501 Feature Not Installed`,并附带通过管理界面安装它的说明。 * `auto` 语言选项使用 whisper 内置的语言检测。显式指定语言可提高准确性和速度。 * SRT 是支持最广泛的字幕格式。VTT(WebVTT)是网页视频播放器的标准格式。 * 在作业完成之前,可通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 获取进度更新。 --- --- url: https://docs.snapotter.com/de/tools/video/auto-subtitles.md description: Untertiteldateien aus Video-Audiospuren mit KI erzeugen. --- # Automatische Untertitel {#auto-subtitles} Erzeugen Sie Untertiteldateien aus der Audiospur eines Videos mithilfe KI-gestützter Spracherkennung (faster-whisper). Unterstützt automatische Erkennung und 10 explizite Sprachen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/auto-subtitles` Akzeptiert Multipart-Formulardaten mit einer Videodatei und einem JSON-Feld `settings`. Dies ist ein asynchroner Endpunkt - er gibt sofort `202 Accepted` zurück, und der Fortschritt wird über SSE unter `GET /api/v1/jobs/{jobId}/progress` gestreamt. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | language | string | Nein | `"auto"` | Sprache der Sprachaufnahme: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | format | string | Nein | `"srt"` | Ausgabeformat der Untertitel: `srt`, `vtt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/auto-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"language": "en", "format": "srt"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Dies ist ein KI-Tool, das die Installation des **transcription**-Feature-Bundles erfordert. Wenn das Bundle nicht installiert ist, gibt die API `501 Feature Not Installed` mit Anweisungen zur Installation über die Admin-Oberfläche zurück. * Die Sprachoption `auto` verwendet die integrierte Spracherkennung von whisper. Die explizite Angabe der Sprache verbessert Genauigkeit und Geschwindigkeit. * SRT ist das am weitesten unterstützte Untertitelformat. VTT (WebVTT) ist der Standard für Web-Videoplayer. * Fortschrittsaktualisierungen sind über SSE unter `GET /api/v1/jobs/{jobId}/progress` verfügbar, bis der Job abgeschlossen ist. --- --- url: https://docs.snapotter.com/hi/tools/image/background-replace.md description: AI का उपयोग करके छवि की पृष्ठभूमि को एक ठोस रंग या ग्रेडिएंट से बदलें। --- # Background Replace {#background-replace} किसी छवि की पृष्ठभूमि को एक ठोस रंग या ग्रेडिएंट से बदलें। AI मॉडल विषय का पता लगाता है, मूल पृष्ठभूमि हटाता है, और विषय को आपकी चुनी हुई पृष्ठभूमि पर कंपोज़िट करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` एक छवि फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"color"` | पृष्ठभूमि मोड: `color` या `gradient` | | color | string | No | `"#ffffff"` | पृष्ठभूमि हेक्स रंग (जब backgroundType `color` हो) | | gradientColor1 | string | No | - | पहला ग्रेडिएंट हेक्स रंग | | gradientColor2 | string | No | - | दूसरा ग्रेडिएंट हेक्स रंग | | gradientAngle | integer | No | `180` | डिग्री में ग्रेडिएंट कोण (0-360) | | feather | integer | No | `0` | एज फ़ेदरिंग त्रिज्या (0-20) | | format | string | No | `"png"` | आउटपुट प्रारूप: `png` या `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` `GET /api/v1/jobs/{jobId}/progress` पर SSE के ज़रिए प्रगति ट्रैक करें। जब जॉब पूरा होता है, तो SSE स्ट्रीम डाउनलोड URL के साथ एक `completed` इवेंट उत्सर्जित करता है। ## Notes {#notes} * यह एक AI-संचालित टूल है जो `202 Accepted` लौटाता है और असिंक्रोनस रूप से प्रोसेस करता है। प्रगति अपडेट और अंतिम परिणाम प्राप्त करने के लिए SSE एंडपॉइंट से कनेक्ट करें। * इसके लिए **background-removal** फ़ीचर बंडल का इंस्टॉल होना आवश्यक है। यदि बंडल उपलब्ध नहीं है तो `501` लौटाता है। * HEIC, RAW, PSD, और SVG इनपुट को प्रोसेसिंग से पहले स्वचालित रूप से डिकोड किया जाता है। * विषय के चारों ओर पारदर्शिता संरक्षित करने के लिए आउटपुट PNG पर डिफ़ॉल्ट होता है। --- --- url: https://docs.snapotter.com/ja/tools/image/background-replace.md description: AI を使用して画像の背景を単色またはグラデーションに置き換えます。 --- # Background Replace {#background-replace} 画像の背景を単色またはグラデーションに置き換えます。AI モデルが被写体を検出し、元の背景を除去して、選択した背景の上に被写体を合成します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` 画像ファイルと JSON の `settings` フィールドを含むマルチパートフォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"color"` | 背景モード: `color` または `gradient` | | color | string | No | `"#ffffff"` | 背景の 16 進カラー (backgroundType が `color` の場合) | | gradientColor1 | string | No | - | グラデーションの 1 番目の 16 進カラー | | gradientColor2 | string | No | - | グラデーションの 2 番目の 16 進カラー | | gradientAngle | integer | No | `180` | グラデーションの角度 (度) (0 ~ 360) | | feather | integer | No | `0` | エッジのぼかし半径 (0 ~ 20) | | format | string | No | `"png"` | 出力形式: `png` または `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` 進捗は `GET /api/v1/jobs/{jobId}/progress` の SSE で追跡できます。ジョブが完了すると、SSE ストリームがダウンロード URL 付きの `completed` イベントを発行します。 ## Notes {#notes} * これは `202 Accepted` を返し、非同期で処理する AI 対応ツールです。SSE エンドポイントに接続して進捗の更新と最終結果を受け取ってください。 * **background-removal** 機能バンドルのインストールが必要です。バンドルが利用できない場合は `501` を返します。 * HEIC、RAW、PSD、SVG の入力は処理前に自動的にデコードされます。 * 被写体周辺の透明度を保持するため、出力はデフォルトで PNG になります。 --- --- url: https://docs.snapotter.com/ko/tools/image/background-replace.md description: AI를 사용하여 이미지 배경을 단색 또는 그라디언트로 교체합니다. --- # Background Replace {#background-replace} 이미지 배경을 단색 또는 그라디언트로 교체합니다. AI 모델이 피사체를 감지하고, 원본 배경을 제거한 후, 선택한 배경 위에 피사체를 합성합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/background-replace` 이미지 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | backgroundType | string | 아니요 | `"color"` | 배경 모드: `color` 또는 `gradient` | | color | string | 아니요 | `"#ffffff"` | 배경 16진수 색상 (backgroundType이 `color`일 때) | | gradientColor1 | string | 아니요 | - | 첫 번째 그라디언트 16진수 색상 | | gradientColor2 | string | 아니요 | - | 두 번째 그라디언트 16진수 색상 | | gradientAngle | integer | 아니요 | `180` | 그라디언트 각도 (0-360) | | feather | integer | 아니요 | `0` | 가장자리 페더링 반경 (0-20) | | format | string | 아니요 | `"png"` | 출력 형식: `png` 또는 `webp` | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 진행 상황을 추적할 수 있습니다. 작업이 완료되면 SSE 스트림이 다운로드 URL과 함께 `completed` 이벤트를 발생시킵니다. ## 참고 사항 {#notes} * 이 도구는 `202 Accepted`을(를) 반환하고 비동기적으로 처리하는 AI 기반 도구입니다. 진행 상황 업데이트와 최종 결과를 받으려면 SSE 엔드포인트에 연결하세요. * **background-removal** 기능 번들이 설치되어 있어야 합니다. 번들을 사용할 수 없는 경우 `501`을(를) 반환합니다. * HEIC, RAW, PSD, SVG 입력은 처리 전에 자동으로 디코딩됩니다. * 피사체 주변의 투명도를 유지하기 위해 출력은 기본적으로 PNG로 설정됩니다. --- --- url: https://docs.snapotter.com/th/tools/image/background-replace.md description: แทนที่พื้นหลังรูปภาพด้วยสีทึบหรือไล่ระดับสีโดยใช้ AI --- # Background Replace {#background-replace} แทนที่พื้นหลังของรูปภาพด้วยสีทึบหรือไล่ระดับสี โมเดล AI จะตรวจจับวัตถุ, ลบพื้นหลังเดิม และวางวัตถุลงบนพื้นหลังที่คุณเลือก ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` รับข้อมูลแบบ multipart form data พร้อมไฟล์รูปภาพและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"color"` | โหมดพื้นหลัง: `color` หรือ `gradient` | | color | string | No | `"#ffffff"` | สีพื้นหลังแบบ hex (เมื่อ backgroundType เป็น `color`) | | gradientColor1 | string | No | - | สีไล่ระดับแบบ hex สีแรก | | gradientColor2 | string | No | - | สีไล่ระดับแบบ hex สีที่สอง | | gradientAngle | integer | No | `180` | มุมไล่ระดับสีเป็นองศา (0-360) | | feather | integer | No | `0` | รัศมีการเบลอขอบ (0-20) | | format | string | No | `"png"` | รูปแบบเอาต์พุต: `png` หรือ `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ติดตามความคืบหน้าผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` เมื่องานเสร็จสมบูรณ์ สตรีม SSE จะปล่อยเหตุการณ์ `completed` พร้อม URL สำหรับดาวน์โหลด ## Notes {#notes} * นี่เป็นเครื่องมือที่ขับเคลื่อนด้วย AI ซึ่งส่งคืน `202 Accepted` และประมวลผลแบบอะซิงโครนัส เชื่อมต่อกับเอนด์พอยต์ SSE เพื่อรับการอัปเดตความคืบหน้าและผลลัพธ์สุดท้าย * ต้องติดตั้งชุดฟีเจอร์ **background-removal** ส่งคืน `501` หากไม่มีชุดนี้ * อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนประมวลผล * เอาต์พุตเริ่มต้นเป็น PNG เพื่อรักษาความโปร่งใสรอบ ๆ วัตถุ --- --- url: https://docs.snapotter.com/vi/tools/image/background-replace.md description: Thay thế nền hình ảnh bằng một màu đơn sắc hoặc dải màu bằng AI. --- # Background Replace {#background-replace} Thay thế nền của một hình ảnh bằng một màu đơn sắc hoặc dải màu. Mô hình AI phát hiện chủ thể, loại bỏ nền gốc và ghép chủ thể lên nền bạn đã chọn. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` Chấp nhận dữ liệu biểu mẫu multipart với một tệp hình ảnh và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"color"` | Chế độ nền: `color` hoặc `gradient` | | color | string | No | `"#ffffff"` | Màu hex của nền (khi backgroundType là `color`) | | gradientColor1 | string | No | - | Màu hex đầu tiên của dải màu | | gradientColor2 | string | No | - | Màu hex thứ hai của dải màu | | gradientAngle | integer | No | `180` | Góc dải màu theo độ (0-360) | | feather | integer | No | `0` | Bán kính làm mờ viền (0-20) | | format | string | No | `"png"` | Định dạng đầu ra: `png` hoặc `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Theo dõi tiến trình qua SSE tại `GET /api/v1/jobs/{jobId}/progress`. Khi công việc hoàn tất, luồng SSE phát ra một sự kiện `completed` với URL tải xuống. ## Notes {#notes} * Đây là một công cụ dựa trên AI trả về `202 Accepted` và xử lý bất đồng bộ. Kết nối tới endpoint SSE để nhận cập nhật tiến trình và kết quả cuối cùng. * Yêu cầu cài đặt gói tính năng **background-removal**. Trả về `501` nếu gói không có sẵn. * Các đầu vào HEIC, RAW, PSD và SVG được tự động giải mã trước khi xử lý. * Đầu ra mặc định là PNG để giữ độ trong suốt quanh chủ thể. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/background-replace.md description: 使用 AI 将图像背景替换为纯色或渐变。 --- # Background Replace {#background-replace} 将图像背景替换为纯色或渐变。AI 模型会检测主体、移除原始背景,并将主体合成到你选择的背景上。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` 接受包含图像文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | 否 | `"color"` | 背景模式:`color` 或 `gradient` | | color | string | 否 | `"#ffffff"` | 背景十六进制颜色(当 backgroundType 为 `color` 时) | | gradientColor1 | string | 否 | - | 第一个渐变十六进制颜色 | | gradientColor2 | string | 否 | - | 第二个渐变十六进制颜色 | | gradientAngle | integer | 否 | `180` | 渐变角度(度,0-360) | | feather | integer | 否 | `0` | 边缘羽化半径(0-20) | | format | string | 否 | `"png"` | 输出格式:`png` 或 `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` 通过 `GET /api/v1/jobs/{jobId}/progress` 处的 SSE 跟踪进度。任务完成后,SSE 流会发出一个带下载 URL 的 `completed` 事件。 ## Notes {#notes} * 这是一个 AI 驱动的工具,返回 `202 Accepted` 并异步处理。连接到 SSE 端点以接收进度更新和最终结果。 * 需要安装 **background-removal** 功能包。如果该包不可用,则返回 `501`。 * HEIC、RAW、PSD 和 SVG 输入在处理前会自动解码。 * 输出默认为 PNG,以保留主体周围的透明度。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/background-replace.md description: 使用 AI 將影像背景替換為純色或漸層。 --- # Background Replace {#background-replace} 將影像背景替換為純色或漸層。AI 模型會偵測主體、移除原始背景,並將主體合成到你所選的背景上。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` 接受包含影像檔案及 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"color"` | 背景模式:`color` 或 `gradient` | | color | string | No | `"#ffffff"` | 背景十六進位色碼(當 backgroundType 為 `color` 時) | | gradientColor1 | string | No | - | 第一個漸層十六進位色碼 | | gradientColor2 | string | No | - | 第二個漸層十六進位色碼 | | gradientAngle | integer | No | `180` | 漸層角度(0-360 度) | | feather | integer | No | `0` | 邊緣羽化半徑(0-20) | | format | string | No | `"png"` | 輸出格式:`png` 或 `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` 可透過 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 追蹤進度。當工作完成時,SSE 串流會發出帶有下載 URL 的 `completed` 事件。 ## Notes {#notes} * 這是一個 AI 驅動的工具,會回傳 `202 Accepted` 並以非同步方式處理。請連線至 SSE 端點以接收進度更新與最終結果。 * 需要安裝 **background-removal** 功能套件。若套件不可用,會回傳 `501`。 * HEIC、RAW、PSD 及 SVG 輸入會在處理前自動解碼。 * 輸出預設為 PNG,以保留主體周圍的透明度。 --- --- url: https://docs.snapotter.com/sv/tools/video/embed-subtitles.md description: Muxa ett undertextspår in i videocontainern. --- # Bädda in undertexter {#embed-subtitles} Muxa en undertextfil in i videocontainern som ett mjukt undertextspår som tittarna kan slå av och på. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Tar emot multipart-formulärdata med en videofil och en undertextfil, plus ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | language | string | Nej | `"eng"` | Språkkod enligt ISO 639-2/B (3 gemena bokstäver, t.ex. `"eng"`, `"fra"`, `"deu"`) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Anteckningar {#notes} * Ladda upp två filer: den första måste vara en video, den andra måste vara en undertextfil (.srt, .vtt eller .ass). * Inbäddade (mjuka) undertexter kan slås av och på av tittaren i deras mediaspelare. För permanent synliga undertexter, använd verktyget Bränn in undertexter i stället. * Språkkoden lagras som metadata i containern och hjälper mediaspelare att märka undertextspåret. --- --- url: https://docs.snapotter.com/id/tools/image/split.md description: >- Membagi satu gambar menjadi petak-petak grid berdasarkan baris dan kolom atau berdasarkan ukuran piksel, dikembalikan sebagai arsip ZIP. --- # Bagi Gambar {#image-splitting} Membagi satu gambar menjadi petak-petak grid berdasarkan jumlah kolom/baris atau berdasarkan dimensi piksel tertentu. Mengembalikan arsip ZIP yang berisi semua petak. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/split` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | columns | integer | No | 3 | Jumlah kolom untuk membagi (1 hingga 100) | | rows | integer | No | 3 | Jumlah baris untuk membagi (1 hingga 100) | | tileWidth | integer | No | - | Lebar petak dalam piksel (min 10). Menggantikan `columns` ketika `tileWidth` dan `tileHeight` keduanya diatur. | | tileHeight | integer | No | - | Tinggi petak dalam piksel (min 10). Menggantikan `rows` ketika `tileWidth` dan `tileHeight` keduanya diatur. | | outputFormat | string | No | `"original"` | Format keluaran untuk petak: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Kualitas keluaran untuk format lossy (1 hingga 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Example Response {#example-response} Responsnya dialirkan langsung sebagai file ZIP dengan `Content-Type: application/zip`. Nama file mengikuti pola `split-.zip`. Setiap petak di dalam ZIP diberi nama `_r_c.` (mis. `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Notes {#notes} * Menerima satu file gambar. * Mendukung format masukan HEIC, RAW, PSD, dan SVG (otomatis didekode). * Ketika `tileWidth` dan `tileHeight` keduanya diberikan, keduanya diprioritaskan di atas `columns`/`rows`. Dimensi grid dihitung sebagai `ceil(imageWidth / tileWidth)` dan `ceil(imageHeight / tileHeight)`. * Petak tepi (kolom paling kanan, baris bawah) mungkin lebih kecil dari ukuran petak yang ditentukan jika dimensi gambar tidak habis dibagi rata. * Ukuran grid maksimum dibatasi hingga 100x100 (10.000 petak). * Responsnya mengalirkan ZIP secara langsung, sehingga tidak ada body respons JSON. Gunakan `--output` dengan curl untuk menyimpan file. --- --- url: https://docs.snapotter.com/pt-BR/guide/database.md description: >- Esquema do banco de dados PostgreSQL, tabelas, migrações e procedimentos de backup do SnapOtter. --- # Banco de dados {#database} O SnapOtter usa PostgreSQL 17 com [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) para persistência de dados. O esquema é definido em `apps/api/src/db/schema.ts`. A conexão é configurada através da variável de ambiente `DATABASE_URL` (padrão `postgres://snapotter:snapotter@postgres:5432/snapotter`). No Docker Compose, o contêiner do Postgres armazena seus dados no volume nomeado `SnapOtter-pgdata`. ## Tabelas {#tables} ### users {#users} Armazena contas de usuário. Criada automaticamente na primeira execução a partir de `DEFAULT_USERNAME` e `DEFAULT_PASSWORD`. | Coluna | Tipo | Observações | |---|---|---| | `id` | uuid | Chave primária | | `username` | varchar | Único, obrigatório | | `passwordHash` | varchar | hash scrypt | | `role` | varchar | `admin`, `editor` ou `user` | | `mustChangePassword` | boolean | Flag de redefinição de senha forçada | | `createdAt` | timestamp | Horário de criação | | `updatedAt` | timestamp | Horário da última atualização | ### sessions {#sessions} Sessões de login ativas. Cada linha vincula um token de sessão a um usuário. | Coluna | Tipo | Observações | |---|---|---| | `id` | varchar | Chave primária (token de sessão) | | `userId` | uuid | Chave estrangeira para `users.id` | | `expiresAt` | timestamp | Horário de expiração | | `createdAt` | timestamp | Horário de criação | ### teams {#teams} Grupos para organizar usuários. Administradores podem atribuir usuários a equipes. | Coluna | Tipo | Descrição | |--------|------|-------------| | `id` | uuid | Chave primária | | `name` | varchar (único, máx. 50 caracteres) | Nome da equipe | | `createdAt` | timestamp | Horário de criação | ### api\_keys {#api-keys} Chaves de API para acesso programático. A chave bruta é exibida uma única vez na criação; apenas o hash é armazenado. | Coluna | Tipo | Observações | |---|---|---| | `id` | uuid | Chave primária | | `userId` | uuid | Chave estrangeira para `users.id` | | `keyHash` | varchar | hash scrypt da chave | | `name` | varchar | Rótulo fornecido pelo usuário | | `createdAt` | timestamp | Horário de criação | | `lastUsedAt` | timestamp | Atualizado a cada requisição autenticada | As chaves têm o prefixo `si_` seguido de 96 caracteres hexadecimais (48 bytes aleatórios). ### pipelines {#pipelines} Cadeias de ferramentas salvas que os usuários criam na interface. | Coluna | Tipo | Observações | |---|---|---| | `id` | uuid | Chave primária | | `name` | varchar | Nome do pipeline | | `description` | varchar | Descrição opcional | | `steps` | jsonb | Array de objetos `{ toolId, settings }` | | `createdAt` | timestamp | Horário de criação | ### user\_files {#user-files} Biblioteca de arquivos persistente. Uma edição salva é inserida por padrão como uma linha raiz independente ("salvar como novo": `version` 1, `parentId` null, então o original permanece listado), ou como uma versão vinculada ao pai quando você sobrescreve o original (`parentId` definido, `version` incrementado, substituindo-o). A coluna `toolChain` registra as ferramentas aplicadas. | Coluna | Tipo | Descrição | |--------|------|-------------| | `id` | uuid | Chave primária | | `userId` | uuid | FK para users (CASCADE DELETE) | | `originalName` | varchar | Nome do arquivo enviado original | | `storedName` | varchar | Nome do arquivo em disco | | `mimeType` | varchar | Tipo MIME | | `size` | integer | Tamanho do arquivo em bytes | | `width` | integer | Largura da imagem em px | | `height` | integer | Altura da imagem em px | | `version` | integer | Número da versão (1 = original) | | `parentId` | uuid ou null | FK para user\_files (versão pai) | | `toolChain` | jsonb | IDs de ferramentas aplicados em ordem para produzir esta versão | | `createdAt` | timestamp | Horário de criação | ### jobs {#jobs} Rastreia jobs de processamento para relatório de progresso e limpeza. | Coluna | Tipo | Observações | |---|---|---| | `id` | uuid | Chave primária | | `type` | varchar | Identificador da ferramenta ou do pipeline | | `status` | varchar | `queued`, `processing`, `completed` ou `failed` | | `progress` | real | Fração de 0.0 a 1.0 | | `inputFiles` | jsonb | Array de caminhos de arquivos de entrada | | `outputPath` | varchar | Caminho para o arquivo de resultado | | `settings` | jsonb | Configurações da ferramenta utilizadas | | `error` | varchar | Mensagem de erro se falhou | | `createdAt` | timestamp | Horário de criação | | `completedAt` | timestamp | Horário de conclusão | ### settings {#settings} Armazenamento de chave-valor para configurações de todo o servidor que os administradores podem alterar pela interface. | Coluna | Tipo | Observações | |---|---|---| | `key` | varchar | Chave primária | | `value` | varchar | Valor da configuração | | `updatedAt` | timestamp | Horário da última atualização | ### roles {#roles} Papéis personalizados com permissões granulares. | Coluna | Tipo | Observações | |---|---|---| | `id` | uuid | Chave primária | | `name` | varchar | Nome único do papel | | `description` | varchar | Descrição opcional | | `permissions` | jsonb | Array de strings de permissão | | `createdAt` | timestamp | Horário de criação | ### audit\_log {#audit-log} Registro de ações relevantes para segurança. | Coluna | Tipo | Observações | |---|---|---| | `id` | uuid | Chave primária | | `userId` | uuid | FK para users | | `action` | varchar | Tipo de ação | | `details` | jsonb | Dados específicos da ação | | `createdAt` | timestamp | Horário da ação | ### user\_preferences {#user-preferences} Estado da interface por usuário, indexado pelo nome da preferência. Guarda as ferramentas fixadas da página inicial, gravadas por meio de `PUT /api/v1/preferences`. | Coluna | Tipo | Observações | |---|---|---| | `userId` | text | FK para users, com exclusão em cascata. Chave primária junto com `key` | | `key` | text | Nome da preferência. Chave primária junto com `userId` | | `value` | jsonb | Conteúdo da preferência | | `updatedAt` | timestamp | Última gravação | ## Migrações {#migrations} O Drizzle cuida das migrações de esquema. Os arquivos de migração ficam em `apps/api/drizzle/`. Durante o desenvolvimento: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Em produção, as migrações pendentes são aplicadas automaticamente na inicialização. ## Backup e restauração {#backup-and-restore} O banco de dados relacional reside no volume `SnapOtter-pgdata` do contêiner Postgres, não no volume `/data` do aplicativo. **Backup lógico com validação (recomendado)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Este dump do banco de dados não contém objetos de biblioteca salvos em `/data/files` ou estado BullMQ durável no Redis. Faça backup e restaure-os com o procedimento coordenado em [Segurança e Proteção](/pt-BR/guide/security#backup-and-recovery). **Instantâneo de volume frio** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Não copie um diretório de dados PostgreSQL ativo com `tar`. Componha nomes de volume de prefixos por projeto, portanto resolva os IDs de volume montados de `docker inspect` ou de sua plataforma de armazenamento em vez de assumir o rótulo literal `SnapOtter-pgdata`. ### Migrando da versão 1.x (SQLite) {#migrating-from-1-x-sqlite} Atualizar do SnapOtter 1.x tem seu próprio guia: veja [Atualizando da 1.x para a 2.0](./upgrading). Em resumo, reutilize seu volume `/data` existente e a 2.0 detecta e importa automaticamente o `/data/snapotter.db` na primeira inicialização (ou defina `SQLITE_MIGRATE_PATH` para apontar para ele explicitamente). Faça backup de todo o volume `/data` primeiro, não apenas de `snapotter.db`: a 1.x usa o modo WAL do SQLite, então um contêiner parado frequentemente deixa a maior parte de seus dados em `snapotter.db-wal` ao lado de um `snapotter.db` quase vazio. --- --- url: https://docs.snapotter.com/id/tools/image/compare.md description: >- Bandingkan dua gambar berdampingan dengan visualisasi diff tingkat piksel dan skor kemiripan. --- # Bandingkan Gambar {#image-compare} Unggah dua gambar untuk menghitung peta perbedaan tingkat piksel dan persentase kemiripan numerik. Outputnya adalah gambar diff yang menyoroti area yang berubah dengan warna merah. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compare` Menerima data formulir multipart dengan **dua** file gambar. Tidak diperlukan field pengaturan. ## Parameter {#parameters} Alat ini tidak memiliki parameter yang dapat dikonfigurasi. Unggah tepat dua file gambar. | Field | Tipe | Wajib | Deskripsi | |-------|------|----------|-------------| | file (pertama) | file | Ya | Gambar pertama | | file (kedua) | file | Ya | Gambar kedua | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Field Respons {#response-fields} | Field | Tipe | Deskripsi | |-------|------|-------------| | jobId | string | Pengenal pekerjaan untuk mengunduh gambar diff | | similarity | number | Persentase kemiripan antara kedua gambar (0 hingga 100) | | dimensions | object | Lebar dan tinggi yang digunakan untuk perbandingan | | downloadUrl | string | URL untuk mengunduh gambar diff yang dihasilkan | | originalSize | number | Gabungan ukuran kedua gambar input dalam byte | | processedSize | number | Ukuran gambar diff output dalam byte | ## Catatan {#notes} * Kedua gambar diubah ukurannya menjadi dimensi yang sama (maksimum dari masing-masing sumbu) sebelum dibandingkan. * Gambar diff menyoroti perbedaan dengan warna merah dengan opasitas sebanding dengan besarnya perubahan. Piksel yang identik atau hampir identik (perbedaan < 10) ditampilkan sebagai versi semi-transparan dari gambar asli. * Kemiripan dihitung sebagai kebalikan dari rata-rata perbedaan piksel di seluruh piksel, dinyatakan sebagai persentase. * Kemiripan 100% berarti gambar-gambar tersebut identik secara piksel (pada resolusi perbandingan). * Output diff selalu berformat PNG terlepas dari format input. * Kedua gambar divalidasi dan didekode (HEIC, RAW, PSD, SVG didukung) sebelum dibandingkan. * Orientasi EXIF diterapkan otomatis pada kedua gambar sebelum diproses. --- --- url: https://docs.snapotter.com/vi/tools/image/color-palette.md description: Trích xuất các màu chủ đạo từ một ảnh dưới dạng bảng màu. --- # Bảng màu {#color-palette} Trích xuất các màu chủ đạo từ một ảnh và trả về dưới dạng giá trị màu hex. Sử dụng phân tích tần suất lượng tử hóa để xác định những màu nổi bật nhất và khác biệt về mặt thị giác. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-palette` Chấp nhận dữ liệu form multipart với một tệp ảnh và một trường JSON `settings` tùy chọn. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | count | integer | Không | `8` | Số màu cần trích xuất (2-16) | | format | string | Không | `"hex"` | Định dạng màu: `hex`, `rgb`, `hsl` | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Các trường phản hồi {#response-fields} | Trường | Kiểu | Mô tả | |-------|------|-------------| | filename | string | Tên tệp đã được làm sạch | | colors | array | Mảng các chuỗi màu theo định dạng yêu cầu, sắp xếp theo mức độ chủ đạo (nhiều nhất trước) | | hex | array | Mảng các chuỗi màu hex (luôn là hex, bất kể thiết lập `format`) | | count | number | Số màu đã trích xuất | ## Ghi chú {#notes} * Trả về tối đa `count` màu chủ đạo (mặc định 8, khoảng 2-16), sắp xếp theo tần suất (phổ biến nhất trước). * Ảnh được thay đổi kích thước nội bộ thành 100x100 pixel để phân tích, nên bảng màu thể hiện phân bố màu tổng thể thay vì các chi tiết nhỏ. * Màu được trích xuất bằng lượng tử hóa cắt trung vị, phương pháp này chia đệ quy các nhóm pixel dọc theo kênh có dải rộng nhất. * Kênh alpha được loại bỏ trước khi phân tích, nên các vùng trong suốt không được tính đến. * Đây là endpoint chỉ đọc. Nó không tạo tệp đầu ra tải xuống được hay `jobId`. * Đầu vào HEIC, RAW, PSD và SVG được giải mã tự động trước khi phân tích. --- --- url: https://docs.snapotter.com/vi/guide/security.md description: >- Hướng dẫn tăng cường bảo mật cho SnapOtter. Bảo mật container, cô lập mạng, Docker secret, triển khai Kubernetes, và các tài liệu tuân thủ. --- # Bảo mật & Tăng cường {#security-hardening} SnapOtter xử lý tập tin hoàn toàn trên hạ tầng của bạn. Nó gửi phân tích sản phẩm và báo cáo sự cố ẩn danh, không chứa nội dung, theo mặc định để giúp cải thiện dự án. Nó không bao giờ gửi tập tin, tên tập tin, nội dung tập tin, kết quả OCR, metadata hình ảnh, hoặc văn bản tài liệu của bạn. Phản hồi tùy chọn chỉ được gửi sau khi người dùng gửi nó, chỉ khi phân tích được bật, và các trường liên hệ chỉ được bao gồm khi có sự đồng ý liên hệ tường minh. Một quản trị viên có thể tắt việc thu thập phân tích và phản hồi chỉ với một cú nhấp trong mục Settings > System > Privacy, không cần xây dựng lại. Việc xử lý tập tin luôn ở bên trong container của bạn. Container chạy dưới danh nghĩa một người dùng không phải root chuyên dụng (`snapotter`) với tất cả các capability của Linux được loại bỏ ngoại trừ tập tối thiểu cần thiết. Để xem đầy đủ chính sách công bố lỗ hổng và kiến trúc bảo mật, xem [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) trên GitHub. ## Làm cứng thùng chứa {#container-hardening} Các tệp soạn thảo [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) và [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml) chuẩn là nguồn gốc của sự thật. Không sao chép một ví dụ viết tắt vào sản xuất; triển khai tệp từ thẻ phát hành mà bạn đã xác minh. Cả hai ngăn xếp đều áp dụng các điều khiển sau: * Các giới hạn về bộ nhớ, trao đổi, CPU và PID chứa quá trình xử lý gốc chạy trốn. * Mọi dịch vụ đều loại bỏ tất cả các khả năng của Linux. Ứng dụng chỉ bổ sung lại `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` để sở hữu khối lượng, giảm danh tính `gosu` một chiều và chuyển tiếp tín hiệu duyên dáng. PostgreSQL và Redis chỉ nhận được tập hợp con mà điểm truy nhập chính thức của họ cần. * `security_opt: [no-new-privileges:true]` ngăn các quy trình trong vùng chứa ứng dụng, PostgreSQL và Redis có được các đặc quyền bổ sung. Điều này vẫn tương thích với `gosu`: điểm vào bắt đầu với quyền root, chuẩn bị các ổ đĩa và chỉ giảm xuống người dùng `snapotter` chuyên dụng. * Đầu vào hình ảnh PostgreSQL và Redis được ghim bằng thông báo. Ứng dụng cũng phải được ghim vào thẻ phát hành hoặc thông báo đã được xác minh thay vì `latest`. * Kiểm tra tình trạng, xoay vòng nhật ký JSON có giới hạn, Redis AOF bền vững và chính sách khởi động lại được xác định tập trung trong các tệp chuẩn. Để triển khai qua Internet, hãy liên kết cổng 1349 với loopback và chấm dứt TLS tại proxy ngược được duy trì. Tạo thông tin đăng nhập PostgreSQL và Redis duy nhất, lưu trữ bí mật trong các tệp được bảo vệ hoặc trình quản lý bí mật và thay đổi mật khẩu quản trị viên ban đầu ngay lập tức. ### Tại sao `read_only` không được đặt {#why-read-only-is-not-set} `read_only: true` không được đặt vì ánh xạ lại PUID/PGID ghi vào `/etc/passwd` và `/etc/group` khi khởi động. Nếu sử dụng cờ `--user` của Docker hoặc Kubernetes `runAsUser` thay vì PUID/PGID, bạn có thể kích hoạt hệ thống tệp gốc chỉ đọc một cách an toàn. ## Cách ly mạng {#network-isolation} Quá trình xử lý tệp diễn ra cục bộ nhưng cài đặt mặc định **không phải là hệ thống không có đầu ra**. Phân tích sản phẩm ẩn danh sử dụng PostHog và báo cáo sự cố sử dụng Sentry khi bật tính năng đo từ xa. Đặt `SNAPOTTER_TELEMETRY=0` (hoặc tắt phân tích trong Cài đặt > Hệ thống > Quyền riêng tư) để tắt cả hai. SnapOtter không bao giờ bao gồm các tệp đã tải lên, tên tệp, đầu ra OCR, văn bản tài liệu hoặc nội dung tệp khác trong các sự kiện đó. Lưu lượng truy cập đi khác được điều khiển theo tính năng: Tải xuống bản cài đặt mô hình/gói AI đã ký các đầu vào phát hành; Nhập URL tìm nạp URL công khai do người dùng yêu cầu; và OIDC, SAML, OpenTelemetry, webhooks, bộ lưu trữ tương thích với S3 hoặc các tích hợp tương tự được định cấu hình rõ ràng sẽ liên hệ với các đích đến do quản trị viên chọn. Tải xuống mô hình trong thời gian chạy bị tắt theo mặc định. Chỉ đặt `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` để bật rõ ràng tính năng tải xuống dự phòng tự động. [Nhập gói ngoại tuyến](/vi/guide/deployment) có thể cung cấp các tính năng AI mà không cần xuất ra mô hình thời gian chạy. **Khuyến nghị về tường lửa:** |Kịch bản|Quy tắc đi| |---|---| |Khe hở không khí|Đặt `SNAPOTTER_TELEMETRY=0` và `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0`, sử dụng tính năng nhập gói AI ngoại tuyến, tắt tính năng nhập URL và tích hợp bên ngoài, sau đó chặn lối ra| |đo từ xa mặc định|Cho phép các điểm cuối PostHog và Sentry được liệt kê theo nhật ký trình duyệt/mạng của bạn; vô hiệu hóa đo từ xa nếu chính sách không cho phép chúng| |Cần có gói AI|Trong quá trình cài đặt, hãy cho phép HTTPS thành `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org`; sau đó chặn những máy chủ đó| |Tích hợp bên ngoài|Chỉ cho phép các đích đến OIDC/SAML/OTLP/webhook/object-storage được định cấu hình chính xác bởi quản trị viên| Các kho lưu trữ gói được cung cấp từ bộ lưu trữ Xet của Hugging Face, lưu trữ này truyền song song qua các điểm cuối `*.xethub.hf.co` và giúp tải xuống gói nhiều GB nhanh chóng. Nếu tường lửa của bạn cho phép `huggingface.co` nhưng chặn `*.xethub.hf.co`, quá trình cài đặt vẫn thành công nhưng quay lại tải xuống một luồng chậm hơn, vì vậy, hãy đưa các máy chủ Xet vào danh sách để tiếp tục hoạt động nhanh chóng. Các bản cài đặt hoàn toàn ngoại tuyến có thể bỏ qua tất cả những điều này và thay vào đó hãy sử dụng [Nhập gói ngoại tuyến](/vi/guide/deployment). Để biết cấu hình proxy ngược (Nginx, Traefik, Caddy, Cloudflare Tunnels), hãy xem [Hướng dẫn triển khai](/vi/guide/deployment#reverse-proxy). ## Docker Secret {#docker-secrets} Đối với các triển khai production, tránh truyền secret dưới dạng biến môi trường văn bản thuần. Entrypoint hỗ trợ quy ước `_FILE` của Docker: mount một secret dưới dạng một tập tin và đặt biến `_FILE` tương ứng thành đường dẫn của nó. **Các secret được hỗ trợ:** | Biến | Tương đương `_FILE` | |---|---| | `DEFAULT_PASSWORD` | `DEFAULT_PASSWORD_FILE` | | `COOKIE_SECRET` | `COOKIE_SECRET_FILE` | | `OIDC_CLIENT_SECRET` | `OIDC_CLIENT_SECRET_FILE` | | `S3_ACCESS_KEY_ID` | `S3_ACCESS_KEY_ID_FILE` | | `S3_SECRET_ACCESS_KEY` | `S3_SECRET_ACCESS_KEY_FILE` | | `SNAPOTTER_LICENSE_KEY` | `SNAPOTTER_LICENSE_KEY_FILE` | **Ví dụ với Docker Compose secret:** ```yaml services: SnapOtter: image: snapotter/snapotter:latest environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD_FILE=/run/secrets/snapotter_password - COOKIE_SECRET_FILE=/run/secrets/cookie_secret secrets: - snapotter_password - cookie_secret secrets: snapotter_password: file: ./secrets/snapotter_password.txt cookie_secret: file: ./secrets/cookie_secret.txt ``` ::: tip Docker Compose secret (không dùng Swarm) yêu cầu Compose v2.23 trở lên. ::: ## Triển khai Kubernetes {#kubernetes-deployment} Entrypoint phát hiện khi container đã chạy sẵn dưới danh nghĩa không phải root (ví dụ, thông qua `runAsUser` của Kubernetes) và tự động bỏ qua việc hạ đặc quyền gosu. Trong trường hợp đó nó không thể tự chown các volume đã mount, nên nó xác minh rằng chúng có thể ghi được và thoát sớm với hướng dẫn khả thi nếu chúng không thể ghi, xem [Quyền lưu trữ](/vi/guide/deployment#storage-permissions) cho các thiết lập `fsGroup` và UID lạ (TrueNAS, OpenShift). **SecurityContext khuyến nghị cho Pod:** ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: snapotter spec: replicas: 1 selector: matchLabels: app: snapotter template: metadata: labels: app: snapotter spec: securityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 fsGroup: 999 containers: - name: snapotter image: snapotter/snapotter:latest ports: - containerPort: 1349 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] resources: requests: cpu: "1" memory: 2Gi limits: cpu: "4" memory: 6Gi livenessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readinessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - name: data mountPath: /data - name: workspace mountPath: /tmp/workspace volumes: - name: data persistentVolumeClaim: claimName: snapotter-data - name: workspace emptyDir: medium: Memory sizeLimit: 2Gi ``` Vì `runAsUser: 999` được đặt ở cấp pod, entrypoint bỏ qua hoàn toàn gosu. Điều này cho phép các capability `allowPrivilegeEscalation: false` và `drop: [ALL]` mà không xung đột. Để xác định kích cỡ tài nguyên, xem [Yêu cầu phần cứng](/vi/guide/deployment#hardware-requirements). ## Sao lưu và phục hồi {#backup-and-recovery} Ngăn xếp Compose sản xuất xác định bốn tập. Dừng xâm nhập và để các công việc đang hoạt động kết thúc trước khi thực hiện một bản sao lưu phối hợp để PostgreSQL, Redis và trạng thái tệp mô tả cùng một thời điểm. |Âm lượng|Nội dung|Điều trị phục hồi| |---|---|---| |`SnapOtter-pgdata`|Người dùng PostgreSQL, cài đặt, quy trình, công việc, siêu dữ liệu tệp và nhật ký kiểm tra|Phê bình; sử dụng kết xuất logic không nhanh để khôi phục di động| |`SnapOtter-data`|Các đối tượng thư viện, nhật ký và trạng thái AI đã lưu (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|Sao lưu toàn bộ âm lượng; để tiết kiệm dung lượng, cố tình bỏ qua tất cả trạng thái AI và cài đặt lại các gói của nó| |`SnapOtter-redisdata`|Redis AOF cho trạng thái hàng đợi BullMQ bền bỉ|Sao lưu sau khi tạm dừng ứng dụng và buộc `SAVE`; bắt buộc phải tiếp tục công việc được xếp hàng đợi một cách chính xác| |`SnapOtter-workspace`|Khóa lưu trữ đối tượng tạm thời (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|Không sao lưu sau khi tất cả công việc đã hoàn thành hoặc bị hủy bỏ; không bao giờ loại bỏ nó trong khi công việc đang hoạt động| Soạn các tên tập tiền tố thông thường với tên dự án. Giải quyết ổ nguồn thực từ vùng chứa được gắn thay vì giả sử rằng tên hiển thị như `SnapOtter-data` là tên ổ Docker. ### Sao lưu cơ sở dữ liệu {#database-backup} Sử dụng định dạng lưu trữ tùy chỉnh của PostgreSQL và xác minh kho lưu trữ trước khi xử lý bản sao lưu hoàn chỉnh: ```bash docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore only into a fresh/disposable target first; any SQL error fails the command. docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Kiểm tra mọi bản sao lưu bằng cách khôi phục nó vào một ngăn xếp riêng biệt, kiểm tra các bản ghi cơ sở dữ liệu và tổng kiểm tra tệp, rồi khởi động ứng dụng. `tests/qa/backup-restore-drill.sh` của kho lưu trữ tự động hóa cổng phát hành đó dựa trên `QA_IMAGE` rõ ràng. Thay vào đó, nếu nền tảng của bạn thực hiện các ảnh chụp nhanh ổ đĩa nhất quán với sự cố, trước tiên hãy dừng toàn bộ ngăn xếp và chụp nhanh tất cả các ổ đĩa quan trọng dưới dạng một bộ. Bản sao thư mục dữ liệu PostgreSQL thô từ vùng chứa đang chạy không phải là bản sao lưu logic được hỗ trợ. ### Sao lưu tệp và hàng đợi {#file-and-queue-backup} Tạm dừng ứng dụng trước khi chụp khối lượng tệp và hàng đợi. Sử dụng `docker inspect` để phân giải tên tập thực tế, buộc Redis duy trì trạng thái hiện tại và lưu trữ với quyền sở hữu và quyền được bảo toàn: ```bash docker stop SnapOtter docker exec SnapOtter-redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning SAVE docker stop SnapOtter-redis DATA_VOLUME="$(docker inspect SnapOtter --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" REDIS_VOLUME="$(docker inspect SnapOtter-redis --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" install -d -m 700 backup docker run --rm -v "$DATA_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-data.tar.gz -C /source . docker run --rm -v "$REDIS_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-redis.tar.gz -C /source . sha256sum backup/snapotter-*.tar.gz > backup/SHA256SUMS ``` Khởi động lại Redis trước ứng dụng. Nếu bạn cố tình loại trừ `/data/ai`, hãy xóa toàn bộ cây con AI thay vì lưu giữ bản ghi `installed.json` mà không có mô hình hoặc môi trường ảo của nó. Giữ các tệp sao lưu được mã hóa, kiểm soát quyền truy cập và tách biệt khỏi máy chủ chạy SnapOtter. ## Cấu phần tuân thủ {#compliance-artifacts} Mỗi bản phát hành SnapOtter bao gồm các tạo phẩm bảo mật sau: | Cổ vật | Định dạng | Tìm nó ở đâu | |---|---|---| | Giải phóng ràng buộc chủ đề | Chứng thực Canonical JSON + GitHub | Nội dung [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases): `snapotter-v{version}-release-subjects.json` | | Lưu trữ SBOM | CycloneDX và SPDX JSON | Nội dung phát hành: `snapotter-v{version}-archive-linux-{arch}-sbom.{cdx,spdx}.json` | | Hình ảnh SBOM | CycloneDX và SPDX JSON | Nội dung phát hành: `snapotter-v{version}-image-linux-{arch}-sbom.{cdx,spdx}.json` | | Quét lỗ hổng | Trivy JSON | Phát hành nội dung có tiền tố `archive-linux-{arch}` hoặc `image-linux-{arch}` phù hợp | | Quét lỗ hổng | SARIF | Tab [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security) | | Phân tích tĩnh | CodeQL (JS/TS + Python) | Tab [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security), chạy hàng tuần + mỗi PR | | Xem xét phụ thuộc | GitHub bản địa | Kiểm tra mỗi PR, không thành công khi bổ sung mức độ nghiêm trọng cao | | Kiểm tra phụ thuộc Python | pip-audit | CI chạy nhật ký trên mỗi lần đẩy | | Chính sách bảo mật | Markdown | [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) trong kho lưu trữ | | Cập nhật phụ thuộc | Dependabot | PR hàng tuần tự động cho npm, pip, Docker, Hành động | **Chạy quá trình quét của riêng bạn:** Tải xuống bản kê khai chủ đề phát hành và xác minh rằng nó đã được chứng thực bởi quy trình phát hành: ```bash gh attestation verify snapotter-v2.2.0-release-subjects.json \ --repo snapotter-hq/SnapOtter \ --signer-workflow snapotter-hq/SnapOtter/.github/workflows/release.yml ``` Tệp kê khai ghi lại `releaseTag`, `releaseCommit` và `workflowTriggerCommit` riêng biệt. Xác minh rằng `releaseCommit` là cam kết được tách khỏi thẻ bất biến, sau đó xác minh thông báo SHA-256 của kho lưu trữ, hình ảnh, SBOM hoặc bản quét mà bạn sử dụng đối với mục nhập của nó trong `subjects`. Sự khác biệt này là có chủ ý: việc kiểm tra cam kết phát hành mới được tạo không làm thay đổi danh tính cam kết trong thông tin xác thực OIDC của quy trình làm việc. Bạn cũng có thể quét trực tiếp SBOM đã tải xuống hoặc hình ảnh: ```bash # Scan with Grype using the CycloneDX SBOM grype sbom:snapotter-v2.2.0-image-linux-amd64-sbom.cdx.json # Scan with Trivy using the SPDX SBOM trivy sbom snapotter-v2.2.0-image-linux-amd64-sbom.spdx.json # Scan the Docker image directly trivy image snapotter/snapotter:2.2.0 ``` ::: info Hình ảnh SBOMs và các bản quét phản ánh chính xác hình ảnh theo kiến ​​trúc cụ thể được xuất bản cho bản phát hành đó. Lưu trữ SBOMs và các bản quét mô tả riêng biệt kho lưu trữ dựng sẵn. Các gói mô hình AI được cài đặt sau khi triển khai không được bao gồm trong các SBOMs này vì chúng được tải xuống khi chạy. ::: --- --- url: https://docs.snapotter.com/hi/tools/image/barcode-generate.md description: >- Code 128, EAN-13, UPC-A, Code 39, ITF-14, और Data Matrix प्रारूपों में बारकोड उत्पन्न करें। --- # Barcode Generator {#barcode-generator} टेक्स्ट इनपुट से बारकोड छवियाँ उत्पन्न करें। Code 128, EAN-13, UPC-A, Code 39, ITF-14, और Data Matrix प्रारूपों का समर्थन करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` एक `application/json` बॉडी स्वीकार करता है (multipart नहीं)। बारकोड प्रदान किए गए टेक्स्ट से उत्पन्न होता है, अपलोड की गई फ़ाइल से नहीं। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | बारकोड में एनकोड करने के लिए टेक्स्ट (1-256 वर्ण) | | type | string | No | `"code128"` | बारकोड प्रारूप: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | No | `3` | छवि स्केल कारक (1-8) | | includeText | boolean | No | `true` | बारकोड के नीचे टेक्स्ट रेंडर करना है या नहीं | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * अधिकांश टूल के विपरीत, यह एंडपॉइंट multipart form data नहीं बल्कि एक JSON बॉडी स्वीकार करता है, क्योंकि बारकोड अपलोड की गई फ़ाइल के बजाय टेक्स्ट से उत्पन्न होते हैं। * EAN-13 के लिए ठीक 12 या 13 अंक आवश्यक हैं। UPC-A के लिए ठीक 11 या 12 अंक आवश्यक हैं। यदि चेक अंक छोड़ दिया जाता है, तो इसकी गणना स्वचालित रूप से की जाती है। * Code 128 सबसे लचीला प्रारूप है और पूर्ण ASCII वर्ण सेट का समर्थन करता है। * Data Matrix एक 2D बारकोड उत्पन्न करता है जो लंबी स्ट्रिंग्स को एक सघन वर्ग में एनकोड करने के लिए उपयुक्त है। --- --- url: https://docs.snapotter.com/ja/tools/image/barcode-generate.md description: Code 128、EAN-13、UPC-A、Code 39、ITF-14、Data Matrix 形式のバーコードを生成します。 --- # Barcode Generator {#barcode-generator} テキスト入力からバーコード画像を生成します。Code 128、EAN-13、UPC-A、Code 39、ITF-14、Data Matrix 形式をサポートします。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` `application/json` ボディを受け付けます (マルチパートではありません)。バーコードはアップロードされたファイルではなく、指定されたテキストから生成されます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | バーコードにエンコードするテキスト (1 ~ 256 文字) | | type | string | No | `"code128"` | バーコード形式: `code128`、`ean13`、`upca`、`code39`、`itf14`、`datamatrix` | | scale | integer | No | `3` | 画像のスケール係数 (1 ~ 8) | | includeText | boolean | No | `true` | バーコードの下にテキストをレンダリングするかどうか | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * 大半のツールとは異なり、このエンドポイントはマルチパートフォームデータではなく JSON ボディを受け付けます。これは、バーコードがアップロードされたファイルではなくテキストから生成されるためです。 * EAN-13 は正確に 12 桁または 13 桁の数字が必要です。UPC-A は正確に 11 桁または 12 桁の数字が必要です。チェックディジットが省略された場合は自動的に計算されます。 * Code 128 は最も柔軟な形式で、完全な ASCII 文字セットをサポートします。 * Data Matrix は、長い文字列をコンパクトな正方形にエンコードするのに適した 2D バーコードを生成します。 --- --- url: https://docs.snapotter.com/ko/tools/image/barcode-generate.md description: Code 128, EAN-13, UPC-A, Code 39, ITF-14, Data Matrix 형식으로 바코드를 생성합니다. --- # Barcode Generator {#barcode-generator} 텍스트 입력으로부터 바코드 이미지를 생성합니다. Code 128, EAN-13, UPC-A, Code 39, ITF-14, Data Matrix 형식을 지원합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` `application/json` 본문(multipart 아님)을 받습니다. 바코드는 업로드된 파일이 아닌 제공된 텍스트로부터 생성됩니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | text | string | 예 | - | 바코드에 인코딩할 텍스트 (1-256자) | | type | string | 아니요 | `"code128"` | 바코드 형식: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | 아니요 | `3` | 이미지 배율 계수 (1-8) | | includeText | boolean | 아니요 | `true` | 바코드 아래에 텍스트를 렌더링할지 여부 | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## 참고 사항 {#notes} * 대부분의 도구와 달리, 바코드는 업로드된 파일이 아닌 텍스트로부터 생성되므로 이 엔드포인트는 multipart form data가 아닌 JSON 본문을 받습니다. * EAN-13은 정확히 12자리 또는 13자리를 요구합니다. UPC-A는 정확히 11자리 또는 12자리를 요구합니다. 검사 숫자가 생략된 경우 자동으로 계산됩니다. * Code 128은 가장 유연한 형식이며 전체 ASCII 문자 집합을 지원합니다. * Data Matrix는 더 긴 문자열을 작은 정사각형에 인코딩하기에 적합한 2D 바코드를 생성합니다. --- --- url: https://docs.snapotter.com/th/tools/image/barcode-generate.md description: สร้างบาร์โค้ดในรูปแบบ Code 128, EAN-13, UPC-A, Code 39, ITF-14 และ Data Matrix --- # Barcode Generator {#barcode-generator} สร้างรูปภาพบาร์โค้ดจากข้อความอินพุต รองรับรูปแบบ Code 128, EAN-13, UPC-A, Code 39, ITF-14 และ Data Matrix ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` รับเนื้อหา `application/json` (ไม่ใช่ multipart) บาร์โค้ดถูกสร้างจากข้อความที่ให้มา ไม่ใช่จากไฟล์ที่อัปโหลด ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | ข้อความที่จะเข้ารหัสในบาร์โค้ด (1-256 ตัวอักษร) | | type | string | No | `"code128"` | รูปแบบบาร์โค้ด: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | No | `3` | ปัจจัยการปรับขนาดรูปภาพ (1-8) | | includeText | boolean | No | `true` | จะเรนเดอร์ข้อความใต้บาร์โค้ดหรือไม่ | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * ต่างจากเครื่องมือส่วนใหญ่ เอนด์พอยต์นี้รับเนื้อหา JSON ไม่ใช่ multipart form data เนื่องจากบาร์โค้ดถูกสร้างจากข้อความมากกว่าไฟล์ที่อัปโหลด * EAN-13 ต้องมี 12 หรือ 13 หลักพอดี UPC-A ต้องมี 11 หรือ 12 หลักพอดี หากละเว้นหลักตรวจสอบ ระบบจะคำนวณให้อัตโนมัติ * Code 128 เป็นรูปแบบที่ยืดหยุ่นที่สุดและรองรับชุดอักขระ ASCII ทั้งหมด * Data Matrix สร้างบาร์โค้ด 2 มิติที่เหมาะสำหรับเข้ารหัสสตริงที่ยาวขึ้นในรูปสี่เหลี่ยมจัตุรัสที่กะทัดรัด --- --- url: https://docs.snapotter.com/vi/tools/image/barcode-generate.md description: >- Tạo mã vạch ở các định dạng Code 128, EAN-13, UPC-A, Code 39, ITF-14 và Data Matrix. --- # Barcode Generator {#barcode-generator} Tạo hình ảnh mã vạch từ văn bản đầu vào. Hỗ trợ các định dạng Code 128, EAN-13, UPC-A, Code 39, ITF-14 và Data Matrix. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Chấp nhận một phần thân `application/json` (không phải multipart). Mã vạch được tạo từ văn bản được cung cấp, không phải từ một tệp được tải lên. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Văn bản để mã hóa trong mã vạch (1-256 ký tự) | | type | string | No | `"code128"` | Định dạng mã vạch: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | No | `3` | Hệ số tỉ lệ hình ảnh (1-8) | | includeText | boolean | No | `true` | Có kết xuất văn bản bên dưới mã vạch hay không | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * Khác với hầu hết các công cụ, endpoint này chấp nhận một phần thân JSON, không phải dữ liệu biểu mẫu multipart, vì mã vạch được tạo từ văn bản thay vì một tệp được tải lên. * EAN-13 yêu cầu chính xác 12 hoặc 13 chữ số. UPC-A yêu cầu chính xác 11 hoặc 12 chữ số. Nếu bỏ qua chữ số kiểm tra, nó được tính toán tự động. * Code 128 là định dạng linh hoạt nhất và hỗ trợ toàn bộ bộ ký tự ASCII. * Data Matrix tạo ra một mã vạch 2D phù hợp để mã hóa các chuỗi dài hơn trong một ô vuông nhỏ gọn. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/barcode-generate.md description: 生成 Code 128、EAN-13、UPC-A、Code 39、ITF-14 和 Data Matrix 格式的条形码。 --- # Barcode Generator {#barcode-generator} 从文本输入生成条形码图像。支持 Code 128、EAN-13、UPC-A、Code 39、ITF-14 和 Data Matrix 格式。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` 接受一个 `application/json` 请求体(而非 multipart)。条形码由提供的文本生成,而不是由上传的文件生成。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | 是 | - | 要编码到条形码中的文本(1-256 个字符) | | type | string | 否 | `"code128"` | 条形码格式:`code128`、`ean13`、`upca`、`code39`、`itf14`、`datamatrix` | | scale | integer | 否 | `3` | 图像缩放系数(1-8) | | includeText | boolean | 否 | `true` | 是否在条形码下方渲染文本 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * 与大多数工具不同,此端点接受 JSON 请求体而非 multipart 表单数据,因为条形码是从文本生成的,而不是从上传的文件生成的。 * EAN-13 要求恰好 12 或 13 位数字。UPC-A 要求恰好 11 或 12 位数字。如果省略校验位,则会自动计算。 * Code 128 是最灵活的格式,支持完整的 ASCII 字符集。 * Data Matrix 生成二维条形码,适合在紧凑的方形中编码较长的字符串。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/barcode-generate.md description: 產生 Code 128、EAN-13、UPC-A、Code 39、ITF-14 及 Data Matrix 格式的條碼。 --- # Barcode Generator {#barcode-generator} 從文字輸入產生條碼影像。支援 Code 128、EAN-13、UPC-A、Code 39、ITF-14 及 Data Matrix 格式。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` 接受 `application/json` 主體(非 multipart)。條碼由提供的文字產生,而非上傳的檔案。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | 要編碼於條碼中的文字(1-256 個字元) | | type | string | No | `"code128"` | 條碼格式:`code128`、`ean13`、`upca`、`code39`、`itf14`、`datamatrix` | | scale | integer | No | `3` | 影像縮放係數(1-8) | | includeText | boolean | No | `true` | 是否在條碼下方算繪文字 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * 與多數工具不同,此端點接受 JSON 主體,而非 multipart form data,因為條碼是由文字產生,而非由上傳的檔案產生。 * EAN-13 需要恰好 12 或 13 個數字。UPC-A 需要恰好 11 或 12 個數字。若省略檢查碼,系統會自動計算。 * Code 128 是最具彈性的格式,支援完整的 ASCII 字元集。 * Data Matrix 會產生 2D 條碼,適合以緊湊的方形編碼較長的字串。 --- --- url: https://docs.snapotter.com/hi/tools/image/barcode-read.md description: >- एनोटेट किए गए आउटपुट के साथ QR कोड, बारकोड, और 2D कोड के लिए छवियाँ स्कैन करें। --- # Barcode Reader {#barcode-reader} अपलोड की गई छवियों को सभी प्रकार के बारकोड और QR कोड के लिए स्कैन करें। प्रत्येक पहचाने गए कोड के लिए डिकोड किया गया टेक्स्ट, बारकोड प्रकार, और स्थिति डेटा लौटाता है। पहचाने गए कोड के चारों ओर रंगीन बाउंडिंग बॉक्स के साथ एक एनोटेट की गई छवि भी उत्पन्न करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` एक छवि फ़ाइल और एक वैकल्पिक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tryHarder | boolean | No | `true` | कठिन-पढ़ने वाले बारकोड के लिए आक्रामक स्कैनिंग मोड सक्षम करें (धीमा लेकिन अधिक गहन) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Example Response {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | मूल फ़ाइल नाम | | barcodes | array | पहचाने गए बारकोड ऑब्जेक्ट्स की सरणी | | annotatedUrl | string or null | एनोटेट की गई छवि डाउनलोड करने का URL (कोई बारकोड न मिलने पर null) | | previewUrl | string or null | annotatedUrl के समान (फ्रंटएंड पूर्वावलोकन संगतता के लिए) | ### Barcode Object {#barcode-object} | Field | Type | Description | |-------|------|-------------| | type | string | बारकोड प्रारूप (QRCode, EAN-13, Code128, DataMatrix, PDF417, आदि) | | text | string | बारकोड की डिकोड की गई सामग्री | | position | object | topLeft, topRight, bottomLeft, bottomRight निर्देशांक के साथ बाउंडिंग बॉक्स | ## Supported Barcode Types {#supported-barcode-types} 1D बारकोड: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E 2D बारकोड: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Notes {#notes} * बारकोड पहचान के लिए zxing-wasm लाइब्रेरी का उपयोग करता है। * एनोटेट की गई छवि प्रत्येक पहचाने गए बारकोड पर रंगीन बहुभुज बाउंडिंग बॉक्स और क्रमांकित लेबल ओवरले करती है। * एक ही छवि में 255 तक बारकोड पहचाने जा सकते हैं। * यदि कोई बारकोड नहीं मिलता है, तो `barcodes` एक खाली सरणी होती है और `annotatedUrl` null होता है। * `tryHarder` मोड प्रोसेसिंग समय की कीमत पर अधिक गहन स्कैनिंग करता है। साफ़, अच्छी तरह संरेखित बारकोड की तेज़ प्रोसेसिंग के लिए इसे अक्षम करें। * एनोटेट किया गया आउटपुट हमेशा PNG प्रारूप में होता है। * HEIC, RAW, PSD, और SVG इनपुट को स्कैन करने से पहले स्वचालित रूप से डिकोड किया जाता है। * प्रोसेसिंग से पहले EXIF ओरिएंटेशन स्वतः लागू किया जाता है। --- --- url: https://docs.snapotter.com/ja/tools/image/barcode-read.md description: 画像内の QR コード、バーコード、2D コードをスキャンし、注釈付きの出力を生成します。 --- # Barcode Reader {#barcode-reader} アップロードされた画像であらゆる種類のバーコードと QR コードをスキャンします。検出された各コードについて、デコードされたテキスト、バーコードの種類、位置データを返します。また、検出されたコードの周囲に色付きのバウンディングボックスを描いた注釈付き画像も生成します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` 画像ファイルとオプションの JSON `settings` フィールドを含むマルチパートフォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tryHarder | boolean | No | `true` | 読み取りが難しいバーコード向けにアグレッシブなスキャンモードを有効にします (低速ですがより徹底的) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Example Response {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | 元のファイル名 | | barcodes | array | 検出されたバーコードオブジェクトの配列 | | annotatedUrl | string or null | 注釈付き画像のダウンロード URL (バーコードが見つからない場合は null) | | previewUrl | string or null | annotatedUrl と同じ (フロントエンドプレビュー互換性のため) | ### Barcode Object {#barcode-object} | Field | Type | Description | |-------|------|-------------| | type | string | バーコード形式 (QRCode、EAN-13、Code128、DataMatrix、PDF417 など) | | text | string | バーコードのデコードされたコンテンツ | | position | object | topLeft、topRight、bottomLeft、bottomRight の座標を持つバウンディングボックス | ## Supported Barcode Types {#supported-barcode-types} 1D バーコード: Code128、Code39、Code93、Codabar、EAN-8、EAN-13、ITF、UPC-A、UPC-E 2D バーコード: QRCode、DataMatrix、PDF417、Aztec、MaxiCode ## Notes {#notes} * バーコード検出には zxing-wasm ライブラリを使用します。 * 注釈付き画像は、検出された各バーコードに色付きのポリゴンバウンディングボックスと番号付きラベルを重ねて表示します。 * 1 枚の画像で最大 255 個のバーコードを検出できます。 * バーコードが見つからない場合、`barcodes` は空の配列になり、`annotatedUrl` は null になります。 * `tryHarder` モードは処理時間を犠牲にしてより徹底的なスキャンを実行します。クリーンでよく整列したバーコードを高速に処理するには無効にしてください。 * 注釈付き出力は常に PNG 形式です。 * HEIC、RAW、PSD、SVG の入力はスキャン前に自動的にデコードされます。 * 処理前に EXIF の向きが自動的に適用されます。 --- --- url: https://docs.snapotter.com/ko/tools/image/barcode-read.md description: 이미지에서 QR 코드, 바코드, 2D 코드를 스캔하여 주석이 달린 출력을 생성합니다. --- # Barcode Reader {#barcode-reader} 업로드된 이미지에서 모든 유형의 바코드와 QR 코드를 스캔합니다. 감지된 각 코드에 대해 디코딩된 텍스트, 바코드 유형, 위치 데이터를 반환합니다. 또한 감지된 코드 주위에 색상이 지정된 경계 상자가 있는 주석 이미지를 생성합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/barcode-read` 이미지 파일과 선택적 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | tryHarder | boolean | 아니요 | `true` | 읽기 어려운 바코드를 위한 적극적인 스캔 모드 활성화 (느리지만 더 철저함) | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## 응답 예시 {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## 응답 필드 {#response-fields} | 필드 | 유형 | 설명 | |-------|------|-------------| | filename | string | 원본 파일명 | | barcodes | array | 감지된 바코드 객체 배열 | | annotatedUrl | string 또는 null | 주석 이미지 다운로드 URL (바코드가 없으면 null) | | previewUrl | string 또는 null | annotatedUrl과 동일 (프론트엔드 미리보기 호환성용) | ### 바코드 객체 {#barcode-object} | 필드 | 유형 | 설명 | |-------|------|-------------| | type | string | 바코드 형식 (QRCode, EAN-13, Code128, DataMatrix, PDF417 등) | | text | string | 바코드의 디코딩된 내용 | | position | object | topLeft, topRight, bottomLeft, bottomRight 좌표가 있는 경계 상자 | ## 지원되는 바코드 유형 {#supported-barcode-types} 1D 바코드: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E 2D 바코드: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## 참고 사항 {#notes} * 바코드 감지에는 zxing-wasm 라이브러리를 사용합니다. * 주석 이미지는 감지된 각 바코드에 색상이 지정된 다각형 경계 상자와 번호가 매겨진 레이블을 오버레이합니다. * 단일 이미지에서 최대 255개의 바코드를 감지할 수 있습니다. * 바코드가 없으면 `barcodes`은(는) 빈 배열이고 `annotatedUrl`은(는) null입니다. * `tryHarder` 모드는 처리 시간을 대가로 더 철저한 스캔을 수행합니다. 깨끗하고 정렬이 잘 된 바코드를 더 빠르게 처리하려면 비활성화하세요. * 주석 출력은 항상 PNG 형식입니다. * HEIC, RAW, PSD, SVG 입력은 스캔 전에 자동으로 디코딩됩니다. * 처리 전에 EXIF 방향이 자동으로 적용됩니다. --- --- url: https://docs.snapotter.com/th/tools/image/barcode-read.md description: สแกนรูปภาพหา QR code, บาร์โค้ด และโค้ด 2 มิติ พร้อมเอาต์พุตที่มีคำอธิบายกำกับ --- # Barcode Reader {#barcode-reader} สแกนรูปภาพที่อัปโหลดหาบาร์โค้ดและ QR code ทุกประเภท ส่งคืนข้อความที่ถอดรหัส, ประเภทบาร์โค้ด และข้อมูลตำแหน่งของแต่ละโค้ดที่ตรวจพบ นอกจากนี้ยังสร้างรูปภาพที่มีคำอธิบายกำกับพร้อมกล่องขอบเขตสีรอบ ๆ โค้ดที่ตรวจพบ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` รับข้อมูลแบบ multipart form data พร้อมไฟล์รูปภาพและฟิลด์ JSON `settings` ที่เป็นทางเลือก ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tryHarder | boolean | No | `true` | เปิดใช้โหมดสแกนแบบเข้มข้นสำหรับบาร์โค้ดที่อ่านยากกว่า (ช้ากว่าแต่ละเอียดกว่า) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Example Response {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | ชื่อไฟล์ต้นฉบับ | | barcodes | array | อาร์เรย์ของอ็อบเจกต์บาร์โค้ดที่ตรวจพบ | | annotatedUrl | string or null | URL สำหรับดาวน์โหลดรูปภาพที่มีคำอธิบายกำกับ (null หากไม่พบบาร์โค้ด) | | previewUrl | string or null | เหมือนกับ annotatedUrl (เพื่อความเข้ากันได้กับการแสดงตัวอย่างในฟรอนต์เอนด์) | ### Barcode Object {#barcode-object} | Field | Type | Description | |-------|------|-------------| | type | string | รูปแบบบาร์โค้ด (QRCode, EAN-13, Code128, DataMatrix, PDF417 ฯลฯ) | | text | string | เนื้อหาที่ถอดรหัสของบาร์โค้ด | | position | object | กล่องขอบเขตพร้อมพิกัด topLeft, topRight, bottomLeft, bottomRight | ## Supported Barcode Types {#supported-barcode-types} บาร์โค้ด 1 มิติ: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E บาร์โค้ด 2 มิติ: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Notes {#notes} * ใช้ไลบรารี zxing-wasm สำหรับตรวจจับบาร์โค้ด * รูปภาพที่มีคำอธิบายกำกับจะซ้อนกล่องขอบเขตรูปหลายเหลี่ยมสีและป้ายกำกับที่มีหมายเลขบนบาร์โค้ดที่ตรวจพบแต่ละอัน * ตรวจจับได้สูงสุด 255 บาร์โค้ดในรูปภาพเดียว * หากไม่พบบาร์โค้ด `barcodes` จะเป็นอาร์เรย์ว่าง และ `annotatedUrl` จะเป็น null * โหมด `tryHarder` ทำการสแกนอย่างละเอียดมากขึ้นโดยแลกกับเวลาประมวลผล ปิดใช้งานเพื่อประมวลผลบาร์โค้ดที่สะอาดและจัดวางเรียบร้อยได้เร็วขึ้น * เอาต์พุตที่มีคำอธิบายกำกับเป็นรูปแบบ PNG เสมอ * อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนสแกน * ทิศทาง EXIF จะถูกนำมาใช้อัตโนมัติก่อนประมวลผล --- --- url: https://docs.snapotter.com/vi/tools/image/barcode-read.md description: Quét hình ảnh để tìm mã QR, mã vạch và mã 2D với đầu ra được chú thích. --- # Barcode Reader {#barcode-reader} Quét các hình ảnh được tải lên để tìm mọi loại mã vạch và mã QR. Trả về văn bản đã giải mã, loại mã vạch và dữ liệu vị trí cho mỗi mã được phát hiện. Cũng tạo một hình ảnh được chú thích với các hộp giới hạn có màu quanh những mã được phát hiện. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` Chấp nhận dữ liệu biểu mẫu multipart với một tệp hình ảnh và một trường JSON `settings` tùy chọn. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tryHarder | boolean | No | `true` | Bật chế độ quét tích cực cho các mã vạch khó đọc hơn (chậm hơn nhưng kỹ càng hơn) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Example Response {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | Tên tệp gốc | | barcodes | array | Mảng các đối tượng mã vạch được phát hiện | | annotatedUrl | string or null | URL để tải hình ảnh được chú thích (null nếu không tìm thấy mã vạch) | | previewUrl | string or null | Giống annotatedUrl (để tương thích xem trước ở frontend) | ### Barcode Object {#barcode-object} | Field | Type | Description | |-------|------|-------------| | type | string | Định dạng mã vạch (QRCode, EAN-13, Code128, DataMatrix, PDF417, v.v.) | | text | string | Nội dung đã giải mã của mã vạch | | position | object | Hộp giới hạn với tọa độ topLeft, topRight, bottomLeft, bottomRight | ## Supported Barcode Types {#supported-barcode-types} Mã vạch 1D: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E Mã vạch 2D: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Notes {#notes} * Sử dụng thư viện zxing-wasm để phát hiện mã vạch. * Hình ảnh được chú thích phủ lên các hộp giới hạn đa giác có màu và nhãn được đánh số trên mỗi mã vạch được phát hiện. * Có thể phát hiện tối đa 255 mã vạch trong một hình ảnh. * Nếu không tìm thấy mã vạch nào, `barcodes` là một mảng rỗng và `annotatedUrl` là null. * Chế độ `tryHarder` thực hiện quét kỹ càng hơn với chi phí là thời gian xử lý. Tắt nó để xử lý nhanh hơn các mã vạch sạch, được căn chỉnh tốt. * Đầu ra được chú thích luôn ở định dạng PNG. * Các đầu vào HEIC, RAW, PSD và SVG được tự động giải mã trước khi quét. * Hướng EXIF được tự động áp dụng trước khi xử lý. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/barcode-read.md description: 扫描图像中的二维码、条形码和 2D 码,并输出带标注的结果。 --- # Barcode Reader {#barcode-reader} 扫描上传图像中的所有类型条形码和二维码。为每个检测到的码返回解码文本、条形码类型和位置数据。还会生成一张带标注的图像,在检测到的码周围绘制彩色边界框。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` 接受包含图像文件和一个可选 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tryHarder | boolean | 否 | `true` | 为更难读取的条形码启用激进扫描模式(更慢但更彻底) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Example Response {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | 原始文件名 | | barcodes | array | 检测到的条形码对象数组 | | annotatedUrl | string 或 null | 下载带标注图像的 URL(未找到条形码时为 null) | | previewUrl | string 或 null | 与 annotatedUrl 相同(用于前端预览兼容) | ### Barcode Object {#barcode-object} | Field | Type | Description | |-------|------|-------------| | type | string | 条形码格式(QRCode、EAN-13、Code128、DataMatrix、PDF417 等) | | text | string | 条形码的解码内容 | | position | object | 带有 topLeft、topRight、bottomLeft、bottomRight 坐标的边界框 | ## Supported Barcode Types {#supported-barcode-types} 1D 条形码:Code128、Code39、Code93、Codabar、EAN-8、EAN-13、ITF、UPC-A、UPC-E 2D 条形码:QRCode、DataMatrix、PDF417、Aztec、MaxiCode ## Notes {#notes} * 使用 zxing-wasm 库进行条形码检测。 * 带标注的图像会在每个检测到的条形码上叠加彩色多边形边界框和编号标签。 * 单张图像中最多可检测 255 个条形码。 * 如果未找到条形码,`barcodes` 为空数组,`annotatedUrl` 为 null。 * `tryHarder` 模式以处理时间为代价进行更彻底的扫描。对于干净、对齐良好的条形码,可禁用它以加快处理速度。 * 带标注的输出始终为 PNG 格式。 * HEIC、RAW、PSD 和 SVG 输入在扫描前会自动解码。 * EXIF 方向会在处理前自动应用。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/barcode-read.md description: 掃描影像中的 QR code、條碼及 2D 碼,並輸出標註影像。 --- # Barcode Reader {#barcode-reader} 掃描上傳的影像中所有類型的條碼與 QR code。針對每個偵測到的碼回傳解碼後的文字、條碼類型及位置資料。同時產生一張標註影像,在偵測到的碼周圍加上彩色邊界框。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` 接受包含影像檔案及選用 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tryHarder | boolean | No | `true` | 針對較難讀取的條碼啟用積極掃描模式(較慢但更徹底) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Example Response {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | 原始檔名 | | barcodes | array | 偵測到的條碼物件陣列 | | annotatedUrl | string or null | 下載標註影像的 URL(若未找到條碼則為 null) | | previewUrl | string or null | 與 annotatedUrl 相同(供前端預覽相容性使用) | ### Barcode Object {#barcode-object} | Field | Type | Description | |-------|------|-------------| | type | string | 條碼格式(QRCode、EAN-13、Code128、DataMatrix、PDF417 等) | | text | string | 條碼解碼後的內容 | | position | object | 含 topLeft、topRight、bottomLeft、bottomRight 座標的邊界框 | ## Supported Barcode Types {#supported-barcode-types} 1D 條碼:Code128、Code39、Code93、Codabar、EAN-8、EAN-13、ITF、UPC-A、UPC-E 2D 條碼:QRCode、DataMatrix、PDF417、Aztec、MaxiCode ## Notes {#notes} * 使用 zxing-wasm 函式庫進行條碼偵測。 * 標註影像會在每個偵測到的條碼上疊加彩色多邊形邊界框及編號標籤。 * 單張影像最多可偵測 255 個條碼。 * 若未找到條碼,`barcodes` 為空陣列,且 `annotatedUrl` 為 null。 * `tryHarder` 模式會以耗費處理時間為代價執行更徹底的掃描。若條碼乾淨、對齊良好,可停用此模式以加快處理。 * 標註輸出一律為 PNG 格式。 * HEIC、RAW、PSD 及 SVG 輸入會在掃描前自動解碼。 * EXIF 方向會在處理前自動套用。 --- --- url: https://docs.snapotter.com/nl/tools/image/barcode-generate.md description: >- Genereer barcodes in de formaten Code 128, EAN-13, UPC-A, Code 39, ITF-14 en Data Matrix. --- # Barcode-generator {#barcode-generator} Genereer barcode-afbeeldingen op basis van tekstinvoer. Ondersteunt de formaten Code 128, EAN-13, UPC-A, Code 39, ITF-14 en Data Matrix. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Accepteert een `application/json`-body (geen multipart). De barcode wordt gegenereerd op basis van de opgegeven tekst, niet op basis van een geüpload bestand. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | text | string | Ja | - | Tekst die in de barcode wordt gecodeerd (1-256 tekens) | | type | string | Nee | `"code128"` | Barcodeformaat: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | Nee | `3` | Schaalfactor van de afbeelding (1-8) | | includeText | boolean | Nee | `true` | Of de tekst onder de barcode wordt weergegeven | ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Opmerkingen {#notes} * In tegenstelling tot de meeste tools accepteert dit endpoint een JSON-body en geen multipart form data, aangezien barcodes worden gegenereerd op basis van tekst in plaats van een geüpload bestand. * EAN-13 vereist precies 12 of 13 cijfers. UPC-A vereist precies 11 of 12 cijfers. Als een controlecijfer wordt weggelaten, wordt het automatisch berekend. * Code 128 is het meest flexibele formaat en ondersteunt de volledige ASCII-tekenset. * Data Matrix produceert een 2D-barcode die geschikt is om langere tekenreeksen in een compact vierkant te coderen. --- --- url: https://docs.snapotter.com/de/tools/image/barcode-generate.md description: >- Barcodes in den Formaten Code 128, EAN-13, UPC-A, Code 39, ITF-14 und Data Matrix erzeugen. --- # Barcode-Generator {#barcode-generator} Erzeugt Barcode-Bilder aus einer Texteingabe. Unterstützt die Formate Code 128, EAN-13, UPC-A, Code 39, ITF-14 und Data Matrix. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Nimmt einen `application/json`-Body (nicht multipart) entgegen. Der Barcode wird aus dem angegebenen Text erzeugt, nicht aus einer hochgeladenen Datei. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | text | string | Ja | - | Im Barcode zu codierender Text (1-256 Zeichen) | | type | string | Nein | `"code128"` | Barcode-Format: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | Nein | `3` | Skalierungsfaktor des Bildes (1-8) | | includeText | boolean | Nein | `true` | Ob der Text unter dem Barcode dargestellt wird | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Hinweise {#notes} * Anders als die meisten Werkzeuge nimmt dieser Endpunkt einen JSON-Body und keine Multipart-Formulardaten entgegen, da Barcodes aus Text statt aus einer hochgeladenen Datei erzeugt werden. * EAN-13 erfordert genau 12 oder 13 Ziffern. UPC-A erfordert genau 11 oder 12 Ziffern. Wird eine Prüfziffer weggelassen, wird sie automatisch berechnet. * Code 128 ist das flexibelste Format und unterstützt den gesamten ASCII-Zeichensatz. * Data Matrix erzeugt einen 2D-Barcode, der sich zum Codieren längerer Zeichenketten in einem kompakten Quadrat eignet. --- --- url: https://docs.snapotter.com/de/tools/image/barcode-read.md description: >- Bilder nach QR-Codes, Barcodes und 2D-Codes durchsuchen und eine annotierte Ausgabe erhalten. --- # Barcode-Leser {#barcode-reader} Durchsucht hochgeladene Bilder nach allen Arten von Barcodes und QR-Codes. Gibt für jeden erkannten Code den decodierten Text, den Barcode-Typ und Positionsdaten zurück. Erzeugt außerdem ein annotiertes Bild mit farbigen Begrenzungsrahmen um die erkannten Codes. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/barcode-read` Nimmt Multipart-Formulardaten mit einer Bilddatei und einem optionalen JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | tryHarder | boolean | Nein | `true` | Aggressiven Scanmodus für schwerer lesbare Barcodes aktivieren (langsamer, aber gründlicher) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Beispielantwort {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Antwortfelder {#response-fields} | Feld | Typ | Beschreibung | |-------|------|-------------| | filename | string | Ursprünglicher Dateiname | | barcodes | array | Array der erkannten Barcode-Objekte | | annotatedUrl | string oder null | URL zum Herunterladen des annotierten Bildes (null, wenn keine Barcodes gefunden wurden) | | previewUrl | string oder null | Wie annotatedUrl (zur Kompatibilität mit der Frontend-Vorschau) | ### Barcode-Objekt {#barcode-object} | Feld | Typ | Beschreibung | |-------|------|-------------| | type | string | Barcode-Format (QRCode, EAN-13, Code128, DataMatrix, PDF417 usw.) | | text | string | Decodierter Inhalt des Barcodes | | position | object | Begrenzungsrahmen mit den Koordinaten topLeft, topRight, bottomLeft, bottomRight | ## Unterstützte Barcode-Typen {#supported-barcode-types} 1D-Barcodes: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E 2D-Barcodes: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Hinweise {#notes} * Verwendet die Bibliothek zxing-wasm zur Barcode-Erkennung. * Das annotierte Bild legt farbige polygonale Begrenzungsrahmen und nummerierte Beschriftungen über jeden erkannten Barcode. * In einem einzelnen Bild können bis zu 255 Barcodes erkannt werden. * Werden keine Barcodes gefunden, ist `barcodes` ein leeres Array und `annotatedUrl` ist null. * Der Modus `tryHarder` führt ein gründlicheres Scannen auf Kosten der Verarbeitungszeit durch. Deaktivieren Sie ihn für eine schnellere Verarbeitung sauberer, gut ausgerichteter Barcodes. * Die annotierte Ausgabe ist stets im PNG-Format. * Eingaben in HEIC, RAW, PSD und SVG werden vor dem Scannen automatisch dekodiert. * Die EXIF-Ausrichtung wird vor der Verarbeitung automatisch angewendet. --- --- url: https://docs.snapotter.com/nl/tools/image/barcode-read.md description: Scan afbeeldingen op QR-codes, barcodes en 2D-codes met geannoteerde uitvoer. --- # Barcodelezer {#barcode-reader} Scan geüploade afbeeldingen op alle soorten barcodes en QR-codes. Retourneert de gedecodeerde tekst, het barcodetype en positiegegevens voor elke gedetecteerde code. Genereert ook een geannoteerde afbeelding met gekleurde omkaderingen rond de gedetecteerde codes. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-read` Accepteert multipart form data met een afbeeldingsbestand en een optioneel JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | tryHarder | boolean | Nee | `true` | Schakel de agressieve scanmodus in voor lastiger te lezen barcodes (langzamer maar grondiger) | ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Voorbeeldantwoord {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Antwoordvelden {#response-fields} | Veld | Type | Beschrijving | |-------|------|-------------| | filename | string | Originele bestandsnaam | | barcodes | array | Array van gedetecteerde barcode-objecten | | annotatedUrl | string of null | URL om de geannoteerde afbeelding te downloaden (null als er geen barcodes zijn gevonden) | | previewUrl | string of null | Hetzelfde als annotatedUrl (voor compatibiliteit met de frontend-voorbeeldweergave) | ### Barcode-object {#barcode-object} | Veld | Type | Beschrijving | |-------|------|-------------| | type | string | Barcodeformaat (QRCode, EAN-13, Code128, DataMatrix, PDF417, enz.) | | text | string | Gedecodeerde inhoud van de barcode | | position | object | Omkadering met de coördinaten topLeft, topRight, bottomLeft, bottomRight | ## Ondersteunde barcodetypen {#supported-barcode-types} 1D-barcodes: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E 2D-barcodes: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Opmerkingen {#notes} * Gebruikt de bibliotheek zxing-wasm voor barcodedetectie. * De geannoteerde afbeelding legt gekleurde veelhoekige omkaderingen en genummerde labels over elke gedetecteerde barcode. * Er kunnen maximaal 255 barcodes in één afbeelding worden gedetecteerd. * Als er geen barcodes worden gevonden, is `barcodes` een lege array en is `annotatedUrl` null. * De modus `tryHarder` voert een grondigere scan uit ten koste van de verwerkingstijd. Schakel deze uit voor snellere verwerking van schone, goed uitgelijnde barcodes. * De geannoteerde uitvoer heeft altijd het PNG-formaat. * HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór het scannen. * De EXIF-oriëntatie wordt automatisch toegepast vóór de verwerking. --- --- url: https://docs.snapotter.com/tr/tools/image/barcode-read.md description: >- Görselleri QR kodları, barkodlar ve 2D kodlar için tarayın ve açıklamalı çıktı alın. --- # Barkod Okuyucu {#barcode-reader} Yüklenen görselleri her türden barkod ve QR kodu için tarayın. Algılanan her kod için çözülmüş metni, barkod türünü ve konum verilerini döndürür. Ayrıca algılanan kodların çevresinde renkli sınırlayıcı kutular bulunan açıklamalı bir görsel oluşturur. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/barcode-read` Bir görsel dosyası ve isteğe bağlı bir JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | tryHarder | boole | Hayır | `true` | Okunması zor barkodlar için agresif tarama modunu etkinleştirir (daha yavaş ama daha kapsamlı) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Örnek Yanıt {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Yanıt Alanları {#response-fields} | Alan | Tür | Açıklama | |-------|------|-------------| | filename | dize | Özgün dosya adı | | barcodes | dizi | Algılanan barkod nesnelerinin dizisi | | annotatedUrl | dize veya null | Açıklamalı görseli indirme URL'si (barkod bulunmazsa null) | | previewUrl | dize veya null | annotatedUrl ile aynı (ön uç önizleme uyumluluğu için) | ### Barkod Nesnesi {#barcode-object} | Alan | Tür | Açıklama | |-------|------|-------------| | type | dize | Barkod biçimi (QRCode, EAN-13, Code128, DataMatrix, PDF417 vb.) | | text | dize | Barkodun çözülmüş içeriği | | position | nesne | topLeft, topRight, bottomLeft, bottomRight koordinatlı sınırlayıcı kutu | ## Desteklenen Barkod Türleri {#supported-barcode-types} 1D barkodlar: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E 2D barkodlar: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Notlar {#notes} * Barkod algılama için zxing-wasm kitaplığını kullanır. * Açıklamalı görsel, algılanan her barkodun üzerine renkli çokgen sınırlayıcı kutular ve numaralandırılmış etiketler yerleştirir. * Tek bir görselde en fazla 255 barkod algılanabilir. * Barkod bulunmazsa, `barcodes` boş bir dizidir ve `annotatedUrl` null'dur. * `tryHarder` modu, işlem süresi pahasına daha kapsamlı tarama yapar. Temiz, düzgün hizalanmış barkodların daha hızlı işlenmesi için devre dışı bırakın. * Açıklamalı çıktı her zaman PNG biçimindedir. * HEIC, RAW, PSD ve SVG girişleri taranmadan önce otomatik olarak çözülür. * İşlemeden önce EXIF yönlendirmesi otomatik olarak uygulanır. --- --- url: https://docs.snapotter.com/tr/tools/image/barcode-generate.md description: >- Code 128, EAN-13, UPC-A, Code 39, ITF-14 ve Data Matrix biçimlerinde barkod oluşturun. --- # Barkod Oluşturucu {#barcode-generator} Metin girişinden barkod görselleri oluşturun. Code 128, EAN-13, UPC-A, Code 39, ITF-14 ve Data Matrix biçimlerini destekler. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Bir `application/json` gövdesi kabul eder (multipart değil). Barkod, yüklenen bir dosyadan değil, sağlanan metinden oluşturulur. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | text | dize | Evet | - | Barkodda kodlanacak metin (1-256 karakter) | | type | dize | Hayır | `"code128"` | Barkod biçimi: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | tam sayı | Hayır | `3` | Görsel ölçek faktörü (1-8) | | includeText | boole | Hayır | `true` | Metnin barkodun altında görüntülenip görüntülenmeyeceği | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notlar {#notes} * Çoğu aracın aksine bu uç nokta, barkodlar yüklenen bir dosya yerine metinden oluşturulduğundan multipart form verisi değil, bir JSON gövdesi kabul eder. * EAN-13 tam olarak 12 veya 13 haneli olmalıdır. UPC-A tam olarak 11 veya 12 haneli olmalıdır. Bir kontrol hanesi atlanırsa otomatik olarak hesaplanır. * Code 128 en esnek biçimdir ve tüm ASCII karakter kümesini destekler. * Data Matrix, daha uzun dizeleri kompakt bir kareye kodlamaya uygun 2 boyutlu bir barkod üretir. --- --- url: https://docs.snapotter.com/es/guide/database.md description: >- Esquema de la base de datos PostgreSQL, tablas, migraciones y procedimientos de copia de seguridad de SnapOtter. --- # Base de datos {#database} SnapOtter usa PostgreSQL 17 con [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) para la persistencia de datos. El esquema se define en `apps/api/src/db/schema.ts`. La conexión se configura mediante la variable de entorno `DATABASE_URL` (por defecto `postgres://snapotter:snapotter@postgres:5432/snapotter`). En Docker Compose, el contenedor de Postgres almacena sus datos en el volumen con nombre `SnapOtter-pgdata`. ## Tablas {#tables} ### users {#users} Almacena las cuentas de usuario. Se crea automáticamente en el primer arranque a partir de `DEFAULT_USERNAME` y `DEFAULT_PASSWORD`. | Columna | Tipo | Notas | |---|---|---| | `id` | uuid | Clave primaria | | `username` | varchar | Único, obligatorio | | `passwordHash` | varchar | hash scrypt | | `role` | varchar | `admin`, `editor` o `user` | | `mustChangePassword` | boolean | Indicador de restablecimiento de contraseña forzado | | `createdAt` | timestamp | Momento de creación | | `updatedAt` | timestamp | Momento de última actualización | ### sessions {#sessions} Sesiones de inicio de sesión activas. Cada fila vincula un token de sesión a un usuario. | Columna | Tipo | Notas | |---|---|---| | `id` | varchar | Clave primaria (token de sesión) | | `userId` | uuid | Clave foránea a `users.id` | | `expiresAt` | timestamp | Momento de expiración | | `createdAt` | timestamp | Momento de creación | ### teams {#teams} Grupos para organizar usuarios. Los administradores pueden asignar usuarios a equipos. | Columna | Tipo | Descripción | |--------|------|-------------| | `id` | uuid | Clave primaria | | `name` | varchar (único, máx. 50 caracteres) | Nombre del equipo | | `createdAt` | timestamp | Momento de creación | ### api\_keys {#api-keys} Claves de API para acceso programático. La clave sin procesar se muestra una sola vez al crearla; solo se almacena el hash. | Columna | Tipo | Notas | |---|---|---| | `id` | uuid | Clave primaria | | `userId` | uuid | Clave foránea a `users.id` | | `keyHash` | varchar | hash scrypt de la clave | | `name` | varchar | Etiqueta proporcionada por el usuario | | `createdAt` | timestamp | Momento de creación | | `lastUsedAt` | timestamp | Actualizado en cada solicitud autenticada | Las claves llevan el prefijo `si_` seguido de 96 caracteres hexadecimales (48 bytes aleatorios). ### pipelines {#pipelines} Cadenas de herramientas guardadas que los usuarios crean en la interfaz. | Columna | Tipo | Notas | |---|---|---| | `id` | uuid | Clave primaria | | `name` | varchar | Nombre del pipeline | | `description` | varchar | Descripción opcional | | `steps` | jsonb | Array de objetos `{ toolId, settings }` | | `createdAt` | timestamp | Momento de creación | ### user\_files {#user-files} Biblioteca de archivos persistente. Una edición guardada se inserta de forma predeterminada como una fila raíz independiente ("guardar como nuevo": `version` 1, `parentId` null, de modo que el original sigue listado), o como una versión enlazada a su padre cuando sobrescribes el original (`parentId` establecido, `version` incrementado, reemplazándolo). La columna `toolChain` registra las herramientas aplicadas. | Columna | Tipo | Descripción | |--------|------|-------------| | `id` | uuid | Clave primaria | | `userId` | uuid | FK a users (CASCADE DELETE) | | `originalName` | varchar | Nombre de archivo original de la subida | | `storedName` | varchar | Nombre de archivo en disco | | `mimeType` | varchar | Tipo MIME | | `size` | integer | Tamaño del archivo en bytes | | `width` | integer | Ancho de la imagen en px | | `height` | integer | Alto de la imagen en px | | `version` | integer | Número de versión (1 = original) | | `parentId` | uuid o null | FK a user\_files (versión padre) | | `toolChain` | jsonb | IDs de las herramientas aplicadas en orden para producir esta versión | | `createdAt` | timestamp | Momento de creación | ### jobs {#jobs} Realiza el seguimiento de los trabajos de procesamiento para el reporte de progreso y la limpieza. | Columna | Tipo | Notas | |---|---|---| | `id` | uuid | Clave primaria | | `type` | varchar | Identificador de la herramienta o el pipeline | | `status` | varchar | `queued`, `processing`, `completed` o `failed` | | `progress` | real | Fracción de 0.0 a 1.0 | | `inputFiles` | jsonb | Array de rutas de archivos de entrada | | `outputPath` | varchar | Ruta al archivo de resultado | | `settings` | jsonb | Ajustes de la herramienta utilizados | | `error` | varchar | Mensaje de error si falló | | `createdAt` | timestamp | Momento de creación | | `completedAt` | timestamp | Momento de finalización | ### settings {#settings} Almacén clave-valor para ajustes de todo el servidor que los administradores pueden cambiar desde la interfaz. | Columna | Tipo | Notas | |---|---|---| | `key` | varchar | Clave primaria | | `value` | varchar | Valor del ajuste | | `updatedAt` | timestamp | Momento de última actualización | ### roles {#roles} Roles personalizados con permisos granulares. | Columna | Tipo | Notas | |---|---|---| | `id` | uuid | Clave primaria | | `name` | varchar | Nombre de rol único | | `description` | varchar | Descripción opcional | | `permissions` | jsonb | Array de cadenas de permisos | | `createdAt` | timestamp | Momento de creación | ### audit\_log {#audit-log} Registro de acciones relevantes para la seguridad. | Columna | Tipo | Notas | |---|---|---| | `id` | uuid | Clave primaria | | `userId` | uuid | FK a users | | `action` | varchar | Tipo de acción | | `details` | jsonb | Datos específicos de la acción | | `createdAt` | timestamp | Momento de la acción | ### user\_preferences {#user-preferences} Estado de la interfaz por usuario, indexado por nombre de preferencia. Almacena las herramientas fijadas de la página de inicio, que se escriben a través de `PUT /api/v1/preferences`. | Columna | Tipo | Notas | |---|---|---| | `userId` | text | FK a users, con borrado en cascada. Clave primaria junto con `key` | | `key` | text | Nombre de la preferencia. Clave primaria junto con `userId` | | `value` | jsonb | Contenido de la preferencia | | `updatedAt` | timestamp | Última escritura | ## Migraciones {#migrations} Drizzle gestiona las migraciones del esquema. Los archivos de migración están en `apps/api/drizzle/`. Durante el desarrollo: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` En producción, las migraciones pendientes se aplican automáticamente al arrancar. ## Copia de seguridad y restauración {#backup-and-restore} La base de datos relacional reside en el volumen `SnapOtter-pgdata` del contenedor de Postgres, no en el volumen `/data` de la aplicación. **Copia de seguridad lógica con validación (recomendado)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Este volcado de base de datos no contiene objetos de biblioteca guardados en `/data/files` ni en estado BullMQ duradero en Redis. Realice una copia de seguridad y restaure aquellos con el procedimiento coordinado en [Seguridad y refuerzo](/es/guide/security#backup-and-recovery). **Instantánea del volumen frío** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` No copie un directorio de datos de PostgreSQL activo con `tar`. Redacte los nombres de los volúmenes con prefijos por proyecto, de modo que resuelva los ID de los volúmenes montados desde `docker inspect` o su plataforma de almacenamiento en lugar de asumir la etiqueta literal `SnapOtter-pgdata`. ### Migrar desde 1.x (SQLite) {#migrating-from-1-x-sqlite} Actualizar desde SnapOtter 1.x tiene su propia guía: consulta [Actualizar de 1.x a 2.0](./upgrading). En resumen, reutiliza tu volumen `/data` existente y 2.0 detecta e importa automáticamente `/data/snapotter.db` en el primer arranque (o define `SQLITE_MIGRATE_PATH` para apuntar a él explícitamente). Haz primero una copia de seguridad de todo el volumen `/data`, no solo de `snapotter.db`: 1.x usa el modo WAL de SQLite, por lo que un contenedor detenido suele dejar la mayor parte de sus datos en `snapotter.db-wal` junto a un `snapotter.db` casi vacío. --- --- url: https://docs.snapotter.com/fr/guide/database.md description: >- Schéma de base de données PostgreSQL, tables, migrations et procédures de sauvegarde pour SnapOtter. --- # Base de données {#database} SnapOtter utilise PostgreSQL 17 avec [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) pour la persistance des données. Le schéma est défini dans `apps/api/src/db/schema.ts`. La connexion est configurée via la variable d'environnement `DATABASE_URL` (par défaut `postgres://snapotter:snapotter@postgres:5432/snapotter`). Dans Docker Compose, le conteneur Postgres stocke ses données dans le volume nommé `SnapOtter-pgdata`. ## Tables {#tables} ### users {#users} Stocke les comptes utilisateurs. Créé automatiquement au premier démarrage à partir de `DEFAULT_USERNAME` et `DEFAULT_PASSWORD`. | Colonne | Type | Notes | |---|---|---| | `id` | uuid | Clé primaire | | `username` | varchar | Unique, requis | | `passwordHash` | varchar | Hachage scrypt | | `role` | varchar | `admin`, `editor` ou `user` | | `mustChangePassword` | boolean | Indicateur de réinitialisation forcée du mot de passe | | `createdAt` | timestamp | Date de création | | `updatedAt` | timestamp | Date de dernière mise à jour | ### sessions {#sessions} Sessions de connexion actives. Chaque ligne associe un jeton de session à un utilisateur. | Colonne | Type | Notes | |---|---|---| | `id` | varchar | Clé primaire (jeton de session) | | `userId` | uuid | Clé étrangère vers `users.id` | | `expiresAt` | timestamp | Date d'expiration | | `createdAt` | timestamp | Date de création | ### teams {#teams} Groupes pour organiser les utilisateurs. Les administrateurs peuvent affecter des utilisateurs à des équipes. | Colonne | Type | Description | |--------|------|-------------| | `id` | uuid | Clé primaire | | `name` | varchar (unique, 50 caractères max) | Nom de l'équipe | | `createdAt` | timestamp | Date de création | ### api\_keys {#api-keys} Clés API pour l'accès programmatique. La clé brute n'est affichée qu'une seule fois lors de la création ; seul le hachage est stocké. | Colonne | Type | Notes | |---|---|---| | `id` | uuid | Clé primaire | | `userId` | uuid | Clé étrangère vers `users.id` | | `keyHash` | varchar | Hachage scrypt de la clé | | `name` | varchar | Libellé fourni par l'utilisateur | | `createdAt` | timestamp | Date de création | | `lastUsedAt` | timestamp | Mise à jour à chaque requête authentifiée | Les clés sont préfixées par `si_` suivi de 96 caractères hexadécimaux (48 octets aléatoires). ### pipelines {#pipelines} Chaînes d'outils enregistrées que les utilisateurs créent dans l'interface. | Colonne | Type | Notes | |---|---|---| | `id` | uuid | Clé primaire | | `name` | varchar | Nom du pipeline | | `description` | varchar | Description facultative | | `steps` | jsonb | Tableau d'objets `{ toolId, settings }` | | `createdAt` | timestamp | Date de création | ### user\_files {#user-files} Bibliothèque de fichiers persistante. Une modification enregistrée est insérée par défaut comme une ligne racine indépendante ("enregistrer comme nouveau" : `version` à 1, `parentId` à null, de sorte que l'original reste répertorié), ou comme une version liée à son parent lorsque vous écrasez l'original (`parentId` défini, `version` incrémenté, remplaçant l'original). La colonne `toolChain` enregistre les outils appliqués. | Colonne | Type | Description | |--------|------|-------------| | `id` | uuid | Clé primaire | | `userId` | uuid | FK vers users (CASCADE DELETE) | | `originalName` | varchar | Nom de fichier d'envoi d'origine | | `storedName` | varchar | Nom de fichier sur le disque | | `mimeType` | varchar | Type MIME | | `size` | integer | Taille du fichier en octets | | `width` | integer | Largeur de l'image en px | | `height` | integer | Hauteur de l'image en px | | `version` | integer | Numéro de version (1 = original) | | `parentId` | uuid ou null | FK vers user\_files (version parente) | | `toolChain` | jsonb | ID d'outils appliqués dans l'ordre pour produire cette version | | `createdAt` | timestamp | Date de création | ### jobs {#jobs} Suit les tâches de traitement pour le rapport de progression et le nettoyage. | Colonne | Type | Notes | |---|---|---| | `id` | uuid | Clé primaire | | `type` | varchar | Identifiant d'outil ou de pipeline | | `status` | varchar | `queued`, `processing`, `completed` ou `failed` | | `progress` | real | Fraction 0.0-1.0 | | `inputFiles` | jsonb | Tableau de chemins de fichiers d'entrée | | `outputPath` | varchar | Chemin vers le fichier de résultat | | `settings` | jsonb | Paramètres d'outil utilisés | | `error` | varchar | Message d'erreur en cas d'échec | | `createdAt` | timestamp | Date de création | | `completedAt` | timestamp | Date d'achèvement | ### settings {#settings} Magasin clé-valeur pour les paramètres à l'échelle du serveur que les administrateurs peuvent modifier depuis l'interface. | Colonne | Type | Notes | |---|---|---| | `key` | varchar | Clé primaire | | `value` | varchar | Valeur du paramètre | | `updatedAt` | timestamp | Date de dernière mise à jour | ### roles {#roles} Rôles personnalisés avec des permissions granulaires. | Colonne | Type | Notes | |---|---|---| | `id` | uuid | Clé primaire | | `name` | varchar | Nom de rôle unique | | `description` | varchar | Description facultative | | `permissions` | jsonb | Tableau de chaînes de permission | | `createdAt` | timestamp | Date de création | ### audit\_log {#audit-log} Journal des actions pertinentes pour la sécurité. | Colonne | Type | Notes | |---|---|---| | `id` | uuid | Clé primaire | | `userId` | uuid | FK vers users | | `action` | varchar | Type d'action | | `details` | jsonb | Données spécifiques à l'action | | `createdAt` | timestamp | Date de l'action | ### user\_preferences {#user-preferences} État de l'interface propre à chaque utilisateur, indexé par nom de préférence. Alimente les outils épinglés de la page d'accueil via `PUT /api/v1/preferences`. | Colonne | Type | Notes | |---|---|---| | `userId` | text | FK vers users, suppression en cascade. Clé primaire avec `key` | | `key` | text | Nom de la préférence. Clé primaire avec `userId` | | `value` | jsonb | Contenu de la préférence | | `updatedAt` | timestamp | Dernière écriture | ## Migrations {#migrations} Drizzle gère les migrations de schéma. Les fichiers de migration se trouvent dans `apps/api/drizzle/`. Pendant le développement : ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` En production, les migrations en attente sont appliquées automatiquement au démarrage. ## Sauvegarde et restauration {#backup-and-restore} La base de données relationnelle réside dans le volume `SnapOtter-pgdata` du conteneur Postgres, et non dans le volume `/data` de l'application. **Sauvegarde logique avec validation (recommandé)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Ce vidage de base de données ne contient pas d'objets de bibliothèque enregistrés dans `/data/files` ni d'état BullMQ durable dans Redis. Sauvegardez et restaurez ceux-ci avec la procédure coordonnée dans [Sécurité et renforcement](/fr/guide/security#backup-and-recovery). **Instantané de volume froid** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Ne copiez pas un répertoire de données PostgreSQL actif avec `tar`. Composez les noms de volumes de préfixes par projet, résolvez donc les ID de volume montés à partir de `docker inspect` ou de votre plate-forme de stockage plutôt que d'assumer l'étiquette littérale `SnapOtter-pgdata`. ### Migration depuis la 1.x (SQLite) {#migrating-from-1-x-sqlite} La mise à niveau depuis SnapOtter 1.x a son propre guide : voir [Mise à niveau de la 1.x vers la 2.0](./upgrading). En bref, réutilisez votre volume `/data` existant et la 2.0 détecte automatiquement et importe `/data/snapotter.db` au premier démarrage (ou définissez `SQLITE_MIGRATE_PATH` pour le pointer explicitement). Sauvegardez d'abord l'intégralité du volume `/data`, pas seulement `snapotter.db` : la 1.x utilise le mode WAL de SQLite, donc un conteneur arrêté laisse souvent la plupart de ses données dans `snapotter.db-wal` à côté d'un `snapotter.db` presque vide. --- --- url: https://docs.snapotter.com/tr/guide/getting-started.md description: >- SnapOtter'ı Docker ile tek komutla kurun. Docker Compose kurulumu, kaynaktan derleme ve tam özellik genel bakışı içerir. --- # Başlarken {#getting-started} ::: tip Kurmadan önce deneyin Tam arayüzü [demo.snapotter.com](https://demo.snapotter.com) adresinde keşfedin - kayıt veya kurulum gerektirmez. ::: ## Hızlı Başlangıç {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Bu tek konteyner ihtiyaç duyduğu her şeyi çalıştırır: `DATABASE_URL` ayarlanmadan, geridöngü arayüzünde (gömülü mod) kendi PostgreSQL ve Redis'ini başlatır ve tüm verileri `SnapOtter-data` biriminde tutar. SnapOtter'yi denemenin veya bir ev laboratuvarında kendi kendine barındırmanın en hızlı yoludur. Üretim için PostgreSQL ve Redis'i kendi kapsayıcılarında tutan [canonical Docker Compose yığınını](#docker-compose) kullanın. Katıştırılmış mod, kök (varsayılan) olarak çalışır ve `DATABASE_URL`'yi ayarladığınız anda otomatik olarak kapanır. Bir Raspberry Pi'ye, eski bir dizüstüne veya küçük bir VPS'e mi kuruyorsunuz? Ayarlanmış adım adım kurulum ve kısıtlı donanımdan neler bekleyeceğiniz için [Düşük Kaynaklı Kurulumlar](/tr/guide/low-resource) bölümüne bakın. İlk oturum açmada parolanızı değiştirmeniz istenecektir. ::: tip Anonim Ürün Analitiği SnapOtter varsayılan olarak anonim ürün analitiği içerir. Kapatmak için **Settings → System → Privacy** bölümünü açın ve **Anonymous Product Analytics**'i kapatın. Tüm örnek için hemen durur. Örnek için tüm telemetriyi yeniden derleme olmadan devre dışı bırakmak için `SNAPOTTER_TELEMETRY=0` ortam değişkenini de ayarlayabilirsiniz (`false` ve `off` da işe yarar). Hata izleme, açık kaynak programı aracılığıyla SnapOtter'a sponsor olan [Sentry](https://sentry.io) tarafından desteklenmektedir. Nelerin toplandığına ilişkin ayrıntılar için [SnapOtter'ın topladıkları](/tr/guide/telemetry) bölümüne bakın. ::: ::: tip NVIDIA CUDA hızlandırması NVIDIA CUDA ile hızlandırılmış arka plan kaldırma, ölçeklendirme, yüz geliştirme ve restorasyon için `--gpus all` ekleyin. OCR CPU tabanlı kalır ve GPU erişimi olsun veya olmasın aynı görüntüde çalışır: ```bash docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest ``` [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) gerektirir. CUDA kullanılamadığında otomatik olarak CPU'ya geri döner. VA-API, Quick Sync veya OpenCL aracılığıyla Intel/AMD iGPU hızlandırma, günümüzde yapay zeka çıkarımı için desteklenmemektedir. Karşılaştırmalar için [Docker Etiketleri](/tr/guide/docker-tags) konusuna bakın. AI araçları `--gpus all`'ye rağmen CPU üzerinde çalışıyorsa, bkz. [GPU hızlandırmasını doğrulama](/tr/guide/deployment#verify-gpu-acceleration). ::: ::: details GHCR'de de mevcut ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snapotter-hq/snapotter:latest ``` Her iki kayıt defteri de her sürümde aynı imajı yayınlar. ::: ## Docker Oluşturma {#docker-compose} Bu sayfadaki kısaltılmış bir Oluşturma örneğini kopyalamak yerine, her sürümde bakımı yapılan ve test edilen üretim dosyasını kullanın: ```bash install -d -m 700 snapotter && cd snapotter curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \ https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.2.0/docker/docker-compose.yml # Keep generated service credentials out of shell history and world-readable files. umask 077 POSTGRES_PASSWORD="$(openssl rand -hex 32)" REDIS_PASSWORD="$(openssl rand -hex 32)" printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \ "$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --no-build ``` Kurallı [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.2.0/docker/docker-compose.yml) dört çalışma zamanı biriminin tümünü, durum denetimlerini, kaynak sınırlarını, dayanıklı Redis yapılandırmasını, sabitlenmiş veritabanı/önbellek görüntülerini ve geçerli kapsayıcı güçlendirmeyi içerir. İlk girişten hemen sonra varsayılan yönetici şifresini değiştirin. Tekrarlanabilir bir dağıtım için `latest`'yi takip etmek yerine SnapOtter uygulama görüntüsünü doğruladığınız sürüm etiketine veya özete sabitleyin. Tüm ortam değişkenleri için [Yapılandırma](/tr/guide/configuration)'ya ve gizli diziler, ağ politikası ve yedekleme kılavuzu için [Güvenlik ve Güçlendirme](/tr/guide/security)'ye bakın. ## Kaynaktan Derleme {#build-from-source} **Ön koşullar:** Node.js 22.22+, pnpm 9+, Docker (Postgres + Redis için), Python 3.11+ (AI özellikleri için), Git. ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` * Ön yüz: * Arka uç: ## Neler Yapabilirsiniz {#what-you-can-do} ### Dosya İşleme (200+ Araç) {#file-processing-200-tools} | Modalite | Sayı | Örnek Araçlar | |----------|-------|---------------| | **Görsel** | 107 | Yeniden Boyutlandır, Kırp, Sıkıştır, Dönüştür, Arka Planı Kaldır, Ölçek Büyüt, OCR, Filigran, Kolaj, Renklendir, GIF Araçları, format ön ayarları | | **Video** | 57 | Kırp, Kes, Sıkıştır, Dönüştür, Birleştir, Ses Çıkar, Otomatik Altyazılar, Video'dan GIF'e, Yeniden Boyutlandır, Sabitle, format ön ayarları | | **Ses** | 27 | Kırp, Birleştir, Dönüştür, Normalleştir, Gürültü Azaltma, Transkribe Et, Perde Kaydırma, Kısılma, Zil Sesi Oluşturucu, format ön ayarları | | **PDF / Belge** | 29 | Birleştir, Böl, Sıkıştır, OCR, Filigran, Sansürle, Word'den PDF'e, Excel'den PDF'e, Döndür, Koru, Onar | | **Dosyalar** | 23 | CSV'den JSON'a, JSON'dan XML'e, CSV'leri Birleştir, CSV Böl, ZIP Oluştur, ZIP Çıkar, Grafik Oluşturucu, YAML/JSON | ### Ardışık Düzenler {#pipelines} Araçları çok adımlı iş akışlarına zincirleyin ve bunları tek bir görsele veya bütün bir gruba uygulayın: 1. Kenar çubuğunda **Pipelines** bölümünü açın. 2. Adımlar ekleyin (herhangi bir araç, herhangi bir ayar). 3. Tek bir dosyada veya bir kerede bütün bir grupta çalıştırın. 4. Daha sonra yeniden kullanmak için ardışık düzeni kaydedin. Ardışık düzenler varsayılan olarak 20 adıma izin verir. Limiti sınırsız yapmak için `MAX_PIPELINE_STEPS=0` ayarlayın. ### Dosya Kitaplığı {#file-library} İşlediğiniz her dosya **Files** kitaplığınıza kaydedilebilir. SnapOtter tam sürüm geçmişini izler, böylece orijinal yüklemeden son çıktıya kadar her işleme adımını takip edebilirsiniz. Kaydetme açıktır: kitaplığa kaydettiğiniz sonuçlar siz silene kadar tutulurken, işleyip kaydetmeden bıraktığınız sonuçlar 72 saat sonra otomatik olarak temizlenir (`FILE_MAX_AGE_HOURS` aracılığıyla yapılandırılabilir). ### REST API ve API Anahtarları {#rest-api-api-keys} Her araca HTTP üzerinden erişilebilir: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800,"height":600,"fit":"cover"}' ``` **Settings → API Keys** altında API anahtarları oluşturun. Tüm uç noktalar için [REST API referansına](/tr/api/rest) bakın veya etkileşimli referans için adresini ziyaret edin. ### Çok Kullanıcı ve Ekipler {#multi-user-teams} Rol tabanlı erişim kontrolü ile birden fazla kullanıcıyı etkinleştirin: * **Yönetici**: tam erişim - kullanıcıları, ekipleri, ayarları, tüm dosyaları/ardışık düzenleri/API anahtarlarını yönetir * **Kullanıcı**: araçları kullanır, kendi dosyalarını/ardışık düzenlerini/API anahtarlarını yönetir Kullanıcıları gruplamak için **Settings → Teams** altında ekipler oluşturun. `AUTH_ENABLED=true` ayarlayın (veya oturum açma olmadan tek kullanıcı/kendi kullanımı için `false`). ## Telefonunuzdan Kullanın {#use-it-from-your-phone} SnapOtter mobil tarayıcılarda çalışır ve uygulama olarak yüklenebilir. Örneğinizi telefonda açın, ardından: * **iPhone / iPad (Safari):** Paylaş'a, ardından **Ana Ekrana Ekle**'ye dokunun. * **Android (Chrome):** tarayıcı menüsünü açın ve **Uygulamayı yükle**'ye dokunun. Yüklenen uygulama kendi penceresinde, doğrudan örneğinizde açılır. Tek bir pürüz var: tarayıcılar yükleme seçeneğini yalnızca HTTPS üzerinden sunar. Yerel ağınızdaki düz bir HTTP adresi tarayıcı sekmesinde sorunsuz çalışmaya devam eder; gerçek yükleme için örneği sertifikalı bir ters proxy arkasına alın (bkz. [dağıtım kılavuzu](/tr/guide/deployment)). Telefon ve tabletlerde görüntü araçları, yükleme düğmesinin yanında bir **Fotoğraf çek** düğmesi gösterir. Bir fişin veya beyaz tahtanın fotoğrafını çekin, görüntü doğrudan araca gelir. --- --- url: https://docs.snapotter.com/vi/guide/getting-started.md description: >- Cài đặt SnapOtter với Docker trong một lệnh. Bao gồm thiết lập Docker Compose, build từ mã nguồn, và tổng quan đầy đủ về tính năng. --- # Bắt đầu {#getting-started} ::: tip Dùng thử trước khi cài đặt Khám phá toàn bộ giao diện tại [demo.snapotter.com](https://demo.snapotter.com), không cần đăng ký hay cài đặt. ::: ## Bắt đầu nhanh {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Vùng chứa duy nhất này chạy mọi thứ nó cần: không có bộ `DATABASE_URL`, nó khởi động PostgreSQL và Redis của riêng nó trên giao diện loopback (chế độ nhúng) và giữ tất cả dữ liệu trong ổ `SnapOtter-data`. Đây là cách nhanh nhất để dùng thử SnapOtter hoặc tự lưu trữ trên homelab. Để sản xuất, hãy sử dụng [ngăn xếp Docker Compose chuẩn](#docker-compose), để giữ PostgreSQL và Redis trong các vùng chứa riêng của chúng. Chế độ nhúng chạy bằng root (mặc định) và tự động tắt ngay khi bạn đặt `DATABASE_URL`. Cài đặt trên Raspberry Pi, laptop cũ, hay một VPS nhỏ? Xem [Thiết lập trên phần cứng hạn chế](/vi/guide/low-resource) để có hướng dẫn từng bước đã tinh chỉnh và biết nên kỳ vọng gì từ phần cứng hạn chế. Bạn sẽ được yêu cầu đổi mật khẩu ở lần đăng nhập đầu tiên. ::: tip Phân tích sản phẩm ẩn danh SnapOtter bao gồm phân tích sản phẩm ẩn danh theo mặc định. Để tắt nó, mở **Settings → System → Privacy** và tắt **Anonymous Product Analytics**. Nó dừng ngay lập tức cho toàn bộ instance. Bạn cũng có thể đặt biến môi trường `SNAPOTTER_TELEMETRY=0` (`false` và `off` cũng hoạt động) để tắt toàn bộ telemetry cho instance mà không cần xây dựng lại. Việc giám sát lỗi được cung cấp bởi [Sentry](https://sentry.io), đơn vị tài trợ cho SnapOtter thông qua chương trình mã nguồn mở của họ. Để biết chi tiết về những gì được thu thập, xem [SnapOtter thu thập gì](/vi/guide/telemetry). ::: ::: tip Tăng tốc NVIDIA CUDA Thêm `--gpus all` để loại bỏ nền, nâng cấp, nâng cấp và phục hồi khuôn mặt được tăng tốc CUDA của NVIDIA. OCR vẫn dựa trên CPU và hoạt động trong cùng một hình ảnh có hoặc không có quyền truy cập GPU: ```bash docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest ``` Yêu cầu [Bộ công cụ bộ chứa NVIDIA](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). Tự động quay trở lại CPU khi CUDA không khả dụng. Hiện nay, khả năng tăng tốc iGPU của Intel/AMD thông qua VA-API, Quick Sync hoặc OpenCL không được hỗ trợ cho suy luận AI. Xem [Thẻ Docker](/vi/guide/docker-tags) để biết điểm chuẩn. Nếu các công cụ AI chạy trên CPU mặc dù có `--gpus all`, hãy xem [Xác minh khả năng tăng tốc GPU](/vi/guide/deployment#verify-gpu-acceleration). ::: ::: details Cũng có trên GHCR ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snapotter-hq/snapotter:latest ``` Cả hai registry đều phát hành cùng một image trong mỗi bản phát hành. ::: ## Docker Soạn {#docker-compose} Sử dụng tệp sản xuất được duy trì và thử nghiệm với mỗi bản phát hành thay vì sao chép ví dụ Compose viết tắt từ trang này: ```bash install -d -m 700 snapotter && cd snapotter curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \ https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.2.0/docker/docker-compose.yml # Keep generated service credentials out of shell history and world-readable files. umask 077 POSTGRES_PASSWORD="$(openssl rand -hex 32)" REDIS_PASSWORD="$(openssl rand -hex 32)" printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \ "$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --no-build ``` [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.2.0/docker/docker-compose.yml) chuẩn bao gồm tất cả bốn khối thời gian chạy, kiểm tra tình trạng, giới hạn tài nguyên, cấu hình Redis bền vững, hình ảnh bộ đệm/cơ sở dữ liệu được ghim và tăng cường vùng chứa hiện tại. Thay đổi mật khẩu quản trị mặc định ngay sau lần đăng nhập đầu tiên. Để triển khai có thể lặp lại, hãy ghim hình ảnh ứng dụng SnapOtter vào thẻ phát hành hoặc thông báo mà bạn đã xác minh thay vì theo dõi `latest`. Xem [Cấu hình](/vi/guide/configuration) để biết tất cả các biến môi trường và [Bảo mật & tăng cường](/vi/guide/security) để biết bí mật, chính sách mạng và hướng dẫn sao lưu. ## Build từ mã nguồn {#build-from-source} **Điều kiện tiên quyết:** Node.js 22.22+, pnpm 9+, Docker (cho Postgres + Redis), Python 3.11+ (cho các tính năng AI), Git. ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` * Frontend: * Backend: ## Những gì bạn có thể làm {#what-you-can-do} ### Xử lý tập tin (200+ công cụ) {#file-processing-200-tools} | Phương thức | Số lượng | Công cụ ví dụ | |----------|-------|---------------| | **Hình ảnh** | 107 | Thay đổi kích thước, Cắt, Nén, Chuyển đổi, Xóa nền, Nâng cấp độ phân giải, OCR, Đóng dấu, Ghép ảnh, Tô màu, Công cụ GIF, preset định dạng | | **Video** | 57 | Cắt, Cắt khung, Nén, Chuyển đổi, Gộp, Trích xuất âm thanh, Phụ đề tự động, Video sang GIF, Thay đổi kích thước, Ổn định, preset định dạng | | **Âm thanh** | 27 | Cắt, Gộp, Chuyển đổi, Chuẩn hóa, Giảm nhiễu, Phiên âm, Dịch cao độ, Fade, Tạo nhạc chuông, preset định dạng | | **PDF / Tài liệu** | 29 | Gộp, Tách, Nén, OCR, Đóng dấu, Che thông tin, Word sang PDF, Excel sang PDF, Xoay, Bảo vệ, Sửa chữa | | **Tập tin** | 23 | CSV sang JSON, JSON sang XML, Gộp CSV, Tách CSV, Tạo ZIP, Giải nén ZIP, Tạo biểu đồ, YAML/JSON | ### Pipeline {#pipelines} Ghép chuỗi các công cụ thành các quy trình nhiều bước và áp dụng chúng cho một hình ảnh hoặc cả một lô: 1. Mở **Pipelines** ở thanh bên. 2. Thêm các bước (công cụ bất kỳ, cài đặt bất kỳ). 3. Chạy trên một tập tin đơn, hoặc cả một lô cùng lúc. 4. Lưu pipeline để tái sử dụng sau này. Pipeline cho phép 20 bước theo mặc định. Đặt `MAX_PIPELINE_STEPS=0` để giới hạn thành không giới hạn. ### Thư viện tập tin {#file-library} Mọi tập tin bạn xử lý đều có thể được lưu vào thư viện **Files** của bạn. SnapOtter theo dõi toàn bộ lịch sử phiên bản để bạn có thể lần theo mọi bước xử lý từ tải lên gốc đến kết quả cuối cùng. Việc lưu là tường minh: các kết quả bạn lưu vào thư viện được giữ lại cho đến khi bạn xóa chúng, trong khi các kết quả bạn xử lý và để chưa lưu sẽ tự động bị xóa sau 72 giờ (có thể cấu hình thông qua `FILE_MAX_AGE_HOURS`). ### REST API & API Key {#rest-api-api-keys} Mọi công cụ đều có thể truy cập qua HTTP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800,"height":600,"fit":"cover"}' ``` Tạo API key trong mục **Settings → API Keys**. Xem [tham chiếu REST API](/vi/api/rest) để biết tất cả các endpoint, hoặc truy cập để có tham chiếu tương tác. ### Đa người dùng & Nhóm {#multi-user-teams} Bật nhiều người dùng với kiểm soát truy cập dựa trên vai trò: * **Admin**: toàn quyền, quản lý người dùng, nhóm, cài đặt, tất cả tập tin/pipeline/API key * **User**: dùng công cụ, quản lý tập tin/pipeline/API key của riêng mình Tạo các nhóm trong mục **Settings → Teams** để nhóm người dùng lại. Đặt `AUTH_ENABLED=true` (hoặc `false` cho trường hợp một người dùng/tự sử dụng mà không cần đăng nhập). ## Dùng trên điện thoại {#use-it-from-your-phone} SnapOtter chạy tốt trên trình duyệt di động, và bạn có thể cài nó như một ứng dụng. Mở instance của bạn trên điện thoại, sau đó: * **iPhone / iPad (Safari):** nhấn Chia sẻ, rồi chọn **Thêm vào MH chính**. * **Android (Chrome):** mở menu trình duyệt rồi nhấn **Cài đặt ứng dụng**. Ứng dụng sau khi cài sẽ mở trong cửa sổ riêng, vào thẳng instance của bạn. Có một lưu ý: trình duyệt chỉ đưa ra lời mời cài đặt qua HTTPS. Địa chỉ HTTP thường trong mạng LAN vẫn dùng tốt trong một thẻ trình duyệt; còn muốn cài đặt thật sự, hãy đặt instance sau một reverse proxy có chứng chỉ (xem [hướng dẫn triển khai](/vi/guide/deployment)). Trên điện thoại và máy tính bảng, các công cụ hình ảnh hiển thị nút **Chụp ảnh** bên cạnh nút tải lên. Chụp một tờ hóa đơn hay tấm bảng trắng, ảnh sẽ vào thẳng công cụ. --- --- url: https://docs.snapotter.com/pl/guide/database.md description: >- Schemat bazy danych PostgreSQL, tabele, migracje i procedury tworzenia kopii zapasowych w SnapOtter. --- # Baza danych {#database} SnapOtter używa PostgreSQL 17 z [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) do trwałego przechowywania danych. Schemat jest zdefiniowany w `apps/api/src/db/schema.ts`. Połączenie konfiguruje się za pomocą zmiennej środowiskowej `DATABASE_URL` (domyślnie `postgres://snapotter:snapotter@postgres:5432/snapotter`). W Docker Compose kontener Postgres przechowuje swoje dane w nazwanym wolumenie `SnapOtter-pgdata`. ## Tabele {#tables} ### users {#users} Przechowuje konta użytkowników. Tworzone automatycznie przy pierwszym uruchomieniu na podstawie `DEFAULT_USERNAME` i `DEFAULT_PASSWORD`. | Kolumna | Typ | Uwagi | |---|---|---| | `id` | uuid | Klucz główny | | `username` | varchar | Unikalna, wymagana | | `passwordHash` | varchar | Hash scrypt | | `role` | varchar | `admin`, `editor` lub `user` | | `mustChangePassword` | boolean | Flaga wymuszonego resetu hasła | | `createdAt` | timestamp | Czas utworzenia | | `updatedAt` | timestamp | Czas ostatniej aktualizacji | ### sessions {#sessions} Aktywne sesje logowania. Każdy wiersz wiąże token sesji z użytkownikiem. | Kolumna | Typ | Uwagi | |---|---|---| | `id` | varchar | Klucz główny (token sesji) | | `userId` | uuid | Klucz obcy do `users.id` | | `expiresAt` | timestamp | Czas wygaśnięcia | | `createdAt` | timestamp | Czas utworzenia | ### teams {#teams} Grupy służące do organizowania użytkowników. Administratorzy mogą przypisywać użytkowników do zespołów. | Kolumna | Typ | Opis | |--------|------|-------------| | `id` | uuid | Klucz główny | | `name` | varchar (unikalna, maks. 50 znaków) | Nazwa zespołu | | `createdAt` | timestamp | Czas utworzenia | ### api\_keys {#api-keys} Klucze API do dostępu programowego. Surowy klucz jest pokazywany jednorazowo podczas tworzenia; przechowywany jest tylko jego hash. | Kolumna | Typ | Uwagi | |---|---|---| | `id` | uuid | Klucz główny | | `userId` | uuid | Klucz obcy do `users.id` | | `keyHash` | varchar | Hash scrypt klucza | | `name` | varchar | Etykieta podana przez użytkownika | | `createdAt` | timestamp | Czas utworzenia | | `lastUsedAt` | timestamp | Aktualizowany przy każdym uwierzytelnionym żądaniu | Klucze mają prefiks `si_`, po którym następuje 96 znaków szesnastkowych (48 losowych bajtów). ### pipelines {#pipelines} Zapisane łańcuchy narzędzi, które użytkownicy tworzą w interfejsie. | Kolumna | Typ | Uwagi | |---|---|---| | `id` | uuid | Klucz główny | | `name` | varchar | Nazwa potoku | | `description` | varchar | Opcjonalny opis | | `steps` | jsonb | Tablica obiektów `{ toolId, settings }` | | `createdAt` | timestamp | Czas utworzenia | ### user\_files {#user-files} Trwała biblioteka plików. Zapisana edycja jest domyślnie wstawiana jako niezależny wiersz główny („zapisz jako nowy": `version` 1, `parentId` null, więc oryginał pozostaje na liście) albo jako wersja powiązana z rodzicem, gdy nadpisujesz oryginał (`parentId` ustawiony, `version` zwiększony, zastępując go). Kolumna `toolChain` zapisuje zastosowane narzędzia. | Kolumna | Typ | Opis | |--------|------|-------------| | `id` | uuid | Klucz główny | | `userId` | uuid | Klucz obcy do users (CASCADE DELETE) | | `originalName` | varchar | Oryginalna nazwa przesłanego pliku | | `storedName` | varchar | Nazwa pliku na dysku | | `mimeType` | varchar | Typ MIME | | `size` | integer | Rozmiar pliku w bajtach | | `width` | integer | Szerokość obrazu w px | | `height` | integer | Wysokość obrazu w px | | `version` | integer | Numer wersji (1 = oryginał) | | `parentId` | uuid lub null | Klucz obcy do user\_files (wersja rodzica) | | `toolChain` | jsonb | Identyfikatory narzędzi zastosowane w kolejności, aby wytworzyć tę wersję | | `createdAt` | timestamp | Czas utworzenia | ### jobs {#jobs} Śledzi zadania przetwarzania na potrzeby raportowania postępu i porządkowania. | Kolumna | Typ | Uwagi | |---|---|---| | `id` | uuid | Klucz główny | | `type` | varchar | Identyfikator narzędzia lub potoku | | `status` | varchar | `queued`, `processing`, `completed` lub `failed` | | `progress` | real | Ułamek 0.0-1.0 | | `inputFiles` | jsonb | Tablica ścieżek plików wejściowych | | `outputPath` | varchar | Ścieżka do pliku wynikowego | | `settings` | jsonb | Użyte ustawienia narzędzia | | `error` | varchar | Komunikat o błędzie w razie niepowodzenia | | `createdAt` | timestamp | Czas utworzenia | | `completedAt` | timestamp | Czas zakończenia | ### settings {#settings} Magazyn klucz-wartość dla ustawień obowiązujących w całym serwerze, które administratorzy mogą zmieniać z poziomu interfejsu. | Kolumna | Typ | Uwagi | |---|---|---| | `key` | varchar | Klucz główny | | `value` | varchar | Wartość ustawienia | | `updatedAt` | timestamp | Czas ostatniej aktualizacji | ### roles {#roles} Role niestandardowe z uprawnieniami o dużej szczegółowości. | Kolumna | Typ | Uwagi | |---|---|---| | `id` | uuid | Klucz główny | | `name` | varchar | Unikalna nazwa roli | | `description` | varchar | Opcjonalny opis | | `permissions` | jsonb | Tablica ciągów uprawnień | | `createdAt` | timestamp | Czas utworzenia | ### audit\_log {#audit-log} Dziennik działań istotnych dla bezpieczeństwa. | Kolumna | Typ | Uwagi | |---|---|---| | `id` | uuid | Klucz główny | | `userId` | uuid | Klucz obcy do users | | `action` | varchar | Typ działania | | `details` | jsonb | Dane specyficzne dla działania | | `createdAt` | timestamp | Czas działania | ### user\_preferences {#user-preferences} Stan interfejsu dla poszczególnych użytkowników, kluczowany nazwą preferencji. Przechowuje przypięte narzędzia strony głównej, zapisywane przez `PUT /api/v1/preferences`. | Kolumna | Typ | Uwagi | |---|---|---| | `userId` | text | Klucz obcy do users, kasowanie kaskadowe. Razem z `key` tworzy klucz główny | | `key` | text | Nazwa preferencji. Razem z `userId` tworzy klucz główny | | `value` | jsonb | Zawartość preferencji | | `updatedAt` | timestamp | Ostatni zapis | ## Migracje {#migrations} Drizzle zajmuje się migracjami schematu. Pliki migracji znajdują się w `apps/api/drizzle/`. Podczas developmentu: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` W środowisku produkcyjnym oczekujące migracje są stosowane automatycznie przy uruchomieniu. ## Utwórz kopię zapasową i przywróć {#backup-and-restore} Relacyjna baza danych znajduje się w woluminie `SnapOtter-pgdata` kontenera Postgres, a nie w wolumenie `/data` aplikacji. **Logiczna kopia zapasowa z walidacją (zalecane)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Ten zrzut bazy danych nie zawiera zapisanych obiektów biblioteki w `/data/files` ani trwałego stanu BullMQ w Redis. Utwórz kopię zapasową i przywróć te dane, stosując skoordynowaną procedurę w [Bezpieczeństwo i wzmacnianie](/pl/guide/security#backup-and-recovery). **Migawka zimnego woluminu** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Nie kopiuj aktywnego katalogu danych PostgreSQL za pomocą `tar`. Twórz przedrostki nazw woluminów według projektu, więc rozpoznaj identyfikatory zamontowanych woluminów z `docker inspect` lub platformy pamięci masowej, zamiast przyjmować dosłowną etykietę `SnapOtter-pgdata`. ### Migracja z 1.x (SQLite) {#migrating-from-1-x-sqlite} Aktualizacja z SnapOtter 1.x ma własny przewodnik: zobacz [Aktualizacja z 1.x do 2.0](./upgrading). W skrócie, użyj ponownie istniejącego wolumenu `/data`, a 2.0 automatycznie wykryje i zaimportuje `/data/snapotter.db` przy pierwszym uruchomieniu (lub ustaw `SQLITE_MIGRATE_PATH`, aby wskazać go jawnie). Najpierw utwórz kopię zapasową całego wolumenu `/data`, a nie tylko `snapotter.db`: 1.x używa trybu SQLite WAL, więc zatrzymany kontener często pozostawia większość swoich danych w `snapotter.db-wal` obok niemal pustego `snapotter.db`. --- --- url: https://docs.snapotter.com/hi/tools/image/beautify.md description: >- सादे स्क्रीनशॉट को ग्रेडिएंट पृष्ठभूमि, डिवाइस फ़्रेम, छाया, और सोशल मीडिया साइज़िंग के साथ परिष्कृत छवियों में बदलें। --- # Beautify Screenshot {#beautify-screenshot} स्क्रीनशॉट में ग्रेडिएंट पृष्ठभूमि, डिवाइस फ़्रेम, छाया, वॉटरमार्क, और सोशल मीडिया साइज़िंग जोड़ें। उत्पाद मार्केटिंग, सोशल मीडिया, और दस्तावेज़ीकरण के लिए परिष्कृत छवियाँ बनाने हेतु आदर्श। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"linear-gradient"` | पृष्ठभूमि प्रकार: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | string | No | `"#667eea"` | ठोस पृष्ठभूमि रंग (जब `backgroundType` `solid` हो तब उपयोग किया जाता है) | | gradientStops | array | No | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | ग्रेडिएंट रंग स्टॉप (न्यूनतम 2)। प्रत्येक स्टॉप में `color` (hex) और `position` (0-100) होता है। | | gradientAngle | number | No | 135 | डिग्री में ग्रेडिएंट कोण (0 से 360) | | padding | number | No | 64 | पिक्सेल में छवि के चारों ओर पैडिंग (0 से 256) | | borderRadius | number | No | 12 | स्क्रीनशॉट पर कॉर्नर त्रिज्या (0 से 64) | | shadowPreset | string | No | `"subtle"` | छाया प्रीसेट: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | number | No | 20 | कस्टम छाया ब्लर त्रिज्या (0 से 100, जब `shadowPreset` `custom` हो तब उपयोग किया जाता है) | | shadowOffsetX | number | No | 0 | कस्टम छाया क्षैतिज ऑफसेट (-50 से 50) | | shadowOffsetY | number | No | 10 | कस्टम छाया ऊर्ध्वाधर ऑफसेट (-50 से 50) | | shadowColor | string | No | `"#000000"` | hex के रूप में कस्टम छाया रंग | | shadowOpacity | number | No | 30 | कस्टम छाया अपारदर्शिता (0 से 100) | | frame | string | No | `"none"` | डिवाइस या विंडो फ़्रेम: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | string | No | - | विंडो फ़्रेम टाइटल बार में प्रदर्शित टाइटल टेक्स्ट | | socialPreset | string | No | `"none"` | सोशल मीडिया आयामों में आकार बदलें: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | string | No | - | वैकल्पिक वॉटरमार्क टेक्स्ट ओवरले | | watermarkPosition | string | No | `"bottom-right"` | वॉटरमार्क स्थिति: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | number | No | 50 | वॉटरमार्क अपारदर्शिता (0 से 100) | | outputFormat | string | No | `"png"` | आउटपुट प्रारूप: `png`, `jpeg`, `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * दो फ़ाइल फ़ील्ड स्वीकार करता है: `file` (आवश्यक, मुख्य स्क्रीनशॉट) और `backgroundImage` (वैकल्पिक, जब `backgroundType` `image` हो तब उपयोग किया जाता है)। * HEIC, RAW, PSD, और SVG इनपुट प्रारूपों का समर्थन करता है (स्वचालित रूप से डिकोड किए गए)। * छाया प्रीसेट विशिष्ट मानों से मैप होते हैं: * `subtle`: blur 20, offsetY 4, opacity 20% * `medium`: blur 40, offsetY 10, opacity 35% * `dramatic`: blur 80, offsetY 20, opacity 50% * सोशल मीडिया प्रीसेट `contain` मोड का उपयोग करके अंतिम आउटपुट को लक्ष्य आयामों में फ़िट करने के लिए आकार बदलते हैं: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * डिवाइस फ़्रेम (`iphone`, `macbook`, `ipad`) छवि के चारों ओर एक हार्डवेयर बेज़ल लागू करते हैं और `borderRadius` सेटिंग को छोड़ देते हैं। * जब पारदर्शिता आवश्यक हो (छाया, बॉर्डर त्रिज्या, डिवाइस फ़्रेम, या पारदर्शी पृष्ठभूमि), तो आउटपुट को PNG पर बाध्य किया जाता है भले ही `jpeg` चुना गया हो। * पाइपलाइन/बैच मोड में छवि पृष्ठभूमि समर्थित नहीं है। --- --- url: https://docs.snapotter.com/ja/tools/image/beautify.md description: プレーンなスクリーンショットを、グラデーション背景、デバイスフレーム、シャドウ、SNS 向けサイズで洗練された画像に仕上げます。 --- # Beautify Screenshot {#beautify-screenshot} スクリーンショットにグラデーション背景、デバイスフレーム、シャドウ、ウォーターマーク、SNS 向けサイズを追加します。プロダクトマーケティング、SNS、ドキュメント向けに洗練された画像を作成するのに最適です。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"linear-gradient"` | 背景の種類: `solid`、`linear-gradient`、`radial-gradient`、`image`、`transparent` | | backgroundColor | string | No | `"#667eea"` | 単色の背景色 (`backgroundType` が `solid` の場合に使用) | | gradientStops | array | No | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | グラデーションのカラーストップ (最小 2)。各ストップは `color` (16 進) と `position` (0 ~ 100) を持ちます。 | | gradientAngle | number | No | 135 | グラデーションの角度 (度) (0 ~ 360) | | padding | number | No | 64 | 画像周辺のパディング (ピクセル) (0 ~ 256) | | borderRadius | number | No | 12 | スクリーンショットの角の丸み (0 ~ 64) | | shadowPreset | string | No | `"subtle"` | シャドウプリセット: `none`、`subtle`、`medium`、`dramatic`、`custom` | | shadowBlur | number | No | 20 | カスタムシャドウのぼかし半径 (0 ~ 100、`shadowPreset` が `custom` の場合に使用) | | shadowOffsetX | number | No | 0 | カスタムシャドウの水平オフセット (-50 ~ 50) | | shadowOffsetY | number | No | 10 | カスタムシャドウの垂直オフセット (-50 ~ 50) | | shadowColor | string | No | `"#000000"` | カスタムシャドウの色 (16 進) | | shadowOpacity | number | No | 30 | カスタムシャドウの不透明度 (0 ~ 100) | | frame | string | No | `"none"` | デバイスまたはウィンドウのフレーム: `none`、`macos-light`、`macos-dark`、`windows-light`、`windows-dark`、`browser-light`、`browser-dark`、`iphone`、`iphone-dark`、`macbook`、`macbook-dark`、`ipad`、`ipad-dark` | | frameTitle | string | No | - | ウィンドウフレームのタイトルバーに表示されるタイトルテキスト | | socialPreset | string | No | `"none"` | SNS 向けサイズにリサイズ: `none`、`twitter`、`linkedin`、`instagram-square`、`instagram-story`、`facebook`、`producthunt` | | watermarkText | string | No | - | 任意のウォーターマークテキストオーバーレイ | | watermarkPosition | string | No | `"bottom-right"` | ウォーターマークの位置: `top-left`、`top-right`、`bottom-left`、`bottom-right`、`center` | | watermarkOpacity | number | No | 50 | ウォーターマークの不透明度 (0 ~ 100) | | outputFormat | string | No | `"png"` | 出力形式: `png`、`jpeg`、`webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * 2 つのファイルフィールドを受け付けます: `file` (必須、メインのスクリーンショット) と `backgroundImage` (任意、`backgroundType` が `image` の場合に使用)。 * HEIC、RAW、PSD、SVG の入力形式をサポートします (自動的にデコードされます)。 * シャドウプリセットは特定の値にマッピングされます: * `subtle`: ぼかし 20、offsetY 4、不透明度 20% * `medium`: ぼかし 40、offsetY 10、不透明度 35% * `dramatic`: ぼかし 80、offsetY 20、不透明度 50% * SNS プリセットは、`contain` モードを使用して最終出力をターゲットサイズに合わせてリサイズします: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * デバイスフレーム (`iphone`、`macbook`、`ipad`) は画像の周囲にハードウェアのベゼルを適用し、`borderRadius` 設定をスキップします。 * 透明度が必要な場合 (シャドウ、角の丸み、デバイスフレーム、透明背景)、`jpeg` が選択されていても出力は PNG に強制されます。 * 画像背景はパイプライン/バッチモードではサポートされません。 --- --- url: https://docs.snapotter.com/ko/tools/image/beautify.md description: 밋밋한 스크린샷을 그라디언트 배경, 기기 프레임, 그림자, 소셜 미디어 크기 조정으로 세련된 이미지로 만듭니다. --- # Beautify Screenshot {#beautify-screenshot} 스크린샷에 그라디언트 배경, 기기 프레임, 그림자, 워터마크, 소셜 미디어 크기 조정을 추가합니다. 제품 마케팅, 소셜 미디어, 문서용의 세련된 이미지를 만드는 데 이상적입니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/beautify` ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | backgroundType | string | 아니요 | `"linear-gradient"` | 배경 유형: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | string | 아니요 | `"#667eea"` | 단색 배경 색상 (`backgroundType`이(가) `solid`일 때 사용) | | gradientStops | array | 아니요 | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | 그라디언트 색상 정지점 (최소 2개). 각 정지점은 `color`(16진수)과 `position`(0-100)을 가집니다. | | gradientAngle | number | 아니요 | 135 | 그라디언트 각도 (0 ~ 360) | | padding | number | 아니요 | 64 | 이미지 주위의 여백 픽셀 (0 ~ 256) | | borderRadius | number | 아니요 | 12 | 스크린샷의 모서리 반경 (0 ~ 64) | | shadowPreset | string | 아니요 | `"subtle"` | 그림자 프리셋: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | number | 아니요 | 20 | 사용자 지정 그림자 블러 반경 (0 ~ 100, `shadowPreset`이(가) `custom`일 때 사용) | | shadowOffsetX | number | 아니요 | 0 | 사용자 지정 그림자 수평 오프셋 (-50 ~ 50) | | shadowOffsetY | number | 아니요 | 10 | 사용자 지정 그림자 수직 오프셋 (-50 ~ 50) | | shadowColor | string | 아니요 | `"#000000"` | 16진수 형식의 사용자 지정 그림자 색상 | | shadowOpacity | number | 아니요 | 30 | 사용자 지정 그림자 불투명도 (0 ~ 100) | | frame | string | 아니요 | `"none"` | 기기 또는 창 프레임: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | string | 아니요 | - | 창 프레임 제목 표시줄에 표시되는 제목 텍스트 | | socialPreset | string | 아니요 | `"none"` | 소셜 미디어 크기로 조정: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | string | 아니요 | - | 선택적 워터마크 텍스트 오버레이 | | watermarkPosition | string | 아니요 | `"bottom-right"` | 워터마크 위치: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | number | 아니요 | 50 | 워터마크 불투명도 (0 ~ 100) | | outputFormat | string | 아니요 | `"png"` | 출력 형식: `png`, `jpeg`, `webp` | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### 배경 이미지 사용 {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## 참고 사항 {#notes} * 두 개의 파일 필드를 받습니다: `file`(필수, 메인 스크린샷)과 `backgroundImage`(선택, `backgroundType`이(가) `image`일 때 사용). * HEIC, RAW, PSD, SVG 입력 형식을 지원합니다(자동 디코딩). * 그림자 프리셋은 특정 값에 매핑됩니다: * `subtle`: 블러 20, offsetY 4, 불투명도 20% * `medium`: 블러 40, offsetY 10, 불투명도 35% * `dramatic`: 블러 80, offsetY 20, 불투명도 50% * 소셜 미디어 프리셋은 `contain` 모드를 사용하여 최종 출력을 대상 크기에 맞게 조정합니다: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * 기기 프레임(`iphone`, `macbook`, `ipad`)은 이미지 주위에 하드웨어 베젤을 적용하고 `borderRadius` 설정을 건너뜁니다. * 투명도가 필요한 경우(그림자, 모서리 반경, 기기 프레임, 투명 배경), `jpeg`을(를) 선택하더라도 출력은 PNG로 강제됩니다. * 이미지 배경은 파이프라인/배치 모드에서 지원되지 않습니다. --- --- url: https://docs.snapotter.com/th/tools/image/beautify.md description: >- เปลี่ยนภาพหน้าจอธรรมดาให้เป็นรูปภาพที่ดูดีด้วยพื้นหลังไล่ระดับสี, เฟรมอุปกรณ์, เงา และขนาดสำหรับโซเชียลมีเดีย --- # Beautify Screenshot {#beautify-screenshot} เพิ่มพื้นหลังไล่ระดับสี, เฟรมอุปกรณ์, เงา, ลายน้ำ และขนาดสำหรับโซเชียลมีเดียให้กับภาพหน้าจอ เหมาะสำหรับสร้างรูปภาพที่ดูดีสำหรับการตลาดผลิตภัณฑ์, โซเชียลมีเดีย และเอกสารประกอบ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"linear-gradient"` | ประเภทพื้นหลัง: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | string | No | `"#667eea"` | สีพื้นหลังทึบ (ใช้เมื่อ `backgroundType` เป็น `solid`) | | gradientStops | array | No | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | จุดไล่ระดับสี (อย่างน้อย 2) แต่ละจุดมี `color` (hex) และ `position` (0-100) | | gradientAngle | number | No | 135 | มุมไล่ระดับสีเป็นองศา (0 ถึง 360) | | padding | number | No | 64 | ระยะขอบรอบรูปภาพเป็นพิกเซล (0 ถึง 256) | | borderRadius | number | No | 12 | รัศมีมุมบนภาพหน้าจอ (0 ถึง 64) | | shadowPreset | string | No | `"subtle"` | พรีเซ็ตเงา: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | number | No | 20 | รัศมีการเบลอเงาแบบกำหนดเอง (0 ถึง 100, ใช้เมื่อ `shadowPreset` เป็น `custom`) | | shadowOffsetX | number | No | 0 | ระยะเลื่อนแนวนอนของเงาแบบกำหนดเอง (-50 ถึง 50) | | shadowOffsetY | number | No | 10 | ระยะเลื่อนแนวตั้งของเงาแบบกำหนดเอง (-50 ถึง 50) | | shadowColor | string | No | `"#000000"` | สีเงาแบบกำหนดเองเป็น hex | | shadowOpacity | number | No | 30 | ความทึบของเงาแบบกำหนดเอง (0 ถึง 100) | | frame | string | No | `"none"` | เฟรมอุปกรณ์หรือหน้าต่าง: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | string | No | - | ข้อความชื่อที่แสดงในแถบชื่อของเฟรมหน้าต่าง | | socialPreset | string | No | `"none"` | ปรับขนาดตามมิติของโซเชียลมีเดีย: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | string | No | - | ข้อความลายน้ำซ้อนทับที่เป็นทางเลือก | | watermarkPosition | string | No | `"bottom-right"` | ตำแหน่งลายน้ำ: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | number | No | 50 | ความทึบของลายน้ำ (0 ถึง 100) | | outputFormat | string | No | `"png"` | รูปแบบเอาต์พุต: `png`, `jpeg`, `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * รับฟิลด์ไฟล์สองฟิลด์: `file` (จำเป็น, ภาพหน้าจอหลัก) และ `backgroundImage` (ทางเลือก, ใช้เมื่อ `backgroundType` เป็น `image`) * รองรับรูปแบบอินพุต HEIC, RAW, PSD และ SVG (ถอดรหัสอัตโนมัติ) * พรีเซ็ตเงาแมปกับค่าเฉพาะดังนี้: * `subtle`: เบลอ 20, offsetY 4, ความทึบ 20% * `medium`: เบลอ 40, offsetY 10, ความทึบ 35% * `dramatic`: เบลอ 80, offsetY 20, ความทึบ 50% * พรีเซ็ตโซเชียลมีเดียปรับขนาดเอาต์พุตสุดท้ายให้พอดีกับมิติเป้าหมายโดยใช้โหมด `contain`: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * เฟรมอุปกรณ์ (`iphone`, `macbook`, `ipad`) ใช้ขอบฮาร์ดแวร์รอบรูปภาพและข้ามการตั้งค่า `borderRadius` * เมื่อจำเป็นต้องมีความโปร่งใส (เงา, รัศมีมุม, เฟรมอุปกรณ์ หรือพื้นหลังโปร่งใส) เอาต์พุตจะถูกบังคับเป็น PNG แม้ว่าจะเลือก `jpeg` ไว้ก็ตาม * พื้นหลังแบบรูปภาพไม่รองรับในโหมดไปป์ไลน์/แบตช์ --- --- url: https://docs.snapotter.com/vi/tools/image/beautify.md description: >- Biến các ảnh chụp màn hình đơn giản thành hình ảnh trau chuốt với nền dải màu, khung thiết bị, bóng đổ và kích thước cho mạng xã hội. --- # Beautify Screenshot {#beautify-screenshot} Thêm nền dải màu, khung thiết bị, bóng đổ, hình mờ và kích thước cho mạng xã hội vào các ảnh chụp màn hình. Lý tưởng để tạo hình ảnh trau chuốt cho tiếp thị sản phẩm, mạng xã hội và tài liệu. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"linear-gradient"` | Loại nền: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | string | No | `"#667eea"` | Màu nền đơn sắc (dùng khi `backgroundType` là `solid`) | | gradientStops | array | No | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | Các điểm dừng màu của dải màu (tối thiểu 2). Mỗi điểm dừng có `color` (hex) và `position` (0-100). | | gradientAngle | number | No | 135 | Góc dải màu theo độ (0 đến 360) | | padding | number | No | 64 | Khoảng đệm quanh hình ảnh tính bằng pixel (0 đến 256) | | borderRadius | number | No | 12 | Bán kính bo góc trên ảnh chụp màn hình (0 đến 64) | | shadowPreset | string | No | `"subtle"` | Cài đặt sẵn bóng đổ: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | number | No | 20 | Bán kính làm mờ bóng đổ tùy chỉnh (0 đến 100, dùng khi `shadowPreset` là `custom`) | | shadowOffsetX | number | No | 0 | Độ lệch ngang tùy chỉnh của bóng đổ (-50 đến 50) | | shadowOffsetY | number | No | 10 | Độ lệch dọc tùy chỉnh của bóng đổ (-50 đến 50) | | shadowColor | string | No | `"#000000"` | Màu bóng đổ tùy chỉnh dạng hex | | shadowOpacity | number | No | 30 | Độ mờ bóng đổ tùy chỉnh (0 đến 100) | | frame | string | No | `"none"` | Khung thiết bị hoặc cửa sổ: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | string | No | - | Văn bản tiêu đề hiển thị trong thanh tiêu đề khung cửa sổ | | socialPreset | string | No | `"none"` | Đổi kích thước sang kích thước mạng xã hội: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | string | No | - | Lớp phủ văn bản hình mờ tùy chọn | | watermarkPosition | string | No | `"bottom-right"` | Vị trí hình mờ: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | number | No | 50 | Độ mờ hình mờ (0 đến 100) | | outputFormat | string | No | `"png"` | Định dạng đầu ra: `png`, `jpeg`, `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * Chấp nhận hai trường tệp: `file` (bắt buộc, ảnh chụp màn hình chính) và `backgroundImage` (tùy chọn, dùng khi `backgroundType` là `image`). * Hỗ trợ các định dạng đầu vào HEIC, RAW, PSD và SVG (được giải mã tự động). * Các cài đặt sẵn bóng đổ ánh xạ tới các giá trị cụ thể: * `subtle`: blur 20, offsetY 4, độ mờ 20% * `medium`: blur 40, offsetY 10, độ mờ 35% * `dramatic`: blur 80, offsetY 20, độ mờ 50% * Các cài đặt sẵn cho mạng xã hội đổi kích thước đầu ra cuối cùng để vừa với kích thước đích bằng chế độ `contain`: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * Khung thiết bị (`iphone`, `macbook`, `ipad`) áp dụng một viền phần cứng quanh hình ảnh và bỏ qua cài đặt `borderRadius`. * Khi cần độ trong suốt (bóng đổ, bán kính bo góc, khung thiết bị hoặc nền trong suốt), đầu ra buộc phải là PNG ngay cả khi `jpeg` được chọn. * Nền hình ảnh không được hỗ trợ ở chế độ pipeline/batch. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/beautify.md description: 将普通截图变成精致的图像,加上渐变背景、设备框架、阴影和社交媒体尺寸。 --- # Beautify Screenshot {#beautify-screenshot} 为截图添加渐变背景、设备框架、阴影、水印和社交媒体尺寸。非常适合为产品营销、社交媒体和文档创建精致的图像。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | 否 | `"linear-gradient"` | 背景类型:`solid`、`linear-gradient`、`radial-gradient`、`image`、`transparent` | | backgroundColor | string | 否 | `"#667eea"` | 纯色背景颜色(当 `backgroundType` 为 `solid` 时使用) | | gradientStops | array | 否 | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | 渐变色标(至少 2 个)。每个色标有 `color`(十六进制)和 `position`(0-100)。 | | gradientAngle | number | 否 | 135 | 渐变角度(度,0 到 360) | | padding | number | 否 | 64 | 图像周围的内边距(像素,0 到 256) | | borderRadius | number | 否 | 12 | 截图的圆角半径(0 到 64) | | shadowPreset | string | 否 | `"subtle"` | 阴影预设:`none`、`subtle`、`medium`、`dramatic`、`custom` | | shadowBlur | number | 否 | 20 | 自定义阴影模糊半径(0 到 100,当 `shadowPreset` 为 `custom` 时使用) | | shadowOffsetX | number | 否 | 0 | 自定义阴影水平偏移(-50 到 50) | | shadowOffsetY | number | 否 | 10 | 自定义阴影垂直偏移(-50 到 50) | | shadowColor | string | 否 | `"#000000"` | 自定义阴影颜色(十六进制) | | shadowOpacity | number | 否 | 30 | 自定义阴影不透明度(0 到 100) | | frame | string | 否 | `"none"` | 设备或窗口框架:`none`、`macos-light`、`macos-dark`、`windows-light`、`windows-dark`、`browser-light`、`browser-dark`、`iphone`、`iphone-dark`、`macbook`、`macbook-dark`、`ipad`、`ipad-dark` | | frameTitle | string | 否 | - | 显示在窗口框架标题栏中的标题文本 | | socialPreset | string | 否 | `"none"` | 调整到社交媒体尺寸:`none`、`twitter`、`linkedin`、`instagram-square`、`instagram-story`、`facebook`、`producthunt` | | watermarkText | string | 否 | - | 可选的水印文本叠加 | | watermarkPosition | string | 否 | `"bottom-right"` | 水印位置:`top-left`、`top-right`、`bottom-left`、`bottom-right`、`center` | | watermarkOpacity | number | 否 | 50 | 水印不透明度(0 到 100) | | outputFormat | string | 否 | `"png"` | 输出格式:`png`、`jpeg`、`webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * 接受两个文件字段:`file`(必填,主截图)和 `backgroundImage`(可选,当 `backgroundType` 为 `image` 时使用)。 * 支持 HEIC、RAW、PSD 和 SVG 输入格式(自动解码)。 * 阴影预设映射到特定的值: * `subtle`:模糊 20,offsetY 4,不透明度 20% * `medium`:模糊 40,offsetY 10,不透明度 35% * `dramatic`:模糊 80,offsetY 20,不透明度 50% * 社交媒体预设使用 `contain` 模式将最终输出调整为适配目标尺寸: * `twitter`:1600x900 * `linkedin`:1200x627 * `instagram-square`:1080x1080 * `instagram-story`:1080x1920 * `facebook`:1200x630 * `producthunt`:1270x760 * 设备框架(`iphone`、`macbook`、`ipad`)会在图像周围应用硬件边框,并跳过 `borderRadius` 设置。 * 当需要透明度时(阴影、圆角、设备框架或透明背景),即使选择了 `jpeg`,输出也会被强制为 PNG。 * 图像背景在管道/批处理模式下不受支持。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/beautify.md description: 透過漸層背景、裝置外框、陰影及社群媒體尺寸,將樸素的截圖轉為精緻影像。 --- # Beautify Screenshot {#beautify-screenshot} 為截圖加上漸層背景、裝置外框、陰影、浮水印及社群媒體尺寸。適合為產品行銷、社群媒體及文件製作精緻影像。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"linear-gradient"` | 背景類型:`solid`、`linear-gradient`、`radial-gradient`、`image`、`transparent` | | backgroundColor | string | No | `"#667eea"` | 純色背景顏色(當 `backgroundType` 為 `solid` 時使用) | | gradientStops | array | No | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | 漸層色標(最少 2 個)。每個色標具有 `color`(十六進位)及 `position`(0-100)。 | | gradientAngle | number | No | 135 | 漸層角度(0 至 360 度) | | padding | number | No | 64 | 影像周圍的內距,以像素為單位(0 至 256) | | borderRadius | number | No | 12 | 截圖的圓角半徑(0 至 64) | | shadowPreset | string | No | `"subtle"` | 陰影預設:`none`、`subtle`、`medium`、`dramatic`、`custom` | | shadowBlur | number | No | 20 | 自訂陰影模糊半徑(0 至 100,當 `shadowPreset` 為 `custom` 時使用) | | shadowOffsetX | number | No | 0 | 自訂陰影水平偏移(-50 至 50) | | shadowOffsetY | number | No | 10 | 自訂陰影垂直偏移(-50 至 50) | | shadowColor | string | No | `"#000000"` | 自訂陰影顏色,以十六進位表示 | | shadowOpacity | number | No | 30 | 自訂陰影不透明度(0 至 100) | | frame | string | No | `"none"` | 裝置或視窗外框:`none`、`macos-light`、`macos-dark`、`windows-light`、`windows-dark`、`browser-light`、`browser-dark`、`iphone`、`iphone-dark`、`macbook`、`macbook-dark`、`ipad`、`ipad-dark` | | frameTitle | string | No | - | 顯示於視窗外框標題列的標題文字 | | socialPreset | string | No | `"none"` | 調整為社群媒體尺寸:`none`、`twitter`、`linkedin`、`instagram-square`、`instagram-story`、`facebook`、`producthunt` | | watermarkText | string | No | - | 選用的浮水印文字疊層 | | watermarkPosition | string | No | `"bottom-right"` | 浮水印位置:`top-left`、`top-right`、`bottom-left`、`bottom-right`、`center` | | watermarkOpacity | number | No | 50 | 浮水印不透明度(0 至 100) | | outputFormat | string | No | `"png"` | 輸出格式:`png`、`jpeg`、`webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * 接受兩個檔案欄位:`file`(必填,主要截圖)及 `backgroundImage`(選填,當 `backgroundType` 為 `image` 時使用)。 * 支援 HEIC、RAW、PSD 及 SVG 輸入格式(自動解碼)。 * 陰影預設對應到特定的數值: * `subtle`:模糊 20、offsetY 4、不透明度 20% * `medium`:模糊 40、offsetY 10、不透明度 35% * `dramatic`:模糊 80、offsetY 20、不透明度 50% * 社群媒體預設會使用 `contain` 模式將最終輸出調整為符合目標尺寸: * `twitter`:1600x900 * `linkedin`:1200x627 * `instagram-square`:1080x1080 * `instagram-story`:1080x1920 * `facebook`:1200x630 * `producthunt`:1270x760 * 裝置外框(`iphone`、`macbook`、`ipad`)會在影像周圍套用硬體邊框,並略過 `borderRadius` 設定。 * 當需要透明度時(陰影、圓角、裝置外框或透明背景),即使選取了 `jpeg`,輸出也會強制為 PNG。 * 影像背景在 pipeline/批次模式中不支援。 --- --- url: https://docs.snapotter.com/de/guide/users-roles.md description: >- Verwalte Benutzer, integrierte und benutzerdefinierte Rollen, Berechtigungen, API-Schlüssel, Teams, Sitzungen und das Audit-Log in SnapOtter. --- # Benutzer, Rollen & Berechtigungen {#users-roles-permissions} SnapOtter wird mit drei integrierten Rollen, 17 granularen Berechtigungen und Unterstützung für benutzerdefinierte Rollen mit optionaler Zugriffssteuerung pro Werkzeug ausgeliefert. Diese Seite behandelt das vollständige Autorisierungsmodell, die Bereichseinschränkung von API-Schlüsseln, die Teamverwaltung und das Audit-Logging. ::: tip Verwandte Seiten [OIDC / SSO](/de/guide/oidc) | [SAML SSO](/de/guide/saml) | [SCIM-Bereitstellung](/de/guide/scim) | [Sicherheit & Härtung](/de/guide/security) ::: ## Benutzer {#users} ### Benutzer erstellen {#creating-users} Administratoren können Benutzer über das Admin-Panel oder den `POST /api/auth/register`-Endpunkt erstellen. Jeder Benutzer hat einen Benutzernamen, eine Rolle, eine Teamzuordnung und eine optionale E-Mail-Adresse. ### Standard-Administrator {#default-admin} Beim ersten Start erstellt SnapOtter ein Standard-Administratorkonto. Die Zugangsdaten stammen aus Umgebungsvariablen: | Variable | Standard | Beschreibung | |---|---|---| | `DEFAULT_USERNAME` | `admin` | Benutzername für das anfängliche Administratorkonto | | `DEFAULT_PASSWORD` | `admin` | Passwort für das anfängliche Administratorkonto | Der Standard-Administrator muss beim ersten Login sein Passwort ändern. ### Authentifizierungsanbieter {#authentication-providers} Benutzer können sich über mehrere Methoden authentifizieren: * **Lokal** - Benutzername und Passwort, gespeichert in der SnapOtter-Datenbank * **OIDC** - jeder OpenID-Connect-Anbieter (siehe [OIDC / SSO](/de/guide/oidc)) * **SAML** - SAML-2.0-Identitätsanbieter (siehe [SAML SSO](/de/guide/saml)) * **SCIM** - automatisierte Bereitstellung durch einen Identitätsanbieter (siehe [SCIM-Bereitstellung](/de/guide/scim)) ### Authentifizierung deaktivieren {#disabling-authentication} Setze `AUTH_ENABLED=false`, um die Authentifizierung vollständig zu deaktivieren. In diesem Modus wird für alle Anfragen ein synthetischer anonymer Benutzer mit der Rolle `admin` verwendet. Es ist kein Login erforderlich. ::: warning Das Deaktivieren der Authentifizierung gewährt jedem, der die Instanz erreichen kann, vollen Administratorzugriff. Verwende dies nur in vertrauenswürdigen Umgebungen. ::: ## Integrierte Rollen {#built-in-roles} SnapOtter enthält drei integrierte Rollen. Sie können weder geändert noch gelöscht werden. ### Admin {#admin} Alle 17 Berechtigungen. Volle Kontrolle über die Instanz. `tools:use` `files:own` `files:all` `apikeys:own` `apikeys:all` `pipelines:own` `pipelines:all` `settings:read` `settings:write` `users:manage` `teams:manage` `features:manage` `system:health` `audit:read` `compliance:manage` `webhooks:manage` `security:manage` ### Editor {#editor} 7 Berechtigungen. Kann alle Werkzeuge verwenden und alle Dateien und Pipelines verwalten, aber nicht auf Administratorfunktionen zugreifen. `tools:use` `files:own` `files:all` `apikeys:own` `pipelines:own` `pipelines:all` `settings:read` ### User {#user} 5 Berechtigungen. Kann Werkzeuge verwenden und eigene Ressourcen verwalten. `tools:use` `files:own` `apikeys:own` `pipelines:own` `settings:read` ## Berechtigungsreferenz {#permissions-reference} | Berechtigung | Beschreibung | |---|---| | `tools:use` | Jedes Verarbeitungswerkzeug verwenden | | `files:own` | Eigene Dateien ansehen und verwalten | | `files:all` | Dateien aller Benutzer ansehen und verwalten | | `apikeys:own` | Eigene API-Schlüssel erstellen und verwalten | | `apikeys:all` | API-Schlüssel aller Benutzer ansehen | | `pipelines:own` | Eigene Pipelines erstellen und verwalten | | `pipelines:all` | Pipelines aller Benutzer ansehen und verwalten | | `settings:read` | Instanzeinstellungen ansehen | | `settings:write` | Instanzeinstellungen ändern | | `users:manage` | Erstellen und verwalten Sie Benutzerkonten innerhalb der Autoritätsgrenzen des Akteurs | | `teams:manage` | Teams erstellen, aktualisieren und löschen | | `features:manage` | KI-Feature-Bundles installieren und verwalten | | `system:health` | Auf Health- und Readiness-Endpunkte zugreifen | | `audit:read` | Das Audit-Log ansehen und Rollen auflisten | | `compliance:manage` | Verwalten Sie den DSGVO-Lebenszyklus und die Compliance-Funktionen. Zerstörerische Benutzeroperationen bleiben autoritätsgebunden | | `webhooks:manage` | Ausgehende Webhooks konfigurieren | | `security:manage` | Sicherheitseinstellungen verwalten (IP-Zulassungsliste, SSO-Erzwingung) | ## Benutzerdefinierte Rollen {#custom-roles} Administratoren mit der Berechtigung `security:manage` können benutzerdefinierte Rollen über das Admin-Panel oder die Rollen-API erstellen. Das Auflisten von Rollen erfordert `audit:read`. ### Eine benutzerdefinierte Rolle erstellen {#creating-a-custom-role} ```bash curl -X POST http://localhost:1349/api/v1/roles \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "reviewer", "description": "Can use tools and view all files", "permissions": ["tools:use", "files:own", "files:all", "settings:read"] }' ``` Rollennamen müssen 2 bis 30 Zeichen lang sein, kleingeschrieben alphanumerisch mit Bindestrichen und Unterstrichen. ### Delegierte Verwaltungsgrenzen {#delegated-administration-boundaries} Alle 17 Berechtigungen können über benutzerdefinierte Rollen delegiert werden, aber eine Administratorberechtigung macht diese Rolle nicht gleichwertig mit der integrierten `admin`-Rolle. Von `users:manage` autorisierte Benutzermutationen, von `compliance:manage` autorisierte destruktive Operationen und von `security:manage` autorisierte benutzerdefinierte Rollenverwaltung unterliegen den aktuellen Berechtigungen des Akteurs: * Integrierte Rollen folgen `admin` > `editor` > `user`; Benutzerdefinierte Rollen sind unterhalb der integrierten Rollen aufgeführt. * Die Berechtigungen des Ziels müssen in den **wirksamen** Berechtigungen des Akteurs enthalten sein. Ein bereichsbezogener API-Schlüssel kann daher keine Berechtigungen ausüben, die in seinem Bereich fehlen. * Der Tool-Zugriff einer Zielrolle muss durch den eigenen Tool-Zugriff des Akteurs begrenzt sein. * Ein deaktiviertes Konto wird mit seiner ursprünglichen Rolle verglichen, wenn diese Rolle als `disabled:` aufgezeichnet ist. * Zum Löschen einer benutzerdefinierten Rolle ist außerdem die Berechtigung zum Zuweisen des integrierten `user`-Fallbacks erforderlich. deaktivierte Mitglieder bleiben als `disabled:user` deaktiviert. Globale Anmeldeinformationen und Konfiguration sind strenger: Das Ausstellen oder Widerrufen des SCIM-Tokens und das Importieren der Instanzkonfiguration erfordern die integrierte `admin`-Rolle mit vollständiger effektiver Administratorberechtigung. ### Berechtigungen auf Werkzeugebene {#tool-level-permissions} Benutzerdefinierte Rollen können optional einschränken, auf welche Werkzeuge Benutzer zugreifen dürfen. Zwei Modi sind verfügbar: | Modus | Verhalten | Lizenzanforderung | |---|---|---| | `category` | Einschränkung nach Modalität (Bild, Video, Audio, Dokument, Datei) | Keine (kostenlos) | | `tool` | Einschränkung nach einzelner Werkzeug-ID | Erfordert das Enterprise-Feature `per_tool_permissions` | Wenn der Modus `tool` gesetzt ist, das Enterprise-Feature aber nicht verfügbar ist, degradiert SnapOtter kontrolliert und erlaubt den Zugriff auf alle Werkzeuge. ```json { "name": "image-only", "permissions": ["tools:use", "files:own"], "toolPermissions": { "mode": "category", "allowed": ["image"] } } ``` ### Eine benutzerdefinierte Rolle löschen {#deleting-a-custom-role} Wenn eine benutzerdefinierte Rolle gelöscht wird, werden alle ihr zugewiesenen Benutzer automatisch der Rolle `user` neu zugewiesen. ## Teams {#teams} Teams gruppieren Benutzer für die Speicher- und Aufbewahrungsverwaltung. Ein `Default`-Team wird beim ersten Start erstellt. | Feld | Typ | Beschreibung | |---|---|---| | `name` | string | Eindeutiger Teamname (1 bis 50 Zeichen) | | `storageQuota` | number | Speicherlimit pro Team in Bytes (funktioniert ohne Enterprise) | | `retentionHours` | number | Ausgaben nach dieser Anzahl von Stunden automatisch löschen (erfordert `team_retention_overrides`, Enterprise) | | `legalHold` | boolean | Automatisches Löschen der Dateien von Teammitgliedern verhindern (erfordert `legal_hold`, Enterprise) | ::: info Das `Default`-Team kann nicht gelöscht werden. Teams, die noch Mitglieder haben, können nicht gelöscht werden. Weise die Mitglieder zuerst neu zu. ::: ## API-Schlüssel {#api-keys} Benutzer können API-Schlüssel für programmatischen Zugriff generieren. Jeder Schlüssel verwendet das Präfix `si_` und wird nur einmal bei der Erstellung angezeigt. ### Bereichseingeschränkte Berechtigungen {#scoped-permissions} API-Schlüssel können optional ein `permissions`-Array tragen. Wenn gesetzt, sind die effektiven Berechtigungen für eine Anfrage die **Schnittmenge** der Rollenberechtigungen des Benutzers und der bereichseingeschränkten Berechtigungen des Schlüssels. Das bedeutet, ein API-Schlüssel kann nie über die eigenen Berechtigungen des Benutzers hinaus eskalieren. ```bash curl -X POST http://localhost:1349/api/v1/api-keys \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "CI pipeline key", "permissions": ["tools:use", "files:own"], "expiresAt": "2027-01-01T00:00:00Z" }' ``` ### Ablauf {#expiration} Schlüssel akzeptieren einen optionalen `expiresAt`-Zeitstempel. Abgelaufene Schlüssel werden bei der Authentifizierung abgewiesen. ## Audit-Log {#audit-log} SnapOtter zeichnet sicherheitsrelevante Ereignisse in einem strukturierten Audit-Log auf, das in der Datenbanktabelle `audit_log` gespeichert wird. ### Das Audit-Log ansehen {#viewing-the-audit-log} ``` GET /api/v1/audit-log?page=1&limit=50&action=LOGIN_FAILED&from=2026-01-01T00:00:00Z&to=2026-12-31T23:59:59Z ``` Erfordert die Berechtigung `audit:read`. Unterstützt Seitennummerierung (`page`, `limit`) und Filter (`action`, `ip`, `from`, `to`). ### Auditing von Werkzeugoperationen {#tool-operation-auditing} ::: warning `TOOL_EXECUTED`-Ereignisse werden standardmäßig **nicht** protokolliert. Sie sind über einen von zwei Wegen aktivierbar (Opt-in): 1. Setze die Admin-Einstellung `auditToolOperations` auf `true`. 2. Halte eine aktive Lizenz mit dem Feature `audit_export` (verfügbar sowohl in den Team- als auch in den Enterprise-Tarifen). Ohne eine dieser Optionen werden einzelne Werkzeugausführungen nicht im Audit-Log erfasst. ::: ### Exportieren {#exporting} ``` GET /api/v1/enterprise/audit/export?format=csv&from=2026-01-01T00:00:00Z ``` Erfordert die Berechtigung `audit:read` und das Enterprise-Feature `audit_export` (verfügbar sowohl in den Team- als auch in den Enterprise-Tarifen). Unterstützt die Formate CSV und JSON, gefiltert nach `action`, `actorId`, `targetType`, `targetId`, `from` und `to`. ### Manipulationssichere Signierung {#tamper-resistant-signing} Wenn aktiviert, wird jeder Audit-Log-Eintrag mit einem HMAC signiert, der aus `DATA_ENCRYPTION_KEY` abgeleitet wird. Dies erfordert: 1. Das Setzen von `DATA_ENCRYPTION_KEY` in deiner Umgebung. 2. Das Aktivieren der Admin-Einstellung `tamperResistantAudit`. 3. Eine Enterprise-Lizenz mit dem Feature `tamper_resistant_audit`. ### Aufbewahrung {#retention} Setze `AUDIT_RETENTION_DAYS`, um alte Einträge automatisch zu bereinigen. Der Standard ist `0`, was bedeutet, dass Einträge unbegrenzt aufbewahrt werden. ### Ereignisreferenz {#event-reference} | Ereignis | Kategorie | |---|---| | `LOGIN_SUCCESS`, `LOGIN_FAILED` | Authentifizierung | | `OIDC_LOGIN_SUCCESS`, `OIDC_LOGIN_FAILED` | Authentifizierung | | `SAML_LOGIN_SUCCESS`, `SAML_LOGIN_FAILED` | Authentifizierung | | `LOGOUT` | Authentifizierung | | `USER_CREATED`, `USER_UPDATED`, `USER_DELETED` | Benutzerverwaltung | | `PASSWORD_CHANGED`, `PASSWORD_RESET` | Benutzerverwaltung | | `MFA_ENROLLED`, `MFA_DISABLED`, `MFA_VERIFIED`, `MFA_VERIFY_FAILED` | MFA | | `MFA_CHALLENGE_ISSUED`, `MFA_RECOVERY_USED`, `MFA_RESET` | MFA | | `ROLE_CREATED`, `ROLE_UPDATED`, `ROLE_DELETED` | Rollen | | `API_KEY_CREATED`, `API_KEY_DELETED` | API-Schlüssel | | `SETTINGS_UPDATED`, `IP_ALLOWLIST_UPDATED` | Einstellungen | | `FILE_UPLOADED`, `FILE_DELETED` | Dateien | | `TOOL_EXECUTED` | Werkzeuge (Opt-in) | | `SCIM_USER_PROVISIONED`, `SCIM_USER_UPDATED`, `SCIM_USER_DEPROVISIONED` | SCIM | | `SCIM_GROUP_SYNCED` | SCIM | | `LEGAL_HOLD_APPLIED`, `LEGAL_HOLD_RELEASED` | Compliance | | `GDPR_EXPORT_INITIATED`, `GDPR_USER_PURGED`, `GDPR_TEAM_PURGED` | Compliance | | `CONFIG_EXPORTED`, `CONFIG_IMPORTED` | Konfiguration | ## Sitzungsverwaltung {#session-management} Sitzungen sind cookiebasiert und werden über `SESSION_DURATION_HOURS` gesteuert (Standard: 168 Stunden / 7 Tage). ### Rollenänderungen machen Sitzungen ungültig {#role-changes-invalidate-sessions} Wenn ein Administrator die Rolle eines Benutzers ändert, werden alle aktiven Sitzungen dieses Benutzers gelöscht. Der Benutzer muss sich erneut anmelden, um seine neuen Berechtigungen zu übernehmen. ### Schutzmechanismen {#safety-guards} * **Schutz des letzten Administrators**: Der letzte verbleibende Administrator kann nicht auf eine niedrigere Rolle herabgestuft werden. Die API gibt einen Fehler zurück, wenn du es versuchst. * **Selbstlöschungsschutz**: Administratoren können ihr eigenes Konto nicht über die API löschen. --- --- url: https://docs.snapotter.com/id/guide/contributing.md description: >- Cara berkontribusi ke SnapOtter. Laporan bug, permintaan fitur, pull request, dan persyaratan CLA. --- # Berkontribusi {#contributing} Terima kasih atas minat Anda untuk berkontribusi. Panduan ini menjelaskan cara berpartisipasi, apa yang kami terima, dan cara memulai. ## Cara berkontribusi {#ways-to-contribute} ### Issue (tanpa penyiapan) {#issues-no-setup-required} * **Laporan bug** - Ada yang rusak? Buka [laporan bug](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) dengan langkah-langkah reproduksi. * **Permintaan fitur** - Punya ide? Mulai sebuah [diskusi](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) agar komunitas dapat menimbang dan mendukungnya. * **Masalah terjemahan** - Menemukan terjemahan yang salah atau hilang? Buka [issue terjemahan](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Masalah dokumentasi** - Ada yang keliru di dokumentasi? Buka [issue dokumentasi](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Kode (memerlukan CLA) {#code-requires-cla} Kami menerima pull request untuk: | Tipe | Proses | |------|---------| | Perbaikan bug | Buka PR langsung (tautkan issue jika ada) | | Terjemahan baru | Buka PR langsung (lihat [Panduan Terjemahan](/id/guide/translations)) | | Peningkatan dokumentasi | Buka PR langsung | | Peningkatan cakupan tes | Buka PR langsung | | Tool atau fitur baru | Mulai sebuah [diskusi](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) terlebih dahulu; seorang maintainer mengubah ide yang disetujui menjadi issue yang dilacak sebelum Anda menulis kode | | Refaktor atau perubahan arsitektur | Mulai sebuah [diskusi](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) terlebih dahulu dan tunggu persetujuan maintainer sebelum menulis kode | ### Apa yang tidak akan kami terima {#what-we-will-not-accept} * Perubahan pada alur kerja CI/CD, konfigurasi rilis, atau konfigurasi linter/compiler * PR tanpa [Contributor License Agreement](#contributor-license-agreement) yang ditandatangani * PR dengan lebih dari 400 baris perubahan (pecah pekerjaan besar menjadi PR yang lebih kecil) * Fitur yang tidak didiskusikan dan disetujui terlebih dahulu * Perubahan pada `packages/ai/` tanpa diskusi sebelumnya ## Contributor License Agreement {#contributor-license-agreement} Sebelum kami dapat menggabungkan PR pertama Anda, Anda harus menandatangani [Individual CLA](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md) kami. Ini adalah persyaratan satu kali. **Mengapa:** SnapOtter berlisensi ganda (AGPLv3 + komersial). CLA memberi kami hak untuk mendistribusikan kontribusi Anda di bawah kedua lisensi tersebut. Anda tetap memegang penuh hak cipta atas karya Anda. **Bagaimana:** Ketika Anda membuka PR pertama, bot CLA Assistant akan berkomentar dengan sebuah tautan. Klik tautan itu, tinjau perjanjiannya, dan tanda tangani dengan akun GitHub Anda. Hanya butuh 30 detik. Jika Anda berkontribusi atas nama pemberi kerja Anda dan pemberi kerja Anda memegang hak kekayaan intelektual atas karya Anda, hubungi contact@snapotter.com untuk mengatur Corporate CLA sebelum mengirimkan. ## Memulai {#getting-started} ### Prasyarat {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (hanya untuk tool AI) * Docker (opsional, untuk pengujian integrasi penuh) ### Penyiapan {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Menjalankan pemeriksaan {#running-checks} Sebelum mengirimkan PR, pastikan semua pemeriksaan lolos secara lokal: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Proses pull request {#pull-request-process} 1. Fork repo dan buat branch dari `main` (`feat/my-feature` atau `fix/issue-123`) 2. Lakukan perubahan Anda dalam commit yang terfokus dan dapat ditinjau menggunakan [conventional commits](https://www.conventionalcommits.org/) 3. Tambahkan atau perbarui tes untuk perubahan Anda 4. Jalankan `pnpm lint && pnpm typecheck && pnpm test` secara lokal 5. Buka PR terhadap `main` dan isi templatnya 6. Tanda tangani CLA jika diminta 7. Tunggu CI lolos dan seorang maintainer meninjau ### Ekspektasi peninjauan {#review-expectations} * Kami berupaya menanggapi PR dalam 7 hari * PR yang kecil dan terfokus ditinjau lebih cepat * Jika Anda belum mendapat kabar dalam 7 hari, tinggalkan komentar untuk mengingatkan thread * Kami mungkin meminta perubahan, menyarankan pendekatan yang berbeda, atau menutup PR jika tidak selaras dengan arah proyek ### Setelah PR Anda digabungkan {#after-your-pr-is-merged} Kontribusi Anda akan disertakan dalam rilis berikutnya dan dicantumkan dalam changelog. ## Good first issue {#good-first-issues} Mencari sesuatu untuk dikerjakan? Lihat [good first issues](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) kami untuk tugas yang ramah pemula, atau [help wanted](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) untuk item yang lebih besar tempat kami menghargai bantuan komunitas. ## Gaya kode {#code-style} * Biome menangani pemformatan dan linting (tanda kutip ganda, titik koma, indentasi 2 spasi) * Hook pra-commit menjalankan `biome check --write` pada file yang di-stage secara otomatis * Jika linter mengeluh, perbaiki kodenya (jangan ubah konfigurasi Biome) * ES module di mana-mana (`import`/`export`) * Conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` Untuk detail arsitektur lengkap, lihat [Panduan Developer](/id/guide/developer). ## Keamanan {#security} **Jangan buka PR atau issue publik untuk kerentanan keamanan.** Laporkan secara privat melalui [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) atau email contact@snapotter.com. Lihat [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) untuk detail lengkap. ## Ada pertanyaan? {#questions} * [Dokumentasi](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/sv/tools/image/crop.md description: Beskär bilder genom att ange ett område med position och dimensioner. --- # Beskär bild {#crop} Beskär bilder genom att definiera ett rektangulärt område med hjälp av position och storlek. Stöder både pixel- och procentenheter. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/crop` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | left | number | Ja | - | X-förskjutning för beskärningsområdet (från vänsterkanten) | | top | number | Ja | - | Y-förskjutning för beskärningsområdet (från överkanten) | | width | number | Ja | - | Bredd på beskärningsområdet | | height | number | Ja | - | Höjd på beskärningsområdet | | unit | string | Nej | `"px"` | Enhet för värdena: `px` eller `percent` | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 100, "top": 50, "width": 800, "height": 600}' ``` Beskär med procentvärden: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 10, "top": 10, "width": 80, "height": 80, "unit": "percent"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1200000 } ``` ## Anteckningar {#notes} * Beskärningsområdet måste rymmas inom bildens gränser. Om området sträcker sig utanför bilden misslyckas begäran. * När enheten `percent` används representerar värdena procent av bildens dimensioner (t.ex. innebär `left: 10` 10 % från vänsterkanten). * Utdataformatet matchar indataformatet. * EXIF-orientering tillämpas automatiskt före beskärning, så koordinaterna motsvarar den visuellt korrekta orienteringen. --- --- url: https://docs.snapotter.com/sv/tools/video/crop-video.md description: Beskär en region ur en video. --- # Beskär video {#crop-video} Beskär en rektangulär region ur en video genom att ange regionens storlek och position. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/crop-video` Tar emot multipart-formulärdata med en videofil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | width | integer | Ja | - | Bredd på beskärningsregionen i pixlar (minimum 16) | | height | integer | Ja | - | Höjd på beskärningsregionen i pixlar (minimum 16) | | x | integer | Nej | `0` | Horisontell förskjutning från övre vänstra hörnet | | y | integer | Nej | `0` | Vertikal förskjutning från övre vänstra hörnet | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Anteckningar {#notes} * Beskärningsregionen måste rymmas inom videons dimensioner. Om `x + width` eller `y + height` överskrider källstorleken returnerar begäran ett 400-fel. * Minsta beskärningsstorlek är 16x16 pixlar. * Dimensioner avrundas till jämna tal enligt kraven hos de flesta videocodecs. --- --- url: https://docs.snapotter.com/nl/guide/security.md description: >- Handleiding voor beveiligingsverharding van SnapOtter. Containerbeveiliging, netwerkisolatie, Docker-secrets, Kubernetes-implementatie en compliance-artefacten. --- # Beveiliging & verharding {#security-hardening} SnapOtter verwerkt bestanden volledig op je eigen infrastructuur. Het verstuurt standaard anonieme, inhoudsloze productanalytics en crashrapporten om het project te helpen verbeteren. Het verstuurt nooit je bestanden, bestandsnamen, bestandsinhoud, OCR-uitvoer, afbeeldingsmetadata of documenttekst. Optionele feedback wordt alleen verzonden nadat een gebruiker deze indient, alleen wanneer analytics is ingeschakeld, en contactvelden worden alleen opgenomen met expliciete contacttoestemming. Een beheerder kan analytics en het vastleggen van feedback met één klik uitschakelen onder Instellingen > Systeem > Privacy, geen herbouw vereist. Bestandsverwerking blijft altijd binnen je container. De container draait als een dedicated niet-root-gebruiker (`snapotter`) met alle Linux-capabilities verwijderd behalve de minimaal vereiste set. Zie voor het volledige beleid voor kwetsbaarheidsonthulling en de beveiligingsarchitectuur [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) op GitHub. ## Containerharding {#container-hardening} De canonieke [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) en [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml) Compose-bestanden zijn de bron van de waarheid. Kopieer geen verkort voorbeeld naar productie; implementeer het bestand vanaf de releasetag die u heeft geverifieerd. Beide stapels passen de volgende besturingselementen toe: * Geheugen-, swap-, CPU- en PID-limieten bevatten op hol geslagen native verwerking. * Elke service laat alle Linux-mogelijkheden vallen. De applicatie voegt alleen `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` toe voor volume-eigendom, de eenrichtings-`gosu`-identiteitsdaling en sierlijke signaaldoorsturing. PostgreSQL en Redis ontvangen alleen de subset die hun officiële toegangspunten nodig hebben. * `security_opt: [no-new-privileges:true]` voorkomt dat processen in de applicatie-, PostgreSQL- en Redis-containers extra rechten krijgen. Dit blijft compatibel met `gosu`: het toegangspunt begint als root, bereidt de volumes voor en gaat alleen naar de toegewijde `snapotter`-gebruiker. * PostgreSQL- en Redis-afbeeldingsinvoer wordt vastgezet door digest. De applicatie moet ook worden vastgemaakt aan een geverifieerde releasetag of samenvatting in plaats van aan `latest`. * Gezondheidscontroles, begrensde JSON-logboekrotatie, duurzame Redis AOF en herstartbeleid worden centraal in de canonieke bestanden gedefinieerd. Voor een internetgerichte implementatie bindt u poort 1349 aan loopback en beëindigt u TLS bij een onderhouden omgekeerde proxy. Genereer unieke PostgreSQL- en Redis-inloggegevens, sla geheimen op in beveiligde bestanden of in een geheime manager en wijzig het initiële beheerderswachtwoord onmiddellijk. ### Waarom `read_only` niet is ingesteld op {#why-read-only-is-not-set} `read_only: true` is niet ingesteld omdat het opnieuw toewijzen van PUID/PGID bij het opstarten naar `/etc/passwd` en `/etc/group` schrijft. Als u Docker's `--user`-vlag of Kubernetes `runAsUser` gebruikt in plaats van PUID/PGID, kunt u veilig een alleen-lezen rootbestandssysteem inschakelen. ## Netwerkisolatie {#network-isolation} Bestandsverwerking is lokaal, maar een standaardinstallatie is **geen uitgaand systeem**. Anonieme productanalyses gebruiken PostHog en crashrapportage gebruikt Sentry wanneer telemetrie is ingeschakeld. Stel `SNAPOTTER_TELEMETRY=0` in (of schakel analyses uit onder Instellingen > Systeem > Privacy) om beide uit te schakelen. SnapOtter neemt nooit geüploade bestanden, bestandsnamen, OCR-uitvoer, documenttekst of andere bestandsinhoud op in deze gebeurtenissen. Ander uitgaand verkeer is functiegestuurd: AI-bundel-/modelinstallatie downloadt ondertekende release-invoer; URL-import haalt een door de gebruiker aangevraagde openbare URL op; en expliciet geconfigureerde OIDC, SAML, OpenTelemetry, webhooks, S3-compatibele opslag of soortgelijke integraties maken contact met de door de beheerder gekozen bestemmingen. Modeldownloads tijdens runtime zijn standaard uitgeschakeld. Stel `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` alleen in om automatische fallback-downloads expliciet in te schakelen. Met een [offlinebundelimport](/nl/guide/deployment) kunnen AI-functies worden ingericht zonder uitgaand runtimemodel. **Firewall-aanbevelingen:** |Scenario|Uitgaande regel| |---|---| |Luchtopening|Stel `SNAPOTTER_TELEMETRY=0` en `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0` in, gebruik offline AI-bundelimport, schakel URL-import en externe integraties uit en blokkeer vervolgens uitgaand verkeer| |Standaardtelemetrie|Sta de PostHog- en Sentry-eindpunten toe die worden vermeld in uw browser-/netwerklogboeken; schakel telemetrie uit als het beleid dit niet toestaat| |AI-bundels nodig|Sta tijdens de installatie HTTPS naar `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org` toe; blokkeer vervolgens die hosts| |Externe integraties|Alleen de exacte door de beheerder geconfigureerde OIDC/SAML/OTLP/webhook/object-storage-bestemmingen toestaan| Bundelarchieven worden geleverd vanuit de Xet-opslag van Hugging Face, die parallel wordt overgedragen via de `*.xethub.hf.co`-eindpunten en waardoor downloads van bundels van meerdere GB snel verlopen. Als uw firewall `huggingface.co` toestaat maar `*.xethub.hf.co` blokkeert, slagen de installaties nog steeds, maar vallen ze terug op een langzamere download in één stream. Zet daarom de Xet-hosts op de toelatingslijst om op het snelle pad te blijven. Bij volledig offline installaties kunt u dit allemaal overslaan en in plaats daarvan [Offline Bundle Import](/nl/guide/deployment) gebruiken. Voor reverse proxy-configuratie (Nginx, Traefik, Caddy, Cloudflare Tunnels), zie de [Implementatiehandleiding](/nl/guide/deployment#reverse-proxy). ## Docker-secrets {#docker-secrets} Vermijd bij productie-implementaties het doorgeven van secrets als platte-tekst-omgevingsvariabelen. De entrypoint ondersteunt Dockers `_FILE`-conventie: koppel een secret als bestand en stel de bijbehorende `_FILE`-variabele in op het pad ervan. **Ondersteunde secrets:** | Variabele | `_FILE`-equivalent | |---|---| | `DEFAULT_PASSWORD` | `DEFAULT_PASSWORD_FILE` | | `COOKIE_SECRET` | `COOKIE_SECRET_FILE` | | `OIDC_CLIENT_SECRET` | `OIDC_CLIENT_SECRET_FILE` | | `S3_ACCESS_KEY_ID` | `S3_ACCESS_KEY_ID_FILE` | | `S3_SECRET_ACCESS_KEY` | `S3_SECRET_ACCESS_KEY_FILE` | | `SNAPOTTER_LICENSE_KEY` | `SNAPOTTER_LICENSE_KEY_FILE` | **Voorbeeld met Docker Compose-secrets:** ```yaml services: SnapOtter: image: snapotter/snapotter:latest environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD_FILE=/run/secrets/snapotter_password - COOKIE_SECRET_FILE=/run/secrets/cookie_secret secrets: - snapotter_password - cookie_secret secrets: snapotter_password: file: ./secrets/snapotter_password.txt cookie_secret: file: ./secrets/cookie_secret.txt ``` ::: tip Docker Compose-secrets (zonder Swarm) vereisen Compose v2.23 of later. ::: ## Kubernetes-implementatie {#kubernetes-deployment} De entrypoint detecteert wanneer de container al als niet-root draait (bijv. via Kubernetes `runAsUser`) en slaat de gosu-privilegeverlaging automatisch over. In dat geval kan het de gekoppelde volumes niet zelf chown'en, dus verifieert het of ze beschrijfbaar zijn en stopt het vroegtijdig met bruikbare aanwijzingen als dat niet zo is — zie [Opslagpermissies](/nl/guide/deployment#storage-permissions) voor `fsGroup` en foreign-UID-configuraties (TrueNAS, OpenShift). **Aanbevolen Pod SecurityContext:** ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: snapotter spec: replicas: 1 selector: matchLabels: app: snapotter template: metadata: labels: app: snapotter spec: securityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 fsGroup: 999 containers: - name: snapotter image: snapotter/snapotter:latest ports: - containerPort: 1349 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] resources: requests: cpu: "1" memory: 2Gi limits: cpu: "4" memory: 6Gi livenessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readinessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - name: data mountPath: /data - name: workspace mountPath: /tmp/workspace volumes: - name: data persistentVolumeClaim: claimName: snapotter-data - name: workspace emptyDir: medium: Memory sizeLimit: 2Gi ``` Omdat `runAsUser: 999` op podniveau is ingesteld, slaat de entrypoint gosu volledig over. Dit maakt `allowPrivilegeEscalation: false`- en `drop: [ALL]`-capabilities zonder conflict mogelijk. Zie voor de dimensionering van resources [Hardwarevereisten](/nl/guide/deployment#hardware-requirements). ## Back-up en herstel {#backup-and-recovery} De productie Compose-stack definieert vier volumes. Stop het binnendringen en laat actieve taken voltooien voordat u een gecoördineerde back-up maakt, zodat PostgreSQL, Redis en de bestandsstatus hetzelfde tijdstip beschrijven. |Volume|Inhoud|Herstelbehandeling| |---|---|---| |`SnapOtter-pgdata`|PostgreSQL-gebruikers, instellingen, pijplijnen, taken, metagegevens van bestanden en auditlogboek|Kritisch; gebruik een fail-fast logische dump voor draagbaar herstel| |`SnapOtter-data`|Opgeslagen bibliotheekobjecten, logboeken en AI-status (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|Maak een back-up van het hele volume; om ruimte te besparen, laat u opzettelijk alle AI-statussen weg en installeert u de bundels opnieuw| |`SnapOtter-redisdata`|Redis AOF voor duurzame BullMQ-wachtrijstatus|Maak een back-up nadat u de app hebt gepauzeerd en `SAVE` hebt geforceerd; vereist om het werk in de wachtrij precies te hervatten| |`SnapOtter-workspace`|Tijdelijke objectopslagsleutels (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|Maak geen back-up nadat alle taken zijn leeggemaakt of geannuleerd; gooi het nooit weg terwijl er banen actief zijn| Bij Compose worden volumenamen normaal gesproken voorafgegaan door de projectnaam. Los het echte bronvolume op vanuit de gekoppelde container in plaats van aan te nemen dat een weergavenaam zoals `SnapOtter-data` de Docker-volumenaam is. ### Databaseback-up {#database-backup} Gebruik het aangepaste archiefformaat van PostgreSQL en verifieer het archief voordat u de back-up als voltooid beschouwt: ```bash docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore only into a fresh/disposable target first; any SQL error fails the command. docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Test elke back-up door deze terug te zetten naar een geïsoleerde stapel, databaserecords en bestandscontrolesommen te controleren en de toepassing te starten. De `tests/qa/backup-restore-drill.sh` van de repository automatiseert de vrijgavepoort tegen een expliciete `QA_IMAGE`. Als uw platform in plaats daarvan crash-consistente volume-snapshots maakt, stop dan eerst de hele stack en maak een snapshot van alle kritieke volumes als één set. Een onbewerkte kopie van de PostgreSQL-gegevensmap uit een actieve container is geen ondersteunde logische back-up. ### Bestands- en wachtrijback-up {#file-and-queue-backup} Pauzeer de toepassing voordat u bestands- en wachtrijvolumes vastlegt. Gebruik `docker inspect` om de daadwerkelijke volumenaam om te zetten, Redis te dwingen de huidige status te behouden en te archiveren met behoud van eigendom en machtigingen: ```bash docker stop SnapOtter docker exec SnapOtter-redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning SAVE docker stop SnapOtter-redis DATA_VOLUME="$(docker inspect SnapOtter --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" REDIS_VOLUME="$(docker inspect SnapOtter-redis --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" install -d -m 700 backup docker run --rm -v "$DATA_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-data.tar.gz -C /source . docker run --rm -v "$REDIS_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-redis.tar.gz -C /source . sha256sum backup/snapotter-*.tar.gz > backup/SHA256SUMS ``` Start Redis opnieuw vóór de toepassing. Als u opzettelijk `/data/ai` uitsluit, verwijder dan de hele AI-subboom in plaats van een `installed.json`-record te behouden zonder de modellen of virtuele omgeving ervan. Houd back-upbestanden gecodeerd, met toegangscontrole en gescheiden van de host waarop SnapOtter draait. ## Nalevingsartefacten {#compliance-artifacts} Elke SnapOtter-release bevat de volgende beveiligingsartefacten: | Artefact | Formaat | Waar je het kunt vinden | |---|---|---| | Onderwerpbinding vrijgeven | Canonieke JSON + GitHub-attest | [GitHub-vrijgave](https://github.com/snapotter-hq/SnapOtter/releases) item: `snapotter-v{version}-release-subjects.json` | | Archief SBOM | CycloneDX en SPDX JSON | Activa vrijgeven: `snapotter-v{version}-archive-linux-{arch}-sbom.{cdx,spdx}.json` | | Afbeelding SBOM | CycloneDX en SPDX JSON | Activa vrijgeven: `snapotter-v{version}-image-linux-{arch}-sbom.{cdx,spdx}.json` | | Kwetsbaarheidsscans | Trivy JSON | Activa vrijgeven met overeenkomende `archive-linux-{arch}`- of `image-linux-{arch}`-voorvoegsels | | Kwetsbaarheidsscan | SARIF | Tabblad [GitHub Beveiliging](https://github.com/snapotter-hq/SnapOtter/security). | | Statische analyse | CodeQL (JS/TS + Python) | Tabblad [GitHub Beveiliging](https://github.com/snapotter-hq/SnapOtter/security), wordt wekelijks + per PR uitgevoerd | | Afhankelijkheidsbeoordeling | GitHub eigen | Controle per PR, mislukt bij zeer ernstige toevoegingen | | Python-afhankelijkheidsaudit | pip-audit | CI voert log uit bij elke druk | | Beveiligingsbeleid | Markdown | [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) in de repository | | Afhankelijkheidsupdates | Dependabot | Geautomatiseerde wekelijkse PR's voor npm, pip, Docker, acties | **Uw eigen scan uitvoeren:** Download het release-onderwerpmanifest en controleer of dit is bevestigd door de releaseworkflow: ```bash gh attestation verify snapotter-v2.2.0-release-subjects.json \ --repo snapotter-hq/SnapOtter \ --signer-workflow snapotter-hq/SnapOtter/.github/workflows/release.yml ``` Het manifest registreert `releaseTag`, `releaseCommit` en `workflowTriggerCommit` afzonderlijk. Controleer of `releaseCommit` de commit is die is gepeld uit de onveranderlijke tag en verifieer vervolgens de SHA-256-samenvatting van het archief, de afbeelding, SBOM of de scan die u gebruikt, ten opzichte van de vermelding ervan in `subjects`. Dit onderscheid is opzettelijk gemaakt: het uitchecken van een nieuw gemaakte release commit verandert niets aan de commit-identiteit in de OIDC-referentie van de workflow. U kunt ook een gedownloade SBOM of de afbeelding rechtstreeks scannen: ```bash # Scan with Grype using the CycloneDX SBOM grype sbom:snapotter-v2.2.0-image-linux-amd64-sbom.cdx.json # Scan with Trivy using the SPDX SBOM trivy sbom snapotter-v2.2.0-image-linux-amd64-sbom.spdx.json # Scan the Docker image directly trivy image snapotter/snapotter:2.2.0 ``` ::: info Afbeelding SBOMs en scans weerspiegelen de exacte architectuurspecifieke afbeelding die voor die release is gepubliceerd. Archief SBOMs en scans beschrijven het vooraf gebouwde archief afzonderlijk. AI-modelbundels die na de implementatie zijn geïnstalleerd, zijn niet opgenomen in deze SBOMs omdat ze tijdens runtime worden gedownload. ::: --- --- url: https://docs.snapotter.com/pl/guide/security.md description: >- Przewodnik po wzmacnianiu bezpieczeństwa SnapOtter. Bezpieczeństwo kontenerów, izolacja sieci, sekrety Docker, wdrożenie Kubernetes i artefakty zgodności. --- # Bezpieczeństwo i wzmacnianie {#security-hardening} SnapOtter przetwarza pliki w całości na twojej infrastrukturze. Domyślnie wysyła anonimową, pozbawioną treści analitykę produktu i raporty o awariach, aby pomóc ulepszać projekt. Nigdy nie wysyła twoich plików, nazw plików, zawartości plików, wyniku OCR, metadanych obrazów ani tekstu dokumentów. Opcjonalna informacja zwrotna jest wysyłana dopiero po jej przesłaniu przez użytkownika, tylko gdy analityka jest włączona, a pola kontaktowe są dołączane wyłącznie za wyraźną zgodą na kontakt. Administrator może wyłączyć analitykę i zbieranie informacji zwrotnej jednym kliknięciem w Ustawienia > System > Prywatność, bez konieczności przebudowy. Przetwarzanie plików zawsze pozostaje wewnątrz twojego kontenera. Kontener działa jako dedykowany użytkownik nie-root (`snapotter`) z odrzuconymi wszystkimi uprawnieniami Linuksa poza minimalnym wymaganym zestawem. Po pełną politykę ujawniania podatności i architekturę bezpieczeństwa zobacz [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) na GitHub. ## Hartowanie kontenera {#container-hardening} Źródłem prawdy są kanoniczne pliki [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) i [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml). Nie kopiuj skróconego przykładu do produkcji; wdróż plik ze zweryfikowanego tagu wydania. Obydwa stosy stosują następujące elementy sterujące: * Limity pamięci, wymiany, procesora i PID powodują niekontrolowane przetwarzanie natywne. * Każda usługa powoduje utratę wszystkich możliwości Linuksa. Aplikacja dodaje tylko `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` dla własności wolumenu, jednokierunkową utratę tożsamości `gosu` i płynne przekazywanie sygnału. PostgreSQL i Redis otrzymują tylko podzbiór potrzebny ich oficjalnym punktom wejścia. * `security_opt: [no-new-privileges:true]` uniemożliwia procesom w aplikacji, kontenerach PostgreSQL i Redis uzyskanie dodatkowych uprawnień. Pozostaje to zgodne z `gosu`: punkt wejścia zaczyna się jako root, przygotowuje woluminy i przechodzi tylko do dedykowanego użytkownika `snapotter`. * Wejścia obrazów PostgreSQL i Redis są przypinane za pomocą skrótu. Aplikację należy również przypiąć do zweryfikowanego tagu wydania lub podsumowania, a nie `latest`. — Kontrole stanu, ograniczona rotacja dzienników JSON, trwała funkcja Redis AOF i zasady ponownego uruchamiania są definiowane centralnie w plikach kanonicznych. W przypadku wdrożenia z dostępem do Internetu powiąż port 1349 z pętlą zwrotną i zakończ protokół TLS na utrzymywanym zwrotnym serwerze proxy. Wygeneruj unikalne dane uwierzytelniające PostgreSQL i Redis, przechowuj sekrety w chronionych plikach lub menedżerze sekretów i natychmiast zmień początkowe hasło administratora. ### Dlaczego `read_only` nie jest ustawione {#why-read-only-is-not-set} `read_only: true` nie jest ustawiony, ponieważ ponowne mapowanie PUID/PGID zapisuje podczas uruchamiania `/etc/passwd` i `/etc/group`. Jeśli zamiast PUID/PGID użyjesz flagi `--user` Dockera lub Kubernetes `runAsUser`, możesz bezpiecznie włączyć główny system plików tylko do odczytu. ## Izolacja sieci {#network-isolation} Przetwarzanie plików odbywa się lokalnie, ale instalacja domyślna **nie jest systemem bez ruchu wychodzącego**. Anonimowe analizy produktów korzystają z PostHog, a raportowanie o awariach korzysta z Sentry, gdy włączona jest telemetria. Ustaw `SNAPOTTER_TELEMETRY=0` (lub wyłącz analizę w obszarze Ustawienia > System > Prywatność), aby wyłączyć oba. SnapOtter nigdy nie uwzględnia w tych zdarzeniach przesłanych plików, nazw plików, danych wyjściowych OCR, tekstu dokumentu ani innej zawartości plików. Pozostały ruch wychodzący jest oparty na funkcjach: instalacja pakietu/modelu AI powoduje pobranie podpisanych danych wejściowych wersji; Import adresu URL powoduje pobranie publicznego adresu URL żądanego przez użytkownika; i jawnie skonfigurowane OIDC, SAML, OpenTelemetry, webhooki, pamięć zgodna z S3 lub podobne integracje łączą się z miejscami docelowymi wybranymi przez administratora. Pobieranie modeli w czasie wykonywania jest domyślnie wyłączone. Ustaw `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` tylko po to, aby jawnie włączyć automatyczne pobieranie zastępcze. [Import pakietu offline](/pl/guide/deployment) może zapewnić funkcje AI bez konieczności wychodzenia z modelu środowiska wykonawczego. **Zalecenia dotyczące zapory sieciowej:** |Scenariusz|Reguła wychodząca| |---|---| |Szczelina powietrzna|Ustaw `SNAPOTTER_TELEMETRY=0` i `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0`, użyj importu pakietów AI offline, wyłącz import adresów URL i integracje zewnętrzne, a następnie zablokuj wyjście| |Domyślna telemetria|Zezwól na punkty końcowe PostHog i Sentry wymienione w dziennikach przeglądarki/sieci; wyłącz telemetrię, jeśli zasady na to nie pozwalają| |Potrzebne pakiety AI|Podczas instalacji zezwól HTTPS na `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org`; następnie zablokuj te hosty| |Integracje zewnętrzne|Zezwalaj tylko na dokładnie skonfigurowane przez administratora miejsca docelowe OIDC/SAML/OTLP/webhook/object-storage| Archiwa pakietów są obsługiwane z pamięci Xet firmy Hugging Face, która jest przesyłana równolegle przez punkty końcowe `*.xethub.hf.co` i dzięki temu pobieranie pakietów o wielkości wielu GB jest szybkie. Jeśli twoja zapora sieciowa pozwala na `huggingface.co`, ale blokuje `*.xethub.hf.co`, instalacje nadal się powiodą, ale powrócą do wolniejszego pobierania w jednym strumieniu, więc umieść hosty Xet na liście dozwolonych, aby pozostały na szybkiej ścieżce. Instalacje w pełni offline mogą to wszystko pominąć i zamiast tego użyć [Import pakietu offline](/pl/guide/deployment). Informacje na temat konfiguracji odwrotnego proxy (Nginx, Traefik, Caddy, Cloudflare Tunnels) można znaleźć w [Przewodniku wdrażania](/pl/guide/deployment#reverse-proxy). ## Sekrety Docker {#docker-secrets} Dla wdrożeń produkcyjnych unikaj przekazywania sekretów jako zmiennych środowiskowych w postaci zwykłego tekstu. Punkt wejścia obsługuje konwencję `_FILE` Dockera: zamontuj sekret jako plik i ustaw odpowiednią zmienną `_FILE` na jego ścieżkę. **Obsługiwane sekrety:** | Zmienna | Odpowiednik `_FILE` | |---|---| | `DEFAULT_PASSWORD` | `DEFAULT_PASSWORD_FILE` | | `COOKIE_SECRET` | `COOKIE_SECRET_FILE` | | `OIDC_CLIENT_SECRET` | `OIDC_CLIENT_SECRET_FILE` | | `S3_ACCESS_KEY_ID` | `S3_ACCESS_KEY_ID_FILE` | | `S3_SECRET_ACCESS_KEY` | `S3_SECRET_ACCESS_KEY_FILE` | | `SNAPOTTER_LICENSE_KEY` | `SNAPOTTER_LICENSE_KEY_FILE` | **Przykład z sekretami Docker Compose:** ```yaml services: SnapOtter: image: snapotter/snapotter:latest environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD_FILE=/run/secrets/snapotter_password - COOKIE_SECRET_FILE=/run/secrets/cookie_secret secrets: - snapotter_password - cookie_secret secrets: snapotter_password: file: ./secrets/snapotter_password.txt cookie_secret: file: ./secrets/cookie_secret.txt ``` ::: tip Sekrety Docker Compose (bez Swarm) wymagają Compose v2.23 lub nowszego. ::: ## Wdrożenie Kubernetes {#kubernetes-deployment} Punkt wejścia wykrywa, kiedy kontener już działa jako nie-root (np. przez `runAsUser` Kubernetes) i automatycznie pomija obniżenie uprawnień gosu. W takim przypadku nie może sam zmienić własności zamontowanych wolumenów przez chown, więc weryfikuje, czy są zapisywalne, i wcześnie kończy z praktycznymi wskazówkami, jeśli nie są, zobacz [Uprawnienia pamięci masowej](/pl/guide/deployment#storage-permissions) po `fsGroup` i konfiguracje z obcym UID (TrueNAS, OpenShift). **Zalecany SecurityContext poda:** ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: snapotter spec: replicas: 1 selector: matchLabels: app: snapotter template: metadata: labels: app: snapotter spec: securityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 fsGroup: 999 containers: - name: snapotter image: snapotter/snapotter:latest ports: - containerPort: 1349 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] resources: requests: cpu: "1" memory: 2Gi limits: cpu: "4" memory: 6Gi livenessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readinessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - name: data mountPath: /data - name: workspace mountPath: /tmp/workspace volumes: - name: data persistentVolumeClaim: claimName: snapotter-data - name: workspace emptyDir: medium: Memory sizeLimit: 2Gi ``` Ponieważ `runAsUser: 999` jest ustawione na poziomie poda, punkt wejścia całkowicie pomija gosu. Pozwala to na uprawnienia `allowPrivilegeEscalation: false` i `drop: [ALL]` bez konfliktu. Po dobór rozmiaru zasobów zobacz [Wymagania sprzętowe](/pl/guide/deployment#hardware-requirements). ## Kopia zapasowa i odzyskiwanie {#backup-and-recovery} Produkcyjny stos Compose definiuje cztery woluminy. Zatrzymaj ruch wejściowy i poczekaj na zakończenie aktywnych zadań przed wykonaniem skoordynowanej kopii zapasowej, tak aby PostgreSQL, Redis i stan pliku opisywały ten sam punkt w czasie. |Tom|Zawartość|Leczenie regeneracyjne| |---|---|---| |`SnapOtter-pgdata`|Użytkownicy PostgreSQL, ustawienia, potoki, zadania, metadane plików i dziennik audytu|Krytyczny; użyj niezawodnego zrzutu logicznego do odzyskiwania przenośnego| |`SnapOtter-data`|Zapisane obiekty biblioteki, dzienniki i stan AI (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|Utwórz kopię zapasową całego woluminu; aby zaoszczędzić miejsce, celowo pomiń cały stan AI i zainstaluj ponownie jego pakiety| |`SnapOtter-redisdata`|Redis AOF dla trwałego stanu kolejki BullMQ|Utwórz kopię zapasową po wstrzymaniu aplikacji i wymuszeniu `SAVE`; wymagane do dokładnego wznowienia pracy w kolejce| |`SnapOtter-workspace`|Tymczasowe klucze do przechowywania obiektów (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|Nie twórz kopii zapasowych po wyczerpaniu lub anulowaniu wszystkich zadań; nigdy go nie wyrzucaj, gdy zadania są aktywne| Funkcja Compose zwykle poprzedza nazwy woluminów nazwą projektu. Rozwiąż rzeczywisty wolumin źródłowy z zamontowanego kontenera, zamiast zakładać, że nazwa wyświetlana, taka jak `SnapOtter-data`, jest nazwą woluminu Docker. ### Kopia zapasowa bazy danych {#database-backup} Użyj niestandardowego formatu archiwum PostgreSQL i zweryfikuj archiwum, zanim potraktujesz kopię zapasową jako kompletną: ```bash docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore only into a fresh/disposable target first; any SQL error fails the command. docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Przetestuj każdą kopię zapasową, przywracając ją do izolowanego stosu, sprawdzając rekordy bazy danych i sumy kontrolne plików oraz uruchamiając aplikację. `tests/qa/backup-restore-drill.sh` repozytorium automatyzuje tę bramkę zwolnienia w stosunku do jawnego `QA_IMAGE`. Jeśli zamiast tego Twoja platforma wykonuje migawki woluminów spójne w czasie awarii, najpierw zatrzymaj cały stos i wykonaj migawkę wszystkich krytycznych woluminów jako jeden zestaw. Surowa kopia katalogu danych PostgreSQL z działającego kontenera nie jest obsługiwaną logiczną kopią zapasową. ### Kopia zapasowa plików i kolejek {#file-and-queue-backup} Wstrzymaj aplikację przed przechwyceniem woluminów plików i kolejek. Użyj `docker inspect`, aby rozwiązać rzeczywistą nazwę woluminu, wymuś na Redis zachowanie bieżącego stanu i zarchiwizuj z zachowaniem własności i uprawnień: ```bash docker stop SnapOtter docker exec SnapOtter-redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning SAVE docker stop SnapOtter-redis DATA_VOLUME="$(docker inspect SnapOtter --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" REDIS_VOLUME="$(docker inspect SnapOtter-redis --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" install -d -m 700 backup docker run --rm -v "$DATA_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-data.tar.gz -C /source . docker run --rm -v "$REDIS_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-redis.tar.gz -C /source . sha256sum backup/snapotter-*.tar.gz > backup/SHA256SUMS ``` Uruchom ponownie Redis przed aplikacją. Jeśli celowo wykluczysz `/data/ai`, usuń całe poddrzewo AI, zamiast zachowywać rekord `installed.json` bez jego modeli i środowiska wirtualnego. Przechowuj pliki kopii zapasowych w sposób szyfrowany, z kontrolą dostępu i oddzielnie od hosta, na którym działa SnapOtter. ## Artefakty zgodności {#compliance-artifacts} Każde wydanie SnapOtter zawiera następujące artefakty zabezpieczeń: | Artefakt | Format | Gdzie to znaleźć | |---|---|---| | Zwolnij powiązanie tematu | Atest kanoniczny JSON + GitHub | [Wydanie GitHub](https://github.com/snapotter-hq/SnapOtter/releases) zasób: `snapotter-v{version}-release-subjects.json` | | Archiwum SBOM | CycloneDX i SPDX JSON | Wydanie zasobów: `snapotter-v{version}-archive-linux-{arch}-sbom.{cdx,spdx}.json` | | Obraz SBOM | CycloneDX i SPDX JSON | Wydanie zasobów: `snapotter-v{version}-image-linux-{arch}-sbom.{cdx,spdx}.json` | | Skanowanie podatności | Trivy JSON | Zwolnij zasoby z pasującymi prefiksami `archive-linux-{arch}` lub `image-linux-{arch}` | | Skanowanie podatności | SARIF | Zakładka [Zabezpieczenia GitHub](https://github.com/snapotter-hq/SnapOtter/security). | | Analiza statyczna | CodeQL (JS/TS + Python) | Karta [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security), uruchamiana co tydzień + za PR | | Przegląd zależności | Natywny GitHub | Kontrola na PR kończy się niepowodzeniem w przypadku dodatków o dużej ważności | | Audyt zależności Python | pip-audit | Dziennik przebiegu CI przy każdym naciśnięciu | | Polityka bezpieczeństwa | Markdown | [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) w repozytorium | | Aktualizacje zależności | Dependabot | Zautomatyzowane cotygodniowe PR dla npm, pip, Docker, Actions | **Uruchamianie własnego skanowania:** Pobierz manifest tematu wydania i sprawdź, czy został on potwierdzony w przepływie pracy wydania: ```bash gh attestation verify snapotter-v2.2.0-release-subjects.json \ --repo snapotter-hq/SnapOtter \ --signer-workflow snapotter-hq/SnapOtter/.github/workflows/release.yml ``` Manifest rejestruje oddzielnie `releaseTag`, `releaseCommit` i `workflowTriggerCommit`. Sprawdź, czy `releaseCommit` jest zatwierdzeniem usuniętym z niezmiennego znacznika, a następnie sprawdź skrót SHA-256 archiwum, obrazu, SBOM lub skanu, który wykorzystujesz, względem jego wpisu w `subjects`. To rozróżnienie jest zamierzone: sprawdzenie nowo utworzonego zatwierdzenia wydania nie zmienia tożsamości zatwierdzenia w poświadczeniu OIDC przepływu pracy. Możesz także zeskanować pobrany plik SBOM lub obraz bezpośrednio: ```bash # Scan with Grype using the CycloneDX SBOM grype sbom:snapotter-v2.2.0-image-linux-amd64-sbom.cdx.json # Scan with Trivy using the SPDX SBOM trivy sbom snapotter-v2.2.0-image-linux-amd64-sbom.spdx.json # Scan the Docker image directly trivy image snapotter/snapotter:2.2.0 ``` ::: info Obraz SBOMs i skany odzwierciedlają dokładnie obraz specyficzny dla architektury opublikowany dla tej wersji. Archiwum SBOMs i skany opisują wstępnie zbudowane archiwum osobno. Pakiety modelu AI zainstalowane po wdrożeniu nie są uwzględnione w tych pakietach SBOMs, ponieważ są pobierane w czasie wykonywania. ::: --- --- url: https://docs.snapotter.com/sv/guide/contributing.md description: >- Så bidrar du till SnapOtter. Buggrapporter, funktionsförslag, pull requests och CLA-krav. --- # Bidra {#contributing} Tack för att du vill bidra. Den här guiden beskriver hur du deltar, vad vi accepterar och hur du kommer igång. ## Sätt att bidra {#ways-to-contribute} ### Ärenden (ingen konfiguration krävs) {#issues-no-setup-required} * **Buggrapporter** - Något som är trasigt? Öppna en [buggrapport](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) med reproduktionssteg. * **Funktionsförslag** - Har du en idé? Starta en [diskussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) så att gemenskapen kan väga in och rösta på den. * **Översättningsproblem** - Hittade du en felaktig eller saknad översättning? Öppna ett [översättningsärende](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Dokumentationsproblem** - Något som inte stämmer i dokumentationen? Öppna ett [dokumentationsärende](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Kod (kräver CLA) {#code-requires-cla} Vi accepterar pull requests för: | Typ | Process | |------|---------| | Buggfixar | Öppna en PR direkt (länka ärendet om ett finns) | | Nya översättningar | Öppna en PR direkt (se [Översättningsguide](/sv/guide/translations)) | | Dokumentationsförbättringar | Öppna en PR direkt | | Förbättrad testtäckning | Öppna en PR direkt | | Nya verktyg eller funktioner | Starta en [diskussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) först; en underhållare omvandlar godkända idéer till ett spårat ärende innan du skriver kod | | Refaktoreringar eller arkitekturändringar | Starta en [diskussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) först och invänta godkännande från en underhållare innan du skriver kod | ### Vad vi inte accepterar {#what-we-will-not-accept} * Ändringar av CI/CD-arbetsflöden, release-konfiguration eller linter/kompilator-konfiguration * PR:er utan ett signerat [Contributor License Agreement](#contributor-license-agreement) * PR:er med över 400 rader ändring (dela upp stort arbete i mindre PR:er) * Funktioner som inte först har diskuterats och godkänts * Ändringar av `packages/ai/` utan föregående diskussion ## Contributor License Agreement {#contributor-license-agreement} Innan vi kan slå samman din första PR måste du signera vårt [individuella CLA](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md). Det här är ett engångskrav. **Varför:** SnapOtter är dubbellicensierat (AGPLv3 + kommersiellt). CLA:t ger oss rätten att distribuera dina bidrag under båda licenserna. Du behåller full upphovsrätt till ditt arbete. **Hur:** När du öppnar din första PR kommenterar CLA Assistant-boten med en länk. Klicka på den, granska avtalet och signera med ditt GitHub-konto. Det tar 30 sekunder. Om du bidrar för din arbetsgivares räkning och din arbetsgivare behåller de immateriella rättigheterna till ditt arbete, kontakta contact@snapotter.com för att ordna ett Corporate CLA innan du skickar in. ## Kom igång {#getting-started} ### Förutsättningar {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (endast för AI-verktyg) * Docker (valfritt, för fullständig integrationstestning) ### Konfiguration {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Köra kontroller {#running-checks} Innan du skickar in en PR, se till att alla kontroller passerar lokalt: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Pull request-processen {#pull-request-process} 1. Forka repot och skapa en gren från `main` (`feat/my-feature` eller `fix/issue-123`) 2. Gör dina ändringar i fokuserade, granskningsbara commits med [conventional commits](https://www.conventionalcommits.org/) 3. Lägg till eller uppdatera tester för dina ändringar 4. Kör `pnpm lint && pnpm typecheck && pnpm test` lokalt 5. Öppna en PR mot `main` och fyll i mallen 6. Signera CLA:t om du uppmanas 7. Invänta att CI passerar och att en underhållare granskar ### Vad du kan förvänta dig av granskningen {#review-expectations} * Vi strävar efter att svara på PR:er inom 7 dagar * Små, fokuserade PR:er granskas snabbare * Om du inte har hört något inom 7 dagar, lämna en kommentar som pingar tråden * Vi kan begära ändringar, föreslå ett annat tillvägagångssätt eller stänga PR:en om den inte stämmer med projektets inriktning ### Efter att din PR har slagits samman {#after-your-pr-is-merged} Ditt bidrag kommer att inkluderas i nästa release och krediteras i ändringsloggen. ## Bra första ärenden {#good-first-issues} Letar du efter något att arbeta med? Kolla våra [bra första ärenden](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) för nybörjarvänliga uppgifter, eller [hjälp önskas](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) för större poster där vi skulle uppskatta hjälp från gemenskapen. ## Kodstil {#code-style} * Biome sköter formatering och linting (dubbla citattecken, semikolon, 2 blanksteg indrag) * Pre-commit-hooken kör `biome check --write` på stagade filer automatiskt * Om lintern klagar, fixa koden (ändra inte Biome-konfigurationen) * ES-moduler överallt (`import`/`export`) * Conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` För fullständiga arkitekturdetaljer, se [Utvecklarguiden](/sv/guide/developer). ## Säkerhet {#security} **Öppna inte en offentlig PR eller ett ärende för säkerhetssårbarheter.** Rapportera dem privat via [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) eller e-post contact@snapotter.com. Se [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) för fullständiga detaljer. ## Frågor? {#questions} * [Dokumentation](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/nl/guide/contributing.md description: >- Hoe je kunt bijdragen aan SnapOtter. Bugmeldingen, functieverzoeken, pull requests en CLA-vereisten. --- # Bijdragen {#contributing} Bedankt voor je interesse om bij te dragen. Deze gids beschrijft hoe je kunt meedoen, wat we accepteren en hoe je begint. ## Manieren om bij te dragen {#ways-to-contribute} ### Issues (geen installatie vereist) {#issues-no-setup-required} * **Bugmeldingen** - Werkt er iets niet? Open een [bugmelding](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) met stappen om het te reproduceren. * **Functieverzoeken** - Heb je een idee? Start een [discussie](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) zodat de community erop kan reageren en erop kan stemmen. * **Vertaalproblemen** - Zie je een verkeerde of ontbrekende vertaling? Open een [vertaalprobleem](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Documentatieproblemen** - Klopt er iets niet in de documentatie? Open een [documentatieprobleem](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Code (vereist CLA) {#code-requires-cla} We accepteren pull requests voor: | Type | Proces | |------|---------| | Bugfixes | Open direct een PR (link de issue als die bestaat) | | Nieuwe vertalingen | Open direct een PR (zie [Vertaalgids](/nl/guide/translations)) | | Documentatieverbeteringen | Open direct een PR | | Verbeteringen aan testdekking | Open direct een PR | | Nieuwe tools of functies | Start eerst een [discussie](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas); een maintainer zet goedgekeurde ideeën om in een bijgehouden issue voordat je code schrijft | | Refactors of architectuurwijzigingen | Start eerst een [discussie](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) en wacht op goedkeuring van een maintainer voordat je code schrijft | ### Wat we niet accepteren {#what-we-will-not-accept} * Wijzigingen aan CI/CD-workflows, release-configuratie of linter-/compilerconfiguratie * PR's zonder een ondertekende [Contributor License Agreement](#contributor-license-agreement) * PR's met meer dan 400 gewijzigde regels (splits groot werk op in kleinere PR's) * Functies die niet vooraf zijn besproken en goedgekeurd * Wijzigingen aan `packages/ai/` zonder voorafgaand overleg ## Contributor License Agreement {#contributor-license-agreement} Voordat we je eerste PR kunnen samenvoegen, moet je onze [Individual CLA](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md) ondertekenen. Dit is een eenmalige vereiste. **Waarom:** SnapOtter heeft een duale licentie (AGPLv3 + commercieel). De CLA geeft ons het recht om je bijdragen onder beide licenties te verspreiden. Je behoudt het volledige auteursrecht op je werk. **Hoe:** Wanneer je je eerste PR opent, plaatst de CLA Assistant-bot een reactie met een link. Klik erop, bekijk de overeenkomst en onderteken met je GitHub-account. Kost 30 seconden. Als je bijdraagt namens je werkgever en je werkgever de IP-rechten op je werk behoudt, neem dan contact op met contact@snapotter.com om een Corporate CLA te regelen voordat je iets indient. ## Aan de slag {#getting-started} ### Vereisten {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (alleen voor AI-tools) * Docker (optioneel, voor volledige integratietests) ### Installatie {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Controles uitvoeren {#running-checks} Zorg voordat je een PR indient dat alle controles lokaal slagen: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Pull request-proces {#pull-request-process} 1. Fork de repo en maak een branch aan vanaf `main` (`feat/my-feature` of `fix/issue-123`) 2. Breng je wijzigingen aan in gerichte, beoordeelbare commits met [conventional commits](https://www.conventionalcommits.org/) 3. Voeg tests toe of werk ze bij voor je wijzigingen 4. Voer `pnpm lint && pnpm typecheck && pnpm test` lokaal uit 5. Open een PR tegen `main` en vul het sjabloon in 6. Onderteken de CLA als daarom wordt gevraagd 7. Wacht tot CI slaagt en een maintainer het beoordeelt ### Beoordelingsverwachtingen {#review-expectations} * We streven ernaar om binnen 7 dagen op PR's te reageren * Kleine, gerichte PR's worden sneller beoordeeld * Als je binnen 7 dagen niets hebt gehoord, plaats dan een reactie om de thread te pingen * We kunnen wijzigingen vragen, een andere aanpak voorstellen of de PR sluiten als die niet aansluit bij de richting van het project ### Nadat je PR is samengevoegd {#after-your-pr-is-merged} Je bijdrage wordt opgenomen in de volgende release en vermeld in de changelog. ## Goede eerste issues {#good-first-issues} Op zoek naar iets om aan te werken? Bekijk onze [good first issues](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) voor toegankelijke taken, of [help wanted](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) voor grotere onderdelen waarbij we hulp uit de community waarderen. ## Codestijl {#code-style} * Biome verzorgt de opmaak en linting (dubbele aanhalingstekens, puntkomma's, inspringen met 2 spaties) * De pre-commit-hook voert `biome check --write` automatisch uit op gestagede bestanden * Als de linter klaagt, pas dan de code aan (wijzig de Biome-configuratie niet) * Overal ES-modules (`import`/`export`) * Conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` Zie voor volledige architectuurdetails de [Ontwikkelaarsgids](/nl/guide/developer). ## Beveiliging {#security} **Open geen publieke PR of issue voor beveiligingslekken.** Meld ze privé via [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) of e-mail contact@snapotter.com. Zie [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) voor alle details. ## Vragen? {#questions} * [Documentatie](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/de/tools/image/image-pad.md description: >- Füllt ein Bild auf ein Zielseitenverhältnis mit einer Volltonfarbe, transparentem oder unscharfem Hintergrund auf. --- # Bild auffüllen {#image-pad} Füllt ein Bild auf ein Zielseitenverhältnis auf, indem ein Hintergrund aus einer Volltonfarbe, transparent oder unscharf darum herum hinzugefügt wird. Nützlich, um Bilder ohne Zuschneiden in feste Seitenverhältnisse für soziale Medien oder den Druck einzupassen. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/image-pad` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | target | string | Nein | `"1:1"` | Zielseitenverhältnis: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` oder `custom` | | ratioW | integer | Nein | `1` | Benutzerdefinierte Verhältnisbreite (1-100, verwendet, wenn target `custom` ist) | | ratioH | integer | Nein | `1` | Benutzerdefinierte Verhältnishöhe (1-100, verwendet, wenn target `custom` ist) | | background | string | Nein | `"color"` | Hintergrundmodus: `color`, `transparent` oder `blur` | | color | string | Nein | `"#ffffff"` | Hintergrund-Hexfarbe (wenn background `color` ist) | | padding | integer | Nein | `0` | Zusätzlicher Innenabstand als Prozentsatz der Leinwand (0-50) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 3100000 } ``` ## Hinweise {#notes} * Der Hintergrundmodus `blur` erzeugt eine unscharfe Kopie des Originalbilds als Füllung, was ein visuell stimmiges Ergebnis liefert. * Bei Verwendung des Hintergrunds `transparent` wird die Ausgabe in PNG umgewandelt, um den Alphakanal zu erhalten. * Das Ausgabeformat entspricht dem Eingabeformat, es sei denn, Transparenz ist beteiligt. HEIC-, RAW-, PSD- und SVG-Eingaben werden vor der Verarbeitung automatisch decodiert. * Setzen Sie `target` auf `custom` und geben Sie `ratioW` und `ratioH` für beliebige Seitenverhältnisse an (z. B. `ratioW: 3, ratioH: 2` für 3:2). --- --- url: https://docs.snapotter.com/de/tools/image/split.md description: >- Ein Bild nach Zeilen und Spalten oder nach Pixelgröße in Rasterkacheln aufteilen, ausgegeben als ZIP-Archiv. --- # Bild aufteilen {#image-splitting} Teilt ein einzelnes Bild nach Spalten-/Zeilenanzahl oder nach bestimmten Pixelmaßen in Rasterkacheln auf. Gibt ein ZIP-Archiv mit allen Kacheln zurück. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/split` ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | columns | integer | Nein | 3 | Anzahl der Spalten, in die aufgeteilt wird (1 bis 100) | | rows | integer | Nein | 3 | Anzahl der Zeilen, in die aufgeteilt wird (1 bis 100) | | tileWidth | integer | Nein | - | Kachelbreite in Pixeln (min. 10). Überschreibt `columns`, wenn sowohl `tileWidth` als auch `tileHeight` gesetzt sind. | | tileHeight | integer | Nein | - | Kachelhöhe in Pixeln (min. 10). Überschreibt `rows`, wenn sowohl `tileWidth` als auch `tileHeight` gesetzt sind. | | outputFormat | string | Nein | `"original"` | Ausgabeformat für Kacheln: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | Nein | 90 | Ausgabequalität für verlustbehaftete Formate (1 bis 100) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Beispielantwort {#example-response} Die Antwort wird direkt als ZIP-Datei mit `Content-Type: application/zip` gestreamt. Der Dateiname folgt dem Muster `split-.zip`. Jede Kachel innerhalb des ZIP-Archivs wird nach dem Schema `_r_c.` benannt (z. B. `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Hinweise {#notes} * Nimmt eine einzelne Bilddatei entgegen. * Unterstützt HEIC-, RAW-, PSD- und SVG-Eingabeformate (automatisch dekodiert). * Wenn sowohl `tileWidth` als auch `tileHeight` angegeben sind, haben sie Vorrang vor `columns`/`rows`. Die Rasterabmessungen werden als `ceil(imageWidth / tileWidth)` und `ceil(imageHeight / tileHeight)` berechnet. * Randkacheln (rechte Spalte, untere Zeile) können kleiner als die angegebene Kachelgröße sein, wenn die Bildabmessungen nicht gleichmäßig teilbar sind. * Die maximale Rastergröße ist auf 100x100 (10.000 Kacheln) begrenzt. * Die Antwort streamt das ZIP direkt, es gibt also keinen JSON-Antworttext. Verwenden Sie `--output` mit curl, um die Datei zu speichern. --- --- url: https://docs.snapotter.com/de/tools/image/rotate.md description: >- Drehe Bilder um jeden beliebigen Winkel und spiegle sie horizontal oder vertikal. --- # Bild drehen & spiegeln {#rotate-flip} Drehe Bilder um einen beliebigen Winkel und/oder spiegle sie horizontal oder vertikal. Dreh- und Spiegeloperationen können in einer einzigen Anfrage kombiniert werden. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/rotate` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | angle | number | Nein | `0` | Drehwinkel in Grad (im Uhrzeigersinn). Akzeptiert jeden numerischen Wert. | | horizontal | boolean | Nein | `false` | Das Bild horizontal spiegeln (Spiegelbild) | | vertical | boolean | Nein | `false` | Das Bild vertikal spiegeln | ## Beispielanfrage {#example-request} 90 Grad im Uhrzeigersinn drehen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 90}' ``` Horizontal spiegeln: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"horizontal": true}' ``` Drehen und Spiegeln zusammen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 45, "vertical": true}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Hinweise {#notes} * Zuerst wird die Drehung angewendet, dann die Spiegeloperationen. * Drehungen, die nicht 90 Grad betragen (z. B. 45 Grad), vergrößern die Leinwand, damit das gedrehte Bild passt, mit transparenter oder schwarzer Füllung je nach Ausgabeformat. * Gängige Werte: 90, 180, 270 für Vierteldrehungen. * Die EXIF-Orientierung wird vor der Verarbeitung automatisch angewendet, sodass die Drehung relativ zur visuellen Orientierung erfolgt. --- --- url: https://docs.snapotter.com/de/tools/image/upscale.md description: >- Bilder mit Real-ESRGAN-KI-Superauflösung 2x bis 4x hochskalieren und dabei feine Details bewahren. --- # Bild hochskalieren {#image-upscaling} KI-Superauflösungsverbesserung mit Real-ESRGAN. Skaliert Bilder 2x-4x hoch und bewahrt dabei Details. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/upscale` **Verarbeitung:** Asynchron (liefert 202 zurück, Status über SSE per `/api/v1/jobs/{jobId}/progress` abrufen) **Modell-Bundle:** `upscale-enhance` (5-6 GB) ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bilddatei (Multipart) | | scale | number | Nein | `2` | Hochskalierungsfaktor (z. B. 2, 3, 4) | | model | string | Nein | `"auto"` | Zu verwendendes Modell (z. B. `auto`, spezifische Modellnamen) | | faceEnhance | boolean | Nein | `false` | Gesichtsverbesserung während der Hochskalierung anwenden | | denoise | number | Nein | `0` | Rauschreduzierungsstärke (0 = aus) | | format | string | Nein | `"auto"` | Ausgabeformat: `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | Nein | `95` | Ausgabequalität (1-100) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Antwort {#response} ### Erste Antwort (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Fortschritt (SSE unter `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Endergebnis (über SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Hinweise {#notes} * Erfordert die Installation des Modell-Bundles `upscale-enhance` (5-6 GB). * Verwendet Real-ESRGAN, sofern verfügbar; fällt auf Lanczos-Interpolation zurück, wenn das KI-Modell nicht verfügbar ist. * Die Option `faceEnhance` wendet während der Hochskalierung eine GFPGAN-Gesichtsrestaurierung für bessere Gesichtsqualität an. * Für nicht im Browser vorschaubare Ausgabeformate (HEIC, JXL, TIFF) wird neben der Hauptausgabe eine WebP-Vorschau erzeugt. * Unterstützt HEIC/HEIF-, RAW-, TGA-, PSD-, EXR- und HDR-Eingabeformate durch automatische Dekodierung. --- --- url: https://docs.snapotter.com/de/tools/image/compress.md description: >- Verringert die Dateigröße eines Bildes über eine Qualitätsstufe oder auf eine Zieldateigröße. --- # Bild komprimieren {#compress} Verringert die Dateigröße eines Bildes durch Angabe einer Qualitätsstufe oder einer Zieldateigröße in Kilobyte. Das Werkzeug verwendet eine iterative binäre Suche, um Größenvorgaben präzise zu treffen. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/compress` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | mode | string | Nein | `"quality"` | Komprimierungsmodus: `quality` oder `targetSize` | | quality | number | Nein | `80` | Qualitätsstufe (1-100). Wird verwendet, wenn der Modus `quality` ist. | | targetSizeKb | number | Nein | - | Zieldateigröße in Kilobyte. Wird verwendet, wenn der Modus `targetSize` ist. | ## Beispielanfrage {#example-request} Auf Qualität 60 komprimieren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Auf eine Zielgröße von 200 KB komprimieren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Hinweise {#notes} * Im Modus `quality` erzeugen niedrigere Werte kleinere Dateien mit mehr Komprimierungsartefakten. Ein Wert von 80 ist ein guter Standard für die Webnutzung. * Im Modus `targetSize` führt die Engine eine iterative Komprimierung durch, um so nah wie möglich an das Ziel zu kommen, ohne es zu überschreiten. * Das Ausgabeformat entspricht dem Eingabeformat. Die Komprimierung wird auf die native Kodierung des Formats angewendet (z. B. JPEG-Qualität für JPEG-Dateien, WebP-Qualität für WebP-Dateien). * Wenn die Standardqualität (80) akzeptabel ist, können Sie den Parameter `quality` ganz weglassen. --- --- url: https://docs.snapotter.com/de/tools/image/convert.md description: >- Konvertiert Bilder zwischen Formaten, einschließlich moderner Formate wie AVIF, JXL und HEIC. --- # Bild konvertieren {#convert} Konvertiert Bilder zwischen Formaten. Unterstützt gängige Webformate sowie spezialisierte Formate wie HEIC, JXL, BMP, ICO, JP2, QOI und PSD. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/convert` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Zielformat: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | Nein | - | Ausgabequalität (1-100). Gilt für verlustbehaftete Formate wie jpg, webp, avif, heic. | ## Unterstützte Ausgabeformate {#supported-output-formats} | Format | Typ | Hinweise | |--------|------|-------| | jpg | Verlustbehaftet | JPEG, beste Kompatibilität | | png | Verlustfrei | Unterstützt Transparenz | | webp | Beides | Modernes Webformat, gute Komprimierung | | avif | Verlustbehaftet | Format der nächsten Generation, ausgezeichnete Komprimierung | | tiff | Beides | Druck-/Publishing-Workflows | | gif | Verlustfrei | Auf 256 Farben beschränkt | | heic / heif | Verlustbehaftet | Format des Apple-Ökosystems | | jxl | Beides | JPEG XL, Format der nächsten Generation | | bmp | Verlustfrei | Unkomprimierte Bitmap | | ico | Verlustfrei | Windows-Symbolformat | | jp2 | Verlustbehaftet | JPEG 2000 | | qoi | Verlustfrei | Quite OK Image-Format | | psd | Ebenen | Adobe Photoshop (erfordert ImageMagick) | | ppm | Verlustfrei | Portable Pixmap (PPM/PGM/PBM) | | eps | Vektor | Encapsulated PostScript | | tga | Verlustfrei | Targa-Bildformat | ## Beispielanfrage {#example-request} In WebP konvertieren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` In PNG konvertieren (verlustfrei): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Hinweise {#notes} * Die Erweiterung des Ausgabedateinamens wird automatisch an das Zielformat angepasst. * SVG-Eingaben werden vor der Konvertierung mit 300 DPI gerastert. * Die PSD-Konvertierung erfordert, dass ImageMagick auf dem Server installiert ist. * BMP, EPS, ICO, JP2, JXL, PPM, QOI und TGA verwenden spezialisierte CLI-Encoder und umgehen die Sharp-Verarbeitung. * Die HEIC/HEIF-Kodierung verwendet die HEIC-Encoder-Bibliothek des Systems. * Die Eingabeformate sind vielfältig: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW usw.), PSD, SVG, BMP und mehr. --- --- url: https://docs.snapotter.com/de/tools/image/sharpening.md description: >- Bilder mit adaptiven, Unschärfemaskierungs- oder Hochpass-Verfahren schärfen, optional mit Rauschreduzierung. --- # Bild schärfen {#sharpening} Erweitertes Schärfungswerkzeug mit drei Verfahren: adaptiv (intelligent kantenbewusst), Unschärfemaskierung (klassisch mit Radius/Stärke) und Hochpass (Texturbetonung). Enthält eine integrierte Rauschreduzierung, um Schärfungsartefakte zu vermeiden. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/sharpening` Nimmt Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | method | string | Nein | `"adaptive"` | Schärfungsalgorithmus: `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | Nein | `1.0` | Adaptiv: Gauß-Sigma (0,5 bis 10) | | m1 | number | Nein | `1.0` | Adaptiv: Schärfung in flachen Bereichen (0 bis 10) | | m2 | number | Nein | `3.0` | Adaptiv: Schärfung in zerklüfteten Bereichen (0 bis 20) | | x1 | number | Nein | `2.0` | Adaptiv: Schwellenwert flach/zerklüftet (0 bis 10) | | y2 | number | Nein | `12` | Adaptiv: maximale Schärfung in flachen Bereichen (0 bis 50) | | y3 | number | Nein | `20` | Adaptiv: maximale Schärfung in zerklüfteten Bereichen (0 bis 50) | | amount | number | Nein | `100` | Unschärfemaskierung: Schärfungsstärke (0 bis 1000) | | radius | number | Nein | `1.0` | Unschärfemaskierung: Weichzeichnungsradius in Pixeln (0,1 bis 5) | | threshold | number | Nein | `0` | Unschärfemaskierung: minimaler Helligkeitsunterschied zum Schärfen (0 bis 255) | | strength | number | Nein | `50` | Hochpass: Filterstärke (0 bis 100) | | kernelSize | number | Nein | `3` | Hochpass: Größe des Faltungskerns (3 oder 5) | | denoise | string | Nein | `"off"` | Rauschreduzierung vor dem Schärfen: `off`, `light`, `medium`, `strong` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Unschärfemaskierung mit Schwellenwert, um glatte Bereiche zu schützen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Hinweise {#notes} * Es werden nur die für das gewählte Verfahren relevanten Parameter verwendet. Beispielsweise werden `amount`, `radius` und `threshold` ignoriert, wenn `method` den Wert `adaptive` hat. * Das adaptive Verfahren nutzt die integrierte adaptive Schärfung von Sharp mit konfigurierbarem Verhalten für flache/zerklüftete Regionen. * Die Option `denoise` wendet vor dem Schärfen eine Rauschreduzierung an, um eine Verstärkung von Rauschen/Körnung zu verhindern. * Die Hochpass-Schärfung extrahiert feine Details, indem eine weichgezeichnete Version vom Original subtrahiert und anschließend wieder eingemischt wird. * Das Ausgabeformat entspricht dem Eingabeformat. HEIC-, RAW-, PSD- und SVG-Eingaben werden vor der Verarbeitung automatisch dekodiert. --- --- url: https://docs.snapotter.com/sv/tools/image/image-to-base64.md description: Konvertera bilder till base64-data-URI:er för inbäddning i HTML, CSS med mera. --- # Bild till Base64 {#image-to-base64} Konvertera en eller flera bilder till base64-kodade strängar och data-URI:er. Stöder valfri formatkonvertering, kvalitetskontroll och storleksändring. Användbart för att bädda in bilder direkt i HTML, CSS, JSON eller e-postmallar. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/image-to-base64` Tar emot multipart-formulärdata med en eller flera bildfiler och ett valfritt JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | outputFormat | string | Nej | `"original"` | Konvertera före kodning: `original`, `jpeg`, `png`, `webp`, `avif`, `jxl` | | quality | number | Nej | `80` | Utdatakvalitet för förlustbehäftade format (1 till 100) | | maxWidth | number | Nej | `0` | Maximal bredd i pixlar (0 = ingen storleksändring, förstoras inte) | | maxHeight | number | Nej | `0` | Maximal höjd i pixlar (0 = ingen storleksändring, förstoras inte) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon.png" \ -F 'settings={"outputFormat": "webp", "quality": 80, "maxWidth": 200}' ``` Flera filer: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon1.png" \ -F "file=@icon2.png" \ -F "file=@icon3.png" \ -F 'settings={"outputFormat": "original"}' ``` ## Exempelsvar {#example-response} ```json { "results": [ { "filename": "icon.png", "mimeType": "image/webp", "width": 200, "height": 200, "originalSize": 45000, "encodedSize": 28800, "overheadPercent": -36.0, "base64": "UklGRlYAAABXRUJQ...", "dataUri": "data:image/webp;base64,UklGRlYAAABXRUJQ..." } ], "errors": [] } ``` ## Svarsfält {#response-fields} | Fält | Typ | Beskrivning | |-------|------|-------------| | results | array | Bilder som konverterats framgångsrikt | | errors | array | Bilder som misslyckades med bearbetning (med filnamn och felmeddelande) | ### Resultatobjekt {#result-object} | Fält | Typ | Beskrivning | |-------|------|-------------| | filename | string | Ursprungligt filnamn | | mimeType | string | MIME-typ för den kodade utdatan | | width | number | Slutlig bredd i pixlar (efter eventuell storleksändring) | | height | number | Slutlig höjd i pixlar (efter eventuell storleksändring) | | originalSize | number | Ursprunglig filstorlek i byte | | encodedSize | number | Storlek på base64-strängen i byte | | overheadPercent | number | Procentuell storleksskillnad jämfört med originalet (positiv = större, negativ = mindre) | | base64 | string | Rå base64-kodad bilddata | | dataUri | string | Komplett data-URI redo att användas i `src`-attribut | ## Anmärkningar {#notes} * Base64-kodning ökar vanligtvis storleken med cirka 33% jämfört med binärfilen. Fältet `overheadPercent` visar den faktiska skillnaden. * När `outputFormat` är `"original"` konverteras HEIC/HEIF-filer till JPEG (eftersom webbläsare inte kan visa HEIC i data-URI:er). * Alternativen `maxWidth` och `maxHeight` storleksändrar med `fit: inside` och `withoutEnlargement`, så bilder som är mindre än de angivna dimensionerna förstoras inte. * Flera filer kan bearbetas i en enda begäran. Varje fil bearbetas oberoende, och misslyckanden hindrar inte andra filer från att lyckas. * SVG-filer skickas vidare som `image/svg+xml` utan omkodning (om inte en formatkonvertering begärs). * Detta är en skrivskyddad slutpunkt. Den producerar ingen nedladdningsbar fil eller `jobId`. Base64-datan returneras direkt i svarskroppen. --- --- url: https://docs.snapotter.com/sv/tools/image/image-to-pdf.md description: >- Kombinera en eller flera bilder till ett PDF-dokument med alternativ för sidstorlek, orientering och målfilstorlek. --- # Bild till PDF {#image-to-pdf} Kombinera en eller flera bilder till ett PDF-dokument. Stöder flera sidstorlekar, orienteringar, marginaler och valfri målfilstorlek via kvalitetsjustering. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/image-to-pdf` Tar emot multipart-formulärdata med en eller flera bildfiler och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | pageSize | string | Nej | `"A4"` | Sidstorlek: `A4`, `Letter`, `A3`, `A5` | | orientation | string | Nej | `"portrait"` | Sidorientering: `portrait` eller `landscape` | | margin | number | Nej | `20` | Sidmarginal i punkter (0-500) | | targetSize | object | Nej | - | Begränsning för målfilstorlek (se nedan) | | collate | boolean | Nej | `true` | Kombinera alla bilder till en PDF. Om `false` skapas en PDF per bild. | ### Målstorleksobjekt {#target-size-object} | Fält | Typ | Obligatorisk | Beskrivning | |-------|------|----------|-------------| | value | number | Ja | Målstorleksvärde | | unit | string | Ja | Enhet: `KB` eller `MB` | Minsta målstorlek är 50 KB. ## Exempelbegäran {#example-request} Grundläggande PDF med flera bilder: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page1.jpg" \ -F "file=@page2.jpg" \ -F "file=@page3.jpg" \ -F 'settings={"pageSize": "A4", "orientation": "portrait", "margin": 20}' ``` Med målfilstorlek: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@scan1.jpg" \ -F "file=@scan2.jpg" \ -F 'settings={"pageSize": "Letter", "targetSize": {"value": 2, "unit": "MB"}}' ``` En PDF per bild: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F 'settings={"collate": false}' ``` ## Exempelsvar (sammanfogat) {#example-response-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 5000000, "processedSize": 1200000, "pages": 3 } ``` ## Exempelsvar (ej sammanfogat) {#example-response-non-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.zip", "originalSize": 5000000, "processedSize": 2400000, "pages": 2, "collated": false } ``` ## Exempelsvar (med målstorlek) {#example-response-with-target-size} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 10000000, "processedSize": 2000000, "pages": 5, "compression": { "targetRequested": 2097152, "targetMet": true, "jpegQuality": 72 } } ``` ## Anmärkningar {#notes} * Bilder centreras på sidan och skalas för att passa inom marginalerna med bibehållet bildförhållande. Bilder förstoras aldrig. * När `collate` är `false` blir varje bild en separat PDF-fil, och nedladdningen är ett ZIP-arkiv som innehåller alla PDF-filer. * Funktionen för målstorlek använder iterativ binärsökning över JPEG-kvalitetsnivåer (10-95) för att hitta den bästa kvaliteten som ryms inom budgeten. * Transparenta bilder plattas ut till vitt innan de bäddas in i PDF-filen. * Format som stöds för inmatning: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW, PSD, SVG med flera. * EXIF-orientering tillämpas automatiskt före inbäddning. --- --- url: https://docs.snapotter.com/sv/tools/image/vectorize.md description: >- Konvertera rasterbilder till SVG med svartvit (potrace) och fullfärgs flerlagersvektorisering. --- # Bild till SVG {#image-to-svg} Vektorisera rasterbilder till SVG med spårningsalgoritmer. Stöder svartvit spårning (potrace) och fullfärgs flerlagersvektorisering. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/vectorize` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | colorMode | string | No | `"bw"` | Spårningsläge: `bw` (svartvitt) eller `color` (flerfärgslager) | | threshold | number | No | 128 | Ljusstyrketröskel för svartvitt läge (0 till 255). Pixlar under blir svarta. | | colorPrecision | number | No | 6 | Precision för färgkvantisering i färgläge (1 till 16). Högre värden ger fler distinkta färglager. | | layerDifference | number | No | 6 | Minsta färgskillnad mellan lager i färgläge (1 till 128) | | filterSpeckle | number | No | 4 | Minsta area för spårade former i pixlar (1 till 256). Tar bort brus/fläckar. | | pathMode | string | No | `"spline"` | Utjämning av banor: `none` (kantiga), `polygon` (raka segment), `spline` (mjuka kurvor) | | cornerThreshold | number | No | 60 | Vinkeltröskel för hörndetektering i färgläge (0 till 180 grader) | | invert | boolean | No | `false` | Invertera bilden före spårning (byt svart/vitt) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@logo.png" \ -F 'settings={"colorMode":"bw","threshold":128,"filterSpeckle":4,"pathMode":"spline"}' ``` ### Color Vectorization {#color-vectorization} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@illustration.png" \ -F 'settings={"colorMode":"color","colorPrecision":8,"layerDifference":6,"filterSpeckle":4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logo.svg", "originalSize": 45678, "processedSize": 12345 } ``` ## Notes {#notes} * Utdata är alltid en SVG-fil oavsett indataformat. * Stöder indataformaten HEIC, RAW, PSD och SVG (avkodas automatiskt till raster före spårning). * Svartvitt läge använder potrace-algoritmen. Bilden konverteras först till gråskala och tröskelvärdesbestäms sedan till rent svartvitt före spårning. * Färgläge använder ett flerlagerstillvägagångssätt: bilden kvantiseras till färglager, som var och en spåras separat och staplas i SVG-utdatan. * Lägre värden på `filterSpeckle` bevarar fler detaljer men ger större SVG-filer med fler banor. * Inställningen `pathMode` påverkar filstorleken avsevärt: `none` ger flest banor, `spline` ger den jämnaste (och vanligtvis minsta) utdatan. * För bästa resultat med logotyper och ikoner, använd svartvitt läge med en ren indata med hög kontrast. För fotografier eller illustrationer, använd färgläge med högre `colorPrecision`. --- --- url: https://docs.snapotter.com/de/tools/image/image-to-base64.md description: Konvertiert Bilder in Base64-Data-URIs zum Einbetten in HTML, CSS und mehr. --- # Bild zu Base64 {#image-to-base64} Konvertiert ein oder mehrere Bilder in Base64-codierte Zeichenketten und Data-URIs. Unterstützt optionale Formatkonvertierung, Qualitätssteuerung und Größenänderung. Nützlich zum direkten Einbetten von Bildern in HTML, CSS, JSON oder E-Mail-Vorlagen. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/image-to-base64` Akzeptiert Multipart-Formulardaten mit einer oder mehreren Bilddateien und einem optionalen JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | outputFormat | string | Nein | `"original"` | Vor der Codierung konvertieren: `original`, `jpeg`, `png`, `webp`, `avif`, `jxl` | | quality | number | Nein | `80` | Ausgabequalität für verlustbehaftete Formate (1 bis 100) | | maxWidth | number | Nein | `0` | Maximale Breite in Pixeln (0 = keine Größenänderung, vergrößert nicht) | | maxHeight | number | Nein | `0` | Maximale Höhe in Pixeln (0 = keine Größenänderung, vergrößert nicht) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon.png" \ -F 'settings={"outputFormat": "webp", "quality": 80, "maxWidth": 200}' ``` Mehrere Dateien: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon1.png" \ -F "file=@icon2.png" \ -F "file=@icon3.png" \ -F 'settings={"outputFormat": "original"}' ``` ## Beispielantwort {#example-response} ```json { "results": [ { "filename": "icon.png", "mimeType": "image/webp", "width": 200, "height": 200, "originalSize": 45000, "encodedSize": 28800, "overheadPercent": -36.0, "base64": "UklGRlYAAABXRUJQ...", "dataUri": "data:image/webp;base64,UklGRlYAAABXRUJQ..." } ], "errors": [] } ``` ## Antwortfelder {#response-fields} | Feld | Typ | Beschreibung | |-------|------|-------------| | results | array | Erfolgreich konvertierte Bilder | | errors | array | Bilder, die nicht verarbeitet werden konnten (mit Dateiname und Fehlermeldung) | ### Ergebnis-Objekt {#result-object} | Feld | Typ | Beschreibung | |-------|------|-------------| | filename | string | Ursprünglicher Dateiname | | mimeType | string | MIME-Typ der codierten Ausgabe | | width | number | Endgültige Breite in Pixeln (nach etwaiger Größenänderung) | | height | number | Endgültige Höhe in Pixeln (nach etwaiger Größenänderung) | | originalSize | number | Ursprüngliche Dateigröße in Bytes | | encodedSize | number | Größe der Base64-Zeichenkette in Bytes | | overheadPercent | number | Prozentuale Größendifferenz gegenüber dem Original (positiv = größer, negativ = kleiner) | | base64 | string | Rohe Base64-codierte Bilddaten | | dataUri | string | Vollständiger Data-URI, bereit zur Verwendung in `src`-Attributen | ## Hinweise {#notes} * Die Base64-Codierung vergrößert die Größe typischerweise um etwa 33 % im Vergleich zur Binärdatei. Das Feld `overheadPercent` zeigt die tatsächliche Differenz. * Wenn `outputFormat` auf `"original"` steht, werden HEIC/HEIF-Dateien in JPEG konvertiert (da Browser HEIC nicht in Data-URIs anzeigen können). * Die Optionen `maxWidth` und `maxHeight` ändern die Größe mit `fit: inside` und `withoutEnlargement`, sodass Bilder, die kleiner als die angegebenen Abmessungen sind, nicht hochskaliert werden. * Mehrere Dateien können in einer einzigen Anfrage verarbeitet werden. Jede Datei wird unabhängig verarbeitet, und Fehler verhindern nicht, dass andere Dateien erfolgreich sind. * SVG-Dateien werden als `image/svg+xml` ohne Neucodierung durchgereicht (es sei denn, es wird eine Formatkonvertierung angefordert). * Dies ist ein schreibgeschützter Endpunkt. Er erzeugt keine herunterladbare Datei und keine `jobId`. Die Base64-Daten werden direkt im Antworttext zurückgegeben. --- --- url: https://docs.snapotter.com/de/tools/image/image-to-pdf.md description: >- Kombiniert ein oder mehrere Bilder zu einem PDF-Dokument mit Optionen für Seitengröße, Ausrichtung und Zieldateigröße. --- # Bild zu PDF {#image-to-pdf} Kombiniert ein oder mehrere Bilder zu einem PDF-Dokument. Unterstützt mehrere Seitengrößen, Ausrichtungen, Ränder und optionale Zieldateigröße über die Qualitätsanpassung. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/image-to-pdf` Akzeptiert Multipart-Formulardaten mit einer oder mehreren Bilddateien und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | pageSize | string | Nein | `"A4"` | Seitengröße: `A4`, `Letter`, `A3`, `A5` | | orientation | string | Nein | `"portrait"` | Seitenausrichtung: `portrait` oder `landscape` | | margin | number | Nein | `20` | Seitenrand in Punkten (0-500) | | targetSize | object | Nein | - | Beschränkung der Zieldateigröße (siehe unten) | | collate | boolean | Nein | `true` | Alle Bilder in einem PDF kombinieren. Falls `false`, wird pro Bild ein PDF erstellt. | ### Objekt „Zielgröße“ {#target-size-object} | Feld | Typ | Erforderlich | Beschreibung | |-------|------|----------|-------------| | value | number | Ja | Wert der Zielgröße | | unit | string | Ja | Einheit: `KB` oder `MB` | Die minimale Zielgröße beträgt 50 KB. ## Beispielanfrage {#example-request} Einfaches PDF aus mehreren Bildern: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page1.jpg" \ -F "file=@page2.jpg" \ -F "file=@page3.jpg" \ -F 'settings={"pageSize": "A4", "orientation": "portrait", "margin": 20}' ``` Mit Zieldateigröße: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@scan1.jpg" \ -F "file=@scan2.jpg" \ -F 'settings={"pageSize": "Letter", "targetSize": {"value": 2, "unit": "MB"}}' ``` Ein PDF pro Bild: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F 'settings={"collate": false}' ``` ## Beispielantwort (zusammengeführt) {#example-response-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 5000000, "processedSize": 1200000, "pages": 3 } ``` ## Beispielantwort (nicht zusammengeführt) {#example-response-non-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.zip", "originalSize": 5000000, "processedSize": 2400000, "pages": 2, "collated": false } ``` ## Beispielantwort (mit Zielgröße) {#example-response-with-target-size} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 10000000, "processedSize": 2000000, "pages": 5, "compression": { "targetRequested": 2097152, "targetMet": true, "jpegQuality": 72 } } ``` ## Hinweise {#notes} * Bilder werden auf der Seite zentriert und so skaliert, dass sie unter Beibehaltung des Seitenverhältnisses innerhalb der Ränder passen. Bilder werden niemals hochskaliert. * Wenn `collate` auf `false` steht, wird jedes Bild zu einer separaten PDF-Datei, und der Download ist ein ZIP-Archiv, das alle PDFs enthält. * Die Funktion für die Zielgröße verwendet eine iterative binäre Suche über die JPEG-Qualitätsstufen (10-95), um die beste Qualität zu finden, die in das Budget passt. * Transparente Bilder werden vor dem Einbetten in das PDF auf Weiß abgeflacht. * Unterstützte Eingabeformate: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW, PSD, SVG und mehr. * Die EXIF-Ausrichtung wird vor dem Einbetten automatisch angewendet. --- --- url: https://docs.snapotter.com/de/tools/image/vectorize.md description: >- Rasterbilder mit Schwarz-Weiß-Vektorisierung (potrace) und vollfarbiger mehrschichtiger Vektorisierung in SVG umwandeln. --- # Bild zu SVG {#image-to-svg} Vektorisiert Rasterbilder mithilfe von Trace-Algorithmen in SVG. Unterstützt Schwarz-Weiß-Tracing (potrace) und vollfarbige mehrschichtige Vektorisierung. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/vectorize` ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | colorMode | string | Nein | `"bw"` | Trace-Modus: `bw` (schwarz-weiß) oder `color` (mehrfarbige Ebenen) | | threshold | number | Nein | 128 | Helligkeitsschwellenwert für den S/W-Modus (0 bis 255). Pixel darunter werden schwarz. | | colorPrecision | number | Nein | 6 | Farbquantisierungspräzision für den Farbmodus (1 bis 16). Höhere Werte erzeugen mehr eigenständige Farbebenen. | | layerDifference | number | Nein | 6 | Minimaler Farbunterschied zwischen Ebenen im Farbmodus (1 bis 128) | | filterSpeckle | number | Nein | 4 | Mindestfläche für getracte Formen in Pixeln (1 bis 256). Entfernt Rauschen/Flecken. | | pathMode | string | Nein | `"spline"` | Pfadglättung: `none` (zackig), `polygon` (gerade Segmente), `spline` (glatte Kurven) | | cornerThreshold | number | Nein | 60 | Winkelschwellenwert für die Eckenerkennung im Farbmodus (0 bis 180 Grad) | | invert | boolean | Nein | `false` | Das Bild vor dem Tracing invertieren (schwarz/weiß tauschen) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@logo.png" \ -F 'settings={"colorMode":"bw","threshold":128,"filterSpeckle":4,"pathMode":"spline"}' ``` ### Farbvektorisierung {#color-vectorization} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@illustration.png" \ -F 'settings={"colorMode":"color","colorPrecision":8,"layerDifference":6,"filterSpeckle":4}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logo.svg", "originalSize": 45678, "processedSize": 12345 } ``` ## Hinweise {#notes} * Die Ausgabe ist unabhängig vom Eingabeformat immer eine SVG-Datei. * Unterstützt HEIC-, RAW-, PSD- und SVG-Eingabeformate (vor dem Tracing automatisch in Raster dekodiert). * Der S/W-Modus verwendet den potrace-Algorithmus. Das Bild wird zuerst in Graustufen umgewandelt und dann vor dem Tracing auf reines Schwarz/Weiß mit einem Schwellenwert versehen. * Der Farbmodus verwendet einen mehrschichtigen Ansatz: Das Bild wird in Farbebenen quantisiert, die jeweils separat getract und in der SVG-Ausgabe gestapelt werden. * Niedrigere `filterSpeckle`-Werte bewahren mehr Details, erzeugen aber größere SVG-Dateien mit mehr Pfaden. * Die Einstellung `pathMode` beeinflusst die Dateigröße erheblich: `none` erzeugt die meisten Pfade, `spline` erzeugt die glatteste (und meist kleinste) Ausgabe. * Für beste Ergebnisse bei Logos und Icons verwenden Sie den S/W-Modus mit einer sauberen, kontrastreichen Eingabe. Für Fotos oder Illustrationen verwenden Sie den Farbmodus mit höherer `colorPrecision`. --- --- url: https://docs.snapotter.com/de/tools/image/crop.md description: >- Schneidet Bilder zu, indem ein Bereich über Position und Abmessungen angegeben wird. --- # Bild zuschneiden {#crop} Schneidet Bilder zu, indem ein rechteckiger Bereich über Position und Größe definiert wird. Unterstützt sowohl Pixel- als auch Prozenteinheiten. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/crop` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | left | number | Ja | - | X-Versatz des Zuschneidebereichs (von der linken Kante) | | top | number | Ja | - | Y-Versatz des Zuschneidebereichs (von der oberen Kante) | | width | number | Ja | - | Breite des Zuschneidebereichs | | height | number | Ja | - | Höhe des Zuschneidebereichs | | unit | string | Nein | `"px"` | Einheit für die Werte: `px` oder `percent` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 100, "top": 50, "width": 800, "height": 600}' ``` Mit Prozentwerten zuschneiden: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 10, "top": 10, "width": 80, "height": 80, "unit": "percent"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1200000 } ``` ## Hinweise {#notes} * Der Zuschneidebereich muss innerhalb der Bildgrenzen liegen. Ragt der Bereich über das Bild hinaus, schlägt die Anfrage fehl. * Bei Verwendung der Einheit `percent` stellen die Werte Prozentsätze der Bildabmessungen dar (z. B. bedeutet `left: 10` 10 % von der linken Kante). * Das Ausgabeformat entspricht dem Eingabeformat. * Die EXIF-Ausrichtung wird vor dem Zuschneiden automatisch angewendet, sodass die Koordinaten der optisch korrekten Ausrichtung entsprechen. --- --- url: https://docs.snapotter.com/de/tools/image/watermark-image.md description: >- Ein Logo oder Bild als Wasserzeichen mit konfigurierbarer Position, Deckkraft und Skalierung überlagern. --- # Bild-Wasserzeichen {#image-watermark} Überlagert ein Logo oder ein sekundäres Bild als Wasserzeichen auf einem Basisbild. Das Wasserzeichen wird relativ zur Breite des Basisbildes skaliert und an einer Ecke oder in der Mitte positioniert. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/watermark-image` Nimmt Multipart-Formulardaten mit **zwei** Bilddateien und einem JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | position | string | Nein | `"bottom-right"` | Platzierung des Wasserzeichens: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` | | opacity | number | Nein | `50` | Deckkraft des Wasserzeichens in Prozent (0 bis 100) | | scale | number | Nein | `25` | Breite des Wasserzeichens als Prozentsatz der Hauptbildbreite (1 bis 100) | ### Dateifelder {#file-fields} | Feldname | Erforderlich | Beschreibung | |------------|----------|-------------| | file | Ja | Das Haupt-/Basisbild | | watermark | Ja | Das Wasserzeichen-/Logobild | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "watermark=@logo.png" \ -F 'settings={"position": "bottom-right", "opacity": 60, "scale": 20}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2520000 } ``` ## Hinweise {#notes} * Beide Bilder werden validiert und dekodiert (HEIC, RAW, PSD, SVG werden unterstützt). * Das Wasserzeichen wird proportional so skaliert, dass seine Breite `scale` % der Hauptbildbreite entspricht. * Die Deckkraft wird über eine mit `dest-in`-Überblendung komponierte Alphamaske angewendet. * Eckpositionen verwenden einen Abstand von 20px zum Bildrand. * Wenn das Wasserzeichenbild Transparenz aufweist (z. B. ein PNG-Logo), wird diese beim Zusammensetzen erhalten. * Die EXIF-Ausrichtung wird bei beiden Bildern vor der Verarbeitung automatisch angewendet. --- --- url: https://docs.snapotter.com/sv/tools/video/images-to-video.md description: Gör en uppsättning bilder till en bildspelsvideo. --- # Bilder till video {#images-to-video} Gör en uppsättning bilder till en bildspelsvideo med konfigurerbar visningstid per bild, upplösning och bildhastighet. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/images-to-video` Tar emot multipart-formulärdata med två eller fler bildfiler och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | secondsPerImage | number | Nej | `2` | Visningstid per bild i sekunder (0.5-10) | | resolution | string | Nej | `"720p"` | Utdataupplösning: `1080p`, `720p`, `square` | | fps | integer | Nej | `30` | Utdatabildhastighet (10-60) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/images-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slide1.jpg" \ -F "file=@slide2.jpg" \ -F "file=@slide3.jpg" \ -F "file=@slide4.jpg" \ -F 'settings={"secondsPerImage": 3, "resolution": "1080p"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/slideshow.mp4", "originalSize": 3500000, "processedSize": 1200000 } ``` ## Anteckningar {#notes} * Tar emot 2-60 bildfiler per begäran. Bilderna visas i videon i uppladdningsordning. * Bilder storleksändras och fylls ut för att passa målupplösningen samtidigt som bildförhållandet bevaras. * Upplösningsalternativet `square` ger en video på 1080x1080, användbart för sociala medier. * Utdataformatet är alltid MP4 (H.264). --- --- url: https://docs.snapotter.com/de/tools/image/stitch.md description: >- Bilder nebeneinander, gestapelt oder in einem Raster zusammenfügen, mit Kontrolle über Ausrichtung, Abstände, Ränder und Skalierungsmodus. --- # Bilder zusammenfügen {#stitch-combine} Fügt mehrere Bilder nebeneinander, vertikal gestapelt oder in einem Raster angeordnet zusammen. Unterstützt Ausrichtung, Abstand, Rand, Eckradius und mehrere Skalierungsmodi. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/stitch` ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | direction | string | Nein | `"horizontal"` | Layout-Richtung: `horizontal`, `vertical`, `grid` | | gridColumns | integer | Nein | 2 | Anzahl der Spalten, wenn die Richtung `grid` ist (2 bis 100) | | resizeMode | string | Nein | `"fit"` | Art der Bildskalierung: `fit`, `original`, `stretch`, `crop` | | alignment | string | Nein | `"center"` | Ausrichtung auf der Querachse: `start`, `center`, `end` | | gap | number | Nein | 0 | Abstand zwischen den Bildern in Pixeln (0 bis 1000) | | border | number | Nein | 0 | Breite des äußeren Rands in Pixeln (0 bis 500) | | cornerRadius | number | Nein | 0 | Auf die finale Ausgabe angewendeter Eckradius (0 bis 500) | | backgroundColor | string | Nein | `"#FFFFFF"` | Hintergrund-/Randfarbe als Hexwert (z. B. `#FF0000`) | | format | string | Nein | `"png"` | Ausgabeformat: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Nein | 90 | Ausgabequalität (1 bis 100) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/stitch \ -F "file=@image1.png" \ -F "file=@image2.png" \ -F "file=@image3.png" \ -F 'settings={"direction":"horizontal","resizeMode":"fit","gap":10,"backgroundColor":"#FFFFFF","format":"png"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stitch.png", "originalSize": 1234567, "processedSize": 987654 } ``` ## Hinweise {#notes} * Erfordert mindestens 2 Bilder. Laden Sie mehrere Bilddateien in der Multipart-Anfrage hoch. * Unterstützt HEIC-, RAW-, PSD- und SVG-Eingabeformate (automatisch dekodiert). * Skalierungsmodi: * `fit` - Bilder so skalieren, dass sie der kleinsten Abmessung entlang der Verbindungsachse entsprechen. * `original` - Originalgrößen beibehalten (kann ungleichmäßige Kanten erzeugen). * `stretch` - Bilder erzwingen auf die kleinste Abmessung ohne Beibehaltung des Seitenverhältnisses bringen. * `crop` - Bilder per Cover-Zuschnitt auf die kleinste Abmessung bringen. * Im Modus `grid` werden die Zellen auf die Medianabmessungen aller Bilder dimensioniert. * Der `cornerRadius` wird auf die gesamte finale Ausgabe angewendet, nicht auf einzelne Bilder. * Die Leinwandgröße ist durch die Serverkonfiguration `MAX_CANVAS_PIXELS` begrenzt, um eine Speichererschöpfung zu verhindern. --- --- url: https://docs.snapotter.com/sv/tools/image/image-enhancement.md description: >- Automatisk förbättring med ett klick som analyserar en bild och korrigerar exponering, kontrast, vitbalans, mättnad och skärpa. --- # Bildförbättring {#image-enhancement} Automatisk förbättring med ett klick och smart analys. Analyserar bilden och tillämpar korrigeringar för exponering, kontrast, vitbalans, mättnad, skärpa och brusreducering. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **Bearbetning:** Synkron (använder fabriken `createToolRoute`, returnerar resultatet direkt) **Modellpaket:** Inget krävs för grundläggande förbättring. Paketet `upscale-enhance` (5-6 GB) används endast när `deepEnhance` är aktiverat (för AI-brusreducering via SCUNet). ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bildfil (multipart) | | mode | string | Nej | `"auto"` | Förbättringsläge: `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | Nej | `50` | Total förbättringsintensitet (0-100) | | corrections | object | Nej | alla `true` | Selektiva korrigeringar att tillämpa (se nedan) | | deepEnhance | boolean | Nej | `false` | Aktivera AI-driven brusreducering (kräver att verktyget `noise-removal` är installerat) | ### Korrigeringsobjekt {#corrections-object} | Fält | Typ | Standard | Beskrivning | |-------|------|---------|-------------| | exposure | boolean | `true` | Korrigera exponering automatiskt | | contrast | boolean | `true` | Korrigera kontrast automatiskt | | whiteBalance | boolean | `true` | Korrigera vitbalans automatiskt | | saturation | boolean | `true` | Korrigera mättnad automatiskt | | sharpness | boolean | `true` | Skärp automatiskt | | denoise | boolean | `true` | Lätt brusreducering | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Svar (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Analysslutpunkt {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Analyserar en bild och returnerar korrigeringsrekommendationer utan att tillämpa dem. ### Parametrar {#parameters-1} | Parameter | Typ | Obligatorisk | Beskrivning | |-----------|------|----------|-------------| | file | file | Ja | Bildfil (multipart) | ### Exempelbegäran {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Svar (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Anmärkningar {#notes} * Detta verktyg använder den synkrona fabriken `createToolRoute`, så det returnerar ett standardsvar (inte 202 asynkront). * Parametern `mode` justerar hur korrigeringar viktas (t.ex. är porträttläget mildare mot hudtoner, landskapsläget höjer mättnaden). * När `deepEnhance` är aktiverat och verktyget `noise-removal` (SCUNet) är installerat tillämpas en extra AI-brusreduceringsomgång efter standardkorrigeringarna. * Analysslutpunkten är användbar för att förhandsgranska vilka korrigeringar som skulle tillämpas innan man bekräftar. * Stöder HEIC/HEIF, RAW, TGA, PSD, EXR och HDR som inmatningsformat via automatisk avkodning. --- --- url: https://docs.snapotter.com/de/tools/image/resize.md description: Ändere die Größe von Bildern nach Pixeln, Prozent oder mit Anpassungsmodi. --- # Bildgröße ändern {#resize} Ändere die Größe von Bildern durch Angabe exakter Pixelabmessungen, eines prozentualen Skalierungsfaktors oder eines Anpassungsmodus, der steuert, wie sich das Bild an die Zielabmessungen anpasst. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/resize` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | width | integer | Nein | - | Zielbreite in Pixeln (maximal 16383) | | height | integer | Nein | - | Zielhöhe in Pixeln (maximal 16383) | | fit | string | Nein | `"contain"` | Wie das Bild an die Abmessungen angepasst wird: `contain`, `cover`, `fill`, `inside`, `outside` | | withoutEnlargement | boolean | Nein | `false` | Hochskalieren verhindern, wenn das Bild kleiner als das Ziel ist | | percentage | number | Nein | - | Nach Prozent skalieren (z. B. 50 für halbe Größe) | Mindestens eines von `width`, `height` oder `percentage` muss angegeben werden. ### Anpassungsmodi {#fit-modes} * **contain** - Größe so ändern, dass das Bild in die Abmessungen passt, unter Beibehaltung des Seitenverhältnisses (kann Leerraum lassen) * **cover** - Größe so ändern, dass das Bild die Abmessungen ausfüllt, unter Beibehaltung des Seitenverhältnisses (kann zuschneiden) * **fill** - Genau auf die Abmessungen strecken (ignoriert das Seitenverhältnis) * **inside** - Wie `contain`, aber nur herunterskalieren, niemals hochskalieren * **outside** - Wie `cover`, aber nur herunterskalieren, niemals hochskalieren ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"width": 800, "height": 600, "fit": "contain"}' ``` Nach Prozent skalieren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"percentage": 50}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 980000 } ``` ## Hinweise {#notes} * Die maximale Abmessung beträgt 16383 Pixel auf jeder Achse (Grenze von Sharp/libvips). * Das Ausgabeformat entspricht dem Eingabeformat. HEIC-, RAW-, PSD- und SVG-Eingaben werden vor der Verarbeitung automatisch dekodiert. * Die EXIF-Orientierung wird vor der Größenänderung automatisch angewendet. * Das Flag `withoutEnlargement` ist nützlich für die Stapelverarbeitung, bei der einige Bilder bereits kleiner als das Ziel sein können. --- --- url: https://docs.snapotter.com/sv/tools/image/info.md description: Visa detaljerad bildmetadata, egenskaper och histogramstatistik per kanal. --- # Bildinformation {#image-info} Skrivskyddat analysverktyg som returnerar omfattande bildmetadata inklusive dimensioner, format, färgrymd, förekomst av EXIF/ICC/XMP och histogramstatistik per kanal. Producerar ingen bearbetad utdatafil. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/info` Tar emot multipart-formulärdata med en bildfil. Inget inställningsfält behövs. ## Parametrar {#parameters} Detta verktyg har inga konfigurerbara parametrar. Ladda bara upp bildfilen. | Fält | Typ | Obligatorisk | Beskrivning | |-------|------|----------|-------------| | file | file | Ja | Bilden att analysera | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/info \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Exempelsvar {#example-response} ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "orientation": 1, "hasProfile": true, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` ## Svarsfält {#response-fields} | Fält | Typ | Beskrivning | |-------|------|-------------| | filename | string | Rensat filnamn | | fileSize | number | Filstorlek i byte | | width | number | Bildbredd i pixlar | | height | number | Bildhöjd i pixlar | | format | string | Upptäckt format (jpeg, png, webp osv.) | | channels | number | Antal färgkanaler | | hasAlpha | boolean | Om bilden har en alfakanal | | colorSpace | string | Färgrymd (srgb, cmyk osv.) | | density | number eller null | DPI/PPI-upplösning | | isProgressive | boolean | Om JPEG använder progressiv kodning | | orientation | number eller null | EXIF-orienteringsvärde (1-8) | | hasProfile | boolean | Om en ICC-profil är inbäddad | | hasExif | boolean | Om EXIF-metadata finns | | hasIcc | boolean | Om en ICC-färgprofil finns | | hasXmp | boolean | Om XMP-metadata finns | | bitDepth | string eller null | Bitar per sampel | | pages | number | Antal sidor (för flersidiga format som TIFF, GIF) | | histogram | array | Statistik per kanal (min, max, medelvärde, standardavvikelse) | ## Anmärkningar {#notes} * Detta är en skrivskyddad slutpunkt. Den producerar ingen nedladdningsbar utdatafil eller `jobId`. * För RAW-formatbilder (DNG, CR2, NEF, ARW osv.) används ExifTool för att extrahera verkliga sensordimensioner och metadataflaggor som Sharp inte kan läsa direkt. * HEIC/HEIF-filer avkodas internt till PNG för att extrahera pixelstatistik, eftersom Sharp inte kan avkoda HEVC-pixlar. * Histogrammet tillhandahåller min/max/medelvärde/stdav per kanal, inte en fullständig 256-bins fördelning. * Fältet `density` återspeglar den inbäddade DPI-metadatan, om den finns. --- --- url: https://docs.snapotter.com/de/tools/image/info.md description: >- Zeigt detaillierte Bildmetadaten, Eigenschaften und Histogrammstatistiken pro Kanal an. --- # Bildinformationen {#image-info} Schreibgeschütztes Analysewerkzeug, das umfassende Bildmetadaten zurückgibt, darunter Abmessungen, Format, Farbraum, das Vorhandensein von EXIF/ICC/XMP und Histogrammstatistiken pro Kanal. Erzeugt keine verarbeitete Ausgabedatei. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/info` Akzeptiert Multipart-Formulardaten mit einer Bilddatei. Es ist kein Einstellungsfeld erforderlich. ## Parameter {#parameters} Dieses Werkzeug hat keine konfigurierbaren Parameter. Laden Sie einfach die Bilddatei hoch. | Feld | Typ | Erforderlich | Beschreibung | |-------|------|----------|-------------| | file | file | Ja | Das zu analysierende Bild | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/info \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Beispielantwort {#example-response} ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "orientation": 1, "hasProfile": true, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` ## Antwortfelder {#response-fields} | Feld | Typ | Beschreibung | |-------|------|-------------| | filename | string | Bereinigter Dateiname | | fileSize | number | Dateigröße in Bytes | | width | number | Bildbreite in Pixeln | | height | number | Bildhöhe in Pixeln | | format | string | Erkanntes Format (jpeg, png, webp usw.) | | channels | number | Anzahl der Farbkanäle | | hasAlpha | boolean | Ob das Bild einen Alphakanal hat | | colorSpace | string | Farbraum (srgb, cmyk usw.) | | density | number oder null | DPI/PPI-Auflösung | | isProgressive | boolean | Ob JPEG progressive Codierung verwendet | | orientation | number oder null | EXIF-Ausrichtungswert (1-8) | | hasProfile | boolean | Ob ein ICC-Profil eingebettet ist | | hasExif | boolean | Ob EXIF-Metadaten vorhanden sind | | hasIcc | boolean | Ob ein ICC-Farbprofil vorhanden ist | | hasXmp | boolean | Ob XMP-Metadaten vorhanden sind | | bitDepth | string oder null | Bits pro Sample | | pages | number | Anzahl der Seiten (bei mehrseitigen Formaten wie TIFF, GIF) | | histogram | array | Statistiken pro Kanal (Minimum, Maximum, Mittelwert, Standardabweichung) | ## Hinweise {#notes} * Dies ist ein schreibgeschützter Endpunkt. Er erzeugt keine herunterladbare Ausgabedatei und keine `jobId`. * Bei Bildern im RAW-Format (DNG, CR2, NEF, ARW usw.) wird ExifTool verwendet, um die tatsächlichen Sensorabmessungen und Metadaten-Flags zu extrahieren, die Sharp nicht direkt lesen kann. * HEIC/HEIF-Dateien werden intern zu PNG decodiert, um Pixelstatistiken zu extrahieren, da Sharp HEVC-Pixel nicht decodieren kann. * Das Histogramm liefert Minimum/Maximum/Mittelwert/Standardabweichung pro Kanal, nicht eine vollständige Verteilung mit 256 Bins. * Das Feld `density` gibt die eingebetteten DPI-Metadaten wieder, sofern vorhanden. --- --- url: https://docs.snapotter.com/sv/tools/image/compare.md description: >- Jämför två bilder sida vid sida med diffvisualisering på pixelnivå och likhetspoäng. --- # Bildjämförelse {#image-compare} Ladda upp två bilder för att beräkna en skillnadskarta på pixelnivå och en numerisk likhetsprocent. Utdatan är en diffbild som markerar ändrade områden i rött. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/compare` Tar emot multipart-formulärdata med **två** bildfiler. Inget inställningsfält behövs. ## Parametrar {#parameters} Detta verktyg har inga konfigurerbara parametrar. Ladda upp exakt två bildfiler. | Fält | Typ | Obligatorisk | Beskrivning | |-------|------|----------|-------------| | file (första) | file | Ja | Den första bilden | | file (andra) | file | Ja | Den andra bilden | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Svarsfält {#response-fields} | Fält | Typ | Beskrivning | |-------|------|-------------| | jobId | string | Jobbidentifierare för att ladda ner diffbilden | | similarity | number | Procentuell likhet mellan de två bilderna (0 till 100) | | dimensions | object | Bredd och höjd som används för jämförelsen | | downloadUrl | string | URL för att ladda ner den genererade diffbilden | | originalSize | number | Sammanlagd storlek på båda indatabilderna i byte | | processedSize | number | Storlek på diffutdatabilden i byte | ## Anteckningar {#notes} * Båda bilderna storleksändras till samma dimensioner (maxvärdet för respektive axel) före jämförelsen. * Diffbilden markerar skillnader i rött med en opacitet som är proportionell mot ändringens storlek. Identiska eller nästan identiska pixlar (skillnad < 10) visas som halvtransparenta versioner av originalet. * Likheten beräknas som inversen av den genomsnittliga pixelskillnaden över alla pixlar, uttryckt i procent. * En likhet på 100 % innebär att bilderna är pixelidentiska (vid jämförelseupplösningen). * Diffutdatan är alltid i PNG-format oavsett indataformat. * Båda bilderna valideras och avkodas (HEIC, RAW, PSD, SVG stöds) före jämförelsen. * EXIF-orientering tillämpas automatiskt på båda bilderna före bearbetning. --- --- url: https://docs.snapotter.com/de/tools/image/compose.md description: >- Legt Bilder mit Position, Deckkraft und Mischmodi für die Komposition übereinander. --- # Bildkomposition {#image-composition} Legt ein Overlay-Bild mit konfigurierbarer Position, Deckkraft und Mischmodus über ein Basisbild. Nützlich zum Zusammenstellen von Logos, Grafiken oder zum Kombinieren mehrerer Bilder. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/compose` Akzeptiert Multipart-Formulardaten mit **zwei** Bilddateien und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | x | number | Nein | `0` | Horizontaler Versatz des Overlays von der oberen linken Ecke in Pixeln (min. 0) | | y | number | Nein | `0` | Vertikaler Versatz des Overlays von der oberen linken Ecke in Pixeln (min. 0) | | opacity | number | Nein | `100` | Deckkraft des Overlays in Prozent (0 bis 100) | | blendMode | string | Nein | `"over"` | Mischmodus für die Komposition | ### Mischmodi {#blend-modes} | Wert | Beschreibung | |-------|-------------| | `over` | Normales Overlay (Standard) | | `multiply` | Abdunkeln durch Multiplizieren der Pixelwerte | | `screen` | Aufhellen durch Invertieren, Multiplizieren und erneutes Invertieren | | `overlay` | Kombiniert Multiplizieren und Negativ multiplizieren je nach Helligkeit des Basisbildes | | `darken` | Behält das dunklere Pixel jeder Ebene | | `lighten` | Behält das hellere Pixel jeder Ebene | | `hard-light` | Starkes Kontrast-Overlay | | `soft-light` | Dezentes Kontrast-Overlay | | `difference` | Absolute Differenz zwischen den Ebenen | | `exclusion` | Ähnlich wie Differenz, aber mit geringerem Kontrast | ### Dateifelder {#file-fields} | Feldname | Erforderlich | Beschreibung | |------------|----------|-------------| | file | Ja | Das Basis-/Hintergrundbild | | overlay | Ja | Das Overlay-/Vordergrundbild | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Mit dem Mischmodus Multiplizieren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Hinweise {#notes} * Beide Bilder werden vor der Komposition validiert und dekodiert (HEIC, RAW, PSD, SVG werden unterstützt). * Das Overlay wird an den exakten Pixelkoordinaten platziert, die durch `x` und `y` angegeben werden. Es wird nicht passend skaliert. * Ist die Deckkraft kleiner als 100, wird vor dem Mischen eine Alphamaske auf das Overlay angewendet. * Das Overlay kann über die Grenzen des Basisbildes hinausragen (es wird dann beschnitten). * Die EXIF-Ausrichtung wird vor der Verarbeitung automatisch auf beide Bilder angewendet. * Die Ausgabeabmessungen entsprechen den Abmessungen des Basisbildes. --- --- url: https://docs.snapotter.com/sv/tools/image/compose.md description: Skikta bilder med position, opacitet och blandningslägen för komposition. --- # Bildkomposition {#image-composition} Lägg en överliggande bild ovanpå en basbild med konfigurerbar position, opacitet och blandningsläge. Användbart för att komponera logotyper, grafik eller kombinera flera bilder. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/compose` Tar emot multipart-formulärdata med **två** bildfiler och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | x | number | Nej | `0` | Horisontell förskjutning av överlägget från det övre vänstra hörnet i pixlar (min 0) | | y | number | Nej | `0` | Vertikal förskjutning av överlägget från det övre vänstra hörnet i pixlar (min 0) | | opacity | number | Nej | `100` | Överläggets opacitet i procent (0 till 100) | | blendMode | string | Nej | `"over"` | Blandningsläge för komposition | ### Blandningslägen {#blend-modes} | Värde | Beskrivning | |-------|-------------| | `over` | Normalt överlägg (standard) | | `multiply` | Mörka genom att multiplicera pixelvärden | | `screen` | Ljusa genom att invertera, multiplicera och invertera igen | | `overlay` | Kombinerar multiplicera och rastrera baserat på basens ljusstyrka | | `darken` | Behåll den mörkare pixeln från varje lager | | `lighten` | Behåll den ljusare pixeln från varje lager | | `hard-light` | Starkt kontrastöverlägg | | `soft-light` | Subtilt kontrastöverlägg | | `difference` | Absolut skillnad mellan lager | | `exclusion` | Liknar skillnad men med lägre kontrast | ### Filfält {#file-fields} | Fältnamn | Obligatorisk | Beskrivning | |------------|----------|-------------| | file | Ja | Bas-/bakgrundsbilden | | overlay | Ja | Överläggs-/förgrundsbilden | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Med blandningsläget multiplicera: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Anteckningar {#notes} * Båda bilderna valideras och avkodas (HEIC, RAW, PSD, SVG stöds) före komposition. * Överlägget placeras vid de exakta pixelkoordinater som anges av `x` och `y`. Det storleksändras inte för att passa. * Om opaciteten är mindre än 100 tillämpas en alfamask på överlägget före blandning. * Överlägget kan sträcka sig utanför basbildens gränser (det kommer att beskäras). * EXIF-orientering tillämpas automatiskt på båda bilderna före bearbetning. * Utdatans dimensioner matchar basbildens dimensioner. --- --- url: https://docs.snapotter.com/de/tools/image/edit-metadata.md description: >- Bearbeitet EXIF-, IPTC-, GPS- und XMP-Metadatenfelder in Bildern, ohne die Pixel neu zu kodieren. --- # Bildmetadaten bearbeiten {#edit-metadata} Bearbeitet Bildmetadatenfelder einschließlich EXIF, IPTC, GPS-Koordinaten, Daten und Schlüsselwörter. Verwendet ExifTool im Hintergrund, sodass Metadaten direkt geschrieben werden, ohne die Pixel neu zu kodieren, wodurch die volle Bildqualität erhalten bleibt. ## API-Endpunkte {#api-endpoints} ### Metadaten bearbeiten {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Schreibt Metadatenfelder in das Bild und gibt die geänderte Datei zurück. ### Metadaten prüfen {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Gibt die vollständigen Metadaten des Bildes über ExifTool als JSON zurück. Verändert das Bild nicht. ## Parameter (Bearbeiten) {#parameters-edit} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | title | string | Nein | - | Bildtitel (XMP/EXIF) | | author | string | Nein | - | Name des Autors | | artist | string | Nein | - | Name des Künstlers (EXIF-Artist-Tag) | | copyright | string | Nein | - | Urheberrechtshinweis | | imageDescription | string | Nein | - | Bildbeschreibung (EXIF) | | software | string | Nein | - | Software-Tag | | dateTime | string | Nein | - | EXIF-DateTime-Wert | | dateTimeOriginal | string | Nein | - | EXIF-DateTimeOriginal-Wert | | setAllDates | string | Nein | - | Alle Datumsfelder auf einmal setzen | | dateShift | string | Nein | - | Alle Daten um einen Versatz verschieben (Format: `+HH:MM` oder `-HH:MM`) | | clearGps | boolean | Nein | `false` | Alle GPS-Daten entfernen | | gpsLatitude | number | Nein | - | GPS-Breitengrad setzen (-90 bis 90) | | gpsLongitude | number | Nein | - | GPS-Längengrad setzen (-180 bis 180) | | gpsAltitude | number | Nein | - | GPS-Höhe in Metern setzen | | keywords | string\[] | Nein | - | Hinzuzufügende oder zu setzende Schlüsselwörter/Tags | | keywordsMode | string | Nein | `"add"` | Umgang mit Schlüsselwörtern: `add` (anhängen) oder `set` (ersetzen) | | fieldsToRemove | string\[] | Nein | `[]` | Liste bestimmter zu entfernender Metadatenfeldnamen | | iptcTitle | string | Nein | - | IPTC Object Name | | iptcHeadline | string | Nein | - | IPTC Headline | | iptcCity | string | Nein | - | IPTC City | | iptcState | string | Nein | - | IPTC Province/State | | iptcCountry | string | Nein | - | IPTC Country | ## Beispielanfrage {#example-request} Autor und Urheberrecht setzen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` GPS-Koordinaten setzen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` GPS entfernen und Schlüsselwörter hinzufügen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Metadaten prüfen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Beispielantwort (Bearbeiten) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Hinweise {#notes} * Dieses Werkzeug erfordert, dass ExifTool auf dem Server installiert ist. Es ist im Docker-Image enthalten. * Metadaten werden direkt geschrieben, sodass keine erneute Pixelkodierung erfolgt. Die Änderung der Dateigröße ist minimal (nur die Metadaten-Bytes). * Der Parameter `dateShift` verschiebt alle Datumsfelder um den angegebenen Versatz, was zur Korrektur von Zeitzonenfehlern nützlich ist (z. B. `+02:00` oder `-05:30`). * Werden keine Änderungen angefordert (alle Parameter weggelassen oder leer), wird die Originaldatei unverändert zurückgegeben. * Unterstützte Formate: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * Für Formate, die nicht im Browser vorschaubar sind (HEIF, TIFF), enthält die Antwort ein Feld `previewUrl` mit einer WebP-Vorschau. --- --- url: https://docs.snapotter.com/de/tools/image/strip-metadata.md description: >- EXIF-, GPS-, ICC- und XMP-Metadaten aus Bildern entfernen, für mehr Datenschutz und kleinere Dateigrößen. --- # Bildmetadaten entfernen {#remove-metadata} Entfernt EXIF-, GPS-, ICC-Farbprofile und XMP-Metadaten aus Bildern. Nützlich für den Datenschutz (Entfernen von GPS-Koordinaten, Kamerainformationen) und zur Reduzierung der Dateigröße. ## API-Endpunkte {#api-endpoints} ### Metadaten entfernen {#strip-metadata} `POST /api/v1/tools/image/strip-metadata` Verarbeitet das Bild und gibt eine bereinigte Version zurück, aus der die ausgewählten Metadaten entfernt wurden. ### Metadaten prüfen {#inspect-metadata} `POST /api/v1/tools/image/strip-metadata/inspect` Gibt die geparsten Metadaten als JSON zurück, ohne das Bild zu verändern. Nützlich, um vor dem Entfernen zu prüfen, welche Metadaten vorhanden sind. ## Parameter (Entfernen) {#parameters-strip} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | stripExif | boolean | Nein | `false` | EXIF-Daten entfernen (Kameraeinstellungen, Datumsangaben usw.) | | stripGps | boolean | Nein | `false` | Nur GPS-/Standortdaten entfernen | | stripIcc | boolean | Nein | `false` | ICC-Farbprofil entfernen | | stripXmp | boolean | Nein | `false` | XMP-Metadaten entfernen (Adobe, IPTC) | | stripAll | boolean | Nein | `true` | Alle Metadaten auf einmal entfernen | Wenn `stripAll` den Wert `true` hat, überschreibt es die einzelnen Flags und entfernt alles. ## Beispielanfrage {#example-request} Alle Metadaten entfernen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": true}' ``` Nur GPS-Daten entfernen (Kamerainformationen und Farbprofil behalten): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": false, "stripGps": true}' ``` Metadaten prüfen, ohne zu verändern: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Beispielantwort (Entfernen) {#example-response-strip} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Beispielantwort (Prüfen) {#example-response-inspect} ```json { "filename": "photo.jpg", "fileSize": 2450000, "exif": { "Make": "Canon", "Model": "EOS R5", "DateTimeOriginal": "2024:03:15 14:30:00", "ExposureTime": "1/250", "FNumber": 2.8, "ISO": 400 }, "gps": { "GPSLatitudeRef": "N", "GPSLatitude": [37, 46, 30], "_latitude": 37.775, "_longitude": -122.4183 }, "icc": { "Profile Size": "3144 bytes", "Color Space": "RGB", "Description": "sRGB IEC61966-2.1" }, "xmp": { "CreatorTool": "Adobe Photoshop 25.0" } } ``` ## Hinweise {#notes} * Das Bild wird nach dem Entfernen in seinem ursprünglichen Format neu kodiert. JPEG verwendet mozjpeg bei Qualität 90, PNG verwendet Kompressionsstufe 9, WebP verwendet Qualität 85. * Das Entfernen von ICC-Profilen kann subtile Farbverschiebungen verursachen, wenn das Bild mit einem Nicht-sRGB-Profil versehen war. Verwenden Sie `stripIcc: false`, wenn Farbgenauigkeit wichtig ist. * Der Prüf-Endpunkt wandelt GPS-Koordinaten der Bequemlichkeit halber in dezimale Werte für Breiten-/Längengrad um (mit einem Unterstrich als Präfix). * Unterstützte Eingabeformate: JPEG, PNG, WebP, AVIF, TIFF, GIF. --- --- url: https://docs.snapotter.com/sv/api/image-engine.md description: >- Referens för bildmotorns operationer. Alla Sharp-baserade bildbehandlingsoperationer och deras parametrar. --- # Bildmotor {#image-engine} Paketet `@snapotter/image-engine` hanterar alla bildoperationer som inte är AI-baserade. Det omsluter [Sharp](https://sharp.pixelplumbing.com/) och körs helt i processen utan externa beroenden. ## Operationer {#operations} ### resize {#resize} Skala en bild till specifika dimensioner eller med procentandel. | Parameter | Typ | Beskrivning | |---|---|---| | `width` | number | Målbredd i pixlar | | `height` | number | Målhöjd i pixlar | | `fit` | string | `cover`, `contain`, `fill`, `inside` eller `outside` | | `withoutEnlargement` | boolean | Om sant kommer mindre bilder inte att skalas upp | | `percentage` | number | Skala med procentandel i stället för absoluta dimensioner | Du kan ange `width`, `height` eller båda. Om du bara anger den ena beräknas den andra för att bibehålla bildförhållandet. ### crop {#crop} Klipp ut ett rektangulärt område från bilden. | Parameter | Typ | Beskrivning | |---|---|---| | `left` | number | X-förskjutning från vänsterkanten | | `top` | number | Y-förskjutning från överkanten | | `width` | number | Bredd på beskärningsområdet | | `height` | number | Höjd på beskärningsområdet | | `unit` | string | `px` (standard) eller `percent` | ### rotate {#rotate} Rotera bilden med en angiven vinkel. | Parameter | Typ | Beskrivning | |---|---|---| | `angle` | number | Rotationsvinkel i grader (0-360) | | `background` | string | Fyllnadsfärg för exponerat område (standard: `#000000`). Gäller endast vinklar som inte är 90 grader. | ### flip {#flip} Spegla bilden horisontellt, vertikalt eller båda. Minst en måste vara sann. | Parameter | Typ | Beskrivning | |---|---|---| | `horizontal` | boolean | Spegla från vänster till höger | | `vertical` | boolean | Spegla från topp till botten | ### convert {#convert} Ändra bildformatet. | Parameter | Typ | Beskrivning | |---|---|---| | `format` | string | Målformat: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `jxl`, `heic`, `heif`, `bmp`, `ico`, `jp2`, `qoi` | | `quality` | number | Komprimeringskvalitet (1-100, gäller förlustbehäftade format) | De första sju formaten (`jpg` till och med `jxl`) kodas av Sharp i processen. De återstående formaten använder externa kodare på API-lagret: `heic`/`heif` via heif-enc, `bmp`/`ico` via ImageMagick, `jp2` via opj\_compress och `qoi` via en inbäddad TypeScript-codec. ### compress {#compress} Minska filstorleken samtidigt som samma format behålls. | Parameter | Typ | Beskrivning | |---|---|---| | `quality` | number | Målkvalitet (1-100) | | `targetSizeBytes` | number | Valfri målfilstorlek i byte | | `format` | string | Valfri åsidosättning av format | ### strip-metadata {#strip-metadata} Ta bort EXIF-, IPTC-, XMP- och ICC-metadata från bilden. Utan parametrar (eller `stripAll: true`) tas allt bort. Skicka enskilda flaggor för selektiv borttagning. | Parameter | Typ | Beskrivning | |---|---|---| | `stripAll` | boolean | Ta bort all metadata (standard när inga flaggor är satta) | | `stripExif` | boolean | Ta bort EXIF-data (inklusive GPS om `stripGps` inte är separat satt) | | `stripGps` | boolean | Ta bort GPS-platsdata | | `stripIcc` | boolean | Ta bort ICC-färgprofil | | `stripXmp` | boolean | Ta bort XMP-metadata | ### Färgjusteringar {#color-adjustments} Dessa operationer ändrar en bilds färgegenskaper. Var och en tar ett enda numeriskt värde. | Operation | Parameter | Intervall | Beskrivning | |---|---|---|---| | `brightness` | `value` | -100 till 100 | Justera ljusstyrka | | `contrast` | `value` | -100 till 100 | Justera kontrast | | `saturation` | `value` | -100 till 100 | Justera färgmättnad | ### Färgfilter {#color-filters} Dessa tillämpar en fast färgtransformation. De tar inga parametrar. | Operation | Beskrivning | |---|---| | `grayscale` | Konvertera till gråskala | | `sepia` | Tillämpa en sepiaton | | `invert` | Invertera alla färger | ### Färgkanaler {#color-channels} Justera enskilda RGB-färgkanaler. Värden är multiplikatorer där 100 = ingen förändring. | Parameter | Typ | Beskrivning | |---|---|---| | `red` | number | Multiplikator för röd kanal (0 till 200, 100 = oförändrad) | | `green` | number | Multiplikator för grön kanal (0 till 200, 100 = oförändrad) | | `blue` | number | Multiplikator för blå kanal (0 till 200, 100 = oförändrad) | ### sharpen {#sharpen} Enkel skärpning som styrs av ett enda värde. | Parameter | Typ | Beskrivning | |---|---|---| | `value` | number | Skärpningsintensitet (0 till 100). Mappas till ett gaussiskt sigma på 0,5-10. | ### sharpen-advanced {#sharpen-advanced} Avancerad skärpning med tre valbara metoder och ett valfritt förpass för brusreducering. | Parameter | Typ | Beskrivning | |---|---|---| | `method` | string | `adaptive`, `unsharp-mask` eller `high-pass` | | `sigma` | number | Radie för gaussisk oskärpa, 0,5-10 (adaptiv) | | `m1` | number | Skärpning av jämna ytor, 0-10 (adaptiv) | | `m2` | number | Skärpning av texturerade ytor, 0-20 (adaptiv) | | `x1` | number | Tröskel för jämnt/ojämnt, 0-10 (adaptiv) | | `y2` | number | Max upplysning (halobegränsning), 0-50 (adaptiv) | | `y3` | number | Max nedmörkning (halobegränsning), 0-50 (adaptiv) | | `amount` | number | Intensitetsprocent, 0-500 (unsharp-mask) | | `radius` | number | Oskärperadie, 0,1-5,0 (unsharp-mask) | | `threshold` | number | Minsta kantljusstyrka, 0-255 (unsharp-mask) | | `strength` | number | Blandningsstyrka, 0-100 (high-pass) | | `kernelSize` | number | `3` eller `5` för 3x3-/5x5-kärna (high-pass) | | `denoise` | string | Förpass för brusreducering: `off`, `light`, `medium` eller `strong` | Parametrarna är metodspecifika. Ange endast de som är relevanta för den valda metoden. ### color-blindness {#color-blindness} Simulera en färgseendedefekt med hjälp av en 3x3-matris för färgrekombination. | Parameter | Typ | Beskrivning | |---|---|---| | `type` | string | En av: `protanopia`, `deuteranopia`, `tritanopia`, `protanomaly`, `deuteranomaly`, `tritanomaly`, `achromatopsia`, `blueConeMonochromacy` | ### edit-metadata {#edit-metadata} Skriv eller ta bort enskilda EXIF-/IPTC-metadatafält utan att ta bort hela blocket. | Parameter | Typ | Beskrivning | |---|---|---| | `artist` | string | EXIF Artist-tagg | | `copyright` | string | EXIF Copyright-tagg | | `imageDescription` | string | EXIF ImageDescription-tagg | | `software` | string | EXIF Software-tagg | | `dateTime` | string | EXIF DateTime-tagg | | `dateTimeOriginal` | string | EXIF DateTimeOriginal-tagg | | `clearGps` | boolean | Ta bort alla GPS-taggar | | `fieldsToRemove` | string\[] | Lista över EXIF-fältnamn att radera | Alla parametrar är valfria. Fält som listas i `fieldsToRemove` raderas från det befintliga EXIF-blocket. Fält som anges via de namngivna parametrarna skrivs (eller skrivs över). Binära/osäkra nycklar som MakerNote ignoreras tyst. ## Formatidentifiering {#format-detection} Motorn identifierar automatiskt indataformat från filhuvuden, inte bara från filändelser. Det innebär att en `.jpg`-fil som egentligen är en PNG hanteras korrekt. Identifieringen använder en flerlagersansats: magiska byte först, sedan filändelse som reserv. SnapOtter stöder **55+ indataformat** och **13 utdataformat**, inklusive 23 kamera-RAW-format från 20+ märken, professionella format (PSD, EPS, OpenEXR, HDR), moderna codecs (JPEG XL, AVIF, HEIC, QOI, JPEG 2000) och vetenskapliga/spelrelaterade format (FITS, DDS). Avkodning hanteras nativt av Sharp där det är möjligt, med automatisk reserv till ImageMagick, LibRaw och specialiserade CLI-avkodare. Se sidan [Format som stöds](/sv/guide/supported-formats) för den fullständiga listan. ## Metadatautvinning {#metadata-extraction} Verktyget `info` returnerar bildmetadata. Se [Bildinfo](/sv/tools/image/info) för den fullständiga fältreferensen. ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` --- --- url: https://docs.snapotter.com/sv/tools/image/upscale.md description: >- Skala upp bilder 2x till 4x med Real-ESRGAN AI-superupplösning samtidigt som fina detaljer bevaras. --- # Bilduppskalning {#image-upscaling} AI-superupplösningsförbättring med Real-ESRGAN. Skalar upp bilder 2x-4x samtidigt som detaljer bevaras. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/upscale` **Processing:** Asynkron (returnerar 202, avfråga `/api/v1/jobs/{jobId}/progress` för status via SSE) **Model bundle:** `upscale-enhance` (5-6 GB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Bildfil (multipart) | | scale | number | No | `2` | Uppskalningsfaktor (t.ex. 2, 3, 4) | | model | string | No | `"auto"` | Modell att använda (t.ex. `auto`, specifika modellnamn) | | faceEnhance | boolean | No | `false` | Tillämpa ansiktsförbättring under uppskalning | | denoise | number | No | `0` | Brusreduceringsstyrka (0 = av) | | format | string | No | `"auto"` | Utdataformat: `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | No | `95` | Utdatakvalitet (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Notes {#notes} * Kräver att modellpaketet `upscale-enhance` är installerat (5-6 GB). * Använder Real-ESRGAN när det är tillgängligt; faller tillbaka till Lanczos-interpolation om AI-modellen inte är tillgänglig. * Alternativet `faceEnhance` tillämpar GFPGAN-ansiktsåterställning under uppskalning för bättre ansiktskvalitet. * För utdataformat som inte kan förhandsgranskas i webbläsare (HEIC, JXL, TIFF) genereras en WebP-förhandsvisning tillsammans med huvudutdatan. * Stöder indataformaten HEIC/HEIF, RAW, TGA, PSD, EXR och HDR via automatisk avkodning. --- --- url: https://docs.snapotter.com/sv/tools/image/image-pad.md description: >- Fyll ut en bild till ett målbildförhållande med en enfärgad, transparent eller suddig bakgrund. --- # Bildutfyllnad {#image-pad} Fyll ut en bild till ett målbildförhållande genom att lägga till en enfärgad, transparent eller suddig bakgrund runt den. Användbart för att passa in bilder i fasta bildförhållanden för sociala medier eller tryck utan beskärning. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/image-pad` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | target | string | Nej | `"1:1"` | Målbildförhållande: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` eller `custom` | | ratioW | integer | Nej | `1` | Anpassad förhållandebredd (1-100, används när target är `custom`) | | ratioH | integer | Nej | `1` | Anpassad förhållandehöjd (1-100, används när target är `custom`) | | background | string | Nej | `"color"` | Bakgrundsläge: `color`, `transparent` eller `blur` | | color | string | Nej | `"#ffffff"` | Bakgrundens hexfärg (när background är `color`) | | padding | integer | Nej | `0` | Extra utfyllnad som procent av arbetsytan (0-50) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 3100000 } ``` ## Anmärkningar {#notes} * Bakgrundsläget `blur` skapar en suddig kopia av originalbilden som utfyllnadsfyllning, vilket ger ett visuellt sammanhängande resultat. * Vid användning av bakgrunden `transparent` konverteras utdata till PNG för att bevara alfa. * Utdataformatet matchar inmatningsformatet om inte transparens är inblandad. HEIC-, RAW-, PSD- och SVG-inmatningar avkodas automatiskt före bearbetning. * Ange `target` till `custom` och tillhandahåll `ratioW` och `ratioH` för godtyckliga bildförhållanden (t.ex. `ratioW: 3, ratioH: 2` för 3:2). --- --- url: https://docs.snapotter.com/sv/tools/image/watermark-image.md description: >- Lägg en logotyp eller bild som vattenstämpel med konfigurerbar position, opacitet och skala. --- # Bildvattenstämpel {#image-watermark} Lägg en logotyp eller sekundär bild som vattenstämpel på en basbild. Vattenstämpeln skalas i förhållande till basbildens bredd och placeras i ett hörn eller i mitten. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/watermark-image` Tar emot multipart-formulärdata med **två** bildfiler och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | position | string | No | `"bottom-right"` | Placering av vattenstämpel: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` | | opacity | number | No | `50` | Vattenstämpelns opacitet i procent (0 till 100) | | scale | number | No | `25` | Vattenstämpelns bredd som procent av huvudbildens bredd (1 till 100) | ### File Fields {#file-fields} | Field Name | Required | Description | |------------|----------|-------------| | file | Yes | Huvud-/basbilden | | watermark | Yes | Vattenstämpel-/logotypbilden | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "watermark=@logo.png" \ -F 'settings={"position": "bottom-right", "opacity": 60, "scale": 20}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2520000 } ``` ## Notes {#notes} * Båda bilderna valideras och avkodas (HEIC, RAW, PSD, SVG stöds). * Vattenstämpeln storleksändras proportionellt så att dess bredd är lika med `scale` % av huvudbildens bredd. * Opacitet tillämpas via en alfamask som komponeras med blandning `dest-in`. * Hörnpositioner använder en 20px utfyllnad från bildkanten. * Om vattenstämpelbilden har transparens (t.ex. en PNG-logotyp) bevaras den under komponeringen. * EXIF-orientering tillämpas automatiskt på båda bilderna före bearbetning. --- --- url: https://docs.snapotter.com/de/tools/image/image-enhancement.md description: >- Automatische Verbesserung mit einem Klick, die ein Bild analysiert und Belichtung, Kontrast, Weißabgleich, Sättigung und Schärfe korrigiert. --- # Bildverbesserung {#image-enhancement} Automatische Verbesserung mit einem Klick und intelligenter Analyse. Analysiert das Bild und wendet Korrekturen für Belichtung, Kontrast, Weißabgleich, Sättigung, Schärfe und Rauschunterdrückung an. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **Verarbeitung:** Synchron (verwendet die `createToolRoute`-Factory, gibt das Ergebnis direkt zurück) **Modell-Bundle:** Für die grundlegende Verbesserung ist keines erforderlich. Das Bundle `upscale-enhance` (5-6 GB) wird nur verwendet, wenn `deepEnhance` aktiviert ist (für die KI-Rauschunterdrückung über SCUNet). ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bilddatei (Multipart) | | mode | string | Nein | `"auto"` | Verbesserungsmodus: `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | Nein | `50` | Gesamtintensität der Verbesserung (0-100) | | corrections | object | Nein | alle `true` | Selektiv anzuwendende Korrekturen (siehe unten) | | deepEnhance | boolean | Nein | `false` | KI-gestützte Rauschunterdrückung aktivieren (erfordert installiertes `noise-removal`-Werkzeug) | ### Objekt „corrections“ {#corrections-object} | Feld | Typ | Standard | Beschreibung | |-------|------|---------|-------------| | exposure | boolean | `true` | Belichtung automatisch korrigieren | | contrast | boolean | `true` | Kontrast automatisch korrigieren | | whiteBalance | boolean | `true` | Weißabgleich automatisch korrigieren | | saturation | boolean | `true` | Sättigung automatisch korrigieren | | sharpness | boolean | `true` | Automatisch schärfen | | denoise | boolean | `true` | Leichte Rauschunterdrückung | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Antwort (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Analyse-Endpunkt {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Analysiert ein Bild und gibt Korrekturempfehlungen zurück, ohne sie anzuwenden. ### Parameter {#parameters-1} | Parameter | Typ | Erforderlich | Beschreibung | |-----------|------|----------|-------------| | file | file | Ja | Bilddatei (Multipart) | ### Beispielanfrage {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Antwort (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Hinweise {#notes} * Dieses Werkzeug verwendet die synchrone `createToolRoute`-Factory und gibt daher eine standardmäßige Antwort zurück (kein asynchrones 202). * Der Parameter `mode` passt an, wie Korrekturen gewichtet werden (z. B. ist der Porträtmodus sanfter zu Hauttönen, der Landschaftsmodus verstärkt die Sättigung). * Wenn `deepEnhance` aktiviert und das `noise-removal`-Werkzeug (SCUNet) installiert ist, wird nach den Standardkorrekturen ein zusätzlicher KI-Rauschunterdrückungsdurchgang angewendet. * Der Analyse-Endpunkt ist nützlich, um eine Vorschau der Korrekturen zu erhalten, bevor sie angewendet werden. * Unterstützt die Eingabeformate HEIC/HEIF, RAW, TGA, PSD, EXR und HDR über automatische Decodierung. --- --- url: https://docs.snapotter.com/de/tools/image/compare.md description: >- Vergleicht zwei Bilder nebeneinander mit pixelgenauer Diff-Visualisierung und Ähnlichkeitswert. --- # Bildvergleich {#image-compare} Laden Sie zwei Bilder hoch, um eine pixelgenaue Differenzkarte und einen numerischen Ähnlichkeitsprozentsatz zu berechnen. Die Ausgabe ist ein Diff-Bild, das veränderte Bereiche in Rot hervorhebt. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/compare` Akzeptiert Multipart-Formulardaten mit **zwei** Bilddateien. Ein Einstellungsfeld ist nicht erforderlich. ## Parameter {#parameters} Dieses Werkzeug hat keine konfigurierbaren Parameter. Laden Sie genau zwei Bilddateien hoch. | Feld | Typ | Erforderlich | Beschreibung | |-------|------|----------|-------------| | file (erste) | file | Ja | Das erste Bild | | file (zweite) | file | Ja | Das zweite Bild | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Antwortfelder {#response-fields} | Feld | Typ | Beschreibung | |-------|------|-------------| | jobId | string | Auftrags-ID zum Herunterladen des Diff-Bildes | | similarity | number | Prozentuale Ähnlichkeit zwischen den beiden Bildern (0 bis 100) | | dimensions | object | Für den Vergleich verwendete Breite und Höhe | | downloadUrl | string | URL zum Herunterladen des erzeugten Diff-Bildes | | originalSize | number | Kombinierte Größe beider Eingabebilder in Byte | | processedSize | number | Größe des Diff-Ausgabebildes in Byte | ## Hinweise {#notes} * Beide Bilder werden vor dem Vergleich auf dieselben Abmessungen skaliert (das Maximum jeder Achse). * Das Diff-Bild hebt Unterschiede in Rot hervor, mit einer Deckkraft proportional zum Ausmaß der Veränderung. Identische oder nahezu identische Pixel (Differenz < 10) werden als halbtransparente Versionen des Originals dargestellt. * Die Ähnlichkeit wird als Kehrwert der durchschnittlichen Pixeldifferenz über alle Pixel berechnet und als Prozentsatz ausgedrückt. * Eine Ähnlichkeit von 100 % bedeutet, dass die Bilder pixelidentisch sind (bei der Vergleichsauflösung). * Die Diff-Ausgabe ist unabhängig von den Eingabeformaten immer im PNG-Format. * Beide Bilder werden vor dem Vergleich validiert und dekodiert (HEIC, RAW, PSD, SVG werden unterstützt). * Die EXIF-Ausrichtung wird vor der Verarbeitung automatisch auf beide Bilder angewendet. --- --- url: https://docs.snapotter.com/id/tools/image/border.md description: >- Tambahkan bingkai, padding, sudut membulat, dan bayangan jatuh ke gambar dalam urutan yang dapat diprediksi dan dikendalikan. --- # Bingkai & Frame {#border-frame} Tambahkan bingkai, padding, sudut membulat, dan bayangan jatuh ke gambar. Alat ini menerapkan efek dalam urutan: padding, bingkai, radius sudut, lalu bayangan. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | borderWidth | number | Tidak | 10 | Ketebalan bingkai dalam piksel (0 hingga 2000) | | borderColor | string | Tidak | `"#000000"` | Warna bingkai sebagai hex (mis. `#FF0000`) | | padding | number | Tidak | 0 | Padding dalam antara gambar dan bingkai dalam piksel (0 hingga 200) | | paddingColor | string | Tidak | `"#FFFFFF"` | Warna isian padding sebagai hex | | cornerRadius | number | Tidak | 0 | Radius sudut dalam piksel (0 hingga 2000) | | shadow | boolean | Tidak | `false` | Apakah akan menambahkan bayangan jatuh | | shadowBlur | number | Tidak | 15 | Radius blur bayangan (1 hingga 200) | | shadowOffsetX | number | Tidak | 0 | Offset horizontal bayangan (-50 hingga 50) | | shadowOffsetY | number | Tidak | 5 | Offset vertikal bayangan (-50 hingga 50) | | shadowColor | string | Tidak | `"#000000"` | Warna bayangan sebagai hex | | shadowOpacity | number | Tidak | 40 | Persentase opasitas bayangan (0 hingga 100) | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Catatan {#notes} * Menggunakan factory `createToolRoute` standar. Menerima satu berkas gambar melalui unggahan multipart. * Mendukung format input HEIC, RAW, PSD, dan SVG (didekode secara otomatis). * Urutan pemrosesan: padding ditambahkan terlebih dahulu, lalu bingkai membungkus di sekelilingnya, lalu radius sudut diterapkan, lalu bayangan digabungkan. * Ketika `cornerRadius` atau `shadow` diaktifkan, keluaran dipaksa menjadi PNG (terlepas dari format input) untuk mempertahankan transparansi. Format yang mendukung alfa (PNG, WebP, AVIF) mempertahankan format aslinya. * Bayangan sadar bentuk: bayangan mengikuti sudut membulat alih-alih membuat bayangan persegi panjang. * Menetapkan `borderWidth` ke 0 dan hanya menggunakan `cornerRadius` + `shadow` menciptakan efek bayangan membulat tanpa bingkai. --- --- url: https://docs.snapotter.com/hi/tools/image/blur-background.md description: AI का उपयोग करके विषय को तीक्ष्ण रखते हुए पृष्ठभूमि को धुंधला करें। --- # Blur Background {#blur-background} विषय को तीक्ष्ण रखते हुए किसी छवि की पृष्ठभूमि को धुंधला करें। AI मॉडल विषय को अलग करता है, मूल पृष्ठभूमि पर एक ब्लर लागू करता है, और तीक्ष्ण विषय को ऊपर कंपोज़िट करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` एक छवि फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | No | `50` | ब्लर तीव्रता (1-100) | | feather | integer | No | `0` | एज फ़ेदरिंग त्रिज्या (0-20) | | format | string | No | `"png"` | आउटपुट प्रारूप: `png` या `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` `GET /api/v1/jobs/{jobId}/progress` पर SSE के ज़रिए प्रगति ट्रैक करें। जब जॉब पूरा होता है, तो SSE स्ट्रीम डाउनलोड URL के साथ एक `completed` इवेंट उत्सर्जित करता है। ## Notes {#notes} * यह एक AI-संचालित टूल है जो `202 Accepted` लौटाता है और असिंक्रोनस रूप से प्रोसेस करता है। प्रगति अपडेट और अंतिम परिणाम प्राप्त करने के लिए SSE एंडपॉइंट से कनेक्ट करें। * इसके लिए **background-removal** फ़ीचर बंडल का इंस्टॉल होना आवश्यक है। यदि बंडल उपलब्ध नहीं है तो `501` लौटाता है। * उच्च तीव्रता मान एक मज़बूत ब्लर प्रभाव उत्पन्न करते हैं। 80 से ऊपर के मान एक स्पष्ट बोकेह जैसा पृथक्करण बनाते हैं। * HEIC, RAW, PSD, और SVG इनपुट को प्रोसेसिंग से पहले स्वचालित रूप से डिकोड किया जाता है। --- --- url: https://docs.snapotter.com/ja/tools/image/blur-background.md description: AI を使用して、被写体をシャープに保ちながら背景をぼかします。 --- # Blur Background {#blur-background} 被写体をシャープに保ちながら画像の背景をぼかします。AI モデルが被写体を切り出し、元の背景にぼかしを適用して、シャープな被写体を上に合成します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` 画像ファイルと JSON の `settings` フィールドを含むマルチパートフォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | No | `50` | ぼかしの強度 (1 ~ 100) | | feather | integer | No | `0` | エッジのぼかし半径 (0 ~ 20) | | format | string | No | `"png"` | 出力形式: `png` または `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` 進捗は `GET /api/v1/jobs/{jobId}/progress` の SSE で追跡できます。ジョブが完了すると、SSE ストリームがダウンロード URL 付きの `completed` イベントを発行します。 ## Notes {#notes} * これは `202 Accepted` を返し、非同期で処理する AI 対応ツールです。SSE エンドポイントに接続して進捗の更新と最終結果を受け取ってください。 * **background-removal** 機能バンドルのインストールが必要です。バンドルが利用できない場合は `501` を返します。 * 強度の値が高いほど、より強いぼかし効果が得られます。80 を超える値は、ボケのような際立った分離を作り出します。 * HEIC、RAW、PSD、SVG の入力は処理前に自動的にデコードされます。 --- --- url: https://docs.snapotter.com/ko/tools/image/blur-background.md description: AI를 사용하여 피사체를 선명하게 유지하면서 배경을 흐리게 합니다. --- # Blur Background {#blur-background} 피사체를 선명하게 유지하면서 이미지 배경을 흐리게 합니다. AI 모델이 피사체를 분리하고, 원본 배경에 블러를 적용한 후, 선명한 피사체를 그 위에 합성합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/blur-background` 이미지 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | intensity | integer | 아니요 | `50` | 블러 강도 (1-100) | | feather | integer | 아니요 | `0` | 가장자리 페더링 반경 (0-20) | | format | string | 아니요 | `"png"` | 출력 형식: `png` 또는 `webp` | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 진행 상황을 추적할 수 있습니다. 작업이 완료되면 SSE 스트림이 다운로드 URL과 함께 `completed` 이벤트를 발생시킵니다. ## 참고 사항 {#notes} * 이 도구는 `202 Accepted`을(를) 반환하고 비동기적으로 처리하는 AI 기반 도구입니다. 진행 상황 업데이트와 최종 결과를 받으려면 SSE 엔드포인트에 연결하세요. * **background-removal** 기능 번들이 설치되어 있어야 합니다. 번들을 사용할 수 없는 경우 `501`을(를) 반환합니다. * 강도 값이 높을수록 더 강한 블러 효과가 생성됩니다. 80을 초과하는 값은 뚜렷한 보케 같은 분리 효과를 만듭니다. * HEIC, RAW, PSD, SVG 입력은 처리 전에 자동으로 디코딩됩니다. --- --- url: https://docs.snapotter.com/th/tools/image/blur-background.md description: เบลอพื้นหลังในขณะที่ยังคงความคมชัดของวัตถุโดยใช้ AI --- # Blur Background {#blur-background} เบลอพื้นหลังของรูปภาพในขณะที่ยังคงความคมชัดของวัตถุ โมเดล AI จะแยกวัตถุออก, เบลอพื้นหลังเดิม และวางวัตถุที่คมชัดซ้อนทับด้านบน ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` รับข้อมูลแบบ multipart form data พร้อมไฟล์รูปภาพและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | No | `50` | ความเข้มของการเบลอ (1-100) | | feather | integer | No | `0` | รัศมีการเบลอขอบ (0-20) | | format | string | No | `"png"` | รูปแบบเอาต์พุต: `png` หรือ `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ติดตามความคืบหน้าผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` เมื่องานเสร็จสมบูรณ์ สตรีม SSE จะปล่อยเหตุการณ์ `completed` พร้อม URL สำหรับดาวน์โหลด ## Notes {#notes} * นี่เป็นเครื่องมือที่ขับเคลื่อนด้วย AI ซึ่งส่งคืน `202 Accepted` และประมวลผลแบบอะซิงโครนัส เชื่อมต่อกับเอนด์พอยต์ SSE เพื่อรับการอัปเดตความคืบหน้าและผลลัพธ์สุดท้าย * ต้องติดตั้งชุดฟีเจอร์ **background-removal** ส่งคืน `501` หากไม่มีชุดนี้ * ค่าความเข้มที่สูงขึ้นให้เอฟเฟกต์เบลอที่แรงขึ้น ค่าที่สูงกว่า 80 สร้างการแยกแบบโบเก้ที่ชัดเจน * อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนประมวลผล --- --- url: https://docs.snapotter.com/vi/tools/image/blur-background.md description: Làm mờ nền trong khi giữ chủ thể sắc nét bằng AI. --- # Blur Background {#blur-background} Làm mờ nền của một hình ảnh trong khi giữ chủ thể sắc nét. Mô hình AI tách chủ thể, làm mờ nền gốc và ghép chủ thể sắc nét lên trên. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` Chấp nhận dữ liệu biểu mẫu multipart với một tệp hình ảnh và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | No | `50` | Cường độ làm mờ (1-100) | | feather | integer | No | `0` | Bán kính làm mờ viền (0-20) | | format | string | No | `"png"` | Định dạng đầu ra: `png` hoặc `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Theo dõi tiến trình qua SSE tại `GET /api/v1/jobs/{jobId}/progress`. Khi công việc hoàn tất, luồng SSE phát ra một sự kiện `completed` với URL tải xuống. ## Notes {#notes} * Đây là một công cụ dựa trên AI trả về `202 Accepted` và xử lý bất đồng bộ. Kết nối tới endpoint SSE để nhận cập nhật tiến trình và kết quả cuối cùng. * Yêu cầu cài đặt gói tính năng **background-removal**. Trả về `501` nếu gói không có sẵn. * Giá trị cường độ cao hơn tạo hiệu ứng làm mờ mạnh hơn. Giá trị trên 80 tạo sự tách biệt kiểu bokeh rõ rệt. * Các đầu vào HEIC, RAW, PSD và SVG được tự động giải mã trước khi xử lý. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/blur-background.md description: 使用 AI 在保持主体清晰的同时模糊背景。 --- # Blur Background {#blur-background} 在保持主体清晰的同时模糊图像背景。AI 模型会隔离主体,对原始背景应用模糊,然后将清晰的主体合成到上方。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` 接受包含图像文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | 否 | `50` | 模糊强度(1-100) | | feather | integer | 否 | `0` | 边缘羽化半径(0-20) | | format | string | 否 | `"png"` | 输出格式:`png` 或 `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` 通过 `GET /api/v1/jobs/{jobId}/progress` 处的 SSE 跟踪进度。任务完成后,SSE 流会发出一个带下载 URL 的 `completed` 事件。 ## Notes {#notes} * 这是一个 AI 驱动的工具,返回 `202 Accepted` 并异步处理。连接到 SSE 端点以接收进度更新和最终结果。 * 需要安装 **background-removal** 功能包。如果该包不可用,则返回 `501`。 * 更高的强度值会产生更强的模糊效果。超过 80 的值会营造出明显的类似焦外虚化的分离感。 * HEIC、RAW、PSD 和 SVG 输入在处理前会自动解码。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/blur-background.md description: 使用 AI 模糊背景,同時保持主體清晰。 --- # Blur Background {#blur-background} 模糊影像背景,同時保持主體清晰。AI 模型會分離主體、對原始背景套用模糊,並將清晰的主體合成於上層。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` 接受包含影像檔案及 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | No | `50` | 模糊強度(1-100) | | feather | integer | No | `0` | 邊緣羽化半徑(0-20) | | format | string | No | `"png"` | 輸出格式:`png` 或 `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` 可透過 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 追蹤進度。當工作完成時,SSE 串流會發出帶有下載 URL 的 `completed` 事件。 ## Notes {#notes} * 這是一個 AI 驅動的工具,會回傳 `202 Accepted` 並以非同步方式處理。請連線至 SSE 端點以接收進度更新與最終結果。 * 需要安裝 **background-removal** 功能套件。若套件不可用,會回傳 `501`。 * 較高的強度值會產生更強的模糊效果。超過 80 的值會產生明顯的散景般的主體分離感。 * HEIC、RAW、PSD 及 SVG 輸入會在處理前自動解碼。 --- --- url: https://docs.snapotter.com/ar/tools/video/blur-pad.md description: ملء الأشرطة بنسخة مموّهة من الفيديو. --- # Blur Pad {#blur-pad} لائم مقطع فيديو ضمن نسبة أبعاد مستهدفة عن طريق ملء منطقة الحشو بنسخة مموّهة ومُقيَّسة من الفيديو بدلاً من أشرطة بلون خالص. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` يقبل بيانات نموذج multipart تحتوي على ملف فيديو وحقل `settings` بصيغة JSON. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | نسبة الأبعاد المستهدفة: `16:9` أو `9:16` أو `1:1` أو `4:3` أو `3:4` | | blur | number | No | `20` | قيمة sigma للتمويه الغاوسي للخلفية (من 2 إلى 50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * تُنتِج قيم التمويه الأعلى خلفية أنعم وأكثر تجريداً. وتُبقي القيم الأقل مزيداً من التفاصيل مرئية. * إذا كان الفيديو يطابق بالفعل نسبة الأبعاد المستهدفة، يُعاد الملف دون تغيير. * للحشو بلون خالص، استخدم أداة Aspect Pad بدلاً من ذلك. --- --- url: https://docs.snapotter.com/de/tools/video/blur-pad.md description: Balken mit einer unscharfen Kopie des Videos füllen. --- # Blur Pad {#blur-pad} Passen Sie ein Video in ein Zielseitenverhältnis ein, indem Sie den Auffüllbereich mit einer unscharfen, skalierten Kopie des Videos statt mit einfarbigen Balken füllen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Akzeptiert Multipart-Formulardaten mit einer Videodatei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | target | string | Nein | `"16:9"` | Zielseitenverhältnis: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | Nein | `20` | Gaußsches Weichzeichnen-Sigma für den Hintergrund (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Höhere Weichzeichnen-Werte erzeugen einen weicheren, abstrakteren Hintergrund. Niedrigere Werte lassen mehr Details sichtbar. * Wenn das Video bereits dem Zielseitenverhältnis entspricht, wird die Datei unverändert zurückgegeben. * Für einfarbige Auffüllung verwenden Sie stattdessen das Tool Aspect Pad. --- --- url: https://docs.snapotter.com/hi/tools/video/blur-pad.md description: पट्टियों को वीडियो की धुंधली कॉपी से भरें। --- # Blur Pad {#blur-pad} ठोस-रंग की पट्टियों के बजाय पैडिंग क्षेत्र को वीडियो की धुंधली, स्केल की गई कॉपी से भरकर किसी वीडियो को एक लक्षित आस्पेक्ट रेशियो में फिट करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | लक्षित आस्पेक्ट रेशियो: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | No | `20` | बैकग्राउंड के लिए Gaussian blur sigma (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * उच्च blur मान एक नरम, अधिक अमूर्त बैकग्राउंड बनाते हैं। कम मान अधिक विवरण दृश्यमान रखते हैं। * यदि वीडियो पहले से ही लक्षित आस्पेक्ट रेशियो से मेल खाता है, तो फ़ाइल अपरिवर्तित लौटाई जाती है। * ठोस-रंग की पैडिंग के लिए, इसके बजाय Aspect Pad टूल का उपयोग करें। --- --- url: https://docs.snapotter.com/id/tools/video/blur-pad.md description: Isi bilah dengan salinan video yang diburamkan. --- # Blur Pad {#blur-pad} Sesuaikan video ke rasio aspek target dengan mengisi area padding menggunakan salinan video yang diburamkan dan diskalakan alih-alih bilah berwarna solid. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Menerima data form multipart berisi file video dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | Rasio aspek target: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | No | `20` | Sigma blur Gaussian untuk latar belakang (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Nilai blur yang lebih tinggi menghasilkan latar belakang yang lebih lembut dan abstrak. Nilai yang lebih rendah mempertahankan lebih banyak detail yang terlihat. * Jika video sudah cocok dengan rasio aspek target, file dikembalikan tanpa perubahan. * Untuk padding berwarna solid, gunakan alat Aspect Pad. --- --- url: https://docs.snapotter.com/ja/tools/video/blur-pad.md description: 動画のぼかしたコピーでバーを埋めます。 --- # Blur Pad {#blur-pad} 単色のバーの代わりに、ぼかしてスケールした動画のコピーでパディング領域を埋めることで、動画を目標のアスペクト比に合わせます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | 目標のアスペクト比: `16:9`、`9:16`、`1:1`、`4:3`、`3:4` | | blur | number | No | `20` | 背景のガウスぼかしシグマ(2〜50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * ぼかしの値を大きくすると、より柔らかく抽象的な背景になります。値を小さくすると、より多くのディテールが見えたままになります。 * 動画がすでに目標のアスペクト比に一致している場合、ファイルは変更されずに返されます。 * 単色パディングにする場合は、代わりに Aspect Pad ツールを使用してください。 --- --- url: https://docs.snapotter.com/ko/tools/video/blur-pad.md description: 비디오의 흐린 복사본으로 막대를 채웁니다. --- # Blur Pad {#blur-pad} 패딩 영역을 단색 막대 대신 흐리게 처리하고 크기를 조정한 비디오 복사본으로 채워 비디오를 목표 화면비에 맞춥니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` 비디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | 목표 화면비: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | No | `20` | 배경의 가우시안 흐림 sigma(2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * 흐림 값이 높을수록 더 부드럽고 추상적인 배경을 생성합니다. 값이 낮을수록 더 많은 디테일이 보입니다. * 비디오가 이미 목표 화면비와 일치하면 파일이 변경 없이 반환됩니다. * 단색 패딩을 원하면 Aspect Pad 도구를 대신 사용하세요. --- --- url: https://docs.snapotter.com/nl/tools/video/blur-pad.md description: Vul balken met een vervaagde kopie van de video. --- # Blur Pad {#blur-pad} Pas een video in een doelbeeldverhouding door het opvulgebied te vullen met een vervaagde, geschaalde kopie van de video in plaats van balken in een effen kleur. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Accepteert multipart-formuliergegevens met een videobestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | target | string | Nee | `"16:9"` | Doelbeeldverhouding: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | Nee | `20` | Gaussische vervaging-sigma voor de achtergrond (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Hogere vervagingswaarden produceren een zachtere, abstractere achtergrond. Lagere waarden houden meer detail zichtbaar. * Als de video al overeenkomt met de doelbeeldverhouding, wordt het bestand ongewijzigd teruggegeven. * Gebruik voor opvulling in een effen kleur in plaats daarvan het hulpmiddel Aspect Pad. --- --- url: https://docs.snapotter.com/pl/tools/video/blur-pad.md description: Wypełnij pasy rozmytą kopią filmu. --- # Blur Pad {#blur-pad} Dopasuj film do docelowych proporcji obrazu, wypełniając obszar wypełnienia rozmytą, przeskalowaną kopią filmu zamiast jednolitych kolorowych pasów. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Przyjmuje dane formularza multipart z plikiem wideo oraz polem JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | Docelowe proporcje obrazu: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | No | `20` | Sigma rozmycia gaussowskiego dla tła (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Wyższe wartości rozmycia dają bardziej miękkie, bardziej abstrakcyjne tło. Niższe wartości zachowują więcej widocznych szczegółów. * Jeśli film już odpowiada docelowym proporcjom obrazu, plik jest zwracany bez zmian. * Aby uzyskać jednolite kolorowe wypełnienie, użyj zamiast tego narzędzia Aspect Pad. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/blur-pad.md description: Preencha as barras com uma cópia desfocada do vídeo. --- # Blur Pad {#blur-pad} Ajuste um vídeo a uma proporção alvo preenchendo a área de preenchimento com uma cópia desfocada e redimensionada do vídeo, em vez de barras de cor sólida. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | target | string | Não | `"16:9"` | Proporção alvo: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | Não | `20` | Sigma de desfoque gaussiano para o plano de fundo (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Valores de desfoque mais altos produzem um plano de fundo mais suave e abstrato. Valores mais baixos mantêm mais detalhes visíveis. * Se o vídeo já corresponder à proporção alvo, o arquivo é retornado sem alteração. * Para preenchimento de cor sólida, use a ferramenta Aspect Pad. --- --- url: https://docs.snapotter.com/ru/tools/video/blur-pad.md description: Заполнение полос размытой копией видео. --- # Blur Pad {#blur-pad} Впишите видео в целевое соотношение сторон, заполнив область отступов размытой, масштабированной копией видео вместо полос сплошного цвета. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Принимает данные multipart form с видеофайлом и JSON-полем `settings`. ## Parameters {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | target | string | Нет | `"16:9"` | Целевое соотношение сторон: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | Нет | `20` | Сигма гауссова размытия для фона (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Более высокие значения размытия дают более мягкий, более абстрактный фон. Более низкие значения сохраняют больше видимых деталей. * Если видео уже соответствует целевому соотношению сторон, файл возвращается без изменений. * Для заполнения сплошным цветом используйте вместо этого инструмент Aspect Pad. --- --- url: https://docs.snapotter.com/sv/tools/video/blur-pad.md description: Fyll fälten med en suddig kopia av videon. --- # Blur Pad {#blur-pad} Få en video att passa in i ett målbildförhållande genom att fylla utfyllnadsområdet med en suddig, skalad kopia av videon istället för enfärgade fält. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Tar emot multipart-formulärdata med en videofil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | target | string | Nej | `"16:9"` | Målbildförhållande: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | Nej | `20` | Gaussisk oskärpa-sigma för bakgrunden (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Högre oskärpevärden ger en mjukare, mer abstrakt bakgrund. Lägre värden behåller mer synliga detaljer. * Om videon redan matchar målbildförhållandet returneras filen oförändrad. * För enfärgad utfyllnad, använd verktyget Aspect Pad istället. --- --- url: https://docs.snapotter.com/th/tools/video/blur-pad.md description: เติมแถบขอบด้วยสำเนาที่เบลอของวิดีโอ --- # Blur Pad {#blur-pad} ปรับวิดีโอให้พอดีกับอัตราส่วนภาพเป้าหมายโดยเติมพื้นที่ขอบด้วยสำเนาของวิดีโอที่เบลอและปรับขนาด แทนที่จะเป็นแถบสีทึบ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` รับข้อมูลแบบ multipart form data พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | อัตราส่วนภาพเป้าหมาย: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | No | `20` | ค่าซิกมาของการเบลอแบบเกาส์เซียนสำหรับพื้นหลัง (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * ค่าเบลอที่สูงขึ้นจะให้พื้นหลังที่นุ่มนวลและเป็นนามธรรมมากขึ้น ค่าที่ต่ำกว่าจะคงรายละเอียดให้มองเห็นได้มากขึ้น * หากวิดีโอตรงกับอัตราส่วนภาพเป้าหมายอยู่แล้ว ไฟล์จะถูกคืนกลับมาโดยไม่เปลี่ยนแปลง * หากต้องการแถบเติมขอบแบบสีทึบ ให้ใช้เครื่องมือ Aspect Pad แทน --- --- url: https://docs.snapotter.com/uk/tools/video/blur-pad.md description: Заповнення смуг розмитою копією відео. --- # Blur Pad {#blur-pad} Впишіть відео в цільове співвідношення сторін, заповнюючи область заповнення розмитою масштабованою копією відео замість суцільнокольорових смуг. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Приймає багаточастинні (multipart) дані форми з відеофайлом та полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | Цільове співвідношення сторін: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | No | `20` | Сигма гаусового розмиття для фону (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Вищі значення розмиття дають м'якший, абстрактніший фон. Нижчі значення зберігають більше видимих деталей. * Якщо відео вже відповідає цільовому співвідношенню сторін, файл повертається без змін. * Для суцільнокольорового заповнення використовуйте натомість інструмент Aspect Pad. --- --- url: https://docs.snapotter.com/vi/tools/video/blur-pad.md description: Lấp đầy các thanh bằng một bản sao được làm mờ của video. --- # Blur Pad {#blur-pad} Đưa một video vừa vào một tỷ lệ khung hình mục tiêu bằng cách lấp đầy vùng đệm bằng một bản sao được làm mờ, co giãn của video thay vì các thanh màu đơn sắc. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Chấp nhận dữ liệu biểu mẫu multipart với một tệp video và một trường JSON `settings`. ## Parameters {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | target | string | Không | `"16:9"` | Tỷ lệ khung hình mục tiêu: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | Không | `20` | Sigma làm mờ Gaussian cho nền (2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * Giá trị làm mờ cao hơn tạo ra nền mềm hơn, trừu tượng hơn. Giá trị thấp hơn giữ nhiều chi tiết hiển thị hơn. * Nếu video đã khớp với tỷ lệ khung hình mục tiêu, tệp được trả về không thay đổi. * Để có đệm màu đơn sắc, hãy dùng công cụ Aspect Pad thay thế. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/blur-pad.md description: 用视频的模糊副本填充条框。 --- # Blur Pad {#blur-pad} 通过用视频的模糊、缩放副本填充填充区域(而不是纯色条框),使视频适应目标宽高比。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/blur-pad` 接受包含一个视频文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | target | string | No | `"16:9"` | 目标宽高比:`16:9`、`9:16`、`1:1`、`4:3`、`3:4` | | blur | number | No | `20` | 背景的高斯模糊 sigma(2-50) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notes {#notes} * 模糊值越高,背景越柔和、越抽象。值越低,保留的细节越多。 * 如果视频已经匹配目标宽高比,则文件将原样返回。 * 若要使用纯色填充,请改用 Aspect Pad 工具。 --- --- url: https://docs.snapotter.com/id/tools/image/blur-faces.md description: >- Deteksi dan buramkan wajah dalam gambar secara otomatis dengan deteksi wajah AI untuk privasi dan anonimisasi yang patuh GDPR. --- # Blur Wajah & Info Pribadi {#face-pii-blur} Deteksi dan buramkan wajah dalam gambar secara otomatis menggunakan deteksi wajah bertenaga AI (MediaPipe). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Pemrosesan:** Asinkron (mengembalikan 202, polling `/api/v1/jobs/{jobId}/progress` untuk status melalui SSE) **Bundel model:** `face-detection` (200-300 MB) ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | file | file | Ya | - | Berkas gambar (multipart) | | blurRadius | number | Tidak | `30` | Radius blur yang diterapkan pada wajah yang terdeteksi (1-100) | | sensitivity | number | Tidak | `0.5` | Sensitivitas deteksi wajah (0-1). Nilai lebih rendah mendeteksi lebih sedikit wajah dengan keyakinan lebih tinggi | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Respons {#response} ### Respons Awal (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progres (SSE di `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Hasil Akhir (melalui SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### Tidak Ada Wajah Terdeteksi {#no-faces-detected} Jika tidak ada wajah ditemukan, hasil menyertakan peringatan: ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Catatan {#notes} * Memerlukan bundel model `face-detection` untuk dipasang (200-300 MB). * Format keluaran mengikuti format input secara otomatis. * Larik `faces` berisi koordinat kotak pembatas (x, y, width, height) untuk setiap wajah yang terdeteksi. * Naikkan `sensitivity` (lebih dekat ke 1,0) untuk mendeteksi lebih banyak wajah, termasuk yang sebagian terhalang. * Mendukung format input HEIC/HEIF, RAW, TGA, PSD, EXR, dan HDR melalui dekode otomatis. --- --- url: https://docs.snapotter.com/vi/tools/pdf/pdfa-convert.md description: Chuyển đổi một PDF sang định dạng lưu trữ PDF/A-2 để bảo tồn dài hạn. --- # Bộ chuyển đổi PDF/A {#pdf-a-convert} Chuyển đổi một PDF sang định dạng lưu trữ PDF/A-2, phù hợp cho việc bảo tồn dài hạn và tuân thủ quy định. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdfa-convert` Chấp nhận dữ liệu biểu mẫu multipart với một tệp PDF. Không cần trường `settings`. ## Parameters {#parameters} Công cụ này không có tham số cài đặt. Tải trực tiếp tệp PDF lên. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdfa-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2600000 } ``` ## Notes {#notes} * Đầu ra tuân theo tiêu chuẩn PDF/A-2. * PDF/A nhúng tất cả phông chữ và không cho phép tham chiếu bên ngoài, vì vậy tệp đầu ra có thể lớn hơn bản gốc. * Mã hóa và JavaScript bị loại bỏ trong quá trình chuyển đổi, vì chúng không được tiêu chuẩn PDF/A cho phép. --- --- url: https://docs.snapotter.com/nl/tools/pdf/booklet-pdf.md description: PDF-pagina's ordenen om te vouwen tot een boekje. --- # Boekje-PDF {#booklet-pdf} Schik pagina's in voor dubbelzijdig printen zodat de gedrukte vellen tot een boekje kunnen worden gevouwen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Accepteert multipart form data met een PDF-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | perSheet | integer | Nee | `2` | Pagina's per vel: `2`, `4`, `6` of `8` | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Opmerkingen {#notes} * De standaard `perSheet: 2` plaatst twee pagina's naast elkaar op elk vel, wat de standaard boekjeslay-out is voor dubbelzijdig printen. * Blanco pagina's worden automatisch toegevoegd als het totale aantal pagina's geen veelvoud is van de velgrootte. * Print de uitvoer dubbelzijdig met binding aan de korte zijde, vouw daarna en niet. --- --- url: https://docs.snapotter.com/hi/tools/pdf/booklet-pdf.md description: PDF पृष्ठों को बुकलेट में मोड़ने के लिए व्यवस्थित करें। --- # Booklet PDF {#booklet-pdf} डुप्लेक्स प्रिंटिंग के लिए पृष्ठों को इम्पोज़ करें ताकि प्रिंट की गई शीटों को एक बुकलेट में मोड़ा जा सके। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` एक PDF फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart फ़ॉर्म डेटा स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | प्रति शीट पृष्ठ: `2`, `4`, `6`, या `8` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * डिफ़ॉल्ट `perSheet: 2` प्रत्येक शीट पर दो पृष्ठों को अगल-बगल रखता है, जो डुप्लेक्स प्रिंटिंग के लिए मानक बुकलेट लेआउट है। * यदि कुल पृष्ठ गणना शीट आकार का गुणज नहीं है तो खाली पृष्ठ स्वचालित रूप से जोड़े जाते हैं। * आउटपुट को short-edge बाइंडिंग पर डबल-साइडेड प्रिंट करें, फिर मोड़ें और स्टेपल करें। --- --- url: https://docs.snapotter.com/id/tools/pdf/booklet-pdf.md description: Menyusun halaman PDF untuk dilipat menjadi buklet. --- # Booklet PDF {#booklet-pdf} Menyusun halaman untuk pencetakan dupleks sehingga lembar yang tercetak dapat dilipat menjadi buklet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Menerima data formulir multipart dengan sebuah file PDF dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | Halaman per lembar: `2`, `4`, `6`, atau `8` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * Default `perSheet: 2` menempatkan dua halaman berdampingan pada setiap lembar, yang merupakan tata letak buklet standar untuk pencetakan dupleks. * Halaman kosong ditambahkan secara otomatis jika jumlah total halaman bukan kelipatan dari ukuran lembar. * Cetak keluaran secara dua sisi pada penjilidan tepi-pendek, lalu lipat dan staples. --- --- url: https://docs.snapotter.com/ja/tools/pdf/booklet-pdf.md description: 冊子に折るためにPDFのページを面付けします。 --- # Booklet PDF {#booklet-pdf} 両面印刷用にページを面付けし、印刷したシートを折って冊子にできるようにします。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` PDFファイルとJSON形式の`settings`フィールドを含むmultipartフォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | 1シートあたりのページ数: `2`, `4`, `6`, または`8` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * デフォルトの`perSheet: 2`は各シートに2ページを横並びで配置します。これは両面印刷における標準的な冊子レイアウトです。 * 総ページ数がシートサイズの倍数でない場合、空白ページが自動的に追加されます。 * 出力を短辺綴じで両面印刷し、折ってホチキス留めしてください。 --- --- url: https://docs.snapotter.com/ko/tools/pdf/booklet-pdf.md description: 소책자로 접을 수 있도록 PDF 페이지를 배열합니다. --- # Booklet PDF {#booklet-pdf} 인쇄된 용지를 접어 소책자로 만들 수 있도록 양면 인쇄용으로 페이지를 배치합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` PDF 파일과 JSON `settings` 필드를 담은 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | 용지당 페이지 수: `2`, `4`, `6`, 또는 `8` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * 기본값 `perSheet: 2`는 각 용지에 두 페이지를 나란히 배치하며, 이는 양면 인쇄를 위한 표준 소책자 레이아웃입니다. * 총 페이지 수가 용지 크기의 배수가 아니면 빈 페이지가 자동으로 추가됩니다. * 출력을 단변 제본으로 양면 인쇄한 다음 접고 스테이플러로 고정하세요. --- --- url: https://docs.snapotter.com/th/tools/pdf/booklet-pdf.md description: จัดเรียงหน้า PDF สำหรับพับเป็นหนังสือเล่มเล็ก --- # Booklet PDF {#booklet-pdf} จัดวางหน้าสำหรับการพิมพ์สองหน้า เพื่อให้แผ่นที่พิมพ์สามารถพับเป็นหนังสือเล่มเล็กได้ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` รับ multipart form data พร้อมไฟล์ PDF และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | หน้าต่อแผ่น: `2`, `4`, `6` หรือ `8` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * ค่าเริ่มต้น `perSheet: 2` จะวางสองหน้าเรียงข้างกันบนแต่ละแผ่น ซึ่งเป็นเลย์เอาต์หนังสือเล่มเล็กมาตรฐานสำหรับการพิมพ์สองหน้า * หน้าว่างจะถูกเพิ่มโดยอัตโนมัติหากจำนวนหน้าทั้งหมดไม่เป็นจำนวนเท่าของขนาดแผ่น * พิมพ์ผลลัพธ์แบบสองหน้าโดยเข้าเล่มขอบสั้น จากนั้นพับและเย็บ --- --- url: https://docs.snapotter.com/vi/tools/pdf/booklet-pdf.md description: Sắp xếp các trang PDF để gấp thành sách nhỏ. --- # Booklet PDF {#booklet-pdf} Bố trí các trang để in hai mặt sao cho các tờ in ra có thể gấp thành một cuốn sách nhỏ. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Chấp nhận dữ liệu form multipart với một tệp PDF và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | perSheet | integer | Không | `2` | Số trang mỗi tờ: `2`, `4`, `6`, hoặc `8` | ## Ví dụ Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Ví dụ Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Ghi chú {#notes} * Mặc định `perSheet: 2` đặt hai trang cạnh nhau trên mỗi tờ, đây là bố cục sách nhỏ tiêu chuẩn cho in hai mặt. * Các trang trống được thêm tự động nếu tổng số trang không phải là bội số của kích thước tờ. * In đầu ra hai mặt theo kiểu đóng gáy cạnh ngắn, sau đó gấp và dập ghim. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/border.md description: >- Adicione bordas, espaçamento, cantos arredondados e sombras às imagens em uma ordem previsível e controlável. --- # Borda e Moldura {#border-frame} Adicione bordas, espaçamento, cantos arredondados e sombras às imagens. A ferramenta aplica os efeitos nesta ordem: espaçamento, borda, raio dos cantos e depois sombra. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | borderWidth | number | Não | 10 | Espessura da borda em pixels (0 a 2000) | | borderColor | string | Não | `"#000000"` | Cor da borda em hex (por exemplo, `#FF0000`) | | padding | number | Não | 0 | Espaçamento interno entre a imagem e a borda em pixels (0 a 200) | | paddingColor | string | Não | `"#FFFFFF"` | Cor de preenchimento do espaçamento em hex | | cornerRadius | number | Não | 0 | Raio dos cantos em pixels (0 a 2000) | | shadow | boolean | Não | `false` | Se deve adicionar uma sombra | | shadowBlur | number | Não | 15 | Raio de desfoque da sombra (1 a 200) | | shadowOffsetX | number | Não | 0 | Deslocamento horizontal da sombra (-50 a 50) | | shadowOffsetY | number | Não | 5 | Deslocamento vertical da sombra (-50 a 50) | | shadowColor | string | Não | `"#000000"` | Cor da sombra em hex | | shadowOpacity | number | Não | 40 | Porcentagem de opacidade da sombra (0 a 100) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Observações {#notes} * Usa a fábrica padrão `createToolRoute`. Aceita um único arquivo de imagem via upload multipart. * Suporta os formatos de entrada HEIC, RAW, PSD e SVG (decodificados automaticamente). * Ordem de processamento: o espaçamento é adicionado primeiro, depois a borda envolve a imagem, em seguida o raio dos cantos é aplicado e por fim a sombra é composta. * Quando `cornerRadius` ou `shadow` está ativado, a saída é forçada para PNG (independentemente do formato de entrada) para preservar a transparência. Formatos que suportam alfa (PNG, WebP, AVIF) mantêm seu formato original. * A sombra é sensível ao formato: ela acompanha os cantos arredondados em vez de criar uma sombra retangular. * Definir `borderWidth` como 0 e usar apenas `cornerRadius` + `shadow` cria um efeito de sombra arredondada sem moldura. --- --- url: https://docs.snapotter.com/es/tools/image/border.md description: >- Añade bordes, relleno, esquinas redondeadas y sombras paralelas a las imágenes en un orden predecible y controlable. --- # Borde y marco {#border-frame} Añade bordes, relleno, esquinas redondeadas y sombras paralelas a las imágenes. La herramienta aplica los efectos en orden: relleno, borde, radio de esquina y luego sombra. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | Grosor del borde en píxeles (0 a 2000) | | borderColor | string | No | `"#000000"` | Color del borde en hex (por ejemplo, `#FF0000`) | | padding | number | No | 0 | Relleno interior entre la imagen y el borde en píxeles (0 a 200) | | paddingColor | string | No | `"#FFFFFF"` | Color de relleno del padding en hex | | cornerRadius | number | No | 0 | Radio de las esquinas en píxeles (0 a 2000) | | shadow | boolean | No | `false` | Si se debe añadir una sombra paralela | | shadowBlur | number | No | 15 | Radio de desenfoque de la sombra (1 a 200) | | shadowOffsetX | number | No | 0 | Desplazamiento horizontal de la sombra (-50 a 50) | | shadowOffsetY | number | No | 5 | Desplazamiento vertical de la sombra (-50 a 50) | | shadowColor | string | No | `"#000000"` | Color de la sombra en hex | | shadowOpacity | number | No | 40 | Porcentaje de opacidad de la sombra (0 a 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * Usa la fábrica estándar `createToolRoute`. Acepta un único archivo de imagen mediante subida multipart. * Admite los formatos de entrada HEIC, RAW, PSD y SVG (se decodifican automáticamente). * Orden de procesamiento: primero se añade el relleno, luego el borde lo envuelve, después se aplica el radio de esquina y por último se compone la sombra. * Cuando `cornerRadius` o `shadow` está habilitado, la salida se fuerza a PNG (independientemente del formato de entrada) para conservar la transparencia. Los formatos que admiten alfa (PNG, WebP, AVIF) mantienen su formato original. * La sombra tiene en cuenta la forma: sigue las esquinas redondeadas en lugar de crear una sombra rectangular. * Ajustar `borderWidth` a 0 y usar solo `cornerRadius` + `shadow` crea un efecto de sombra redondeada sin marco. --- --- url: https://docs.snapotter.com/hi/tools/image/border.md description: >- छवियों में एक पूर्वानुमेय, नियंत्रित क्रम में बॉर्डर, पैडिंग, गोल कोने, और ड्रॉप शैडो जोड़ें। --- # Border & Frame {#border-frame} छवियों में बॉर्डर, पैडिंग, गोल कोने, और ड्रॉप शैडो जोड़ें। यह टूल प्रभावों को क्रम में लागू करता है: पैडिंग, बॉर्डर, कॉर्नर त्रिज्या, फिर छाया। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | पिक्सेल में बॉर्डर मोटाई (0 से 2000) | | borderColor | string | No | `"#000000"` | hex के रूप में बॉर्डर रंग (उदा. `#FF0000`) | | padding | number | No | 0 | पिक्सेल में छवि और बॉर्डर के बीच आंतरिक पैडिंग (0 से 200) | | paddingColor | string | No | `"#FFFFFF"` | hex के रूप में पैडिंग फिल रंग | | cornerRadius | number | No | 0 | पिक्सेल में कॉर्नर त्रिज्या (0 से 2000) | | shadow | boolean | No | `false` | ड्रॉप शैडो जोड़ना है या नहीं | | shadowBlur | number | No | 15 | छाया ब्लर त्रिज्या (1 से 200) | | shadowOffsetX | number | No | 0 | छाया क्षैतिज ऑफसेट (-50 से 50) | | shadowOffsetY | number | No | 5 | छाया ऊर्ध्वाधर ऑफसेट (-50 से 50) | | shadowColor | string | No | `"#000000"` | hex के रूप में छाया रंग | | shadowOpacity | number | No | 40 | छाया अपारदर्शिता प्रतिशत (0 से 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * मानक `createToolRoute` फ़ैक्ट्री का उपयोग करता है। multipart अपलोड के ज़रिए एक ही छवि फ़ाइल स्वीकार करता है। * HEIC, RAW, PSD, और SVG इनपुट प्रारूपों का समर्थन करता है (स्वचालित रूप से डिकोड किए गए)। * प्रोसेसिंग क्रम: पहले पैडिंग जोड़ी जाती है, फिर बॉर्डर चारों ओर लपेटता है, फिर कॉर्नर त्रिज्या लागू की जाती है, फिर छाया कंपोज़िट की जाती है। * जब `cornerRadius` या `shadow` सक्षम होता है, तो पारदर्शिता संरक्षित करने के लिए आउटपुट को PNG पर बाध्य किया जाता है (इनपुट प्रारूप की परवाह किए बिना)। अल्फा का समर्थन करने वाले प्रारूप (PNG, WebP, AVIF) अपना मूल प्रारूप बनाए रखते हैं। * छाया आकार-जागरूक होती है: यह आयताकार छाया बनाने के बजाय गोल कोनों का अनुसरण करती है। * `borderWidth` को 0 पर सेट करना और केवल `cornerRadius` + `shadow` का उपयोग करना एक फ़्रेमरहित गोल छाया प्रभाव बनाता है। --- --- url: https://docs.snapotter.com/ja/tools/image/border.md description: 予測可能で制御しやすい順序で、画像にボーダー、パディング、角丸、ドロップシャドウを追加します。 --- # Border & Frame {#border-frame} 画像にボーダー、パディング、角丸、ドロップシャドウを追加します。このツールは次の順序でエフェクトを適用します: パディング、ボーダー、角の丸み、シャドウ。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | ボーダーの太さ (ピクセル) (0 ~ 2000) | | borderColor | string | No | `"#000000"` | ボーダーの色 (16 進) (例: `#FF0000`) | | padding | number | No | 0 | 画像とボーダーの間の内側パディング (ピクセル) (0 ~ 200) | | paddingColor | string | No | `"#FFFFFF"` | パディングの塗りつぶし色 (16 進) | | cornerRadius | number | No | 0 | 角の丸み (ピクセル) (0 ~ 2000) | | shadow | boolean | No | `false` | ドロップシャドウを追加するかどうか | | shadowBlur | number | No | 15 | シャドウのぼかし半径 (1 ~ 200) | | shadowOffsetX | number | No | 0 | シャドウの水平オフセット (-50 ~ 50) | | shadowOffsetY | number | No | 5 | シャドウの垂直オフセット (-50 ~ 50) | | shadowColor | string | No | `"#000000"` | シャドウの色 (16 進) | | shadowOpacity | number | No | 40 | シャドウの不透明度 (パーセント) (0 ~ 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * 標準の `createToolRoute` ファクトリを使用します。マルチパートアップロードで 1 つの画像ファイルを受け付けます。 * HEIC、RAW、PSD、SVG の入力形式をサポートします (自動的にデコードされます)。 * 処理順序: まずパディングが追加され、次にボーダーが周囲を囲み、その後角の丸みが適用され、最後にシャドウが合成されます。 * `cornerRadius` または `shadow` が有効な場合、透明度を保持するために出力は (入力形式に関係なく) PNG に強制されます。アルファをサポートする形式 (PNG、WebP、AVIF) は元の形式を維持します。 * シャドウは形状を認識します。長方形のシャドウを作成するのではなく、角丸に沿います。 * `borderWidth` を 0 に設定し、`cornerRadius` と `shadow` のみを使用すると、フレームなしの角丸シャドウ効果が作成されます。 --- --- url: https://docs.snapotter.com/ko/tools/image/border.md description: 예측 가능하고 제어 가능한 순서로 이미지에 테두리, 여백, 둥근 모서리, 드롭 섀도를 추가합니다. --- # Border & Frame {#border-frame} 이미지에 테두리, 여백, 둥근 모서리, 드롭 섀도를 추가합니다. 이 도구는 여백, 테두리, 모서리 반경, 그림자 순서로 효과를 적용합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/border` ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | borderWidth | number | 아니요 | 10 | 테두리 두께 픽셀 (0 ~ 2000) | | borderColor | string | 아니요 | `"#000000"` | 16진수 형식의 테두리 색상 (예: `#FF0000`) | | padding | number | 아니요 | 0 | 이미지와 테두리 사이의 안쪽 여백 픽셀 (0 ~ 200) | | paddingColor | string | 아니요 | `"#FFFFFF"` | 16진수 형식의 여백 채우기 색상 | | cornerRadius | number | 아니요 | 0 | 모서리 반경 픽셀 (0 ~ 2000) | | shadow | boolean | 아니요 | `false` | 드롭 섀도 추가 여부 | | shadowBlur | number | 아니요 | 15 | 그림자 블러 반경 (1 ~ 200) | | shadowOffsetX | number | 아니요 | 0 | 그림자 수평 오프셋 (-50 ~ 50) | | shadowOffsetY | number | 아니요 | 5 | 그림자 수직 오프셋 (-50 ~ 50) | | shadowColor | string | 아니요 | `"#000000"` | 16진수 형식의 그림자 색상 | | shadowOpacity | number | 아니요 | 40 | 그림자 불투명도 백분율 (0 ~ 100) | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## 참고 사항 {#notes} * 표준 `createToolRoute` 팩토리를 사용합니다. multipart 업로드를 통해 단일 이미지 파일을 받습니다. * HEIC, RAW, PSD, SVG 입력 형식을 지원합니다(자동 디코딩). * 처리 순서: 먼저 여백이 추가되고, 그다음 테두리가 감싸고, 그다음 모서리 반경이 적용되며, 마지막으로 그림자가 합성됩니다. * `cornerRadius` 또는 `shadow`이(가) 활성화되면, 투명도를 유지하기 위해 출력이 (입력 형식에 관계없이) PNG로 강제됩니다. 알파를 지원하는 형식(PNG, WebP, AVIF)은 원래 형식을 유지합니다. * 그림자는 형태를 인식합니다. 직사각형 그림자를 만드는 대신 둥근 모서리를 따라갑니다. * `borderWidth`을(를) 0으로 설정하고 `cornerRadius` + `shadow`만 사용하면 프레임 없는 둥근 그림자 효과가 생성됩니다. --- --- url: https://docs.snapotter.com/th/tools/image/border.md description: >- เพิ่มขอบ, ระยะขอบ, มุมโค้งมน และเงาทอดให้กับรูปภาพในลำดับที่คาดเดาได้และควบคุมได้ --- # Border & Frame {#border-frame} เพิ่มขอบ, ระยะขอบ, มุมโค้งมน และเงาทอดให้กับรูปภาพ เครื่องมือจะใช้เอฟเฟกต์ตามลำดับ: ระยะขอบ, ขอบ, รัศมีมุม แล้วจึงเงา ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | ความหนาของขอบเป็นพิกเซล (0 ถึง 2000) | | borderColor | string | No | `"#000000"` | สีขอบเป็น hex (เช่น `#FF0000`) | | padding | number | No | 0 | ระยะขอบด้านในระหว่างรูปภาพกับขอบเป็นพิกเซล (0 ถึง 200) | | paddingColor | string | No | `"#FFFFFF"` | สีเติมระยะขอบเป็น hex | | cornerRadius | number | No | 0 | รัศมีมุมเป็นพิกเซล (0 ถึง 2000) | | shadow | boolean | No | `false` | จะเพิ่มเงาทอดหรือไม่ | | shadowBlur | number | No | 15 | รัศมีการเบลอเงา (1 ถึง 200) | | shadowOffsetX | number | No | 0 | ระยะเลื่อนแนวนอนของเงา (-50 ถึง 50) | | shadowOffsetY | number | No | 5 | ระยะเลื่อนแนวตั้งของเงา (-50 ถึง 50) | | shadowColor | string | No | `"#000000"` | สีเงาเป็น hex | | shadowOpacity | number | No | 40 | เปอร์เซ็นต์ความทึบของเงา (0 ถึง 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * ใช้แฟกทอรี `createToolRoute` มาตรฐาน รับไฟล์รูปภาพเดียวผ่านการอัปโหลดแบบ multipart * รองรับรูปแบบอินพุต HEIC, RAW, PSD และ SVG (ถอดรหัสอัตโนมัติ) * ลำดับการประมวลผล: เพิ่มระยะขอบก่อน แล้วขอบจะห่อรอบ ๆ จากนั้นใช้รัศมีมุม แล้วจึงประกอบเงา * เมื่อเปิดใช้งาน `cornerRadius` หรือ `shadow` เอาต์พุตจะถูกบังคับเป็น PNG (ไม่ว่ารูปแบบอินพุตจะเป็นอะไร) เพื่อรักษาความโปร่งใส รูปแบบที่รองรับอัลฟา (PNG, WebP, AVIF) จะคงรูปแบบเดิมไว้ * เงาตระหนักถึงรูปทรง: มันจะติดตามมุมโค้งมนแทนที่จะสร้างเงาสี่เหลี่ยม * การตั้ง `borderWidth` เป็น 0 และใช้เฉพาะ `cornerRadius` + `shadow` สร้างเอฟเฟกต์เงาโค้งมนแบบไม่มีเฟรม --- --- url: https://docs.snapotter.com/vi/tools/image/border.md description: >- Thêm viền, khoảng đệm, góc bo tròn và bóng đổ vào hình ảnh theo một thứ tự có thể dự đoán và kiểm soát được. --- # Border & Frame {#border-frame} Thêm viền, khoảng đệm, góc bo tròn và bóng đổ vào hình ảnh. Công cụ áp dụng các hiệu ứng theo thứ tự: khoảng đệm, viền, bán kính bo góc, rồi bóng đổ. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | Độ dày viền tính bằng pixel (0 đến 2000) | | borderColor | string | No | `"#000000"` | Màu viền dạng hex (ví dụ `#FF0000`) | | padding | number | No | 0 | Khoảng đệm bên trong giữa hình ảnh và viền tính bằng pixel (0 đến 200) | | paddingColor | string | No | `"#FFFFFF"` | Màu lấp khoảng đệm dạng hex | | cornerRadius | number | No | 0 | Bán kính bo góc tính bằng pixel (0 đến 2000) | | shadow | boolean | No | `false` | Có thêm bóng đổ hay không | | shadowBlur | number | No | 15 | Bán kính làm mờ bóng đổ (1 đến 200) | | shadowOffsetX | number | No | 0 | Độ lệch ngang của bóng đổ (-50 đến 50) | | shadowOffsetY | number | No | 5 | Độ lệch dọc của bóng đổ (-50 đến 50) | | shadowColor | string | No | `"#000000"` | Màu bóng đổ dạng hex | | shadowOpacity | number | No | 40 | Phần trăm độ mờ của bóng đổ (0 đến 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * Sử dụng factory `createToolRoute` tiêu chuẩn. Chấp nhận một tệp hình ảnh duy nhất qua tải lên multipart. * Hỗ trợ các định dạng đầu vào HEIC, RAW, PSD và SVG (được giải mã tự động). * Thứ tự xử lý: khoảng đệm được thêm trước, rồi viền bọc quanh, rồi bán kính bo góc được áp dụng, rồi bóng đổ được ghép vào. * Khi `cornerRadius` hoặc `shadow` được bật, đầu ra buộc phải là PNG (bất kể định dạng đầu vào) để giữ độ trong suốt. Các định dạng hỗ trợ kênh alpha (PNG, WebP, AVIF) giữ nguyên định dạng gốc. * Bóng đổ nhận biết hình dạng: nó bám theo các góc bo tròn thay vì tạo một bóng đổ hình chữ nhật. * Đặt `borderWidth` bằng 0 và chỉ dùng `cornerRadius` + `shadow` tạo hiệu ứng bóng đổ bo tròn không khung. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/border.md description: 以可预测、可控的顺序为图像添加边框、内边距、圆角和投影。 --- # Border & Frame {#border-frame} 为图像添加边框、内边距、圆角和投影。该工具按顺序应用效果:内边距、边框、圆角,然后是阴影。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | 否 | 10 | 边框厚度(像素,0 到 2000) | | borderColor | string | 否 | `"#000000"` | 边框颜色(十六进制,例如 `#FF0000`) | | padding | number | 否 | 0 | 图像与边框之间的内边距(像素,0 到 200) | | paddingColor | string | 否 | `"#FFFFFF"` | 内边距填充颜色(十六进制) | | cornerRadius | number | 否 | 0 | 圆角半径(像素,0 到 2000) | | shadow | boolean | 否 | `false` | 是否添加投影 | | shadowBlur | number | 否 | 15 | 阴影模糊半径(1 到 200) | | shadowOffsetX | number | 否 | 0 | 阴影水平偏移(-50 到 50) | | shadowOffsetY | number | 否 | 5 | 阴影垂直偏移(-50 到 50) | | shadowColor | string | 否 | `"#000000"` | 阴影颜色(十六进制) | | shadowOpacity | number | 否 | 40 | 阴影不透明度百分比(0 到 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * 使用标准的 `createToolRoute` 工厂。通过 multipart 上传接受单个图像文件。 * 支持 HEIC、RAW、PSD 和 SVG 输入格式(自动解码)。 * 处理顺序:先添加内边距,然后边框环绕,接着应用圆角,最后合成阴影。 * 当启用 `cornerRadius` 或 `shadow` 时,输出会被强制为 PNG(无论输入格式如何)以保留透明度。支持 alpha 的格式(PNG、WebP、AVIF)保持其原始格式。 * 阴影会感知形状:它会跟随圆角,而不是创建矩形阴影。 * 将 `borderWidth` 设为 0 并仅使用 `cornerRadius` + `shadow`,可创建无框圆角阴影效果。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/border.md description: 以可預期、可控制的順序為影像加上邊框、內距、圓角及投影。 --- # Border & Frame {#border-frame} 為影像加上邊框、內距、圓角及投影。此工具會依序套用效果:內距、邊框、圓角、然後陰影。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/border` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | 邊框粗細,以像素為單位(0 至 2000) | | borderColor | string | No | `"#000000"` | 邊框顏色,以十六進位表示(例如 `#FF0000`) | | padding | number | No | 0 | 影像與邊框之間的內距,以像素為單位(0 至 200) | | paddingColor | string | No | `"#FFFFFF"` | 內距填充顏色,以十六進位表示 | | cornerRadius | number | No | 0 | 圓角半徑,以像素為單位(0 至 2000) | | shadow | boolean | No | `false` | 是否加上投影 | | shadowBlur | number | No | 15 | 陰影模糊半徑(1 至 200) | | shadowOffsetX | number | No | 0 | 陰影水平偏移(-50 至 50) | | shadowOffsetY | number | No | 5 | 陰影垂直偏移(-50 至 50) | | shadowColor | string | No | `"#000000"` | 陰影顏色,以十六進位表示 | | shadowOpacity | number | No | 40 | 陰影不透明度百分比(0 至 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Notes {#notes} * 使用標準的 `createToolRoute` 工廠。透過 multipart 上傳接受單一影像檔案。 * 支援 HEIC、RAW、PSD 及 SVG 輸入格式(自動解碼)。 * 處理順序:先加上內距,接著邊框環繞四周,然後套用圓角,最後合成陰影。 * 當啟用 `cornerRadius` 或 `shadow` 時,輸出會強制為 PNG(不論輸入格式為何)以保留透明度。支援 alpha 的格式(PNG、WebP、AVIF)會保留其原始格式。 * 陰影會依形狀變化:它會沿著圓角,而非產生矩形陰影。 * 將 `borderWidth` 設為 0 並僅使用 `cornerRadius` + `shadow`,可製作出無邊框的圓角陰影效果。 --- --- url: https://docs.snapotter.com/it/tools/image/border.md description: >- Aggiunge bordi, spaziatura, angoli arrotondati e ombre esterne alle immagini in un ordine prevedibile e controllabile. --- # Bordo e cornice {#border-frame} Aggiunge bordi, spaziatura, angoli arrotondati e ombre esterne alle immagini. Lo strumento applica gli effetti in quest'ordine: spaziatura, bordo, raggio degli angoli, poi ombra. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/border` ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | borderWidth | number | No | 10 | Spessore del bordo in pixel (da 0 a 2000) | | borderColor | string | No | `"#000000"` | Colore del bordo in esadecimale (ad es. `#FF0000`) | | padding | number | No | 0 | Spaziatura interna tra immagine e bordo in pixel (da 0 a 200) | | paddingColor | string | No | `"#FFFFFF"` | Colore di riempimento della spaziatura in esadecimale | | cornerRadius | number | No | 0 | Raggio degli angoli in pixel (da 0 a 2000) | | shadow | boolean | No | `false` | Se aggiungere un'ombra esterna | | shadowBlur | number | No | 15 | Raggio di sfocatura dell'ombra (da 1 a 200) | | shadowOffsetX | number | No | 0 | Offset orizzontale dell'ombra (da -50 a 50) | | shadowOffsetY | number | No | 5 | Offset verticale dell'ombra (da -50 a 50) | | shadowColor | string | No | `"#000000"` | Colore dell'ombra in esadecimale | | shadowOpacity | number | No | 40 | Percentuale di opacità dell'ombra (da 0 a 100) | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Note {#notes} * Usa la factory standard `createToolRoute`. Accetta un singolo file immagine tramite caricamento multipart. * Supporta i formati di input HEIC, RAW, PSD e SVG (decodificati automaticamente). * Ordine di elaborazione: viene aggiunta prima la spaziatura, poi il bordo la avvolge, poi viene applicato il raggio degli angoli, poi viene composta l'ombra. * Quando `cornerRadius` o `shadow` è abilitato, l'output viene forzato a PNG (indipendentemente dal formato di input) per preservare la trasparenza. I formati che supportano l'alfa (PNG, WebP, AVIF) mantengono il loro formato originale. * L'ombra tiene conto della forma: segue gli angoli arrotondati anziché creare un'ombra rettangolare. * Impostando `borderWidth` a 0 e usando solo `cornerRadius` + `shadow` si crea un effetto di ombra arrotondata senza cornice. --- --- url: https://docs.snapotter.com/fr/tools/image/border.md description: >- Ajoute des bordures, des marges, des coins arrondis et des ombres portées aux images dans un ordre prévisible et contrôlable. --- # Bordure et cadre {#border-frame} Ajoute des bordures, des marges, des coins arrondis et des ombres portées aux images. L'outil applique les effets dans l'ordre suivant : marge, bordure, rayon des coins, puis ombre. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/border` ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | borderWidth | nombre | Non | 10 | Épaisseur de la bordure en pixels (0 à 2000) | | borderColor | chaîne | Non | `"#000000"` | Couleur de la bordure en hex (par exemple `#FF0000`) | | padding | nombre | Non | 0 | Marge intérieure entre l'image et la bordure en pixels (0 à 200) | | paddingColor | chaîne | Non | `"#FFFFFF"` | Couleur de remplissage de la marge en hex | | cornerRadius | nombre | Non | 0 | Rayon des coins en pixels (0 à 2000) | | shadow | booléen | Non | `false` | Indique s'il faut ajouter une ombre portée | | shadowBlur | nombre | Non | 15 | Rayon de flou de l'ombre (1 à 200) | | shadowOffsetX | nombre | Non | 0 | Décalage horizontal de l'ombre (-50 à 50) | | shadowOffsetY | nombre | Non | 5 | Décalage vertical de l'ombre (-50 à 50) | | shadowColor | chaîne | Non | `"#000000"` | Couleur de l'ombre en hex | | shadowOpacity | nombre | Non | 40 | Pourcentage d'opacité de l'ombre (0 à 100) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/border \ -F "file=@photo.jpg" \ -F 'settings={"borderWidth":20,"borderColor":"#333333","cornerRadius":16,"shadow":true,"shadowBlur":25,"shadowOpacity":50}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 456789, "processedSize": 523456 } ``` ## Remarques {#notes} * Utilise la fabrique standard `createToolRoute`. Accepte un seul fichier image via un téléversement multipart. * Prend en charge les formats d'entrée HEIC, RAW, PSD et SVG (décodés automatiquement). * Ordre de traitement : la marge est ajoutée en premier, puis la bordure l'entoure, puis le rayon des coins est appliqué, puis l'ombre est composée. * Lorsque `cornerRadius` ou `shadow` est activé, la sortie est forcée en PNG (quel que soit le format d'entrée) afin de préserver la transparence. Les formats prenant en charge la couche alpha (PNG, WebP, AVIF) conservent leur format d'origine. * L'ombre tient compte de la forme : elle suit les coins arrondis au lieu de créer une ombre rectangulaire. * Régler `borderWidth` sur 0 en n'utilisant que `cornerRadius` + `shadow` crée un effet d'ombre arrondie sans cadre. --- --- url: https://docs.snapotter.com/es/tools/image/erase-object.md description: >- Elimina objetos no deseados de imágenes con inpainting por IA (LaMa), guiado por una máscara de la región que se va a borrar. --- # Borrador de objetos {#object-eraser} Elimina objetos no deseados de imágenes usando inpainting por IA (modelo LaMa). Acepta una imagen y una máscara que indica la región que se va a borrar. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/erase-object` **Procesamiento:** Asíncrono (devuelve 202, consulta `/api/v1/jobs/{jobId}/progress` para conocer el estado mediante SSE) **Paquete de modelo:** `object-eraser-colorize` (1-2 GB) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen de origen (multipart) | | mask | file | Sí | - | Imagen de máscara (blanco = área que se borra, negro = se conserva). Debe subirse con el nombre de campo `mask` | | format | string | No | `"auto"` | Formato de salida: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | Calidad de salida (1-100) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/erase-object \ -F "file=@photo.jpg" \ -F "mask=@mask.png" \ -F "format=png" \ -F "quality=95" ``` ## Respuesta {#response} ### Respuesta inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progreso (SSE en `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Inpainting...","percent":70} ``` ### Resultado final (mediante SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_erased.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 245000, "processedSize": 230000 } } ``` ## Notas {#notes} * Requiere que el paquete de modelo `object-eraser-colorize` esté instalado (1-2 GB). * La máscara debe tener las mismas dimensiones que la imagen de origen. Los píxeles blancos indican las áreas que se van a borrar; la IA las rellena con contenido plausible. * Usa LaMa (Large Mask Inpainting) para una eliminación de objetos de alta calidad. * Para los formatos de salida que no se pueden previsualizar en el navegador, se genera una vista previa WebP junto a la salida principal. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/sv/tools/image/red-eye-removal.md description: AI-driven detektering och korrigering av röda ögon orsakade av kamerablixt. --- # Borttagning av röda ögon {#red-eye-removal} AI-driven detektering och korrigering av röda ögon orsakade av kamerablixt. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/red-eye-removal` **Bearbetning:** Asynkron (returnerar 202, polla `/api/v1/jobs/{jobId}/progress` för status via SSE) **Modellpaket:** `face-detection` (200-300 MB) ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bildfil (multipart) | | sensitivity | number | Nej | `50` | Detekteringskänslighet för röda ögon (0-100). Högre värden detekterar mer subtila röda ögon | | strength | number | Nej | `70` | Korrigeringsstyrka (0-100). Hur aggressivt rött ska neutraliseras | | format | string | Nej | - | Utdataformat (valfri åsidosättning) | | quality | number | Nej | `90` | Utdatakvalitet (1-100) | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/red-eye-removal \ -F "file=@flash-photo.jpg" \ -F 'settings={"sensitivity":60,"strength":80}' ``` ## Svar {#response} ### Inledande svar (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Förlopp (SSE på `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting red eyes...","percent":40} ``` ### Slutresultat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/flash-photo_redeye_fixed.png", "originalSize": 280000, "processedSize": 290000, "facesDetected": 2, "eyesCorrected": 4 } } ``` ## Anteckningar {#notes} * Kräver att modellpaketet `face-detection` är installerat (200-300 MB). * Detekterar först ansikten, lokaliserar sedan ögonregioner inom varje ansikte och identifierar och korrigerar slutligen pixlar med röda ögon. * Antalet `facesDetected` anger hur många ansikten som hittades; `eyesCorrected` är det totala antalet enskilda ögon som fick röda ögon korrigerade. * Utdata är alltid PNG för maximalt bevarande av kvaliteten. * Stöder HEIC/HEIF-, RAW-, TGA-, PSD-, EXR- och HDR-indataformat via automatisk avkodning. --- --- url: https://docs.snapotter.com/sv/tools/video/burn-subtitles.md description: Rendrera undertexter permanent på videobildrutor. --- # Bränn in undertexter {#burn-subtitles} Rendrera (hårdkoda) permanent undertexter från en SRT-, VTT- eller ASS-fil på varje bildruta i en video. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Tar emot multipart-formulärdata med en videofil och en undertextfil. Detta är en asynkron slutpunkt - den returnerar `202 Accepted` omedelbart och förloppet strömmas via SSE på `GET /api/v1/jobs/{jobId}/progress`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | fontSize | integer | Nej | `24` | Teckenstorlek för undertext i pixlar (8-72) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Anteckningar {#notes} * Ladda upp två filer: den första måste vara en video, den andra måste vara en undertextfil (.srt, .vtt eller .ass). * Inbrända undertexter är permanent en del av videon och kan inte stängas av av tittaren. För undertexter som kan slås av och på, använd verktyget Bädda in undertexter i stället. * Förloppsuppdateringar finns tillgängliga via SSE på `GET /api/v1/jobs/{jobId}/progress` tills jobbet är klart. --- --- url: https://docs.snapotter.com/de/tools/pdf/booklet-pdf.md description: PDF-Seiten so anordnen, dass sie zu einer Broschüre gefaltet werden können. --- # Broschüren-PDF {#booklet-pdf} Ordnet Seiten für den beidseitigen Druck an, sodass die gedruckten Bögen zu einer Broschüre gefaltet werden können. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Nimmt Multipart-Formulardaten mit einer PDF-Datei und einem JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | perSheet | integer | Nein | `2` | Seiten pro Bogen: `2`, `4`, `6` oder `8` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Hinweise {#notes} * Der Standardwert `perSheet: 2` platziert zwei Seiten nebeneinander auf jedem Bogen, was das übliche Broschürenlayout für den beidseitigen Druck ist. * Leere Seiten werden automatisch hinzugefügt, wenn die Gesamtseitenzahl kein Vielfaches der Bogengröße ist. * Drucken Sie die Ausgabe doppelseitig mit Bindung an der kurzen Kante, falten und heften Sie sie anschließend. --- --- url: https://docs.snapotter.com/pl/tools/pdf/booklet-pdf.md description: Rozmieść strony PDF do złożenia w broszurę. --- # Broszura PDF {#booklet-pdf} Rozmieść strony do druku dwustronnego, aby zadrukowane arkusze można było złożyć w broszurę. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Przyjmuje dane formularza multipart z plikiem PDF i polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | perSheet | integer | Nie | `2` | Strony na arkusz: `2`, `4`, `6` lub `8` | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Uwagi {#notes} * Domyślna wartość `perSheet: 2` umieszcza dwie strony obok siebie na każdym arkuszu, co jest standardowym układem broszury do druku dwustronnego. * Puste strony są dodawane automatycznie, jeśli całkowita liczba stron nie jest wielokrotnością rozmiaru arkusza. * Wydrukuj wynik dwustronnie z oprawą wzdłuż krótszej krawędzi, a następnie złóż i zszyj. --- --- url: https://docs.snapotter.com/sv/tools/image/noise-removal.md description: AI-driven brus- och kornborttagning med kvalitetsalternativ i flera nivåer. --- # Brusborttagning {#noise-removal} AI-driven brus- och kornborttagning med kvalitetsalternativ i flera nivåer, med Python-sidovagnen (SCUNet-modellen). ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/noise-removal` **Bearbetning:** Asynkron (returnerar 202, polla `/api/v1/jobs/{jobId}/progress` för status via SSE) **Modellpaket:** `upscale-enhance` (5-6 GB) ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bildfil (multipart) | | tier | string | Nej | `"balanced"` | Kvalitetsnivå: `quick`, `balanced`, `quality`, `maximum` | | strength | number | Nej | `50` | Brusreduceringsstyrka (0-100) | | detailPreservation | number | Nej | `50` | Hur mycket detaljer som ska bevaras (0-100). Högre värden behåller mer textur | | colorNoise | number | Nej | `30` | Reduceringsstyrka för färgbrus (0-100) | | format | string | Nej | `"original"` | Utdataformat: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Nej | `90` | Kodningskvalitet för utdata (1-100) | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/noise-removal \ -F "file=@noisy-photo.jpg" \ -F 'settings={"tier":"quality","strength":60,"detailPreservation":70,"colorNoise":40}' ``` ## Svar {#response} ### Inledande svar (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Förlopp (SSE på `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Denoising...","percent":65} ``` ### Slutresultat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/noisy-photo_denoised.jpg", "originalSize": 500000, "processedSize": 380000 } } ``` ## Anteckningar {#notes} * Kräver att modellpaketet `upscale-enhance` är installerat (5-6 GB). * Kvalitetsnivåer byter hastighet mot kvalitet: `quick` är snabbast med grundläggande brusreducering, `maximum` använder den mest grundliga metoden i flera pass. * Parametern `detailPreservation` är avgörande för texturerade motiv (tyg, hår, lövverk). Högre värden hindrar brusreduceraren från att jämna ut fina detaljer. * När `format` är satt till `"original"` matchar utdataformatet indatafilens format. * Stöder HEIC/HEIF-, RAW-, TGA-, PSD-, EXR- och HDR-indataformat via automatisk avkodning. --- --- url: https://docs.snapotter.com/tr/tools/video/blur-pad.md description: Çubukları videonun bulanık bir kopyasıyla doldurun. --- # Bulanık Dolgu {#blur-pad} Dolgu alanını düz renkli çubuklar yerine videonun bulanık, ölçeklenmiş bir kopyasıyla doldurarak bir videoyu hedef bir en boy oranına sığdırın. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/video/blur-pad` Bir video dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | target | string | Hayır | `"16:9"` | Hedef en boy oranı: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | blur | number | Hayır | `20` | Arka plan için Gauss bulanıklık sigması (2-50) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/blur-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "16:9", "blur": 30}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 14100000 } ``` ## Notlar {#notes} * Daha yüksek bulanıklık değerleri daha yumuşak, daha soyut bir arka plan üretir. Daha düşük değerler daha fazla ayrıntıyı görünür tutar. * Video zaten hedef en boy oranıyla eşleşiyorsa, dosya değiştirilmeden döndürülür. * Düz renkli dolgu için bunun yerine En Boy Dolgusu aracını kullanın. --- --- url: https://docs.snapotter.com/nl/tools/image/bulk-rename.md description: Hernoem meerdere bestanden met een patroonsjabloon en download ze als ZIP. --- # Bulk hernoemen {#bulk-rename} Hernoem meerdere bestanden met een patroonsjabloon met plaatshouders voor index, opgevulde index en originele bestandsnaam. Retourneert een ZIP-archief met alle hernoemde bestanden. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` Accepteert multipart form data met meerdere bestanden en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | pattern | string | Nee | `"image-{{index}}"` | Naamgevingspatroon met plaatshouders (max. 1000 tekens) | | startIndex | number | Nee | `1` | Startindexnummer | ### Patroonplaatshouders {#pattern-placeholders} | Plaatshouder | Beschrijving | Voorbeeld | |-------------|-------------|---------| | `{{index}}` | Volgnummer beginnend vanaf `startIndex` | `1`, `2`, `3` | | `{{padded}}` | Volgnummer opgevuld met nullen | `01`, `02`, `03` | | `{{original}}` | Originele bestandsnaam zonder extensie | `photo`, `IMG_001` | De originele bestandsextensie blijft altijd behouden. ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` Dit produceert: `vacation-1.jpg`, `vacation-2.jpg`, `vacation-3.jpg` Met gebruik van de originele bestandsnaam: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` Dit produceert: `2024-trip-IMG_001-1.jpg`, `2024-trip-IMG_002-2.jpg` ## Voorbeeldantwoord {#example-response} Het antwoord is een ZIP-bestand dat direct wordt gestreamd (geen JSON-antwoord). De antwoordheaders zijn: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Opmerkingen {#notes} * Deze tool verwerkt geen afbeeldingen. Hij hernoemt alleen bestanden en verpakt ze in een ZIP-archief. * De opvulbreedte met nullen voor `{{padded}}` wordt automatisch bepaald op basis van het totale aantal bestanden (100 bestanden zouden bijvoorbeeld 3-cijferige opvulling gebruiken: `001`, `002`, enz.). * Bestandsextensies blijven behouden van de originele bestandsnamen. * Bestandsnamen worden opgeschoond om onveilige tekens te verwijderen. * Er moet ten minste één bestand worden opgegeven. --- --- url: https://docs.snapotter.com/hi/tools/image/bulk-rename.md description: >- पैटर्न टेम्प्लेट का उपयोग करके कई फ़ाइलों का नाम बदलें और ZIP के रूप में डाउनलोड करें। --- # Bulk Rename {#bulk-rename} इंडेक्स, पैडेड इंडेक्स, और मूल फ़ाइल नाम के लिए प्लेसहोल्डर वाले पैटर्न टेम्प्लेट का उपयोग करके कई फ़ाइलों का नाम बदलें। सभी नाम-बदली गई फ़ाइलों वाला एक ZIP संग्रह लौटाता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` कई फ़ाइलों और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pattern | string | No | `"image-{{index}}"` | प्लेसहोल्डर के साथ नामकरण पैटर्न (अधिकतम 1000 वर्ण) | | startIndex | number | No | `1` | प्रारंभिक इंडेक्स संख्या | ### Pattern Placeholders {#pattern-placeholders} | Placeholder | Description | Example | |-------------|-------------|---------| | `{{index}}` | `startIndex` से शुरू होने वाली क्रमिक संख्या | `1`, `2`, `3` | | `{{padded}}` | शून्य-पैडेड क्रमिक संख्या | `01`, `02`, `03` | | `{{original}}` | एक्सटेंशन के बिना मूल फ़ाइल नाम | `photo`, `IMG_001` | मूल फ़ाइल एक्सटेंशन हमेशा संरक्षित रहता है। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` यह उत्पन्न करता है: `vacation-1.jpg`, `vacation-2.jpg`, `vacation-3.jpg` मूल फ़ाइल नाम का उपयोग करते हुए: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` यह उत्पन्न करता है: `2024-trip-IMG_001-1.jpg`, `2024-trip-IMG_002-2.jpg` ## Example Response {#example-response} प्रतिक्रिया एक ZIP फ़ाइल है जो सीधे स्ट्रीम की जाती है (JSON प्रतिक्रिया नहीं)। प्रतिक्रिया हेडर हैं: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Notes {#notes} * यह टूल छवियों को प्रोसेस नहीं करता। यह केवल फ़ाइलों का नाम बदलता है और उन्हें एक ZIP संग्रह में पैकेज करता है। * `{{padded}}` के लिए शून्य-पैडिंग चौड़ाई फ़ाइलों की कुल संख्या के आधार पर स्वचालित रूप से निर्धारित होती है (उदा. 100 फ़ाइलें 3-अंकीय पैडिंग का उपयोग करेंगी: `001`, `002`, आदि)। * फ़ाइल एक्सटेंशन मूल फ़ाइल नामों से संरक्षित रहते हैं। * असुरक्षित वर्णों को हटाने के लिए फ़ाइल नामों को स्वच्छ किया जाता है। * कम से कम एक फ़ाइल प्रदान की जानी चाहिए। --- --- url: https://docs.snapotter.com/ja/tools/image/bulk-rename.md description: パターンテンプレートを使用して複数のファイルをリネームし、ZIP としてダウンロードします。 --- # Bulk Rename {#bulk-rename} インデックス、ゼロ埋めインデックス、元のファイル名のプレースホルダーを持つパターンテンプレートを使用して、複数のファイルをリネームします。リネームされたすべてのファイルを含む ZIP アーカイブを返します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` 複数のファイルと JSON の `settings` フィールドを含むマルチパートフォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pattern | string | No | `"image-{{index}}"` | プレースホルダーを含む命名パターン (最大 1000 文字) | | startIndex | number | No | `1` | 開始インデックス番号 | ### Pattern Placeholders {#pattern-placeholders} | Placeholder | Description | Example | |-------------|-------------|---------| | `{{index}}` | `startIndex` から始まる連番 | `1`、`2`、`3` | | `{{padded}}` | ゼロ埋めされた連番 | `01`、`02`、`03` | | `{{original}}` | 拡張子なしの元のファイル名 | `photo`、`IMG_001` | 元のファイル拡張子は常に保持されます。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` これは次を生成します: `vacation-1.jpg`、`vacation-2.jpg`、`vacation-3.jpg` 元のファイル名を使用する: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` これは次を生成します: `2024-trip-IMG_001-1.jpg`、`2024-trip-IMG_002-2.jpg` ## Example Response {#example-response} レスポンスは (JSON レスポンスではなく) 直接ストリームされる ZIP ファイルです。レスポンスヘッダーは次のとおりです: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Notes {#notes} * このツールは画像を処理しません。ファイルをリネームして ZIP アーカイブにパッケージ化するだけです。 * `{{padded}}` のゼロ埋め幅は、ファイルの総数に基づいて自動的に決定されます (例: 100 個のファイルの場合は 3 桁のゼロ埋めを使用: `001`、`002` など)。 * ファイル拡張子は元のファイル名から保持されます。 * ファイル名は安全でない文字を除去するためにサニタイズされます。 * 少なくとも 1 つのファイルを指定する必要があります。 --- --- url: https://docs.snapotter.com/ko/tools/image/bulk-rename.md description: 패턴 템플릿을 사용하여 여러 파일의 이름을 바꾸고 ZIP으로 다운로드합니다. --- # Bulk Rename {#bulk-rename} 인덱스, 자릿수를 맞춘 인덱스, 원본 파일명에 대한 자리 표시자가 있는 패턴 템플릿을 사용하여 여러 파일의 이름을 바꿉니다. 이름이 바뀐 모든 파일을 담은 ZIP 아카이브를 반환합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` 여러 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | pattern | string | 아니요 | `"image-{{index}}"` | 자리 표시자가 있는 이름 지정 패턴 (최대 1000자) | | startIndex | number | 아니요 | `1` | 시작 인덱스 번호 | ### 패턴 자리 표시자 {#pattern-placeholders} | 자리 표시자 | 설명 | 예시 | |-------------|-------------|---------| | `{{index}}` | `startIndex`부터 시작하는 순차 번호 | `1`, `2`, `3` | | `{{padded}}` | 0으로 채워진 순차 번호 | `01`, `02`, `03` | | `{{original}}` | 확장자 없는 원본 파일명 | `photo`, `IMG_001` | 원본 파일 확장자는 항상 보존됩니다. ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` 다음을 생성합니다: `vacation-1.jpg`, `vacation-2.jpg`, `vacation-3.jpg` 원본 파일명 사용: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` 다음을 생성합니다: `2024-trip-IMG_001-1.jpg`, `2024-trip-IMG_002-2.jpg` ## 응답 예시 {#example-response} 응답은 (JSON 응답이 아닌) 직접 스트리밍되는 ZIP 파일입니다. 응답 헤더는 다음과 같습니다: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## 참고 사항 {#notes} * 이 도구는 이미지를 처리하지 않습니다. 파일 이름만 바꾸고 ZIP 아카이브로 패키징합니다. * `{{padded}}`의 0 채우기 자릿수는 전체 파일 수에 따라 자동으로 결정됩니다(예: 100개 파일은 3자리 채우기 사용: `001`, `002` 등). * 파일 확장자는 원본 파일명에서 보존됩니다. * 파일명은 안전하지 않은 문자를 제거하도록 정리됩니다. * 최소 하나의 파일이 제공되어야 합니다. --- --- url: https://docs.snapotter.com/th/tools/image/bulk-rename.md description: เปลี่ยนชื่อไฟล์หลายไฟล์โดยใช้เทมเพลตรูปแบบ และดาวน์โหลดเป็น ZIP --- # Bulk Rename {#bulk-rename} เปลี่ยนชื่อไฟล์หลายไฟล์โดยใช้เทมเพลตรูปแบบพร้อมตัวยึดตำแหน่งสำหรับดัชนี, ดัชนีที่เติมเลขศูนย์ และชื่อไฟล์ต้นฉบับ ส่งคืนไฟล์เก็บถาวร ZIP ที่มีไฟล์ที่เปลี่ยนชื่อทั้งหมด ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` รับข้อมูลแบบ multipart form data พร้อมไฟล์หลายไฟล์และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pattern | string | No | `"image-{{index}}"` | รูปแบบการตั้งชื่อพร้อมตัวยึดตำแหน่ง (สูงสุด 1000 ตัวอักษร) | | startIndex | number | No | `1` | หมายเลขดัชนีเริ่มต้น | ### Pattern Placeholders {#pattern-placeholders} | Placeholder | Description | Example | |-------------|-------------|---------| | `{{index}}` | หมายเลขลำดับที่เริ่มจาก `startIndex` | `1`, `2`, `3` | | `{{padded}}` | หมายเลขลำดับที่เติมเลขศูนย์ | `01`, `02`, `03` | | `{{original}}` | ชื่อไฟล์ต้นฉบับโดยไม่มีนามสกุล | `photo`, `IMG_001` | นามสกุลไฟล์ต้นฉบับจะถูกรักษาไว้เสมอ ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` นี่จะผลิต: `vacation-1.jpg`, `vacation-2.jpg`, `vacation-3.jpg` ใช้ชื่อไฟล์ต้นฉบับ: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` นี่จะผลิต: `2024-trip-IMG_001-1.jpg`, `2024-trip-IMG_002-2.jpg` ## Example Response {#example-response} การตอบสนองเป็นไฟล์ ZIP ที่สตรีมโดยตรง (ไม่ใช่การตอบสนอง JSON) ส่วนหัวของการตอบสนองคือ: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Notes {#notes} * เครื่องมือนี้ไม่ประมวลผลรูปภาพ เพียงเปลี่ยนชื่อไฟล์และแพ็กลงในไฟล์เก็บถาวร ZIP เท่านั้น * ความกว้างของการเติมเลขศูนย์สำหรับ `{{padded}}` กำหนดโดยอัตโนมัติตามจำนวนไฟล์ทั้งหมด (เช่น 100 ไฟล์จะใช้การเติม 3 หลัก: `001`, `002` เป็นต้น) * นามสกุลไฟล์ถูกรักษาไว้จากชื่อไฟล์ต้นฉบับ * ชื่อไฟล์ถูกทำให้ปลอดภัยโดยลบอักขระที่ไม่ปลอดภัย * ต้องมีไฟล์อย่างน้อยหนึ่งไฟล์ --- --- url: https://docs.snapotter.com/vi/tools/image/bulk-rename.md description: Đổi tên nhiều tệp bằng một mẫu khuôn dạng và tải xuống dưới dạng ZIP. --- # Bulk Rename {#bulk-rename} Đổi tên nhiều tệp bằng một mẫu khuôn dạng với các trình giữ chỗ cho chỉ số, chỉ số được đệm và tên tệp gốc. Trả về một kho lưu trữ ZIP chứa tất cả tệp đã đổi tên. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` Chấp nhận dữ liệu biểu mẫu multipart với nhiều tệp và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pattern | string | No | `"image-{{index}}"` | Mẫu đặt tên với các trình giữ chỗ (tối đa 1000 ký tự) | | startIndex | number | No | `1` | Số chỉ số bắt đầu | ### Pattern Placeholders {#pattern-placeholders} | Placeholder | Description | Example | |-------------|-------------|---------| | `{{index}}` | Số tuần tự bắt đầu từ `startIndex` | `1`, `2`, `3` | | `{{padded}}` | Số tuần tự được đệm bằng số không | `01`, `02`, `03` | | `{{original}}` | Tên tệp gốc không có phần mở rộng | `photo`, `IMG_001` | Phần mở rộng tệp gốc luôn được giữ nguyên. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` Điều này tạo ra: `vacation-1.jpg`, `vacation-2.jpg`, `vacation-3.jpg` Sử dụng tên tệp gốc: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` Điều này tạo ra: `2024-trip-IMG_001-1.jpg`, `2024-trip-IMG_002-2.jpg` ## Example Response {#example-response} Phản hồi là một tệp ZIP được truyền trực tiếp (không phải phản hồi JSON). Các tiêu đề phản hồi là: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Notes {#notes} * Công cụ này không xử lý hình ảnh. Nó chỉ đổi tên tệp và đóng gói chúng vào một kho lưu trữ ZIP. * Độ rộng đệm số không cho `{{padded}}` được xác định tự động dựa trên tổng số tệp (ví dụ 100 tệp sẽ dùng đệm 3 chữ số: `001`, `002`, v.v.). * Phần mở rộng tệp được giữ nguyên từ tên tệp gốc. * Tên tệp được làm sạch để loại bỏ các ký tự không an toàn. * Phải cung cấp ít nhất một tệp. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/bulk-rename.md description: 使用模式模板重命名多个文件并以 ZIP 下载。 --- # Bulk Rename {#bulk-rename} 使用带有索引、补零索引和原始文件名占位符的模式模板重命名多个文件。返回一个包含所有重命名文件的 ZIP 归档。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` 接受包含多个文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pattern | string | 否 | `"image-{{index}}"` | 带占位符的命名模式(最多 1000 个字符) | | startIndex | number | 否 | `1` | 起始索引编号 | ### Pattern Placeholders {#pattern-placeholders} | Placeholder | Description | Example | |-------------|-------------|---------| | `{{index}}` | 从 `startIndex` 开始的顺序编号 | `1`、`2`、`3` | | `{{padded}}` | 补零的顺序编号 | `01`、`02`、`03` | | `{{original}}` | 不含扩展名的原始文件名 | `photo`、`IMG_001` | 原始文件扩展名始终会被保留。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` 这会产生:`vacation-1.jpg`、`vacation-2.jpg`、`vacation-3.jpg` 使用原始文件名: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` 这会产生:`2024-trip-IMG_001-1.jpg`、`2024-trip-IMG_002-2.jpg` ## Example Response {#example-response} 响应是直接流式传输的 ZIP 文件(不是 JSON 响应)。响应标头为: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Notes {#notes} * 此工具不处理图像。它只重命名文件并将其打包成 ZIP 归档。 * `{{padded}}` 的补零宽度会根据文件总数自动确定(例如 100 个文件会使用 3 位补零:`001`、`002` 等)。 * 文件扩展名会从原始文件名中保留。 * 文件名会被清理以移除不安全字符。 * 至少必须提供一个文件。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/bulk-rename.md description: 使用模式範本重新命名多個檔案並以 ZIP 下載。 --- # Bulk Rename {#bulk-rename} 使用帶有索引、補零索引及原始檔名預留位置的模式範本重新命名多個檔案。回傳包含所有已重新命名檔案的 ZIP 壓縮檔。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` 接受包含多個檔案及 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pattern | string | No | `"image-{{index}}"` | 帶有預留位置的命名模式(最多 1000 個字元) | | startIndex | number | No | `1` | 起始索引編號 | ### Pattern Placeholders {#pattern-placeholders} | Placeholder | Description | Example | |-------------|-------------|---------| | `{{index}}` | 從 `startIndex` 開始的序號 | `1`、`2`、`3` | | `{{padded}}` | 補零的序號 | `01`、`02`、`03` | | `{{original}}` | 不含副檔名的原始檔名 | `photo`、`IMG_001` | 原始檔案副檔名一律會保留。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` 這會產生:`vacation-1.jpg`、`vacation-2.jpg`、`vacation-3.jpg` 使用原始檔名: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` 這會產生:`2024-trip-IMG_001-1.jpg`、`2024-trip-IMG_002-2.jpg` ## Example Response {#example-response} 回應是直接串流的 ZIP 檔案(而非 JSON 回應)。回應標頭為: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Notes {#notes} * 此工具不會處理影像。它只會重新命名檔案並將其打包成 ZIP 壓縮檔。 * `{{padded}}` 的補零寬度會根據檔案總數自動決定(例如 100 個檔案會使用 3 位數補零:`001`、`002` 等)。 * 檔案副檔名會從原始檔名保留。 * 檔名會經過清理以移除不安全的字元。 * 至少必須提供一個檔案。 --- --- url: https://docs.snapotter.com/id/tools/image/blur-background.md description: Buramkan latar belakang sambil menjaga subjek tetap tajam menggunakan AI. --- # Buramkan Latar Belakang {#blur-background} Buramkan latar belakang gambar sambil menjaga subjek tetap tajam. Model AI mengisolasi subjek, menerapkan blur pada latar belakang asli, dan menggabungkan subjek tajam di atasnya. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` Menerima data formulir multipart dengan berkas gambar dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | intensity | integer | Tidak | `50` | Intensitas blur (1-100) | | feather | integer | Tidak | `0` | Radius pelunakan tepi (0-20) | | format | string | Tidak | `"png"` | Format keluaran: `png` atau `webp` | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Lacak progres melalui SSE di `GET /api/v1/jobs/{jobId}/progress`. Ketika pekerjaan selesai, aliran SSE memancarkan peristiwa `completed` dengan URL unduhan. ## Catatan {#notes} * Ini adalah alat bertenaga AI yang mengembalikan `202 Accepted` dan memproses secara asinkron. Sambungkan ke endpoint SSE untuk menerima pembaruan progres dan hasil akhir. * Memerlukan bundel fitur **background-removal** untuk dipasang. Mengembalikan `501` jika bundel tidak tersedia. * Nilai intensitas yang lebih tinggi menghasilkan efek blur yang lebih kuat. Nilai di atas 80 menciptakan pemisahan mirip bokeh yang jelas. * Input HEIC, RAW, PSD, dan SVG didekode secara otomatis sebelum diproses. --- --- url: https://docs.snapotter.com/ar/tools/video/burn-subtitles.md description: عرض الترجمات بشكل دائم على إطارات الفيديو. --- # Burn Subtitles {#burn-subtitles} عرض (تثبيت) الترجمات بشكل دائم من ملف SRT أو VTT أو ASS على كل إطار من إطارات الفيديو. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو وملف ترجمة. هذه نقطة نهاية غير متزامنة - تُرجع `202 Accepted` فوراً ويُبَثّ التقدم عبر SSE على `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | حجم خط الترجمة بالبكسل (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * ارفع ملفين: يجب أن يكون الأول فيديو، ويجب أن يكون الثاني ملف ترجمة (.srt أو .vtt أو .ass). * الترجمات المثبّتة تصبح جزءاً دائماً من الفيديو ولا يمكن للمشاهد إيقافها. للحصول على ترجمات قابلة للتبديل، استخدم أداة Embed Subtitles بدلاً من ذلك. * تحديثات التقدم متاحة عبر SSE على `GET /api/v1/jobs/{jobId}/progress` حتى تكتمل المهمة. --- --- url: https://docs.snapotter.com/de/tools/video/burn-subtitles.md description: Untertitel dauerhaft in Videoframes einbrennen. --- # Burn Subtitles {#burn-subtitles} Untertitel aus einer SRT-, VTT- oder ASS-Datei dauerhaft (fest kodiert) in jeden Frame eines Videos einbrennen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Nimmt Multipart-Formulardaten mit einer Videodatei und einer Untertiteldatei entgegen. Dies ist ein asynchroner Endpunkt: Er gibt sofort `202 Accepted` zurück, und der Fortschritt wird per SSE unter `GET /api/v1/jobs/{jobId}/progress` gestreamt. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Schriftgröße der Untertitel in Pixeln (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Laden Sie zwei Dateien hoch: Die erste muss ein Video sein, die zweite eine Untertiteldatei (.srt, .vtt oder .ass). * Eingebrannte Untertitel sind dauerhaft Teil des Videos und können vom Betrachter nicht ausgeschaltet werden. Für umschaltbare Untertitel verwenden Sie stattdessen das Tool Embed Subtitles. * Fortschrittsaktualisierungen sind per SSE unter `GET /api/v1/jobs/{jobId}/progress` verfügbar, bis der Job abgeschlossen ist. --- --- url: https://docs.snapotter.com/es/tools/video/burn-subtitles.md description: Renderiza subtítulos de forma permanente sobre los fotogramas del vídeo. --- # Burn Subtitles {#burn-subtitles} Renderiza de forma permanente (incrusta) subtítulos de un archivo SRT, VTT o ASS sobre cada fotograma de un vídeo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Acepta datos de formulario multipart con un archivo de vídeo y un archivo de subtítulos. Este es un endpoint asíncrono: devuelve `202 Accepted` de inmediato y el progreso se transmite vía SSE en `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Tamaño de fuente del subtítulo en píxeles (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Sube dos archivos: el primero debe ser un vídeo y el segundo un archivo de subtítulos (.srt, .vtt o .ass). * Los subtítulos incrustados forman parte permanente del vídeo y el espectador no puede desactivarlos. Para subtítulos que se puedan activar y desactivar, usa la herramienta Embed Subtitles en su lugar. * Las actualizaciones de progreso están disponibles vía SSE en `GET /api/v1/jobs/{jobId}/progress` hasta que el trabajo se completa. --- --- url: https://docs.snapotter.com/fr/tools/video/burn-subtitles.md description: Incruste définitivement les sous-titres sur les images de la vidéo. --- # Burn Subtitles {#burn-subtitles} Incruste définitivement (en dur) les sous-titres d'un fichier SRT, VTT ou ASS sur chaque image d'une vidéo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Accepte des données de formulaire multipart avec un fichier vidéo et un fichier de sous-titres. Il s'agit d'un point de terminaison asynchrone : il renvoie immédiatement `202 Accepted` et la progression est diffusée via SSE sur `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Taille de police des sous-titres en pixels (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Téléversez deux fichiers : le premier doit être une vidéo, le second doit être un fichier de sous-titres (.srt, .vtt ou .ass). * Les sous-titres incrustés font partie intégrante de la vidéo et ne peuvent pas être désactivés par le spectateur. Pour des sous-titres activables, utilisez plutôt l'outil Embed Subtitles. * Les mises à jour de progression sont disponibles via SSE sur `GET /api/v1/jobs/{jobId}/progress` jusqu'à la fin de la tâche. --- --- url: https://docs.snapotter.com/hi/tools/video/burn-subtitles.md description: सबटाइटल को वीडियो फ्रेम पर स्थायी रूप से रेंडर करें। --- # Burn Subtitles {#burn-subtitles} किसी SRT, VTT, या ASS फ़ाइल से सबटाइटल को वीडियो के हर फ्रेम पर स्थायी रूप से रेंडर (हार्ड-कोड) करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` एक वीडियो फ़ाइल और एक सबटाइटल फ़ाइल के साथ multipart form data स्वीकार करता है। यह एक async endpoint है - यह तुरंत `202 Accepted` लौटाता है और प्रगति `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से स्ट्रीम की जाती है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | पिक्सेल में सबटाइटल फ़ॉन्ट आकार (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * दो फ़ाइलें अपलोड करें: पहली एक वीडियो होनी चाहिए, दूसरी एक सबटाइटल फ़ाइल (.srt, .vtt, या .ass) होनी चाहिए। * बर्न किए गए सबटाइटल स्थायी रूप से वीडियो का हिस्सा होते हैं और दर्शक द्वारा बंद नहीं किए जा सकते। टॉगल किए जा सकने वाले सबटाइटल के लिए, इसके बजाय Embed Subtitles टूल का उपयोग करें। * जॉब पूरा होने तक `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति अपडेट उपलब्ध रहते हैं। --- --- url: https://docs.snapotter.com/id/tools/video/burn-subtitles.md description: Merender subtitle secara permanen ke dalam frame video. --- # Burn Subtitles {#burn-subtitles} Merender secara permanen (hard-code) subtitle dari file SRT, VTT, atau ASS ke setiap frame video. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Menerima multipart form data dengan file video dan file subtitle. Ini adalah endpoint asinkron - ia langsung mengembalikan `202 Accepted` dan progres dialirkan melalui SSE di `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Ukuran font subtitle dalam piksel (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Unggah dua file: yang pertama harus berupa video, yang kedua harus berupa file subtitle (.srt, .vtt, atau .ass). * Subtitle yang di-burn menjadi bagian permanen dari video dan tidak dapat dimatikan oleh penonton. Untuk subtitle yang bisa dialihkan, gunakan alat Embed Subtitles sebagai gantinya. * Pembaruan progres tersedia melalui SSE di `GET /api/v1/jobs/{jobId}/progress` hingga job selesai. --- --- url: https://docs.snapotter.com/it/tools/video/burn-subtitles.md description: Renderizza in modo permanente i sottotitoli sui fotogrammi del video. --- # Burn Subtitles {#burn-subtitles} Renderizza in modo permanente (hard-code) i sottotitoli da un file SRT, VTT o ASS su ogni fotogramma di un video. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Accetta dati form multipart con un file video e un file di sottotitoli. Questo è un endpoint asincrono: restituisce `202 Accepted` immediatamente e l'avanzamento viene trasmesso tramite SSE su `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Dimensione del carattere dei sottotitoli in pixel (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Carica due file: il primo deve essere un video, il secondo deve essere un file di sottotitoli (.srt, .vtt o .ass). * I sottotitoli renderizzati sono parte permanente del video e non possono essere disattivati dallo spettatore. Per sottotitoli attivabili e disattivabili, usa invece lo strumento Embed Subtitles. * Gli aggiornamenti sull'avanzamento sono disponibili tramite SSE su `GET /api/v1/jobs/{jobId}/progress` finché il job non è completato. --- --- url: https://docs.snapotter.com/ja/tools/video/burn-subtitles.md description: 字幕を動画のフレームに恒久的に焼き込みます。 --- # Burn Subtitles {#burn-subtitles} SRT、VTT、または ASS ファイルの字幕を、動画のすべてのフレームに恒久的にレンダリング(ハードコード)します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` 動画ファイルと字幕ファイルを含む multipart フォームデータを受け付けます。これは非同期エンドポイントで、即座に `202 Accepted` を返し、進捗は `GET /api/v1/jobs/{jobId}/progress` の SSE でストリーミングされます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | 字幕のフォントサイズ(ピクセル単位、8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * ファイルを2つアップロードします。1つ目は動画、2つ目は字幕ファイル(.srt、.vtt、または .ass)である必要があります。 * 焼き込まれた字幕は動画の恒久的な一部となり、視聴者側でオフにすることはできません。切り替え可能な字幕には、代わりに Embed Subtitles ツールを使用してください。 * ジョブが完了するまで、進捗の更新は `GET /api/v1/jobs/{jobId}/progress` の SSE で確認できます。 --- --- url: https://docs.snapotter.com/ko/tools/video/burn-subtitles.md description: 자막을 비디오 프레임에 영구적으로 렌더링합니다. --- # Burn Subtitles {#burn-subtitles} SRT, VTT 또는 ASS 파일의 자막을 비디오의 모든 프레임에 영구적으로 렌더링(하드코딩)합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` 비디오 파일과 자막 파일이 담긴 multipart form data를 받습니다. 이 엔드포인트는 비동기입니다. 즉시 `202 Accepted`를 반환하고 진행 상황은 `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 스트리밍됩니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | 자막 글꼴 크기(픽셀, 8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 파일 두 개를 업로드하세요. 첫 번째는 비디오여야 하고 두 번째는 자막 파일(.srt, .vtt 또는 .ass)이어야 합니다. * 구워진 자막은 비디오의 영구적인 일부가 되며 시청자가 끌 수 없습니다. 켜고 끌 수 있는 자막을 원한다면 대신 Embed Subtitles 도구를 사용하세요. * 작업이 완료될 때까지 진행 상황 업데이트는 `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 제공됩니다. --- --- url: https://docs.snapotter.com/nl/tools/video/burn-subtitles.md description: Ondertitels permanent in videoframes renderen. --- # Burn Subtitles {#burn-subtitles} Render (hardcode) ondertitels uit een SRT-, VTT- of ASS-bestand permanent in elk frame van een video. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Accepteert multipart form data met een videobestand en een ondertitelbestand. Dit is een async endpoint: het retourneert direct `202 Accepted` en de voortgang wordt via SSE gestreamd op `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | fontSize | integer | Nee | `24` | Lettergrootte van de ondertitels in pixels (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Upload twee bestanden: het eerste moet een video zijn, het tweede moet een ondertitelbestand zijn (.srt, .vtt of .ass). * Ingebrande ondertitels zijn permanent onderdeel van de video en kunnen door de kijker niet worden uitgezet. Gebruik voor in- en uitschakelbare ondertitels in plaats daarvan de tool Embed Subtitles. * Voortgangsupdates zijn beschikbaar via SSE op `GET /api/v1/jobs/{jobId}/progress` totdat de taak is voltooid. --- --- url: https://docs.snapotter.com/pl/tools/video/burn-subtitles.md description: Trwałe wtapianie napisów w klatki wideo. --- # Burn Subtitles {#burn-subtitles} Trwale renderuje (wtapia na stałe) napisy z pliku SRT, VTT lub ASS na każdą klatkę wideo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Przyjmuje dane formularza multipart z plikiem wideo i plikiem napisów. To jest endpoint asynchroniczny - zwraca `202 Accepted` natychmiast, a postęp jest przesyłany strumieniowo przez SSE pod `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | fontSize | integer | Nie | `24` | Rozmiar czcionki napisów w pikselach (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Prześlij dwa pliki: pierwszy musi być wideo, drugi musi być plikiem napisów (.srt, .vtt lub .ass). * Wtopione napisy stają się trwałą częścią wideo i nie mogą zostać wyłączone przez widza. Aby uzyskać przełączalne napisy, użyj zamiast tego narzędzia Embed Subtitles. * Aktualizacje postępu są dostępne przez SSE pod `GET /api/v1/jobs/{jobId}/progress` aż do zakończenia zadania. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/burn-subtitles.md description: Renderiza legendas permanentemente nos quadros do vídeo. --- # Burn Subtitles {#burn-subtitles} Renderiza permanentemente (embute) legendas de um arquivo SRT, VTT ou ASS em cada quadro de um vídeo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Aceita dados de formulário multipart com um arquivo de vídeo e um arquivo de legenda. Este é um endpoint assíncrono - ele retorna `202 Accepted` imediatamente e o progresso é transmitido via SSE em `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | fontSize | integer | Não | `24` | Tamanho da fonte da legenda em pixels (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Envie dois arquivos: o primeiro deve ser um vídeo, o segundo deve ser um arquivo de legenda (.srt, .vtt ou .ass). * As legendas embutidas passam a fazer parte permanente do vídeo e não podem ser desativadas pelo espectador. Para legendas que podem ser ativadas e desativadas, use a ferramenta Embed Subtitles. * As atualizações de progresso ficam disponíveis via SSE em `GET /api/v1/jobs/{jobId}/progress` até que o job seja concluído. --- --- url: https://docs.snapotter.com/ru/tools/video/burn-subtitles.md description: Постоянное встраивание субтитров в кадры видео. --- # Burn Subtitles {#burn-subtitles} Постоянное встраивание (жёсткое кодирование) субтитров из файла SRT, VTT или ASS в каждый кадр видео. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Принимает multipart form data с файлом видео и файлом субтитров. Это асинхронная конечная точка: она сразу возвращает `202 Accepted`, а прогресс передаётся через SSE по адресу `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Размер шрифта субтитров в пикселях (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Загрузите два файла: первым должно быть видео, вторым - файл субтитров (.srt, .vtt или .ass). * Встроенные субтитры становятся постоянной частью видео, и зритель не может их отключить. Для переключаемых субтитров используйте вместо этого инструмент Embed Subtitles. * Обновления прогресса доступны через SSE по адресу `GET /api/v1/jobs/{jobId}/progress` до завершения задания. --- --- url: https://docs.snapotter.com/th/tools/video/burn-subtitles.md description: เรนเดอร์คำบรรยายลงบนเฟรมของวิดีโออย่างถาวร --- # Burn Subtitles {#burn-subtitles} เรนเดอร์ (ฝังถาวร) คำบรรยายจากไฟล์ SRT, VTT หรือ ASS ลงบนทุกเฟรมของวิดีโอ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอและไฟล์คำบรรยาย นี่คือ endpoint แบบ async โดยจะคืนค่า `202 Accepted` ทันที และความคืบหน้าจะถูกสตรีมผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | ขนาดฟอนต์ของคำบรรยายเป็นพิกเซล (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * อัปโหลดสองไฟล์: ไฟล์แรกต้องเป็นวิดีโอ ไฟล์ที่สองต้องเป็นไฟล์คำบรรยาย (.srt, .vtt หรือ .ass) * คำบรรยายที่ฝังลงไปจะเป็นส่วนหนึ่งของวิดีโออย่างถาวรและผู้ชมไม่สามารถปิดได้ หากต้องการคำบรรยายที่เปิด/ปิดได้ ให้ใช้เครื่องมือ Embed Subtitles แทน * การอัปเดตความคืบหน้าดูได้ผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` จนกว่างานจะเสร็จสมบูรณ์ --- --- url: https://docs.snapotter.com/tr/tools/video/burn-subtitles.md description: Altyazıları kalıcı olarak video karelerine işleyin. --- # Burn Subtitles {#burn-subtitles} Bir SRT, VTT veya ASS dosyasındaki altyazıları bir videonun her karesine kalıcı olarak işleyin (sabit kodlayın). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Bir video dosyası ve bir altyazı dosyası içeren multipart form data kabul eder. Bu asenkron bir uç noktadır; hemen `202 Accepted` döndürür ve ilerleme `GET /api/v1/jobs/{jobId}/progress` adresinde SSE ile aktarılır. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Piksel cinsinden altyazı yazı tipi boyutu (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * İki dosya yükleyin: ilki bir video, ikincisi bir altyazı dosyası (.srt, .vtt veya .ass) olmalıdır. * İşlenen altyazılar videonun kalıcı bir parçasıdır ve izleyici tarafından kapatılamaz. Açılıp kapatılabilen altyazılar için bunun yerine Embed Subtitles aracını kullanın. * İş tamamlanana kadar ilerleme güncellemeleri `GET /api/v1/jobs/{jobId}/progress` adresinde SSE ile sunulur. --- --- url: https://docs.snapotter.com/uk/tools/video/burn-subtitles.md description: Назавжди вбудовує субтитри в кадри відео. --- # Burn Subtitles {#burn-subtitles} Назавжди рендерить (жорстко вбудовує) субтитри з файлу SRT, VTT або ASS у кожен кадр відео. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Приймає дані форми multipart із відеофайлом і файлом субтитрів. Це асинхронний ендпоінт: він одразу повертає `202 Accepted`, а прогрес передається через SSE за адресою `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Розмір шрифту субтитрів у пікселях (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Завантажте два файли: перший має бути відео, другий має бути файлом субтитрів (.srt, .vtt або .ass). * Вбудовані субтитри назавжди стають частиною відео, і глядач не може їх вимкнути. Для перемикних субтитрів використовуйте натомість інструмент Embed Subtitles. * Оновлення прогресу доступні через SSE за адресою `GET /api/v1/jobs/{jobId}/progress` до завершення завдання. --- --- url: https://docs.snapotter.com/vi/tools/video/burn-subtitles.md description: Kết xuất phụ đề vĩnh viễn lên các khung hình video. --- # Burn Subtitles {#burn-subtitles} Kết xuất vĩnh viễn (hard-code) phụ đề từ file SRT, VTT hoặc ASS lên mọi khung hình của video. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` Nhận multipart form data gồm một file video và một file phụ đề. Đây là endpoint bất đồng bộ - nó trả về `202 Accepted` ngay lập tức và tiến độ được truyền qua SSE tại `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | Cỡ chữ phụ đề tính bằng pixel (8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Tải lên hai file: file đầu tiên phải là video, file thứ hai phải là file phụ đề (.srt, .vtt hoặc .ass). * Phụ đề đã burn là một phần vĩnh viễn của video và người xem không thể tắt được. Để có phụ đề bật/tắt được, hãy dùng công cụ Embed Subtitles. * Cập nhật tiến độ có sẵn qua SSE tại `GET /api/v1/jobs/{jobId}/progress` cho đến khi tác vụ hoàn tất. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/burn-subtitles.md description: 将字幕永久渲染到视频画面上。 --- # Burn Subtitles {#burn-subtitles} 将 SRT、VTT 或 ASS 文件中的字幕永久渲染(硬编码)到视频的每一帧画面上。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` 接受包含视频文件和字幕文件的 multipart 表单数据。这是一个异步端点:它会立即返回 `202 Accepted`,进度通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 处流式传输。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | 字幕字号,单位为像素(8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 上传两个文件:第一个必须是视频,第二个必须是字幕文件(.srt、.vtt 或 .ass)。 * 烧录的字幕会永久成为视频的一部分,观看者无法关闭。若需要可切换的字幕,请改用 Embed Subtitles 工具。 * 在任务完成前,可通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 处获取进度更新。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/burn-subtitles.md description: 將字幕永久燒錄到影片畫面上。 --- # Burn Subtitles {#burn-subtitles} 將 SRT、VTT 或 ASS 檔案中的字幕永久渲染(硬編碼)到影片的每一個畫面上。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/burn-subtitles` 接受包含一個影片檔案和一個字幕檔案的 multipart form data。這是一個非同步端點,它會立即回傳 `202 Accepted`,進度則透過 SSE 於 `GET /api/v1/jobs/{jobId}/progress` 串流傳送。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fontSize | integer | No | `24` | 字幕字型大小(以像素為單位,8-72) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/burn-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"fontSize": 28}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 上傳兩個檔案:第一個必須是影片,第二個必須是字幕檔案(.srt、.vtt 或 .ass)。 * 燒錄的字幕會永久成為影片的一部分,觀看者無法將其關閉。若需要可切換的字幕,請改用 Embed Subtitles 工具。 * 在工作完成之前,可透過 SSE 於 `GET /api/v1/jobs/{jobId}/progress` 取得進度更新。 --- --- url: https://docs.snapotter.com/es/tools/image/find-duplicates.md description: Detecta imágenes duplicadas y casi duplicadas mediante hashing perceptual. --- # Buscar duplicados {#find-duplicates} Sube varias imágenes para detectar duplicados y casi duplicados mediante hashing perceptual (dHash). Agrupa las imágenes similares, identifica la versión de mejor calidad de cada grupo y calcula el ahorro de espacio potencial. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` Acepta datos de formulario multipart con varios archivos de imagen y un campo JSON `settings` opcional. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | threshold | number | No | `8` | Distancia de Hamming máxima para considerar imágenes como duplicadas (0 a 20). Menor = coincidencia más estricta | ### Campos de archivo {#file-fields} Sube al menos 2 archivos de imagen en la solicitud multipart (todos usando el nombre de campo `file` o cualquier nombre de campo para las partes de archivo). ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Ejemplo de respuesta {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Campos de la respuesta {#response-fields} | Campo | Tipo | Descripción | |-------|------|-------------| | totalImages | number | Número de imágenes analizadas correctamente | | duplicateGroups | array | Grupos de imágenes duplicadas | | uniqueImages | number | Número de imágenes que no forman parte de ningún grupo de duplicados | | spaceSaveable | number | Total de bytes que podrían ahorrarse al eliminar los duplicados que no son los mejores | | skippedFiles | array | Archivos que no pudieron procesarse (con nombre de archivo y motivo) | ### Objeto de grupo de duplicados {#duplicate-group-object} | Campo | Tipo | Descripción | |-------|------|-------------| | groupId | number | Identificador del grupo | | files | array | Imágenes de este grupo de duplicados | ### Objeto de archivo (dentro de un grupo) {#file-object-within-a-group} | Campo | Tipo | Descripción | |-------|------|-------------| | filename | string | Nombre de archivo original | | similarity | number | Porcentaje de similitud con la imagen de referencia (la primera del grupo) | | width | number | Ancho de la imagen en píxeles | | height | number | Alto de la imagen en píxeles | | fileSize | number | Tamaño del archivo en bytes | | format | string | Formato de la imagen | | isBest | boolean | Si es la versión de mayor calidad (más píxeles, archivo más grande) | | thumbnail | string o null | Miniatura JPEG en base64 (200 px de ancho) para la vista previa | ## Notas {#notes} * Usa un dHash de 128 bits (64 bits de fila + 64 bits de columna) para la detección de similitud perceptual. Esto detecta duplicados incluso tras redimensionar, recomprimir y realizar ediciones menores. * El umbral representa la distancia de Hamming máxima entre hashes. El valor predeterminado de 8 detecta casi duplicados evitando falsos positivos. Usa 0 para solo idénticos a nivel de píxel, o 15-20 para una coincidencia muy laxa. * La imagen "mejor" de cada grupo es la que tiene más píxeles (ancho x alto), con el tamaño del archivo como criterio de desempate. * Se requieren al menos 2 imágenes. Los archivos que no superan la validación o la decodificación se reportan en `skippedFiles` en lugar de hacer fallar toda la solicitud. * Las miniaturas son vistas previas JPEG de 200 px de ancho codificadas como URI de datos. * Se admiten todos los formatos comunes (HEIC, RAW, PSD, SVG se decodifican automáticamente). --- --- url: https://docs.snapotter.com/vi/guide/supported-formats.md description: >- Các định dạng tệp được hỗ trợ trên tất cả các modality - hơn 55 định dạng đầu vào hình ảnh, video, audio, PDF, và các định dạng tệp. --- # Các định dạng được hỗ trợ {#supported-formats} SnapOtter xử lý tệp trên năm modality: hình ảnh, video, audio, PDF, và tệp. Trang này liệt kê tất cả các định dạng được hỗ trợ. ## Định dạng hình ảnh {#image-formats} SnapOtter hỗ trợ hơn 55 định dạng hình ảnh đầu vào và 17 định dạng đầu ra. ## Định dạng đầu vào {#input-formats} ### Chuẩn Web (9) {#web-standards-9} | Định dạng | Phần mở rộng | Bộ giải mã | Ghi chú | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (native) | | | PNG | .png | Sharp (native) | Trích xuất khung hình đầu tiên của APNG | | WebP | .webp | Sharp (native) | | | GIF | .gif | Sharp (native) | Hỗ trợ ảnh động | | AVIF | .avif | Sharp (native) | | | SVG | .svg | Sharp (librsvg) | Được làm sạch chống XXE/SSRF | | SVGZ | .svgz | gunzip + Sharp | Bảo vệ chống Gzip bomb | | APNG | .apng | Sharp (native) | Chỉ khung hình đầu tiên | | JPEG XL | .jxl | djxl / ImageMagick | Dự phòng hai tầng | ### Chuyên nghiệp (7) {#professional-7} | Định dạng | Phần mở rộng | Bộ giải mã | Ghi chú | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (native) | Hỗ trợ nhiều trang | | PSD | .psd | ImageMagick | Composite được làm phẳng | | EPS | .eps, .epsf | ImageMagick + Ghostscript | Rasterize 300dpi, tăng cường bảo mật | | OpenEXR | .exr | ImageMagick | Chuyển đổi Linear-to-sRGB | | Radiance HDR | .hdr | ImageMagick | Chuyển đổi Linear-to-sRGB | | DPX | .dpx | ImageMagick | Chuyển đổi Log-to-sRGB | | Cineon | .cin | ImageMagick | Định dạng Film/VFX | ### Camera RAW (23) {#camera-raw-23} | Định dạng | Phần mở rộng | Hãng máy ảnh | Bộ giải mã | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (phổ quát) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (trước 2018) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (cũ) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (compact) | exiftool / ImageMagick + LibRaw | ### Định dạng hiện đại (3) {#modern-formats-3} | Định dạng | Phần mở rộng | Bộ giải mã | Ghi chú | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Điện ảnh số, chẩn đoán hình ảnh y tế | | QOI | .qoi | Codec TypeScript nội tuyến | Phát triển game, hệ thống nhúng | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | Ảnh iPhone | ### Cũ/Hệ thống (4) {#legacy-system-4} | Định dạng | Phần mở rộng | Bộ giải mã | Ghi chú | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | Trích xuất layer lớn nhất | | CUR | .cur | ImageMagick | Con trỏ Windows (biến thể ICO) | | TGA | .tga | ImageMagick | Chỉ phát hiện theo phần mở rộng | ### Khoa học và Game (2) {#scientific-and-gaming-2} | Định dạng | Phần mở rộng | Bộ giải mã | Ghi chú | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Thiên văn học (chuẩn NASA) | | DDS | .dds | ImageMagick | Texture game (DirectX) | ### Trao đổi (6) {#interchange-6} | Định dạng | Phần mở rộng | Bộ giải mã | Ghi chú | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (native) | Pixmap màu | | PGM | .pgm | Sharp (native) | Thang xám | | PBM | .pbm | Sharp (native) | Bitmap 1-bit | | PNM | .pnm | Sharp (native) | Định dạng tổng hợp | | PAM | .pam | Sharp (native) | Bản đồ tùy ý | | PFM | .pfm | Sharp (native) | Bản đồ số thực | ## Định dạng đầu ra (17) {#output-formats-13} | Định dạng | Bộ mã hóa | Kiểm soát chất lượng | Có sẵn trong | |--------|---------|----------------|-------------| | JPEG | Sharp native | 1-100 | Tất cả công cụ | | PNG | Sharp native | Nén 0-9 | Tất cả công cụ | | WebP | Sharp native | 1-100 | Tất cả công cụ | | AVIF | Sharp native | 1-100 | Tất cả công cụ | | TIFF | Sharp native | 1-100 | Công cụ chuyển đổi đầy đủ | | GIF | Sharp native | 1-100 | Công cụ chuyển đổi đầy đủ | | JXL | Sharp native | 1-100 | Tất cả công cụ | | HEIC | heif-enc CLI | 1-100 | Công cụ chuyển đổi đầy đủ | | HEIF | heif-enc CLI | 1-100 | Công cụ chuyển đổi đầy đủ | | BMP | ImageMagick CLI | Không mất dữ liệu | Công cụ chuyển đổi | | ICO | ImageMagick CLI | Không mất dữ liệu | Công cụ chuyển đổi | | JP2 | opj\_compress CLI | Tỷ lệ nén | Công cụ chuyển đổi | | QOI | Codec nội tuyến | Không mất dữ liệu | Công cụ chuyển đổi | | PSD | ImageMagick CLI | Không mất dữ liệu | Công cụ chuyển đổi | | PPM | ImageMagick CLI | Không mất dữ liệu | Công cụ chuyển đổi | | EPS | ImageMagick CLI | Không mất dữ liệu | Công cụ chuyển đổi | | TGA | ImageMagick CLI | Không mất dữ liệu | Công cụ chuyển đổi | ## Định dạng video {#video-formats} Việc giải mã và mã hóa video được xử lý bởi FFmpeg (bản build tĩnh), nên mọi container và codec phổ biến đều được hỗ trợ ở đầu vào. ### Container đầu vào (15) {#input-containers-15} | Định dạng | Phần mở rộng | Codec điển hình | Ghi chú | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | Container được dùng rộng rãi nhất | | QuickTime | .mov | H.264, ProRes | Quay/chỉnh sửa của Apple | | WebM | .webm | VP8, VP9, AV1 | Định dạng web miễn phí bản quyền | | Matroska | .mkv | Bất kỳ | Container mở linh hoạt | | AVI | .avi | Đa dạng | Container Microsoft cũ | | M4V | .m4v | H.264 | Biến thể MP4 của Apple | | AVCHD | .mts | H.264 | Bản ghi máy quay | | BDAV | .m2ts | H.264 | Luồng truyền tải Blu-ray / AVCHD | | 3GP | .3gp | H.264, MPEG-4 | Quay trên di động | | Flash Video | .flv | H.264, VP6 | Streaming cũ | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | Video thời DVD | | MPEG-TS | .ts | MPEG-2, H.264 | Luồng truyền tải phát sóng | | Ogg | .ogv | Theora | Video Ogg mở | ### Định dạng đầu ra {#output-formats} | Định dạng | Phần mở rộng | Codec video | Được tạo bởi | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Chuyển đổi, nén, và hầu hết các công cụ video | | QuickTime | .mov | H.264 | Convert Video | | WebM | .webm | VP9 | Convert Video | | GIF | .gif | - | Video to GIF | | WebP | .webp | - | Video to WebP (ảnh động) | ### Phụ đề {#subtitles} | Định dạng | Phần mở rộng | Thao tác | |--------|-----------|-----------| | SubRip | .srt | Nhúng, khắc lên hình, trích xuất, tự động tạo | | WebVTT | .vtt | Nhúng, khắc lên hình, trích xuất, tự động tạo | | ASS / SSA | .ass | Nhúng, khắc lên hình (hỗ trợ định kiểu) | ## Định dạng audio {#audio-formats} Audio cũng được xử lý bởi FFmpeg. ### Định dạng đầu vào (11) {#input-formats-11} | Định dạng | Phần mở rộng | Nén | Ghi chú | |--------|-----------|-------------|-------| | MP3 | .mp3 | Có mất dữ liệu | Tương thích phổ quát | | WAV | .wav | Không nén (PCM) | Studio / chỉnh sửa | | FLAC | .flac | Không mất dữ liệu | Codec không mất dữ liệu mở | | AAC | .aac | Có mất dữ liệu | Luồng AAC thô | | M4A | .m4a | Có mất dữ liệu (AAC) / Không mất dữ liệu (ALAC) | Audio MPEG-4 | | Ogg Vorbis | .ogg | Có mất dữ liệu | Định dạng mở | | Opus | .opus | Có mất dữ liệu | Hiện đại, độ trễ thấp | | WMA | .wma | Có mất dữ liệu | Windows Media Audio | | AIFF | .aiff | Không nén (PCM) | Không nén của Apple | | AMR | .amr | Có mất dữ liệu | Giọng nói / di động | | AC-3 | .ac3 | Có mất dữ liệu | Dolby Digital | ### Định dạng đầu ra {#output-formats-1} | Định dạng | Phần mở rộng | Codec | Được tạo bởi | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Convert Audio, Extract Audio | | WAV | .wav | PCM | Convert Audio, Extract Audio | | FLAC | .flac | FLAC (không mất dữ liệu) | Convert Audio | | Ogg | .ogg | Vorbis | Convert Audio | | M4A | .m4a | AAC | Convert Audio, Extract Audio | ## Định dạng tài liệu {#document-formats} Việc xử lý tài liệu dùng qpdf, LibreOffice, Ghostscript, Pandoc, và WeasyPrint. ### Định dạng đầu vào (15) {#input-formats-15} | Định dạng | Phần mở rộng | Engine | Ghi chú | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Định dạng tài liệu cốt lõi | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Văn bản, bảng tính, thuyết trình | | Rich Text | .rtf | LibreOffice | Văn bản định dạng đa ứng dụng | | Plain Text | .txt | LibreOffice, Pandoc | Văn bản UTF-8 | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | Kết xuất thành PDF | | EPUB | .epub | Pandoc, LibreOffice | Định dạng sách điện tử | ### Định dạng đầu ra {#output-formats-2} | Định dạng | Phần mở rộng | Được tạo bởi | |--------|-----------|-------------| | PDF | .pdf | Word/Excel/PowerPoint to PDF, Markdown to PDF, HTML to PDF | | PDF/A | .pdf | PDF/A Convert (lưu trữ) | | Word | .docx, .odt, .rtf, .txt | Convert Document, PDF to Word, Markdown to Word | | Presentation | .pptx, .odp | Convert Presentation | | Spreadsheet | .xlsx, .ods, .csv | Convert Spreadsheet | | HTML | .html | Markdown to HTML | | EPUB | .epub | Convert to EPUB | | Images | .png, .jpg | PDF to Image | ## Định dạng tệp {#file-formats} Các công cụ dữ liệu và lưu trữ chuyển đổi giữa các định dạng có cấu trúc và đóng gói tệp. | Định dạng | Phần mở rộng | Chuyển đổi | |--------|-----------|-------------| | CSV | .csv | Sang/từ JSON và Excel; tách và gộp; từ XML | | JSON | .json | Sang/từ CSV, XML, và YAML | | XML | .xml | Sang/từ JSON; sang CSV | | YAML | .yaml, .yml | Sang/từ JSON | | Excel | .xlsx | Sang/từ CSV | | ZIP | .zip | Tạo lưu trữ, trích xuất nội dung | --- --- url: https://docs.snapotter.com/vi/tools/image/image-enhancement.md description: >- Tự động cải thiện một chạm, phân tích ảnh và điều chỉnh phơi sáng, độ tương phản, cân bằng trắng, độ bão hòa và độ sắc nét. --- # Cải thiện ảnh {#image-enhancement} Tự động cải thiện một chạm với phân tích thông minh. Phân tích ảnh và áp dụng các điều chỉnh phơi sáng, độ tương phản, cân bằng trắng, độ bão hòa, độ sắc nét và khử nhiễu. ## Điểm cuối API {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **Xử lý:** Đồng bộ (dùng factory `createToolRoute`, trả về kết quả trực tiếp) **Gói mô hình:** Không cần cho cải thiện cơ bản. Gói `upscale-enhance` (5-6 GB) chỉ được dùng khi `deepEnhance` được bật (để khử nhiễu bằng AI qua SCUNet). ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | file | file | Có | - | Tệp ảnh (multipart) | | mode | string | Không | `"auto"` | Chế độ cải thiện: `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | Không | `50` | Cường độ cải thiện tổng thể (0-100) | | corrections | object | Không | tất cả `true` | Các điều chỉnh chọn lọc để áp dụng (xem bên dưới) | | deepEnhance | boolean | Không | `false` | Bật khử nhiễu bằng AI (yêu cầu cài đặt công cụ `noise-removal`) | ### Đối tượng Corrections {#corrections-object} | Trường | Kiểu | Mặc định | Mô tả | |-------|------|---------|-------------| | exposure | boolean | `true` | Tự động điều chỉnh phơi sáng | | contrast | boolean | `true` | Tự động điều chỉnh độ tương phản | | whiteBalance | boolean | `true` | Tự động điều chỉnh cân bằng trắng | | saturation | boolean | `true` | Tự động điều chỉnh độ bão hòa | | sharpness | boolean | `true` | Tự động làm sắc nét | | denoise | boolean | `true` | Khử nhiễu nhẹ | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Phản hồi (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Điểm cuối Analyze {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Phân tích một ảnh và trả về các khuyến nghị điều chỉnh mà không áp dụng chúng. ### Tham số {#parameters-1} | Tham số | Kiểu | Bắt buộc | Mô tả | |-----------|------|----------|-------------| | file | file | Có | Tệp ảnh (multipart) | ### Ví dụ yêu cầu {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Phản hồi (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Ghi chú {#notes} * Công cụ này dùng factory đồng bộ `createToolRoute`, nên nó trả về một phản hồi tiêu chuẩn (không phải 202 bất đồng bộ). * Tham số `mode` điều chỉnh cách các điều chỉnh được cân trọng (ví dụ, chế độ chân dung nhẹ nhàng hơn với tông da, chế độ phong cảnh tăng cường độ bão hòa). * Khi `deepEnhance` được bật và công cụ `noise-removal` (SCUNet) đã được cài đặt, một lượt khử nhiễu bằng AI bổ sung được áp dụng sau các điều chỉnh tiêu chuẩn. * Điểm cuối analyze hữu ích để xem trước những điều chỉnh sẽ được áp dụng trước khi thực hiện. * Hỗ trợ các định dạng đầu vào HEIC/HEIF, RAW, TGA, PSD, EXR và HDR qua giải mã tự động. --- --- url: https://docs.snapotter.com/es/tools/audio/pitch-shift.md description: Sube o baja el tono del audio en semitonos sin cambiar la velocidad. --- # Cambio de tono {#pitch-shift} Sube o baja el tono de un archivo de audio en una cantidad de semitonos sin cambiar su velocidad de reproducción. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/audio/pitch-shift` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | semitones | integer | No | `3` | Semitonos a desplazar (-12 a 12). Debe ser distinto de cero. | ## Solicitud de ejemplo {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/pitch-shift \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"semitones": -5}' ``` ## Respuesta de ejemplo {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notas {#notes} * Los valores positivos suben el tono; los negativos lo bajan. * Un desplazamiento de 12 semitonos equivale a una octava hacia arriba; -12 equivale a una octava hacia abajo. * La duración de reproducción se mantiene igual independientemente del desplazamiento. * La salida suele conservar el contenedor de entrada. La entrada AAC se escribe como M4A, y las entradas de solo decodificación no compatibles recurren a MP3. --- --- url: https://docs.snapotter.com/pt-BR/tools/audio/audio-channels.md description: Converta entre mono e estéreo ou troque os canais esquerdo e direito. --- # Canais de Áudio {#audio-channels} Converta áudio entre layouts mono e estéreo, ou troque os canais esquerdo e direito de um arquivo estéreo. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Aceita dados de formulário multipart com um arquivo de áudio e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | mode | string | Sim | - | Operação de canal: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Notas {#notes} * `stereo-to-mono` mistura os dois canais em uma única trilha mono. * `mono-to-stereo` duplica o canal mono para os canais esquerdo e direito. * `swap` troca os canais esquerdo e direito de um arquivo estéreo. * A saída normalmente mantém o contêiner de entrada. Entrada AAC é gravada como M4A, e entradas apenas de decodificação não suportadas recorrem a MP3. --- --- url: https://docs.snapotter.com/es/tools/audio/audio-channels.md description: Convierte entre mono y estéreo o intercambia los canales izquierdo y derecho. --- # Canales de audio {#audio-channels} Convierte el audio entre disposiciones mono y estéreo, o intercambia los canales izquierdo y derecho de un archivo estéreo. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | mode | string | Sí | - | Operación de canal: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Solicitud de ejemplo {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Respuesta de ejemplo {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Notas {#notes} * `stereo-to-mono` mezcla ambos canales en una única pista mono. * `mono-to-stereo` duplica el canal mono en el izquierdo y el derecho. * `swap` intercambia los canales izquierdo y derecho de un archivo estéreo. * La salida suele conservar el contenedor de entrada. La entrada AAC se escribe como M4A, y las entradas de solo decodificación no compatibles recurren a MP3. --- --- url: https://docs.snapotter.com/it/tools/audio/audio-channels.md description: Converti tra mono e stereo o scambia i canali sinistro e destro. --- # Canali audio {#audio-channels} Converti l'audio tra layout mono e stereo, oppure scambia i canali sinistro e destro di un file stereo. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Accetta dati di form multipart con un file audio e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | mode | string | Sì | - | Operazione sui canali: `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Note {#notes} * `stereo-to-mono` mixa entrambi i canali in un'unica traccia mono. * `mono-to-stereo` duplica il canale mono su sinistro e destro. * `swap` scambia i canali sinistro e destro di un file stereo. * L'output di solito mantiene il container di input. L'input AAC viene scritto come M4A, e gli input decodificabili solo in lettura non supportati ricadono su MP3. --- --- url: https://docs.snapotter.com/fr/tools/audio/audio-channels.md description: Convertir entre mono et stéréo ou intervertir les canaux gauche et droit. --- # Canaux audio {#audio-channels} Convertir l'audio entre les dispositions mono et stéréo, ou intervertir les canaux gauche et droit d'un fichier stéréo. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/audio/audio-channels` Accepte des données de formulaire multipart avec un fichier audio et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | mode | string | Oui | - | Opération sur les canaux : `stereo-to-mono`, `mono-to-stereo`, `swap` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/audio-channels \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "stereo-to-mono"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2300000 } ``` ## Notes {#notes} * `stereo-to-mono` mixe les deux canaux en une seule piste mono. * `mono-to-stereo` duplique le canal mono vers la gauche et la droite. * `swap` échange les canaux gauche et droit d'un fichier stéréo. * La sortie conserve généralement le conteneur d'entrée. Une entrée AAC est écrite en M4A, et les entrées à décodage seul non prises en charge se replient sur le MP3. --- --- url: https://docs.snapotter.com/vi/tools/image/crop.md description: Cắt ảnh bằng cách chỉ định một vùng với vị trí và kích thước. --- # Cắt ảnh {#crop} Cắt ảnh bằng cách xác định một vùng hình chữ nhật dựa trên vị trí và kích thước. Hỗ trợ cả đơn vị pixel và phần trăm. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/crop` Chấp nhận dữ liệu form multipart với một tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | left | number | Có | - | Độ lệch X của vùng cắt (tính từ cạnh trái) | | top | number | Có | - | Độ lệch Y của vùng cắt (tính từ cạnh trên) | | width | number | Có | - | Chiều rộng của vùng cắt | | height | number | Có | - | Chiều cao của vùng cắt | | unit | string | Không | `"px"` | Đơn vị cho các giá trị: `px` hoặc `percent` | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 100, "top": 50, "width": 800, "height": 600}' ``` Cắt bằng giá trị phần trăm: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 10, "top": 10, "width": 80, "height": 80, "unit": "percent"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1200000 } ``` ## Ghi chú {#notes} * Vùng cắt phải nằm trong ranh giới ảnh. Nếu vùng vượt ra ngoài ảnh, yêu cầu sẽ thất bại. * Khi dùng đơn vị `percent`, các giá trị biểu thị phần trăm của kích thước ảnh (ví dụ `left: 10` nghĩa là 10% tính từ cạnh trái). * Định dạng đầu ra khớp với định dạng đầu vào. * Định hướng EXIF được áp dụng tự động trước khi cắt, nên tọa độ tương ứng với định hướng đúng về mặt thị giác. --- --- url: https://docs.snapotter.com/vi/guide/configuration.md description: >- Tất cả các biến môi trường của SnapOtter kèm giá trị mặc định. Cấu hình xác thực, lưu trữ, mô hình AI, phân tích và hơn thế. --- # Cấu hình {#configuration} Mọi cấu hình được thực hiện qua các biến môi trường. Mỗi biến đều có một giá trị mặc định hợp lý, nên SnapOtter hoạt động ngay từ đầu mà không cần đặt biến nào. ## Các biến môi trường {#environment-variables} ### Máy chủ {#server} | Biến | Mặc định | Mô tả | |---|---|---| | `PORT` | `1349` | Cổng máy chủ lắng nghe. | | `RATE_LIMIT_PER_MIN` | `1000` | Số yêu cầu tối đa mỗi phút cho mỗi IP. Đặt thành 0 để tắt giới hạn tốc độ. | | `CORS_ORIGIN` | (trống) | Danh sách các origin được phép cho CORS, phân tách bằng dấu phẩy, hoặc để trống chỉ cho phép cùng origin. | | `LOG_LEVEL` | `info` | Mức độ chi tiết của nhật ký. Một trong: `fatal`, `error`, `warn`, `info`, `debug`, `trace`. | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Những peer nào được phép đặt IP của client qua `X-Forwarded-For`. Giá trị mặc định chỉ tin một peer thuộc mạng riêng, nên một reverse proxy trên mạng Docker hoặc trong mạng LAN thì được tin, còn header giả mạo từ một client công khai thì không. Chỉ đặt `true` khi có một proxy do bạn kiểm soát đứng phía trước trên một địa chỉ công khai. | ### Xác thực {#authentication} Hai giá trị boolean bên dưới chỉ chấp nhận `true` và `false`. Bất kỳ giá trị nào khác, `1` hay `yes` hay `on`, đều không qua được kiểm tra và máy chủ thoát trước khi bắt đầu lắng nghe. | Biến | Mặc định | Mô tả | |---|---|---| | `AUTH_ENABLED` | `true` | Yêu cầu đăng nhập. Đặt thành `false` để chạy hoàn toàn không có tài khoản nào, điều này cấp quyền admin cho mọi yêu cầu, nên chỉ dùng trong một mạng đáng tin cậy. | | `DEFAULT_USERNAME` | `admin` | Tên đăng nhập cho tài khoản admin ban đầu. Chỉ dùng ở lần chạy đầu tiên. | | `DEFAULT_PASSWORD` | `admin` | Mật khẩu cho tài khoản admin ban đầu. Đổi mật khẩu này sau lần đăng nhập đầu. | | `MAX_USERS` | `0` (không giới hạn) | Số tài khoản người dùng đã đăng ký tối đa. Đặt thành 0 để không giới hạn. | | `SESSION_DURATION_HOURS` | `168` | Thời gian sống của phiên đăng nhập tính bằng giờ (mặc định là 7 ngày). | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Đặt thành `true` để bỏ qua lời nhắc buộc đổi mật khẩu ở lần đăng nhập đầu. | ### Lưu trữ {#storage} | Biến | Mặc định | Mô tả | |---|---|---| | `STORAGE_MODE` | `local` | `local` hoặc `s3`. S3 và MinIO cần một giấy phép có tính năng s3\_storage cùng các biến `S3_*` bên dưới. | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | Chuỗi kết nối PostgreSQL. Ngăn xếp Compose trỏ biến này tới dịch vụ `postgres` của nó; hãy để nó không được đặt (cùng với `REDIS_URL`) để dùng chế độ nhúng. | | `REDIS_URL` | `redis://localhost:6379` | Chuỗi kết nối Redis (dùng cho các hàng đợi công việc BullMQ). Compose trỏ biến này tới dịch vụ `redis` của nó. | | `WORKSPACE_PATH` | `./tmp/workspace` | Thư mục cho các tệp tạm thời trong quá trình xử lý. Được dọn dẹp tự động. Image đặt thành `/tmp/workspace`. | | `FILES_STORAGE_PATH` | `./data/files` | Thư mục cho các tệp người dùng bền vững (ảnh đã tải lên, kết quả đã lưu). Image đặt thành `/data/files`. | ### Lưu trữ đối tượng S3 {#s3-object-storage} Chỉ được đọc khi `STORAGE_MODE=s3`. Thiếu bất kỳ biến nào trong ba biến bắt buộc thì quá trình khởi động thất bại và nêu tên biến bạn đã bỏ sót. | Biến | Mặc định | Mô tả | |---|---|---| | `S3_BUCKET` | (trống) | Bucket chứa các tệp tải lên và đầu ra. Bắt buộc. | | `S3_ACCESS_KEY_ID` | (trống) | Access key. Bắt buộc. Trong container bạn có thể gắn nó dưới dạng tệp, qua `S3_ACCESS_KEY_ID_FILE`. | | `S3_SECRET_ACCESS_KEY` | (trống) | Secret key. Bắt buộc. Cùng quy ước tệp: `S3_SECRET_ACCESS_KEY_FILE`. | | `S3_REGION` | `us-east-1` | Vùng của bucket. | | `S3_ENDPOINT` | (trống) | Endpoint tùy chỉnh cho MinIO, R2, Backblaze và các kho lưu trữ tương thích S3 khác. Để trống nghĩa là AWS. | | `S3_FORCE_PATH_STYLE` | `false` | Đặt thành `true` cho MinIO và bất kỳ thứ gì khác cần `endpoint/bucket/key` thay vì địa chỉ kiểu virtual-host. | | `S3_PREFIX` | (trống) | Tiền tố key, để một bucket có thể chứa nhiều instance. | ### Mã hóa khi lưu trữ {#encryption-at-rest} | Biến | Mặc định | Mô tả | |---|---|---| | `DATA_ENCRYPTION_KEY` | (trống) | 64 ký tự hex (32 byte). Mã hóa các cài đặt nhạy cảm được lưu trong cơ sở dữ liệu. Bất cứ giá trị nào không phải 64 ký tự hex đều bị từ chối khi khởi động. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (trống) | Khóa mà bạn đang xoay vòng để rời khỏi, cùng định dạng. Hãy đặt cả hai trong lúc xoay khóa để các hàng hiện có vẫn giải mã được, rồi bỏ khóa này đi. | ### Chế độ nhúng {#embedded-mode} Chạy image mà không có `DATABASE_URL` và không có `REDIS_URL` thì nó khởi động PostgreSQL 17 và Redis của riêng nó bên trong container, gắn vào loopback, với tất cả dữ liệu trên volume `/data`. Điều này khôi phục trải nghiệm `docker run` một-lệnh cho khởi động nhanh, homelab, và nâng cấp từ 1.x. Đây là một đường tiện lợi, không phải một triển khai sản xuất: đối với sản xuất, hãy chạy ngăn xếp Compose 3 container với PostgreSQL và Redis riêng. Chế độ nhúng yêu cầu chạy container với quyền root và không tương thích với các runtime dùng UID tùy ý (OpenShift, Kubernetes `runAsNonRoot`); hãy dùng Compose ở đó. | Biến | Mặc định | Mô tả | |---|---|---| | `EMBEDDED` | `auto` | Tự động bật khi cả `DATABASE_URL` và `REDIS_URL` đều không được đặt. Đặt thành `0` để tắt nó (ứng dụng khi đó thất bại nhanh nếu không có `DATABASE_URL`/`REDIS_URL` bên ngoài nào được đặt, thay vì âm thầm khởi động một cơ sở dữ liệu trong container). | | `REDIS_MAXMEMORY` | `512mb` | Giới hạn bộ nhớ cho Redis nhúng (chỉ chế độ nhúng). Hãy hạ nó xuống trên các máy chủ bị hạn chế bộ nhớ như Raspberry Pi. | Nâng cấp từ 1.x: đặt `snapotter.db` cũ của bạn tại `/data/snapotter.db` trong volume và chế độ nhúng nhập nó vào PostgreSQL nhúng ở lần khởi động đầu tiên. Việc nhập chạy một lần; các lần khởi động sau bỏ qua nó. Lưu ý về đo lường từ xa: chế độ nhúng thừa hưởng mặc định phân tích của image như mọi cấu hình khác. Image được phát hành đi kèm phân tích được bật; hãy build với `--build-arg SNAPOTTER_ANALYTICS=off`, hoặc dùng tùy chọn từ chối của admin trong ứng dụng, để tắt nó. ### Giới hạn xử lý {#processing-limits} | Biến | Mặc định | Mô tả | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (không giới hạn) | Kích thước tệp tối đa cho mỗi lần tải lên tính bằng megabyte. Đặt thành 0 để không giới hạn. Image được phát hành đi kèm `0`; bản build từ mã nguồn bắt đầu ở 100. | | `MAX_BATCH_SIZE` | `0` (không giới hạn) | Số tệp tối đa trong một yêu cầu hàng loạt. Đặt thành 0 để không giới hạn. Image được phát hành đi kèm `0`; bản build từ mã nguồn bắt đầu ở 100. | | `CONCURRENT_JOBS` | `0` (tự động) | Số công việc hàng loạt chạy song song. Đặt thành 0 để tự động phát hiện dựa trên số lõi CPU khả dụng. | | `MAX_MEGAPIXELS` | `0` (không giới hạn) | Độ phân giải ảnh tối đa được phép tính bằng megapixel. Đặt thành 0 để không giới hạn. | | `MAX_WORKER_THREADS` | `0` (tự động) | Số luồng worker tối đa cho xử lý ảnh. Đặt thành 0 để tự động phát hiện dựa trên số lõi CPU khả dụng. | | `PROCESSING_TIMEOUT_S` | `0` (không giới hạn) | Thời gian xử lý tối đa cho mỗi yêu cầu tính bằng giây. Đặt thành 0 để không có thời gian chờ. | | `MAX_PIPELINE_STEPS` | `20` | Số bước tối đa trong một pipeline. Đặt thành 0 để không giới hạn. | | `MAX_CANVAS_PIXELS` | `0` (không giới hạn) | Kích thước khung vẽ tối đa tính bằng pixel cho các ảnh đầu ra. Đặt thành 0 để không giới hạn. | | `MAX_SVG_SIZE_MB` | `50` | Tệp SVG lớn nhất được chấp nhận trước khi làm sạch, tính bằng megabyte. `0` ở đây hành xử khác với các hàng xung quanh. Nó gỡ bỏ hoàn toàn giới hạn kích thước trước khi phân tích thay vì nâng giới hạn lên, nên hãy luôn đặt giá trị cho biến này. | | `MAX_PDF_PAGES` | `0` (không giới hạn) | Số trang PDF tối đa cho việc chuyển đổi PDF-to-image. Đặt thành 0 để không giới hạn. | ### Dọn dẹp {#cleanup} | Biến | Mặc định | Mô tả | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | Các kết quả xử lý chưa lưu (các tệp tải lên thô và đầu ra công cụ) được giữ bao lâu trước khi bị xóa tự động. Các tệp bạn lưu rõ ràng vào thư viện Files không bị ảnh hưởng và tồn tại cho đến khi bạn xóa chúng. | | `CLEANUP_INTERVAL_MINUTES` | `60` | Công việc dọn dẹp chạy thường xuyên đến mức nào. | ### Giao diện {#appearance} | Biến | Mặc định | Mô tả | |---|---|---| | `DEFAULT_THEME` | `light` | Chủ đề mặc định cho các phiên mới. `light`, `dark` hoặc `system`. | | `DEFAULT_LOCALE` | `en` | Ngôn ngữ giao diện mặc định. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Bố cục công cụ mặc định. `sidebar` hoặc `fullscreen`. | ### Quyền Docker {#docker-permissions} | Biến | Mặc định | Mô tả | |---|---|---| | `PUID` | `999` | Chạy tiến trình container với UID này. Đặt cho khớp với người dùng host của bạn cho các bind mount (`id -u`). | | `PGID` | `999` | Chạy tiến trình container với GID này. Đặt cho khớp với nhóm host của bạn cho các bind mount (`id -g`). | ## Ví dụ Docker {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Thay đổi điều này cho việc triển khai không cục bộ POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Các volume {#volumes} Ngăn xếp Docker Compose dùng bốn volume: * `/data` (app) - Các mô hình AI, venv Python và tệp người dùng. Gắn cái này để giữ các tệp đã tải lên và các gói AI đã cài đặt qua các lần khởi động lại. * `/tmp/workspace` (app) - Lưu trữ tạm thời cho các tệp đang được xử lý. Cái này có thể là tạm thời, nhưng gắn nó tránh làm đầy lớp có thể ghi của container. * `SnapOtter-pgdata` (postgres) - Thư mục dữ liệu PostgreSQL. Cái này chứa tất cả dữ liệu quan hệ (người dùng, cài đặt, pipeline, công việc, nhật ký kiểm toán). Sao lưu qua `pg_dump` hoặc ảnh chụp nhanh volume. * `SnapOtter-redisdata` (redis) - Tệp chỉ-ghi-thêm của Redis cho các hàng đợi công việc bền vững. --- --- url: https://docs.snapotter.com/fr/guide/telemetry.md description: >- Quelles données d'utilisation anonymes SnapOtter collecte, quand elles sont envoyées et comment désactiver les analyses produit à l'échelle de l'instance. --- # Ce que SnapOtter collecte {#what-snapotter-collects} Les analyses produit anonymes sont activées par défaut et définies pour l'ensemble de l'instance par un administrateur. Désactivez-les sous Paramètres > Système > Confidentialité. ## Événements que nous envoyons (lorsqu'ils sont activés) {#events-we-send-when-enabled} * tool\_used : identifiant de l'outil, statut, durée, catégorie, s'il s'agit d'un outil IA, un code d'erreur en cas d'échec. * pipeline\_executed : nombre d'étapes, identifiants des outils, indicateur de lot, nombre de fichiers, durée, statut. * ai\_bundle\_action : identifiant du bundle, action, durée. * Utilisation du frontend : quelles pages d'outils sont ouvertes, fichiers ajoutés (nombres uniquement), outil démarré, téléchargements, enregistrements, recherche (nombre de résultats uniquement), lot traité. * Rapports de plantage : type d'erreur et une pile source avec uniquement les noms de base des fichiers. ## Ce que nous ne collectons jamais {#what-we-never-collect} * Noms ou chemins de fichiers * Contenus de fichiers * Texte de sortie OCR * Métadonnées d'image (EXIF) * Texte extrait de documents * Votre adresse IP ou votre identité de compte ## Désactivation {#turning-it-off} Administrateurs : Paramètres > Système > Confidentialité, désactivez « Analyses produit anonymes ». Cela s'arrête immédiatement, à l'échelle de l'instance. Pour construire une image qui ne peut jamais émettre, définissez l'argument de build `SNAPOTTER_ANALYTICS=off`. --- --- url: https://docs.snapotter.com/fr/tools/pdf/redact-pdf.md description: >- Supprimer définitivement des occurrences de texte d'un PDF (censure véritable et vérifiée). --- # Censurer un PDF {#redact-pdf} Supprimez définitivement des occurrences de texte spécifiées d'un PDF à l'aide d'une censure véritable et vérifiée. Le texte censuré est complètement retiré du fichier, et pas seulement recouvert d'un rectangle noir. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/redact-pdf` Accepte des données de formulaire multipart avec un fichier PDF et un champ `settings` au format JSON. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | terms | string\[] | Oui | - | Chaînes de texte à censurer (1-50 termes, chacun jusqu'à 200 caractères) | | caseSensitive | boolean | Non | `false` | Indique si la correspondance est sensible à la casse | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/redact-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@contract.pdf" \ -F 'settings={"terms": ["John Doe", "555-0123"], "caseSensitive": false}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/contract.pdf", "originalSize": 245000, "processedSize": 243000, "found": 7 } ``` ## Remarques {#notes} * Format d'entrée accepté : `.pdf`. * Il s'agit d'un outil rapide (synchrone) qui renvoie le résultat directement. * Cet outil effectue une censure véritable : le texte correspondant est retiré du flux de contenu du PDF, et non simplement masqué visuellement. * Le champ `found` de la réponse indique le nombre d'occurrences censurées. * Vous pouvez censurer jusqu'à 50 termes en une seule requête. --- --- url: https://docs.snapotter.com/tr/guide/translations.md description: >- Desteklenen 21 dil ve TypeScript ile zorunlu kılınan i18n sistemini kullanarak SnapOtter için nasıl çeviri oluşturulacağı veya iyileştirileceği. --- # Çeviri kılavuzu {#translation-guide} SnapOtter kutudan çıktığı gibi 21 dille gelir. i18n sistemi, TypeScript ile zorunlu kılınan yerel ayar bütünlüğü ve dinamik kod bölme özelliğine sahip hafif, özel bir çalışma zamanı kullanır. ## Desteklenen diller {#supported-languages} | Code | Language | Native Name | Direction | |------|----------|-------------|-----------| | `en` | İngilizce | English | LTR | | `zh-CN` | Çince (Basitleştirilmiş) | 简体中文 | LTR | | `zh-TW` | Çince (Geleneksel) | 繁體中文 | LTR | | `ja` | Japonca | 日本語 | LTR | | `ko` | Korece | 한국어 | LTR | | `es` | İspanyolca | Español | LTR | | `fr` | Fransızca | Français | LTR | | `it` | İtalyanca | Italiano | LTR | | `pt-BR` | Portekizce (Brezilya) | Português (Brasil) | LTR | | `de` | Almanca | Deutsch | LTR | | `nl` | Felemenkçe | Nederlands | LTR | | `sv` | İsveççe | Svenska | LTR | | `ru` | Rusça | Русский | LTR | | `pl` | Lehçe | Polski | LTR | | `uk` | Ukraynaca | Українська | LTR | | `ar` | Arapça | العربية | RTL | | `tr` | Türkçe | Türkçe | LTR | | `hi` | Hintçe | हिन्दी | LTR | | `vi` | Vietnamca | Tiếng Việt | LTR | | `id` | Endonezce | Bahasa Indonesia | LTR | | `th` | Tayca | ไทย | LTR | ## Dil algılama nasıl çalışır {#how-language-detection-works} SnapOtter üç katmanlı bir çözümleme sırası kullanır: 1. **Kullanıcı tercihi** - `localStorage("snapotter-locale")` içinde saklanır ve kimlik doğrulaması yapıldığında kullanıcı ayarlarıyla eşitlenir 2. **Tarayıcı otomatik algılama** - `navigator.languages` dizisini BCP 47 önek eşleştirmesiyle dolaşır 3. **Örnek varsayılanı** - yöneticinin `DEFAULT_LOCALE` ortam değişkeni (`GET /api/v1/config/locale` üzerinden getirilir) 4. **İngilizce yedeği** - her zaman kullanılabilir Kullanıcılar dili şuralardan değiştirebilir: * **Alt bilgideki Küre seçici** (masaüstü, her zaman görünür) * **Oturum açma sayfası** dil seçici (kimlik doğrulama öncesi) * **Ayarlar > Genel** bölümü (kullanıcı başına tercih) * **Mobil kenar çubuğu** dil açılır menüsü * **Ayarlar > Sistem** bölümü, örnek genelindeki varsayılanı ayarlar (yalnızca yönetici) ## Çeviriler nasıl çalışır {#how-translations-work} Tüm arayüz dizeleri `packages/shared/src/i18n/` içinde yer alır. Referans dosyası `en.ts` olup, uygulamanın kullandığı her dizeyi (~1500 anahtar) içeren türlenmiş bir nesne dışa aktarır. Diğer diller, aynı yapıyı dışa aktaran ayrı dosyalardır (örneğin `de.ts`, `fr.ts`). `TranslationKeys` türü, anahtar yapısını zorunlu kılarken herhangi bir dize değerini kabul etmek için `DeepStringRecord` kullanır. TypeScript, herhangi bir çeviri dosyasındaki eksik anahtarları derleme zamanında yakalar. Çalışma zamanında yalnızca etkin yerel ayar dinamik `import()` aracılığıyla yüklenir, böylece ana paket küçük kalır. ## Çevirileri bileşenlerde kullanma {#using-translations-in-components} ```tsx import { useTranslation } from "@/contexts/i18n-context"; import { format, plural } from "@/lib/format"; function MyComponent() { const { t, locale, setLocale } = useTranslation(); return (

{t.common.settings}

{format(t.settings.people.deleteConfirm, { username: "admin" })}

{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}

); } ``` ## Bir çeviriye katkıda bulunma {#contributing-a-translation} Çeviri PR'lerini doğrudan memnuniyetle karşılıyoruz. Mevcut bir yerel ayarı iyileştirebilir veya yeni bir tane ekleyebilirsiniz. Kod göndermeden bir çeviri hatasını bildirmek için, dili, hatalı dizeyi ve önerilen düzeltmeyi belirterek bir [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) açın. ::: tip Çeviri PR'leri önceden onay gerektirmez. Depoyu çatallayın, değişikliklerinizi yapın ve bir PR açın. Tam PR süreci ve CLA gereksinimi için [Katkı Kılavuzu](/tr/guide/contributing) bölümüne bakın. ::: ## Bir çeviriyi nasıl oluşturur veya güncellersiniz {#how-to-create-or-update-a-translation} ### 1. Çatallayın ve klonlayın {#\_1-fork-and-clone} ```bash git clone https://github.com//snapotter.git cd snapotter pnpm install ``` ### 2. Referans dosyasını kopyalayın (yalnızca yeni dil) {#\_2-copy-the-reference-file-new-language-only} Mevcut bir çeviriyi iyileştiriyorsanız bu adımı atlayın. ```bash cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts ``` ### 3. Dizeleri çevirin {#\_3-translate-the-strings} Yeni dosyanızı açın ve her dize değerini çevirin. Nesne yapısını ve anahtarları tam olarak aynı tutun. ```ts import type { TranslationKeys } from "./en.js"; export const xx: TranslationKeys = { common: { upload: "Your translation here", // ... translate all entries }, // ... translate all sections } as const; ``` Kurallar: * Nesne anahtarlarını çevirmeyin, yalnızca dize değerlerini çevirin * `as const` öğesini sonda tutun * `TranslationKeys` öğesini `./en.js` konumundan içe aktarın ve dışa aktarımınızı türleyin * `{variable}` yer tutucularını tam olduğu gibi tutun * Diziler (`rotatingPhrases`, `progressMessages`) aynı sayıda girdiye sahip olmalıdır * Şunları çevirmeyin: SnapOtter, JPEG, PNG, WebP, EXIF, API ve diğer teknik terimler ### 4. Yerel ayarı kaydedin (yalnızca yeni dil) {#\_4-register-the-locale-new-language-only} Yerel ayarınızı `packages/shared/src/i18n/index.ts` içindeki `SUPPORTED_LOCALES` öğesine ekleyin: ```ts { code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" }, ``` ### 5. Doğrulayın {#\_5-verify} ```bash pnpm typecheck # catches missing or mistyped keys pnpm lint # formatting check pnpm dev # manually verify strings appear correctly ``` ### 6. Gönderin {#\_6-submit} `main` deposuna karşı `feat(i18n): add Swedish translation` veya `fix(i18n): correct German typos` gibi bir başlıkla bir PR açın. CLA botu ilk katkınızda imzalamanızı isteyecektir. ## Yeni çeviri anahtarları ekleme {#adding-new-translation-keys} Yeni arayüz dizeleri gerektiren yeni bir özellik eklerken: 1. Yeni anahtarları önce `en.ts` (referans dosyası) içine ekleyin 2. `pnpm typecheck` komutunu çalıştırın - yeni anahtar eksikse her yerel ayar dosyası başarısız olur 3. Yeni anahtarı tüm yerel ayar dosyalarına ekleyin (geçici yedek olarak İngilizceyi kullanın) ## Yapılandırma {#configuration} Örnek varsayılan dilini ortam değişkeni aracılığıyla ayarlayın: ```yaml DEFAULT_LOCALE: "de" # German as the default for all new users ``` ## Dosya referansı {#file-reference} | File | Purpose | |------|---------| | `packages/shared/src/i18n/en.ts` | İngilizce dizeler (referans yerel ayar, ~1500 anahtar) | | `packages/shared/src/i18n/index.ts` | `SUPPORTED_LOCALES`, `loadTranslations()`, tür dışa aktarımları | | `packages/shared/src/i18n/.ts` | Dil başına çeviri dosyaları | | `apps/web/src/contexts/i18n-context.tsx` | `I18nProvider`, `useTranslation()` kancası | | `apps/web/src/lib/format.ts` | `format()`, `plural()`, `formatFileSize()` yardımcıları | | `apps/api/src/routes/config.ts` | `GET /api/v1/config/locale` genel uç noktası | ## Web sitesini, belgeleri ve API referansını çevirme {#translating-the-web-surfaces} Yukarıdaki 21 dil desteği **uygulamayı** kapsar. Herkese açık web sitesi (snapotter.com), bu belge sitesi ve REST API referansı da, terminolojinin her yerde tutarlı kalması için `packages/shared/src/i18n` kaynağındaki aynı araç adlarını ve açıklamalarını yeniden kullanan ayrı bir hash denetimli işlem hattı tarafından 21 dilin tümüne çevrilir. ### Varsayılan olarak makine tarafından çevrilir {#machine-translated-by-default} Web sitesindeki ve belgelerdeki İngilizce olmayan her sayfa ilk geçişte **makine tarafından çevrilir** (üçüncü taraf bir hizmet tarafından değil, bir Claude Code oturumu tarafından) ve bunu belirten, buraya geri bağlantı içeren küçük, kapatılabilir bir başlık taşır. Bu bilinçli bir tercihtir: 21 dilin tümünü hızlı ve dürüst bir şekilde sunar, ardından topluluğu en önemli sayfaları rafine etmeye davet eder. Makine çevirisi anlamı aktarır; insan incelemesi ise metnin doğal okunmasını sağlar. ### İşlem hattı neyi çevireceğine nasıl karar verir {#how-the-web-pipeline-decides} Her çevrilebilir İngilizce kaynak birimi hash'lenir ve hash, çevirisinin yanında saklanır. Her çalıştırmada işlem hattı: * henüz çevirisi olmayan her birimi çevirir, * saklanan hash'i hâlâ İngilizce kaynakla eşleşen her birimi atlar, * İngilizce kaynağı değiştiğinde bir **makine** birimini yeniden çevirir, * ve bir **insan** tarafından rafine edilmiş bir birimi, İngilizce kaynağı değiştiğinde çalışmanızın üzerine yazmak yerine `stale` (inceleme gerekir) olarak işaretler. ### Bir web çevirisini PR ile rafine etme {#refining-a-web-translation-by-pr} Bir web sitesi, belge veya API referansı çevirisini, bir uygulama yerel ayarını iyileştirdiğiniz şekilde iyileştirirsiniz: oluşturulan dosyayı düzenleyerek ve bir PR açarak. 1. Dilinize ait oluşturulan çeviriyi bulun: * web sitesi arayüz dizeleri: `apps/landing/src/i18n/.json` * bir belge sayfası: `apps/docs//**.md` * API referansı: `apps/api/src/openapi..yaml` 2. Metni düzenleyin. Kodu, bağlantıları, `{placeholders}` ve tüm `⸤I18N…⸥` işaretlerini tam olduğu gibi tutun; işlem hattının doğrulayıcısı, bunları düşüren veya yeniden sıralayan bir çeviriyi reddeder. 3. Bir PR açın. Bir birimi düzenlemek, kaynağını `machine` konumundan `human` konumuna çevirir, böylece işlem hattı daha sonraki bir çalıştırmada onun **asla üzerine yazmaz**. İngilizce kaynak sonradan değişirse, biriminiz sessizce değiştirilmek yerine inceleme için `stale` olarak işaretlenir. Kod göndermeden bir çeviri hatasını bildirmek için, sayfa URL'sini, dili, hatalı metni ve önerilen düzeltmenizi belirterek bir [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) açın. ::: tip Çeviri işlem hattını bakım yapanlar çalıştırır; katkıda bulunmak için bir API anahtarına ihtiyacınız yoktur. Yalnızca oluşturulan dosyayı düzenleyin ve bir PR açın. İşlem hattının nasıl çalıştığı için [`scripts/i18n/README.md`](https://github.com/snapotter-hq/SnapOtter/blob/main/scripts/i18n/README.md) bölümüne bakın. ::: --- --- url: https://docs.snapotter.com/ar/tools/video/change-fps.md description: تغيير معدل الإطارات في الفيديو. --- # Change FPS {#change-fps} تغيير معدل إطارات الفيديو إلى قيمة مستهدفة بين 1 و120 إطاراً في الثانية. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو وحقل JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | معدل الإطارات المستهدف (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * خفض معدل الإطارات يُسقط إطارات ويقلل حجم الملف. رفعه يكرر الإطارات لسد الفجوة لكنه لا يضيف تفاصيل حركة حقيقية. * القيم المستهدفة الشائعة: 24 (السينما)، 30 (الويب/البث)، 60 (تشغيل سلس). * يُحفَظ مسار الصوت بمعدل العينات الأصلي. --- --- url: https://docs.snapotter.com/de/tools/video/change-fps.md description: Die Bildrate eines Videos ändern. --- # Change FPS {#change-fps} Die Bildrate eines Videos auf einen Zielwert zwischen 1 und 120 fps ändern. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Nimmt Multipart-Formulardaten mit einer Videodatei und einem JSON-Feld `settings` entgegen. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Ziel-Bildrate (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Das Senken der Bildrate lässt Frames weg und verringert die Dateigröße. Das Erhöhen dupliziert Frames, um die Lücke zu füllen, fügt aber keine echten Bewegungsdetails hinzu. * Gängige Zielwerte: 24 (Kino), 30 (Web/Broadcast), 60 (flüssige Wiedergabe). * Die Audiospur wird mit ihrer ursprünglichen Abtastrate beibehalten. --- --- url: https://docs.snapotter.com/es/tools/video/change-fps.md description: Cambia la velocidad de fotogramas de un vídeo. --- # Change FPS {#change-fps} Cambia la velocidad de fotogramas de un vídeo a un valor objetivo entre 1 y 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Acepta datos de formulario multipart con un archivo de vídeo y un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Velocidad de fotogramas objetivo (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Reducir la velocidad de fotogramas descarta fotogramas y reduce el tamaño del archivo. Aumentarla duplica fotogramas para rellenar el hueco, pero no añade detalle real de movimiento. * Valores objetivo comunes: 24 (cine), 30 (web/emisión), 60 (reproducción fluida). * La pista de audio se conserva a su frecuencia de muestreo original. --- --- url: https://docs.snapotter.com/fr/tools/video/change-fps.md description: Change la fréquence d'images d'une vidéo. --- # Change FPS {#change-fps} Change la fréquence d'images d'une vidéo vers une valeur cible comprise entre 1 et 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Accepte des données de formulaire multipart avec un fichier vidéo et un champ JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Fréquence d'images cible (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Réduire la fréquence d'images supprime des images et réduit la taille du fichier. L'augmenter duplique des images pour combler l'écart, mais n'ajoute pas de véritables détails de mouvement. * Valeurs cibles courantes : 24 (cinéma), 30 (web/diffusion), 60 (lecture fluide). * La piste audio est conservée à sa fréquence d'échantillonnage d'origine. --- --- url: https://docs.snapotter.com/hi/tools/video/change-fps.md description: किसी वीडियो की फ्रेम दर बदलें। --- # Change FPS {#change-fps} किसी वीडियो की फ्रेम दर को 1 और 120 fps के बीच के किसी लक्ष्य मान पर बदलें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | लक्ष्य फ्रेम दर (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * फ्रेम दर घटाने से फ्रेम हटते हैं और फ़ाइल आकार कम होता है। इसे बढ़ाने से अंतर भरने के लिए फ्रेम डुप्लिकेट होते हैं, लेकिन असली गति का विवरण नहीं जुड़ता। * सामान्य लक्ष्य मान: 24 (cinema), 30 (web/broadcast), 60 (सहज प्लेबैक)। * ऑडियो ट्रैक अपनी मूल sample rate पर सुरक्षित रहता है। --- --- url: https://docs.snapotter.com/id/tools/video/change-fps.md description: Mengubah frame rate sebuah video. --- # Change FPS {#change-fps} Mengubah frame rate sebuah video ke nilai target antara 1 dan 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Menerima multipart form data dengan file video dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Frame rate target (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Menurunkan frame rate akan membuang frame dan mengurangi ukuran file. Menaikkannya akan menduplikasi frame untuk mengisi celah tetapi tidak menambahkan detail gerak yang sebenarnya. * Nilai target umum: 24 (sinema), 30 (web/siaran), 60 (pemutaran mulus). * Trek audio dipertahankan pada sample rate aslinya. --- --- url: https://docs.snapotter.com/it/tools/video/change-fps.md description: Cambia la frequenza dei fotogrammi di un video. --- # Change FPS {#change-fps} Cambia la frequenza dei fotogrammi di un video su un valore target compreso tra 1 e 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Accetta dati form multipart con un file video e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Frequenza dei fotogrammi target (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Abbassare la frequenza dei fotogrammi elimina fotogrammi e riduce la dimensione del file. Aumentarla duplica i fotogrammi per riempire il vuoto ma non aggiunge un reale dettaglio di movimento. * Valori target comuni: 24 (cinema), 30 (web/broadcast), 60 (riproduzione fluida). * La traccia audio viene conservata alla sua frequenza di campionamento originale. --- --- url: https://docs.snapotter.com/ja/tools/video/change-fps.md description: 動画のフレームレートを変更します。 --- # Change FPS {#change-fps} 動画のフレームレートを 1 から 120 fps の間の目標値に変更します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | 目標フレームレート(1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * フレームレートを下げるとフレームが間引かれ、ファイルサイズが小さくなります。上げるとフレームが複製されてギャップを埋めますが、実際の動きの詳細が追加されるわけではありません。 * 一般的な目標値: 24(映画)、30(ウェブ/放送)、60(滑らかな再生)。 * 音声トラックは元のサンプルレートで保持されます。 --- --- url: https://docs.snapotter.com/ko/tools/video/change-fps.md description: 비디오의 프레임 레이트를 변경합니다. --- # Change FPS {#change-fps} 비디오의 프레임 레이트를 1에서 120 fps 사이의 목표 값으로 변경합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` 비디오 파일과 JSON `settings` 필드가 담긴 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | 목표 프레임 레이트(1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * 프레임 레이트를 낮추면 프레임이 삭제되어 파일 크기가 줄어듭니다. 높이면 빈 공간을 채우기 위해 프레임이 복제되지만 실제 모션 디테일이 추가되지는 않습니다. * 일반적인 목표 값: 24(영화), 30(웹/방송), 60(부드러운 재생). * 오디오 트랙은 원래 샘플 레이트로 유지됩니다. --- --- url: https://docs.snapotter.com/nl/tools/video/change-fps.md description: De framerate van een video wijzigen. --- # Change FPS {#change-fps} Wijzig de framerate van een video naar een doelwaarde tussen 1 en 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Accepteert multipart form data met een videobestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | fps | number | Nee | `30` | Doelframerate (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Een lagere framerate laat frames vallen en verkleint de bestandsgrootte. Een hogere framerate dupliceert frames om het gat op te vullen, maar voegt geen echte bewegingsdetails toe. * Gebruikelijke doelwaarden: 24 (cinema), 30 (web/broadcast), 60 (vloeiende weergave). * Het audiospoor blijft op de oorspronkelijke samplerate behouden. --- --- url: https://docs.snapotter.com/pl/tools/video/change-fps.md description: Zmiana liczby klatek na sekundę wideo. --- # Change FPS {#change-fps} Zmienia liczbę klatek na sekundę wideo na wartość docelową z zakresu od 1 do 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Przyjmuje dane formularza multipart z plikiem wideo i polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | fps | number | Nie | `30` | Docelowa liczba klatek na sekundę (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Obniżenie liczby klatek pomija klatki i zmniejsza rozmiar pliku. Zwiększenie jej powiela klatki, aby wypełnić lukę, ale nie dodaje rzeczywistych szczegółów ruchu. * Typowe wartości docelowe: 24 (kino), 30 (web/transmisja), 60 (płynne odtwarzanie). * Ścieżka audio jest zachowywana z jej oryginalną częstotliwością próbkowania. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/change-fps.md description: Altera a taxa de quadros de um vídeo. --- # Change FPS {#change-fps} Altera a taxa de quadros de um vídeo para um valor de destino entre 1 e 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | fps | number | Não | `30` | Taxa de quadros de destino (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Reduzir a taxa de quadros descarta quadros e diminui o tamanho do arquivo. Aumentá-la duplica quadros para preencher a lacuna, mas não adiciona detalhes reais de movimento. * Valores de destino comuns: 24 (cinema), 30 (web/broadcast), 60 (reprodução suave). * A faixa de áudio é preservada na sua taxa de amostragem original. --- --- url: https://docs.snapotter.com/ru/tools/video/change-fps.md description: Изменение частоты кадров видео. --- # Change FPS {#change-fps} Изменение частоты кадров видео до целевого значения от 1 до 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Принимает multipart form data с файлом видео и полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Целевая частота кадров (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Понижение частоты кадров отбрасывает кадры и уменьшает размер файла. Повышение дублирует кадры, чтобы заполнить пробел, но не добавляет реальной детализации движения. * Распространённые целевые значения: 24 (кино), 30 (веб/вещание), 60 (плавное воспроизведение). * Аудиодорожка сохраняется с исходной частотой дискретизации. --- --- url: https://docs.snapotter.com/th/tools/video/change-fps.md description: เปลี่ยนอัตราเฟรมของวิดีโอ --- # Change FPS {#change-fps} เปลี่ยนอัตราเฟรมของวิดีโอเป็นค่าเป้าหมายระหว่าง 1 ถึง 120 fps ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | อัตราเฟรมเป้าหมาย (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * การลดอัตราเฟรมจะตัดเฟรมออกและลดขนาดไฟล์ การเพิ่มอัตราเฟรมจะทำเฟรมซ้ำเพื่อเติมช่องว่างแต่ไม่ได้เพิ่มรายละเอียดการเคลื่อนไหวจริง * ค่าเป้าหมายที่พบบ่อย: 24 (โรงภาพยนตร์), 30 (เว็บ/การออกอากาศ), 60 (การเล่นที่ราบรื่น) * แทร็กเสียงจะถูกคงไว้ที่อัตราการสุ่มตัวอย่างเดิม --- --- url: https://docs.snapotter.com/tr/tools/video/change-fps.md description: Bir videonun kare hızını değiştirin. --- # Change FPS {#change-fps} Bir videonun kare hızını 1 ile 120 fps arasında bir hedef değere değiştirin. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Bir video dosyası ve bir JSON `settings` alanı içeren multipart form data kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Hedef kare hızı (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Kare hızını düşürmek kareleri atar ve dosya boyutunu azaltır. Artırmak, boşluğu doldurmak için kareleri çoğaltır ancak gerçek hareket ayrıntısı eklemez. * Yaygın hedef değerler: 24 (sinema), 30 (web/yayın), 60 (akıcı oynatma). * Ses parçası orijinal örnekleme hızında korunur. --- --- url: https://docs.snapotter.com/uk/tools/video/change-fps.md description: Змінює частоту кадрів відео. --- # Change FPS {#change-fps} Змінює частоту кадрів відео на цільове значення в діапазоні від 1 до 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Приймає дані форми multipart із відеофайлом і полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Цільова частота кадрів (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Зниження частоти кадрів відкидає кадри й зменшує розмір файлу. Підвищення дублює кадри, щоб заповнити прогалину, але не додає реальної деталізації руху. * Поширені цільові значення: 24 (кіно), 30 (веб/мовлення), 60 (плавне відтворення). * Аудіодоріжка зберігається з її вихідною частотою дискретизації. --- --- url: https://docs.snapotter.com/vi/tools/video/change-fps.md description: Thay đổi tốc độ khung hình của video. --- # Change FPS {#change-fps} Thay đổi tốc độ khung hình của video sang một giá trị mục tiêu từ 1 đến 120 fps. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` Nhận multipart form data gồm một file video và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | Tốc độ khung hình mục tiêu (1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * Giảm tốc độ khung hình sẽ loại bỏ các khung hình và giảm kích thước file. Tăng nó sẽ nhân đôi các khung hình để lấp đầy khoảng trống nhưng không thêm chi tiết chuyển động thực. * Các giá trị mục tiêu phổ biến: 24 (điện ảnh), 30 (web/phát sóng), 60 (phát mượt). * Track âm thanh được giữ nguyên ở tốc độ lấy mẫu gốc. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/change-fps.md description: 更改视频的帧率。 --- # Change FPS {#change-fps} 将视频的帧率更改为 1 到 120 fps 之间的目标值。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` 接受包含视频文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | 目标帧率(1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * 降低帧率会丢弃帧并减小文件大小。提高帧率会复制帧以填补空缺,但不会增加真实的运动细节。 * 常用目标值:24(电影)、30(网络/广播)、60(流畅播放)。 * 音轨会按其原始采样率保留。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/change-fps.md description: 變更影片的影格率。 --- # Change FPS {#change-fps} 將影片的影格率變更為介於 1 到 120 fps 之間的目標值。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/change-fps` 接受包含一個影片檔案和一個 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fps | number | No | `30` | 目標影格率(1-120) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/change-fps \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"fps": 24}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 10200000 } ``` ## Notes {#notes} * 降低影格率會捨棄影格並縮小檔案大小。提高影格率會複製影格來填補空缺,但不會增加真實的動態細節。 * 常見的目標值:24(電影)、30(網路/廣播)、60(流暢播放)。 * 音訊軌會以其原始取樣率保留。 --- --- url: https://docs.snapotter.com/de/changelog.md description: >- Release Notes und Versionsverlauf für SnapOtter. Sieh dir an, was in jedem Release neu ist, verbessert und behoben wurde. --- # Changelog {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 macht aus dem Bildwerkzeugkasten eine vollständige Suite zur Dateibearbeitung: 200+ Werkzeuge über fünf Modalitäten hinweg (Image, Video, Audio, PDF und Files), neu aufgebaut auf Postgres 17 und einer Redis-gestützten Job-Warteschlange, mit einem `docker run` mit nur einem Befehl. Dies ist ein Major-Release; lies vor dem Upgrade von 1.x den Abschnitt Breaking Changes. ### Neue Funktionen {#new-features} * **Vier neue Werkzeug-Modalitäten**: Video, Audio, PDF und Files ergänzen Image und bringen den Katalog auf 200+ Werkzeuge. * **Dauerhafte Hintergrund-Jobs**: Eine Redis-gestützte Warteschlange (BullMQ) führt jedes Werkzeug als nachverfolgten Job mit Live-SSE-Fortschritt aus. * **All-in-One-Modus mit einem einzigen Container**: Ein `docker run` startet eine vollständige Instanz mit eingebettetem Postgres und Redis. * **KI-Bundles auf Abruf**: Hintergrundentfernung, OCR, Transkription, Hochskalierung, Gesichtserkennung und -verbesserung, Objektradierer, Kolorierung und Fotorestaurierung lassen sich über die UI installieren. Die GPU-Beschleunigung wird pro Framework erkannt. * **Sign PDF**: Zeichne, tippe oder lade eine Signatur hoch und platziere sie im Browser auf einer PDF. * **Automate**: Ein visueller Pipeline-Builder, der Werkzeuge verkettet, mit neun vorgefertigten Vorlagen. * **83 Konvertierungs-Presets mit einem Klick**: Dedizierte JPG-zu-PNG-, MP4-zu-GIF- und ähnliche Konverter mit unscharfer Suche. * **Ebenenbasierter Bildeditor**: Ein Konva-basierter Editor unter `/editor` mit Pinseln, Formen, Anpassungen, Filtern und Kurven. * **Files-Bibliothek**: Speichere jedes Ergebnis und verwende es als Eingabe für ein anderes Werkzeug erneut. * Angeheftete Werkzeuge, Zoom und Verschieben direkt auf der Leinwand, 21 Sprachen und Enterprise-Fähigkeiten (OIDC/SSO, SAML, SCIM, S3-Storage, werkzeugspezifische Berechtigungen, Audit-Export, verteiltes Tracing). ### Verbesserungen {#improvements} * Einen laufenden Vorgang abbrechen. (#137) * Vollauflösendes RAW-Decoding über LibRaw, einschließlich DNG. (#289) * Deployments ohne Root und mit fremder UID (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Genaue Erkennung der KI-Installation und ein gehärteter Installationsablauf. (#214, #352) * Datenschutzhärtung: kein automatischer Drittanbieter-Egress, plus ein optionaler strikter Offline-Modus. * Immer sichtbarer Feedback-Button, auch bei deaktivierter Analyse. ### Fehlerbehebungen {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` deaktiviert die Ratenbegrenzung für Werkzeug-Routen wieder. (#271) * Reparierte KI-virtualenv-Pfade innerhalb des Docker-Images. (#390) * Kompatibilität mit sharp 0.35.2+. (#362) * Layout-Korrekturen im Bildeditor: Lineale, Füllverhalten, Seitenleiste und Leinwandgröße. (#258, #259) * Die italienische Übersetzung abgeschlossen. (#231, #206, #425) * Audio-Normalisierung und loudnorm behalten die Abtastrate der Quelle bei. * SSRF-Härtung: numerischer IPv6-CIDR-Abgleich und ein erweiterter URL-Vorabscan. (#287) * Erzeugte PDFs werden mit SnapOtter als Producer gestempelt. * mediapipe installiert sich unter Python 3.13 und Debian 13. ### Breaking Changes {#breaking-changes} 2.0 ersetzt die eingebettete SQLite-Datenbank durch Postgres 17 und fügt Redis 8 für die Job-Warteschlange hinzu. Deine 1.x-Daten migrieren beim ersten Start automatisch, aber der Container-Stack hat sich geändert, sichere daher zuerst dein gesamtes `/data`-Volume (1.x betreibt SQLite im WAL-Modus, sodass die committeten Daten normalerweise in `snapotter.db-wal` liegen). Wähle dann das Single-Container-Image (eingebettetes Postgres und Redis, nur als Root) oder den Compose-Stack (App plus Postgres 17 und Redis 8). Siehe den [Migrationsleitfaden](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) und den [Upgrade-Leitfaden](/de/guide/upgrading). ### Upgrade {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Oder mit Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Vollständiger Diff auf GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Neues HTML-zu-Image-Werkzeug, Barrierefreiheit nach WCAG 2.2 AA, Sicherheitshärtung aus Penetrationstests und 5 kritische Docker-Fixes. ### Neue Funktionen {#new-features-1} * **HTML zu Image**: Erfasse Screenshots von URLs oder rohem HTML als PNG/JPEG/WebP. Ganzseitige Aufnahmen, benutzerdefinierte Viewports, Dark Mode. * **Docker-\_FILE-Secret-Konvention**: Binde sensible Umgebungsvariablen als Dateien statt im Klartext ein. (#205) * **Enterprise-Lizenzierung und S3-Storage**: Optionaler kommerzieller Lizenzschlüssel und S3-kompatibler Objektspeicher. * **Verbesserungen am Formeneditor**: Transparenz für Füllung/Kontur, RGBA-Farbwähler, gestrichelte Linienstile. * **Vorgefertigte Release-Archive**: Lade Tarballs aus den GitHub Releases für Nicht-Docker-Installationen (Proxmox, Bare Metal, LXC) herunter. (#202) ### Verbesserungen {#improvements-1} * **Barrierefreiheit nach WCAG 2.2 AA**: Sprungnavigation, Fokus-Trapping, aria-live-Bereiche, Unterstützung für reduzierte Bewegung, korrekte Kontrastverhältnisse. (#209) * **Mobile Reaktionsfähigkeit**: Responsive Einstellungen, automatische SSE-Wiederverbindung beim Tab-Wechsel auf Mobilgeräten. (#203, #204) * **Qualität der Hintergrundentfernung**: Kantenglättung, Farbdekontamination, Auswahl des Ausgabeformats. * **Italienische Übersetzung**: ~145 neue Strings von @albanobattistella. (#206) * **Werkzeugspezifische API-Dokumentation**: 53 Doku-Seiten mit Parametern, Beispielen und Antwortformaten. * **KI-Modell-Downloads**: Wiederholungslogik mit exponentiellem Backoff für HuggingFace. (#201) ### Fehlerbehebungen {#bug-fixes-1} * Frische Docker-Container waren völlig unbrauchbar (die Ratenbegrenzung blockierte alle Anfragen). * KI-Werkzeuge zur Gesichtserkennung (blur-faces, red-eye-removal, enhance-faces, passport-photo) schlugen auf allen Plattformen fehl. * HEIC-Dateien auf ARM defekt (libheif-Symbolkonflikt). * Die KI-Bundles für Upscale und restore-photo ließen sich auf ARM nicht installieren. * OCR verwendete auf GPU-Containern die falsche CUDA-Version. * Umgehung des SSRF-Schutzes über hexadezimale IPv4-in-IPv6-Adressen. (Dank an: @tonghuaroot) * iPhone-HEIC-Decoding mit Zusatzbildern. (#183, #199) * Real-ESRGAN-CUDA-OOM auf 8-GB-GPUs. (#200) * 6 Sentry-Fehler aus der Produktion und 7 QA-Bugs. (#208) ### Sicherheit {#security} * 10 Befunde aus Penetrationstests behoben (XFF-Umgehung, Abstürze durch fehlerhaftes JSON, unbegrenzte Pipelines, XSS im Audit-Log, TRACE-Methode und mehr). (#207) * Hexadezimale IPv6-SSRF-Umgehung blockiert. (Dank an: @tonghuaroot) * Basis-Images im Dockerfile per Digest gepinnt. ### Upgrade {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Oder mit Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Vollständiger Diff auf GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Live-Demo, werkzeugspezifische Landing Pages und eine Reihe von Feinschliff-Korrekturen. ### Neue Funktionen {#new-features-2} * **Live-Demo** - Mit [demo.snapotter.com](https://demo.snapotter.com) können Leute SnapOtter ausprobieren, ohne etwas zu installieren. * **Werkzeug-Übersichtsseite** - Durchstöbere alle 50+ Werkzeuge unter `/tools` mit Suche und Kategoriefiltern. * **50+ SEO-Landing-Pages** - Jedes Werkzeug hat jetzt eine eigene Landing Page mit FAQs, Anwendungsfällen und Vergleichstabellen. * **Hintergrundvorschau** - Ein Vorher-Nachher-Schieberegler zeigt einen karierten Hintergrund hinter transparenten Bildern. * **Generator für starke Passwörter** - Button mit einem Klick im Formular Mitglieder hinzufügen. ### Fehlerbehebungen {#bug-fixes-2} * Das HEIC/HEIF-Info-Werkzeug schlägt nicht mehr fehl (Pre-Decode hinzugefügt). * Die Installation von KI-Modell-Bundles zeigt bessere Fehlermeldungen und respektiert Ressourcenlimits. * Bibliotheks-Thumbnails laden korrekt (Auth-Header fehlten). * Dropdown-Menüs werden in den Tabellen der People- und Teams-Einstellungen nicht mehr abgeschnitten. * Der Prozentwert des Größenvergleichs bei Nicht-Komprimierungswerkzeugen ausgeblendet. * Doppelten Link zur Datenschutzrichtlinie entfernt. * Italienische Übersetzung für die Einstellungen der KI-Funktionen hinzugefügt. * Umbenannte Lucide-Icons aktualisiert (Wand2, Columns). ### Infrastruktur {#infrastructure} * OpenSSF Scorecard von 4.3 auf ~7.0 gehärtet. * CI-Tests in 4 Shards parallelisiert mit verkleinerten Fixtures. * 41 Abhängigkeits-Updates. ### Upgrade {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Oder mit Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Vollständiger Diff auf GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Fünf neue Werkzeuge, ein vollständiger Bildeditor, SSO-Login, 20 Sprachen. Wahrscheinlich hätten das drei separate Releases sein sollen, aber hier sind wir. ### Neue Funktionen {#new-features-3} * **Bildeditor** - Ebenen, Pinsel, Formen, Anpassungen, Filter, Kurven, Tastenkürzel. Läuft in deinem Browser, verarbeitet auf deiner Hardware. * **OIDC-/SSO-Authentifizierung** - Anmeldung mit Google, GitHub, Okta oder einem beliebigen OpenID-Connect-Anbieter. Setze ein paar Umgebungsvariablen und dein Team nutzt seine bestehenden Konten. * **Meme-Generator** - 100 integrierte Vorlagen mit Textdarstellung über opentype.js. Oder lade dein eigenes Bild hoch. * **Beautify** - Wirf einen Screenshot hinein, erhalte ein poliertes Bild. Geräterahmen (macOS, Windows, Browser), Schatten, Farbverläufe, Social-Media-Presets. * **Simulation von Farbfehlsichtigkeit** - Sieh dir eine Vorschau an, wie Bilder mit Protanopie, Deuteranopie, Tritanopie und anderen Farbsehschwächen aussehen. * **PNG-Transparenz-Fixer** - Erkennt scheintransparente PNGs und behebt sie mit BiRefNet-HR-Matting. Optionale Wasserzeichenentfernung über LaMa-Inpainting. * **KI-Leinwanderweiterung** - Erweitere Bildgrenzen mit KI-Füllung. Drei Qualitätsstufen (schnell, ausgewogen, Qualität), je nachdem, wie viel GPU-Zeit du eintauschen möchtest. * **20 Sprachen** - Arabisch, Chinesisch (vereinfacht/traditionell), Tschechisch, Niederländisch, Französisch, Deutsch, Hindi, Indonesisch, Italienisch, Japanisch, Koreanisch, Polnisch, Portugiesisch, Russisch, Spanisch, Thai, Türkisch, Ukrainisch, Vietnamesisch. RTL funktioniert für Arabisch. * **URL-Import** - Füge URLs in die Dropzone ein oder importiere sie in Massen aus einer Liste. Serverseitiger Abruf mit SSRF-Schutz. * **Mehrdatei-Radierer** - Zeichne Radiermasken über mehrere Bilder und verarbeite sie alle mit einem Klick. Striche bleiben pro Bild erhalten. * **Pipeline-Import/-Export** - Speichere Werkzeugketten als JSON und teile sie mit anderen. * **17 neue Kamera-RAW-Formate** über exiftool, plus QOI-, JP2-, EPS-, DDS-, CUR-, DPX-, FITS-, PPM/PGM/PBM-, SVGZ- und APNG-Eingabe. Neue Ausgabe-Codecs für BMP, ICO, JP2, QOI. AVIF-, TIFF-, GIF-, JXL- und PSD-Export aus einem zuvor verlorenen Branch wiederhergestellt. ### Verbesserungen {#improvements-2} * **Bildverbesserung** - Die alte Pipeline durch CLAHE + normalise + gamma ersetzt. Ein neuer Deep-Enhance-Schalter nutzt das KI-Modell für aggressivere Ergebnisse. * **Foto restaurieren** - Kratzererkennung neu geschrieben mit 8-Winkel-Otsu-Filterung. LaMa-Inpainting läuft jetzt in nativer Auflösung. * **Exotische Formate überall** - OCR, image-to-PDF, Favicon-Generator, Komposition, Stitch und Vektorisierung decodieren jetzt alle HEIC, RAW, PSD. * **Komprimieren** - Toleranz für die Zielgröße von 5 % auf 1 % verengt. Die Zielgröße ist der Standardmodus. Stepper-Buttons und eine KB/MB-Einheitenauswahl hinzugefügt. * **Sentry-Bereinigung** - 644 nicht handlungsrelevante Ereignisse gefiltert. Echte Fehler werden jetzt korrekt behandelt. * **GPU-Erkennung** - Bessere Diagnose für Container, in denen CUDA vorhanden ist, nvidia-smi aber nicht. * **Modus mit deaktivierter Authentifizierung** - Ein anonymer Benutzer wird mit der Admin-Rolle in der DB angelegt. API-Schlüssel, Pipelines und Benutzerdateien scheitern nicht mehr an FK-Constraints. * **2.705+ neue Tests** über Unit, Integration und E2E. ### Fehlerbehebungen {#bug-fixes-3} * Upscale auf der CPU läuft auf NAS-Boxen und stromsparender Hardware nicht mehr in ein Timeout. * Ein QR-Code-Logo lässt die Vorschau nicht mehr dauerhaft verschwinden. * Überlauf beim Zuschneiden bei hohen Hochformatbildern behoben. * TIFF-Alpha-Dateien erzwingen korrekt eine PNG-Ausgabe, statt Korruption zu erzeugen. * Das HDR/EXR-Decoding konvertiert vor CLAHE nach 8-Bit und behebt so Decoding-Fehler. * Eingabepuffer für Gesichtslandmarken werden vor dem Python-Sidecar nach PNG konvertiert und beheben so Abstürze. * Die Duplikatsuche kommt mit gemischten Formatstapeln und Netzwerkfehlern zurecht. * Die Beautify-Vorschau aktualisiert sich in Echtzeit. * Fortschrittsbalken für Stitch und Vektorisierung. * SVGZ wird von SVG-zu-Raster verarbeitet. * Nicht-ASCII-Dateinamen über einen prozentkodierten X-File-Results-Header behoben. ### Upgrade {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Oder mit Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Vollständiger Diff auf GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Vereinheitlichtes Docker-Image mit GPU-Autoerkennung. Ein Image bewältigt sowohl CPU- als auch GPU-Workloads. Compose zu einer einzigen Datei mit Log-Rotation vereinfacht. Modell-Vorabdownloads umfassen jetzt Verifikation und einen Smoke-Test. *** ## v1.13.0 {#v1-13-0} Rollenbasierte Zugriffskontrolle (RBAC). 14 granulare Berechtigungen, drei integrierte Rollen (admin, editor, user), Unterstützung für benutzerdefinierte Rollen. Berechtigungsprüfungen auf allen API-Routen. Frontend-Tabs nach Benutzerberechtigungen gefiltert. *** ## v1.12.0 {#v1-12-0} PDF-zu-Image-Werkzeug. Konvertiere PDF-Seiten nach PNG, JPEG, WebP oder TIFF mit benutzerdefinierter DPI. Vereinheitlichtes Docker-Image mit GPU-Autoerkennung. *** ## v1.11.0 {#v1-11-0} Automatisch generierte llms.txt über vitepress-plugin-llms für KI-freundliche Dokumentation. *** ## v1.10.0 {#v1-10-0} Inhaltsbewusstes Skalieren (Seam Carving) mit Gesichtsschutz. Skaliere Bilder unter Beibehaltung wichtiger Inhalte. *** ## v1.9.0 {#v1-9-0} Stitch-/Combine-Werkzeug. Füge Bilder nebeneinander, vertikal gestapelt oder in einem benutzerdefinierten Raster zusammen. *** ## v1.8.0 {#v1-8-0} Metadaten-bearbeiten-Werkzeug. Zeige und bearbeite EXIF-, IPTC- und XMP-Metadaten mit einer granularen Entfernen-/Behalten-Oberfläche. *** ## Ältere Releases {#older-releases} Das vollständige Changelog auf Commit-Ebene inklusive Patch-Releases findest du in den [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/hi/changelog.md description: >- SnapOtter के लिए रिलीज़ नोट्स और संस्करण इतिहास। देखें कि हर रिलीज़ में क्या नया, बेहतर और ठीक हुआ है। --- # Changelog {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 इमेज टूलकिट को एक पूर्ण फ़ाइल-मैनिपुलेशन सुइट में बदल देता है: पाँच मोडैलिटी (Image, Video, Audio, PDF, और Files) में 200+ टूल, जो Postgres 17 और Redis-समर्थित जॉब क्यू पर फिर से बनाए गए हैं, साथ में एक ही कमांड वाला `docker run`। यह एक बड़ी रिलीज़ है; 1.x से अपग्रेड करने से पहले Breaking changes पढ़ें। ### New features {#new-features} * **चार नई टूल मोडैलिटी**: Video, Audio, PDF, और Files, Image के साथ जुड़ते हैं, जिससे कैटलॉग 200+ टूल तक पहुँच जाता है। * **टिकाऊ बैकग्राउंड जॉब्स**: एक Redis-समर्थित क्यू (BullMQ) हर टूल को लाइव SSE प्रगति के साथ एक ट्रैक किए गए जॉब के रूप में चलाता है। * **ऑल-इन-वन सिंगल-कंटेनर मोड**: एक `docker run` एम्बेडेड Postgres और Redis के साथ एक पूर्ण इंस्टेंस बूट करता है। * **ऑन-डिमांड AI बंडल**: बैकग्राउंड हटाना, OCR, ट्रांसक्रिप्शन, अपस्केलिंग, चेहरा पहचान और सुधार, ऑब्जेक्ट इरेज़र, कलराइज़, और फ़ोटो रीस्टोरेशन UI से इंस्टॉल होते हैं। GPU त्वरण प्रति फ़्रेमवर्क पहचाना जाता है। * **Sign PDF**: एक हस्ताक्षर बनाएँ, टाइप करें, या अपलोड करें और उसे ब्राउज़र में PDF पर रखें। * **Automate**: एक विज़ुअल पाइपलाइन बिल्डर जो टूल्स को श्रृंखलाबद्ध करता है, नौ पूर्व-निर्मित टेम्पलेट के साथ। * **83 एक-क्लिक रूपांतरण प्रीसेट**: फ़ज़ी खोज के साथ समर्पित JPG-to-PNG, MP4-to-GIF, और समान कन्वर्टर। * **लेयर-आधारित इमेज एडिटर**: `/editor` पर एक Konva-संचालित एडिटर, जिसमें ब्रश, आकृतियाँ, समायोजन, फ़िल्टर, और कर्व्स हैं। * **Files लाइब्रेरी**: किसी भी परिणाम को सहेजें और उसे किसी अन्य टूल के इनपुट के रूप में पुनः उपयोग करें। * पिन किए गए टूल, इन-कैनवास ज़ूम और पैन, 21 भाषाएँ, और एंटरप्राइज़ क्षमताएँ (OIDC/SSO, SAML, SCIM, S3 स्टोरेज, प्रति-टूल अनुमतियाँ, ऑडिट एक्सपोर्ट, वितरित ट्रेसिंग)। ### Improvements {#improvements} * चल रही प्रक्रिया को रद्द करें। (#137) * LibRaw के माध्यम से पूर्ण-रिज़ॉल्यूशन RAW डिकोडिंग, DNG सहित। (#289) * नॉन-रूट और विदेशी-UID परिनियोजन (TrueNAS, Unraid, OpenShift, PUID/PGID)। (#230, #127) * सटीक AI इंस्टॉल पहचान और एक सुदृढ़ किया गया इंस्टॉल फ़्लो। (#214, #352) * गोपनीयता सुदृढ़ीकरण: कोई स्वचालित तृतीय-पक्ष एग्रेस नहीं, साथ में एक वैकल्पिक सख्त-ऑफ़लाइन मोड। * हमेशा चालू रहने वाला फ़ीडबैक बटन, एनालिटिक्स बंद होने पर भी। ### Bug fixes {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` टूल रूट के लिए रेट लिमिटिंग को फिर से अक्षम करता है। (#271) * Docker इमेज के अंदर AI virtualenv पथों की मरम्मत की गई। (#390) * sharp 0.35.2+ अनुकूलता। (#362) * इमेज एडिटर लेआउट सुधार: रूलर, फ़िल व्यवहार, साइडबार, और कैनवास साइज़िंग। (#258, #259) * इतालवी अनुवाद पूरा किया। (#231, #206, #425) * Audio normalize और loudnorm स्रोत सैंपल रेट को संरक्षित करते हैं। * SSRF सुदृढ़ीकरण: संख्यात्मक IPv6 CIDR मिलान और एक विस्तृत URL पूर्व-स्कैन। (#287) * जनरेट की गई PDF पर Producer के रूप में SnapOtter की मुहर लगाई जाती है। * mediapipe Python 3.13 और Debian 13 पर इंस्टॉल होता है। ### Breaking changes {#breaking-changes} 2.0 एम्बेडेड SQLite डेटाबेस को Postgres 17 से बदल देता है और जॉब क्यू के लिए Redis 8 जोड़ता है। आपका 1.x डेटा पहली बार बूट होने पर स्वचालित रूप से माइग्रेट होता है, लेकिन कंटेनर स्टैक बदल गया है, इसलिए पहले अपने पूरे `/data` वॉल्यूम का बैकअप लें (1.x SQLite को WAL मोड में चलाता है, इसलिए कमिट किया गया डेटा आमतौर पर `snapotter.db-wal` में रहता है)। फिर सिंगल-कंटेनर इमेज (एम्बेडेड Postgres और Redis, केवल रूट) या Compose स्टैक (ऐप के साथ Postgres 17 और Redis 8) चुनें। [माइग्रेशन गाइड](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) और [अपग्रेड गाइड](/hi/guide/upgrading) देखें। ### Upgrade {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` या Docker Compose के साथ: ```bash docker compose pull && docker compose up -d ``` [GitHub पर पूर्ण diff](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} नया HTML to Image टूल, WCAG 2.2 AA सुगम्यता, पेनिट्रेशन टेस्टिंग से सुरक्षा सुदृढ़ीकरण, और 5 महत्वपूर्ण Docker सुधार। ### New features {#new-features-1} * **HTML to Image**: URL या कच्चे HTML के स्क्रीनशॉट PNG/JPEG/WebP के रूप में कैप्चर करें। फ़ुल-पेज कैप्चर, कस्टम व्यूपोर्ट, डार्क मोड। * **Docker \_FILE सीक्रेट परंपरा**: संवेदनशील env वेरिएबल्स को सादे-टेक्स्ट के बजाय फ़ाइलों के रूप में माउंट करें। (#205) * **एंटरप्राइज़ लाइसेंसिंग और S3 स्टोरेज**: वैकल्पिक व्यावसायिक लाइसेंस कुंजी और S3-संगत ऑब्जेक्ट स्टोरेज। * **आकृति एडिटर सुधार**: फ़िल/स्ट्रोक पारदर्शिता, RGBA रंग चयनकर्ता, डैश लाइन शैलियाँ। * **पूर्व-निर्मित रिलीज़ आर्काइव**: नॉन-Docker इंस्टॉल (Proxmox, बेयर मेटल, LXC) के लिए GitHub Releases से tarball डाउनलोड करें। (#202) ### Improvements {#improvements-1} * **WCAG 2.2 AA सुगम्यता**: नेविगेशन स्किप, फ़ोकस ट्रैपिंग, aria-live क्षेत्र, कम मोशन समर्थन, सही कंट्रास्ट अनुपात। (#209) * **मोबाइल रिस्पॉन्सिवनेस**: रिस्पॉन्सिव सेटिंग्स, मोबाइल टैब स्विच पर SSE स्वतः-पुनर्संयोजन। (#203, #204) * **बैकग्राउंड हटाने की गुणवत्ता**: एज स्मूदिंग, रंग डीकंटैमिनेशन, आउटपुट फ़ॉर्मेट चयन। * **इतालवी अनुवाद**: @albanobattistella द्वारा ~145 नई स्ट्रिंग्स। (#206) * **प्रति-टूल API दस्तावेज़**: पैरामीटर, उदाहरण, और प्रतिक्रिया फ़ॉर्मेट के साथ 53 डॉक पेज। * **AI मॉडल डाउनलोड**: HuggingFace के लिए एक्सपोनेंशियल बैकऑफ़ के साथ रिट्राई लॉजिक। (#201) ### Bug fixes {#bug-fixes-1} * नए Docker कंटेनर पूरी तरह अनुपयोगी थे (रेट लिमिट सभी अनुरोधों को रोक रहा था)। * चेहरा पहचान AI टूल (blur-faces, red-eye-removal, enhance-faces, passport-photo) सभी प्लेटफ़ॉर्म पर विफल हो रहे थे। * ARM पर HEIC फ़ाइलें टूटी हुई थीं (libheif सिंबल बेमेल)। * Upscale और restore-photo AI बंडल ARM पर इंस्टॉल होने में विफल रहे। * OCR ने GPU कंटेनरों पर गलत CUDA संस्करण का उपयोग किया। * हेक्स IPv4-मैप्ड IPv6 पतों के माध्यम से SSRF गार्ड बायपास। (श्रेय: @tonghuaroot) * सहायक इमेज के साथ iPhone HEIC डिकोडिंग। (#183, #199) * 8GB GPU पर Real-ESRGAN CUDA OOM। (#200) * 6 प्रोडक्शन Sentry त्रुटियाँ और 7 QA बग। (#208) ### Security {#security} * 10 पेनिट्रेशन टेस्ट निष्कर्षों का समाधान किया गया (XFF बायपास, विकृत JSON क्रैश, असीमित पाइपलाइन, ऑडिट लॉग XSS, TRACE विधि, और अधिक)। (#207) * SSRF हेक्स IPv6 बायपास अवरुद्ध किया गया। (श्रेय: @tonghuaroot) * Dockerfile बेस इमेज को डाइजेस्ट द्वारा पिन किया गया। ### Upgrade {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` या Docker Compose के साथ: ```bash docker compose pull && docker compose up -d ``` [GitHub पर पूर्ण diff](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} लाइव डेमो, प्रति-टूल लैंडिंग पेज, और पॉलिश सुधारों का एक बैच। ### New features {#new-features-2} * **लाइव डेमो** - [demo.snapotter.com](https://demo.snapotter.com) लोगों को बिना कुछ इंस्टॉल किए SnapOtter आज़माने देता है। * **टूल्स इंडेक्स पेज** - खोज और श्रेणी फ़िल्टर के साथ `/tools` पर सभी 50+ टूल ब्राउज़ करें। * **50+ SEO लैंडिंग पेज** - अब हर टूल के पास FAQ, उपयोग के मामले, और तुलना तालिकाओं के साथ एक समर्पित लैंडिंग पेज है। * **बैकग्राउंड पूर्वावलोकन** - बिफ़ोर-आफ़्टर स्लाइडर पारदर्शी इमेज के पीछे एक चेकर्ड बैकग्राउंड दिखाता है। * **मज़बूत पासवर्ड जनरेटर** - Add Members फ़ॉर्म में एक-क्लिक बटन। ### Bug fixes {#bug-fixes-2} * HEIC/HEIF इन्फ़ो टूल अब विफल नहीं होता (पूर्व-डिकोड जोड़ा गया)। * AI मॉडल बंडल इंस्टॉल बेहतर त्रुटि संदेश दिखाता है और संसाधन सीमाओं का सम्मान करता है। * लाइब्रेरी थंबनेल सही ढंग से लोड होते हैं (auth हेडर गायब थे)। * People और Teams सेटिंग्स तालिकाओं में ड्रॉपडाउन मेनू अब क्लिप नहीं होते। * नॉन-कंप्रेशन टूल पर आकार तुलना प्रतिशत छिपा हुआ। * डुप्लिकेट गोपनीयता नीति लिंक हटाया गया। * AI features सेटिंग्स के लिए इतालवी अनुवाद जोड़ा गया। * नाम बदले गए Lucide आइकन अपडेट किए गए (Wand2, Columns)। ### Infrastructure {#infrastructure} * OpenSSF Scorecard 4.3 से ~7.0 तक सुदृढ़ किया गया। * CI परीक्षणों को छोटे किए गए फ़िक्स्चर के साथ 4 शार्ड में समानांतर किया गया। * 41 डिपेंडेंसी अपडेट। ### Upgrade {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` या Docker Compose के साथ: ```bash docker compose pull && docker compose up -d ``` [GitHub पर पूर्ण diff](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} पाँच नए टूल, एक पूर्ण इमेज एडिटर, SSO लॉगिन, 20 भाषाएँ। शायद इसे तीन अलग-अलग रिलीज़ होना चाहिए था, लेकिन यहाँ हम हैं। ### New features {#new-features-3} * **इमेज एडिटर** - लेयर्स, ब्रश, आकृतियाँ, समायोजन, फ़िल्टर, कर्व्स, कीबोर्ड शॉर्टकट। आपके ब्राउज़र में चलता है, आपके हार्डवेयर पर प्रोसेस करता है। * **OIDC / SSO प्रमाणीकरण** - Google, GitHub, Okta, या किसी भी OpenID Connect प्रदाता के साथ लॉगिन करें। कुछ env वेरिएबल्स सेट करें और आपकी टीम अपने मौजूदा अकाउंट का उपयोग करती है। * **मीम जनरेटर** - opentype.js के माध्यम से टेक्स्ट रेंडरिंग के साथ 100 अंतर्निहित टेम्पलेट। या अपनी खुद की इमेज अपलोड करें। * **Beautify** - एक स्क्रीनशॉट डालें, एक पॉलिश की गई इमेज पाएँ। डिवाइस फ़्रेम (macOS, Windows, ब्राउज़र), छायाएँ, ग्रेडिएंट, सोशल मीडिया प्रीसेट। * **रंग अंधता सिमुलेशन** - पूर्वावलोकन करें कि प्रोटानोपिया, ड्यूटेरानोपिया, ट्रिटानोपिया, और अन्य रंग दृष्टि कमियों के साथ इमेज कैसी दिखती हैं। * **PNG पारदर्शिता फ़िक्सर** - नकली-पारदर्शी PNG का पता लगाता है और उन्हें BiRefNet HR-matting से ठीक करता है। LaMa इनपेंटिंग के माध्यम से वैकल्पिक वॉटरमार्क हटाना। * **AI कैनवास विस्तार** - AI फ़िल के साथ इमेज सीमाओं को बढ़ाएँ। तीन गुणवत्ता स्तर (fast, balanced, quality) इस पर निर्भर करते हैं कि आप कितना GPU समय व्यापार करना चाहते हैं। * **20 भाषाएँ** - अरबी, चीनी (सरलीकृत/परंपरागत), चेक, डच, फ़्रेंच, जर्मन, हिंदी, इंडोनेशियाई, इतालवी, जापानी, कोरियाई, पोलिश, पुर्तगाली, रूसी, स्पेनिश, थाई, तुर्की, यूक्रेनी, वियतनामी। अरबी के लिए RTL काम करता है। * **URL आयात** - ड्रॉपज़ोन में URL पेस्ट करें या किसी सूची से बल्क-आयात करें। SSRF सुरक्षा के साथ सर्वर-साइड फ़ेच। * **मल्टी-फ़ाइल इरेज़र** - कई इमेज पर इरेज़ मास्क बनाएँ, उन सभी को एक क्लिक से प्रोसेस करें। स्ट्रोक प्रति-इमेज बने रहते हैं। * **पाइपलाइन आयात/निर्यात** - टूल श्रृंखलाओं को JSON के रूप में सहेजें, उन्हें दूसरों के साथ साझा करें। * exiftool के माध्यम से **17 नए कैमरा RAW फ़ॉर्मेट**, साथ में QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ, और APNG इनपुट। BMP, ICO, JP2, QOI के लिए नए आउटपुट कोडेक। AVIF, TIFF, GIF, JXL, और PSD एक्सपोर्ट पहले खोई हुई शाखा से पुनर्प्राप्त किया गया। ### Improvements {#improvements-2} * **इमेज सुधार** - पुरानी पाइपलाइन को CLAHE + normalise + gamma से बदला गया। नया Deep Enhance टॉगल अधिक आक्रामक परिणामों के लिए AI मॉडल का उपयोग करता है। * **फ़ोटो रीस्टोर** - 8-कोण Otsu फ़िल्टरिंग के साथ स्क्रैच पहचान को फिर से लिखा गया। LaMa इनपेंटिंग अब नेटिव रिज़ॉल्यूशन पर चलता है। * **हर जगह विदेशी फ़ॉर्मेट** - OCR, image-to-PDF, फ़ेविकॉन जनरेटर, कंपोज़िशन, स्टिच, और वेक्टराइज़ सभी अब HEIC, RAW, PSD डिकोड करते हैं। * **Compress** - लक्ष्य-आकार सहनशीलता 5% से 1% तक कड़ी की गई। लक्ष्य आकार डिफ़ॉल्ट मोड है। स्टेपर बटन और KB/MB यूनिट चयनकर्ता जोड़े गए। * **Sentry सफ़ाई** - 644 गैर-क्रियाशील घटनाएँ फ़िल्टर की गईं। असली त्रुटियाँ अब सही ढंग से संभाली जाती हैं। * **GPU पहचान** - उन कंटेनरों के लिए बेहतर डायग्नोस्टिक्स जहाँ CUDA मौजूद है लेकिन nvidia-smi नहीं है। * **Auth-अक्षम मोड** - admin भूमिका के साथ DB में अनाम उपयोगकर्ता सीड किया जाता है। API कुंजियाँ, पाइपलाइनें, और उपयोगकर्ता फ़ाइलें अब FK बाधाओं पर नहीं टूटतीं। * यूनिट, इंटीग्रेशन, और E2E में **2,705+ नए परीक्षण**। ### Bug fixes {#bug-fixes-3} * CPU पर Upscale अब NAS बॉक्स और कम-पावर हार्डवेयर पर टाइम आउट नहीं होता। * QR कोड लोगो अब पूर्वावलोकन को स्थायी रूप से गायब नहीं करता। * लंबी पोर्ट्रेट इमेज के लिए क्रॉप ओवरफ़्लो ठीक किया गया। * TIFF अल्फ़ा फ़ाइलें भ्रष्टता उत्पन्न करने के बजाय सही ढंग से PNG आउटपुट को बाध्य करती हैं। * HDR/EXR डिकोड CLAHE से पहले 8-बिट में बदल जाता है, जिससे डिकोड विफलताएँ ठीक होती हैं। * Python साइडकार से पहले फ़ेस लैंडमार्क इनपुट बफ़र को PNG में बदला जाता है, जिससे क्रैश ठीक होते हैं। * Find duplicates मिश्रित-फ़ॉर्मेट बैच और नेटवर्क त्रुटियों को संभालता है। * Beautify पूर्वावलोकन वास्तविक समय में अपडेट होता है। * स्टिच और वेक्टराइज़ के लिए प्रगति बार। * SVGZ को SVG-to-raster द्वारा संभाला जाता है। * नॉन-ASCII फ़ाइलनाम प्रतिशत-एन्कोडेड X-File-Results हेडर के माध्यम से ठीक किए गए। ### Upgrade {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` या Docker Compose के साथ: ```bash docker compose pull && docker compose up -d ``` [GitHub पर पूर्ण diff](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} GPU स्वतः-पहचान के साथ एकीकृत Docker इमेज। एक इमेज CPU और GPU दोनों वर्कलोड संभालती है। लॉग रोटेशन के साथ compose को एक ही फ़ाइल में सरल किया गया। मॉडल पूर्व-डाउनलोड में अब सत्यापन और एक स्मोक टेस्ट शामिल है। *** ## v1.13.0 {#v1-13-0} भूमिका-आधारित पहुँच नियंत्रण (RBAC)। 14 सूक्ष्म अनुमतियाँ, तीन अंतर्निहित भूमिकाएँ (admin, editor, user), कस्टम भूमिका समर्थन। सभी API रूट पर अनुमति जाँच। उपयोगकर्ता अनुमतियों द्वारा फ़िल्टर किए गए फ़्रंटएंड टैब। *** ## v1.12.0 {#v1-12-0} PDF to Image टूल। PDF पृष्ठों को कस्टम DPI पर PNG, JPEG, WebP, या TIFF में बदलें। GPU स्वतः-पहचान के साथ एकीकृत Docker इमेज। *** ## v1.11.0 {#v1-11-0} AI-अनुकूल दस्तावेज़ीकरण के लिए vitepress-plugin-llms के माध्यम से स्वतः-जनरेट किया गया llms.txt। *** ## v1.10.0 {#v1-10-0} चेहरा सुरक्षा के साथ कंटेंट-अवेयर रीसाइज़ (सीम कार्विंग)। महत्वपूर्ण कंटेंट को संरक्षित करते हुए इमेज का आकार बदलें। *** ## v1.9.0 {#v1-9-0} Stitch / Combine टूल। इमेज को अगल-बगल, ऊर्ध्वाधर रूप से ढेर करके, या एक कस्टम ग्रिड में जोड़ें। *** ## v1.8.0 {#v1-8-0} Edit Metadata टूल। एक सूक्ष्म strip/keep इंटरफ़ेस के साथ EXIF, IPTC, और XMP मेटाडेटा देखें और संपादित करें। *** ## Older releases {#older-releases} पैच रिलीज़ सहित पूर्ण कमिट-स्तरीय changelog के लिए, [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases) देखें। --- --- url: https://docs.snapotter.com/id/changelog.md description: >- Catatan rilis dan riwayat versi untuk SnapOtter. Lihat apa yang baru, ditingkatkan, dan diperbaiki di setiap rilis. --- # Changelog {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 mengubah toolkit gambar menjadi rangkaian manipulasi file yang lengkap: 200+ tool di lima modalitas (Image, Video, Audio, PDF, dan Files), dibangun ulang di atas Postgres 17 dan antrean job berbasis Redis, dengan `docker run` satu perintah. Ini adalah rilis besar; baca Perubahan yang merusak kompatibilitas sebelum melakukan upgrade dari 1.x. ### Fitur baru {#new-features} * **Empat modalitas tool baru**: Video, Audio, PDF, dan Files bergabung dengan Image, membawa katalog ke 200+ tool. * **Background job yang tahan lama**: Antrean berbasis Redis (BullMQ) menjalankan setiap tool sebagai job yang dilacak dengan progres SSE langsung. * **Mode all-in-one kontainer tunggal**: Satu `docker run` mem-boot instance lengkap dengan Postgres dan Redis tertanam. * **Bundel AI sesuai permintaan**: Penghapusan latar belakang, OCR, transkripsi, upscaling, deteksi dan penyempurnaan wajah, penghapus objek, pewarnaan, dan restorasi foto dipasang dari UI. Akselerasi GPU terdeteksi per framework. * **Sign PDF**: Gambar, ketik, atau unggah tanda tangan lalu tempatkan di PDF langsung di browser. * **Automate**: Pembuat pipeline visual yang merangkai tool, dengan sembilan templat siap pakai. * **83 preset konversi sekali klik**: Konverter khusus JPG-ke-PNG, MP4-ke-GIF, dan sejenisnya dengan pencarian fuzzy. * **Editor gambar berbasis layer**: Editor bertenaga Konva di `/editor` dengan kuas, bentuk, penyesuaian, filter, dan kurva. * **Pustaka Files**: Simpan hasil apa pun dan gunakan kembali sebagai input untuk tool lain. * Tool yang disematkan, zoom dan pan dalam kanvas, 21 bahasa, dan kemampuan enterprise (OIDC/SSO, SAML, SCIM, penyimpanan S3, izin per tool, ekspor audit, pelacakan terdistribusi). ### Peningkatan {#improvements} * Membatalkan proses yang sedang berjalan. (#137) * Dekode RAW resolusi penuh melalui LibRaw, termasuk DNG. (#289) * Deployment non-root dan foreign-UID (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Deteksi pemasangan AI yang akurat dan alur pemasangan yang diperkuat. (#214, #352) * Penguatan privasi: tidak ada egress pihak ketiga otomatis, plus mode strict-offline opsional. * Tombol umpan balik yang selalu aktif, bahkan dengan analitik dimatikan. ### Perbaikan bug {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` menonaktifkan pembatasan laju untuk route tool lagi. (#271) * Memperbaiki jalur virtualenv AI di dalam image Docker. (#390) * Kompatibilitas sharp 0.35.2+. (#362) * Perbaikan tata letak editor gambar: penggaris, perilaku isian, sidebar, dan ukuran kanvas. (#258, #259) * Menyelesaikan terjemahan bahasa Italia. (#231, #206, #425) * Audio normalize dan loudnorm mempertahankan sample rate sumber. * Penguatan SSRF: pencocokan CIDR IPv6 numerik dan pra-pemindaian URL yang diperluas. (#287) * PDF yang dihasilkan diberi cap SnapOtter sebagai Producer. * mediapipe terpasang di Python 3.13 dan Debian 13. ### Perubahan yang merusak kompatibilitas {#breaking-changes} 2.0 mengganti basis data SQLite tertanam dengan Postgres 17 dan menambahkan Redis 8 untuk antrean job. Data 1.x Anda bermigrasi secara otomatis pada boot pertama, tetapi stack kontainer berubah, jadi cadangkan seluruh volume `/data` Anda terlebih dahulu (1.x menjalankan SQLite dalam mode WAL, jadi data yang telah di-commit biasanya berada di `snapotter.db-wal`). Kemudian pilih image kontainer tunggal (Postgres dan Redis tertanam, hanya root) atau stack Compose (aplikasi plus Postgres 17 dan Redis 8). Lihat [panduan migrasi](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) dan [panduan upgrade](/id/guide/upgrading). ### Upgrade {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Atau dengan Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff lengkap di GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Tool HTML ke Image baru, aksesibilitas WCAG 2.2 AA, penguatan keamanan dari pengujian penetrasi, dan 5 perbaikan Docker penting. ### Fitur baru {#new-features-1} * **HTML ke Image**: Tangkap tangkapan layar dari URL atau HTML mentah sebagai PNG/JPEG/WebP. Tangkapan halaman penuh, viewport kustom, mode gelap. * **Konvensi secret Docker \_FILE**: Pasang variabel env sensitif sebagai file alih-alih teks biasa. (#205) * **Lisensi enterprise dan penyimpanan S3**: Kunci lisensi komersial opsional dan penyimpanan objek yang kompatibel dengan S3. * **Peningkatan editor bentuk**: Transparansi isian/goresan, pemilih warna RGBA, gaya garis putus-putus. * **Arsip rilis siap pakai**: Unduh tarball dari GitHub Releases untuk instalasi non-Docker (Proxmox, bare metal, LXC). (#202) ### Peningkatan {#improvements-1} * **Aksesibilitas WCAG 2.2 AA**: Lewati navigasi, jebakan fokus, region aria-live, dukungan gerakan tereduksi, rasio kontras yang benar. (#209) * **Responsivitas seluler**: Pengaturan responsif, sambung ulang otomatis SSE saat beralih tab di seluler. (#203, #204) * **Kualitas penghapusan latar belakang**: Penghalusan tepi, dekontaminasi warna, pemilihan format keluaran. * **Terjemahan bahasa Italia**: ~145 string baru oleh @albanobattistella. (#206) * **Dokumentasi API per tool**: 53 halaman dokumen dengan parameter, contoh, dan format respons. * **Unduhan model AI**: Logika coba ulang dengan backoff eksponensial untuk HuggingFace. (#201) ### Perbaikan bug {#bug-fixes-1} * Kontainer Docker yang baru sama sekali tidak dapat digunakan (pembatasan laju memblokir semua permintaan). * Tool AI deteksi wajah (blur-faces, red-eye-removal, enhance-faces, passport-photo) gagal di semua platform. * File HEIC rusak di ARM (ketidakcocokan simbol libheif). * Bundel AI upscale dan restore-photo gagal dipasang di ARM. * OCR menggunakan versi CUDA yang salah pada kontainer GPU. * Bypass penjaga SSRF melalui alamat IPv6 yang dipetakan ke IPv4 heksadesimal. (Kredit: @tonghuaroot) * Dekode HEIC iPhone dengan gambar tambahan. (#183, #199) * Real-ESRGAN CUDA OOM pada GPU 8GB. (#200) * 6 error Sentry produksi dan 7 bug QA. (#208) ### Keamanan {#security} * 10 temuan uji penetrasi ditangani (bypass XFF, crash JSON cacat, pipeline tak terbatas, XSS log audit, metode TRACE, dan lainnya). (#207) * Bypass SSRF IPv6 heksadesimal diblokir. (Kredit: @tonghuaroot) * Image dasar Dockerfile disematkan berdasarkan digest. ### Upgrade {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Atau dengan Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff lengkap di GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Demo langsung, halaman landing per tool, dan sekumpulan perbaikan penyempurnaan. ### Fitur baru {#new-features-2} * **Demo langsung** - [demo.snapotter.com](https://demo.snapotter.com) memungkinkan orang mencoba SnapOtter tanpa memasang apa pun. * **Halaman indeks tool** - Jelajahi semua 50+ tool di `/tools` dengan pencarian dan filter kategori. * **50+ halaman landing SEO** - Setiap tool kini memiliki halaman landing khusus dengan FAQ, kasus penggunaan, dan tabel perbandingan. * **Pratinjau latar belakang** - Slider sebelum-sesudah menampilkan latar belakang kotak-kotak di balik gambar transparan. * **Generator kata sandi kuat** - Tombol sekali klik di formulir Add Members. ### Perbaikan bug {#bug-fixes-2} * Tool info HEIC/HEIF tidak lagi gagal (pra-dekode ditambahkan). * Pemasangan bundel model AI menampilkan pesan error yang lebih baik dan menghormati batas sumber daya. * Thumbnail pustaka dimuat dengan benar (header autentikasi hilang). * Menu dropdown tidak lagi terpotong pada tabel pengaturan People dan Teams. * Persentase perbandingan ukuran disembunyikan pada tool non-kompresi. * Tautan kebijakan privasi ganda dihapus. * Terjemahan bahasa Italia ditambahkan untuk pengaturan fitur AI. * Ikon Lucide yang diganti nama diperbarui (Wand2, Columns). ### Infrastruktur {#infrastructure} * OpenSSF Scorecard diperkuat dari 4.3 ke ~7.0. * Tes CI diparalelkan menjadi 4 shard dengan fixture yang diperkecil. * 41 pembaruan dependensi. ### Upgrade {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Atau dengan Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff lengkap di GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Lima tool baru, editor gambar lengkap, login SSO, 20 bahasa. Mungkin seharusnya menjadi tiga rilis terpisah, tetapi jadinya begini. ### Fitur baru {#new-features-3} * **Editor gambar** - Layer, kuas, bentuk, penyesuaian, filter, kurva, pintasan keyboard. Berjalan di browser Anda, memproses di perangkat keras Anda. * **Autentikasi OIDC / SSO** - Login dengan Google, GitHub, Okta, atau penyedia OpenID Connect apa pun. Atur beberapa variabel env dan tim Anda memakai akun mereka yang sudah ada. * **Generator meme** - 100 templat bawaan dengan render teks melalui opentype.js. Atau unggah gambar Anda sendiri. * **Beautify** - Masukkan tangkapan layar, keluarkan gambar yang dipoles. Bingkai perangkat (macOS, Windows, browser), bayangan, gradien, preset media sosial. * **Simulasi buta warna** - Pratinjau tampilan gambar dengan protanopia, deuteranopia, tritanopia, dan defisiensi penglihatan warna lainnya. * **Pemperbaiki transparansi PNG** - Mendeteksi PNG transparan-palsu dan memperbaikinya dengan matting HR BiRefNet. Penghapusan watermark opsional melalui inpainting LaMa. * **Perluasan kanvas AI** - Perluas batas gambar dengan isian AI. Tiga tingkat kualitas (cepat, seimbang, kualitas) tergantung berapa banyak waktu GPU yang ingin Anda korbankan. * **20 bahasa** - Arab, Mandarin (Sederhana/Tradisional), Ceko, Belanda, Prancis, Jerman, Hindi, Indonesia, Italia, Jepang, Korea, Polandia, Portugis, Rusia, Spanyol, Thai, Turki, Ukraina, Vietnam. RTL berfungsi untuk bahasa Arab. * **Impor URL** - Tempelkan URL ke dropzone atau impor massal dari daftar. Pengambilan sisi server dengan proteksi SSRF. * **Penghapus multi-file** - Gambar mask penghapus di beberapa gambar, proses semuanya dengan satu klik. Goresan bertahan per gambar. * **Impor/ekspor pipeline** - Simpan rantai tool sebagai JSON, bagikan dengan orang lain. * **17 format RAW kamera baru** melalui exiftool, plus input QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ, dan APNG. Codec keluaran baru untuk BMP, ICO, JP2, QOI. Ekspor AVIF, TIFF, GIF, JXL, dan PSD dipulihkan dari cabang yang sebelumnya hilang. ### Peningkatan {#improvements-2} * **Penyempurnaan gambar** - Mengganti pipeline lama dengan CLAHE + normalise + gamma. Toggle Deep Enhance baru menggunakan model AI untuk hasil yang lebih agresif. * **Restore photo** - Deteksi goresan ditulis ulang dengan pemfilteran Otsu 8-sudut. Inpainting LaMa kini berjalan pada resolusi native. * **Format eksotis di mana-mana** - OCR, image-to-PDF, generator favicon, komposisi, stitch, dan vectorize semuanya kini mendekode HEIC, RAW, PSD. * **Compress** - Toleransi ukuran target diperketat dari 5% ke 1%. Ukuran target adalah mode default. Menambahkan tombol stepper dan pemilih unit KB/MB. * **Pembersihan Sentry** - 644 peristiwa tak dapat ditindaklanjuti difilter. Error nyata kini ditangani dengan benar. * **Deteksi GPU** - Diagnostik lebih baik untuk kontainer di mana CUDA ada tetapi nvidia-smi tidak. * **Mode auth dinonaktifkan** - Pengguna anonim ditanamkan di DB dengan peran admin. Kunci API, pipeline, dan file pengguna tidak lagi rusak karena kendala FK. * **2.705+ tes baru** di seluruh unit, integrasi, dan E2E. ### Perbaikan bug {#bug-fixes-3} * Upscale di CPU tidak lagi kehabisan waktu pada perangkat NAS dan perangkat keras berdaya rendah. * Logo kode QR tidak lagi membuat pratinjau menghilang secara permanen. * Overflow crop diperbaiki untuk gambar potret tinggi. * File alfa TIFF dengan benar memaksa keluaran PNG alih-alih menghasilkan korupsi. * Dekode HDR/EXR mengonversi ke 8-bit sebelum CLAHE, memperbaiki kegagalan dekode. * Buffer input landmark wajah dikonversi ke PNG sebelum sidecar Python, memperbaiki crash. * Find duplicates menangani batch berformat campuran dan error jaringan. * Pratinjau Beautify diperbarui secara real time. * Bilah progres untuk stitch dan vectorize. * SVGZ ditangani oleh SVG-to-raster. * Nama file non-ASCII diperbaiki melalui header X-File-Results yang di-percent-encode. ### Upgrade {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Atau dengan Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff lengkap di GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Image Docker terpadu dengan deteksi otomatis GPU. Satu image menangani beban kerja CPU dan GPU. Compose yang disederhanakan menjadi satu file dengan rotasi log. Pra-unduh model kini menyertakan verifikasi dan smoke test. *** ## v1.13.0 {#v1-13-0} Kontrol akses berbasis peran (RBAC). 14 izin granular, tiga peran bawaan (admin, editor, user), dukungan peran kustom. Pemeriksaan izin pada semua route API. Tab frontend difilter berdasarkan izin pengguna. *** ## v1.12.0 {#v1-12-0} Tool PDF ke Image. Konversi halaman PDF ke PNG, JPEG, WebP, atau TIFF pada DPI kustom. Image Docker terpadu dengan deteksi otomatis GPU. *** ## v1.11.0 {#v1-11-0} llms.txt yang dibuat otomatis melalui vitepress-plugin-llms untuk dokumentasi yang ramah AI. *** ## v1.10.0 {#v1-10-0} Pengubahan ukuran sadar-konten (seam carving) dengan proteksi wajah. Ubah ukuran gambar sambil mempertahankan konten penting. *** ## v1.9.0 {#v1-9-0} Tool Stitch / Combine. Gabungkan gambar secara berdampingan, ditumpuk vertikal, atau dalam kisi kustom. *** ## v1.8.0 {#v1-8-0} Tool Edit Metadata. Lihat dan edit metadata EXIF, IPTC, dan XMP dengan antarmuka strip/keep yang granular. *** ## Rilis lama {#older-releases} Untuk changelog tingkat commit yang lengkap termasuk rilis patch, lihat [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/it/changelog.md description: >- Note di rilascio e cronologia delle versioni di SnapOtter. Scopri le novità, i miglioramenti e le correzioni di ogni release. --- # Changelog {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 trasforma il toolkit per immagini in una suite completa di manipolazione file: oltre 200 strumenti su cinque modalità (Immagine, Video, Audio, PDF e File), ricostruita su Postgres 17 e una coda di lavori basata su Redis, con un `docker run` a comando singolo. Questa è una release importante; leggi le Modifiche incompatibili prima di aggiornare dalla 1.x. ### Nuove funzionalità {#new-features} * **Quattro nuove modalità di strumenti**: Video, Audio, PDF e File si aggiungono a Immagine, portando il catalogo a oltre 200 strumenti. * **Lavori in background durevoli**: una coda basata su Redis (BullMQ) esegue ogni strumento come lavoro tracciato con avanzamento SSE in tempo reale. * **Modalità all-in-one a container singolo**: un solo `docker run` avvia un'istanza completa con Postgres e Redis incorporati. * **Bundle AI su richiesta**: rimozione dello sfondo, OCR, trascrizione, upscaling, rilevamento e miglioramento dei volti, gomma per oggetti, colorazione e restauro fotografico si installano dall'interfaccia. L'accelerazione GPU viene rilevata per ogni framework. * **Firma PDF**: disegna, digita o carica una firma e posizionala su un PDF direttamente nel browser. * **Automazione**: un costruttore visuale di pipeline che concatena strumenti, con nove modelli predefiniti. * **83 preset di conversione con un clic**: convertitori dedicati JPG-a-PNG, MP4-a-GIF e simili con ricerca fuzzy. * **Editor di immagini a livelli**: un editor basato su Konva in `/editor` con pennelli, forme, regolazioni, filtri e curve. * **Libreria File**: salva qualsiasi risultato e riutilizzalo come input per un altro strumento. * Strumenti fissati, zoom e panoramica in-canvas, 21 lingue e funzionalità enterprise (OIDC/SSO, SAML, SCIM, archiviazione S3, permessi per singolo strumento, esportazione dei log di audit, tracciamento distribuito). ### Miglioramenti {#improvements} * Annulla un processo in esecuzione. (#137) * Decodifica RAW a piena risoluzione tramite LibRaw, incluso DNG. (#289) * Deployment non-root e con UID esterno (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Rilevamento accurato dell'installazione AI e un flusso di installazione irrobustito. (#214, #352) * Rafforzamento della privacy: nessuna trasmissione automatica a terze parti, più una modalità offline stretta opzionale. * Pulsante di feedback sempre attivo, anche con le analisi disattivate. ### Correzioni di bug {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` disabilita di nuovo il rate limiting per le route degli strumenti. (#271) * Riparati i percorsi del virtualenv AI all'interno dell'immagine Docker. (#390) * Compatibilità con sharp 0.35.2+. (#362) * Correzioni al layout dell'editor di immagini: righelli, comportamento del riempimento, barra laterale e dimensionamento del canvas. (#258, #259) * Completata la traduzione italiana. (#231, #206, #425) * La normalizzazione audio e loudnorm preservano la frequenza di campionamento sorgente. * Rafforzamento SSRF: corrispondenza numerica dei CIDR IPv6 e una pre-scansione URL ampliata. (#287) * I PDF generati vengono marcati con SnapOtter come Producer. * mediapipe si installa su Python 3.13 e Debian 13. ### Modifiche incompatibili {#breaking-changes} 2.0 sostituisce il database SQLite incorporato con Postgres 17 e aggiunge Redis 8 per la coda dei lavori. I tuoi dati 1.x vengono migrati automaticamente al primo avvio, ma lo stack di container è cambiato, quindi esegui prima il backup dell'intero volume `/data` (la 1.x esegue SQLite in modalità WAL, quindi i dati committati risiedono di solito in `snapotter.db-wal`). Poi scegli l'immagine a container singolo (Postgres e Redis incorporati, solo root) o lo stack Compose (app più Postgres 17 e Redis 8). Consulta la [guida alla migrazione](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) e la [guida all'aggiornamento](/it/guide/upgrading). ### Aggiornamento {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Oppure con Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo su GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Nuovo strumento HTML a Immagine, accessibilità WCAG 2.2 AA, rafforzamento della sicurezza dai penetration test e 5 correzioni Docker critiche. ### Nuove funzionalità {#new-features-1} * **HTML a Immagine**: cattura screenshot di URL o HTML grezzo come PNG/JPEG/WebP. Catture a pagina intera, viewport personalizzati, modalità scura. * **Convenzione Docker \_FILE per i segreti**: monta le variabili d'ambiente sensibili come file invece che in testo semplice. (#205) * **Licenza enterprise e archiviazione S3**: chiave di licenza commerciale opzionale e archiviazione a oggetti compatibile con S3. * **Miglioramenti all'editor di forme**: trasparenza di riempimento/contorno, selettore di colore RGBA, stili di linea tratteggiata. * **Archivi di release predefiniti**: scarica i tarball dalle GitHub Releases per installazioni non-Docker (Proxmox, bare metal, LXC). (#202) ### Miglioramenti {#improvements-1} * **Accessibilità WCAG 2.2 AA**: salto della navigazione, focus trapping, regioni aria-live, supporto per il movimento ridotto, rapporti di contrasto corretti. (#209) * **Reattività mobile**: impostazioni responsive, riconnessione automatica SSE al cambio di scheda su mobile. (#203, #204) * **Qualità della rimozione dello sfondo**: smussatura dei bordi, decontaminazione del colore, selezione del formato di output. * **Traduzione italiana**: ~145 nuove stringhe di @albanobattistella. (#206) * **Documentazione API per singolo strumento**: 53 pagine di documentazione con parametri, esempi e formati di risposta. * **Download dei modelli AI**: logica di retry con backoff esponenziale per HuggingFace. (#201) ### Correzioni di bug {#bug-fixes-1} * I container Docker appena avviati erano completamente inutilizzabili (il rate limit bloccava tutte le richieste). * Gli strumenti AI di rilevamento volti (blur-faces, red-eye-removal, enhance-faces, passport-photo) fallivano su tutte le piattaforme. * File HEIC non funzionanti su ARM (mismatch dei simboli libheif). * I bundle AI di upscale e restore-photo non riuscivano a installarsi su ARM. * OCR usava la versione CUDA errata sui container GPU. * Bypass del guard SSRF tramite indirizzi IPv6 esadecimali mappati su IPv4. (Merito: @tonghuaroot) * Decodifica HEIC di iPhone con immagini ausiliarie. (#183, #199) * OOM CUDA di Real-ESRGAN su GPU da 8GB. (#200) * 6 errori Sentry di produzione e 7 bug QA. (#208) ### Sicurezza {#security} * 10 risultati dei penetration test risolti (bypass XFF, crash su JSON malformato, pipeline illimitate, XSS nei log di audit, metodo TRACE e altro). (#207) * Bloccato il bypass SSRF con IPv6 esadecimale. (Merito: @tonghuaroot) * Immagini base del Dockerfile fissate tramite digest. ### Aggiornamento {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Oppure con Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo su GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Demo live, pagine di destinazione per singolo strumento e un lotto di correzioni di rifinitura. ### Nuove funzionalità {#new-features-2} * **Demo live** - [demo.snapotter.com](https://demo.snapotter.com) permette di provare SnapOtter senza installare nulla. * **Pagina indice degli strumenti** - Sfoglia tutti i 50+ strumenti in `/tools` con ricerca e filtri per categoria. * **50+ pagine di destinazione SEO** - Ogni strumento ha ora una pagina di destinazione dedicata con FAQ, casi d'uso e tabelle di confronto. * **Anteprima dello sfondo** - Lo slider prima-dopo mostra uno sfondo a scacchiera dietro le immagini trasparenti. * **Generatore di password robuste** - Pulsante con un clic nel modulo Aggiungi membri. ### Correzioni di bug {#bug-fixes-2} * Lo strumento info HEIC/HEIF non fallisce più (aggiunta pre-decodifica). * L'installazione dei bundle di modelli AI mostra messaggi di errore migliori e rispetta i limiti di risorse. * Le miniature della libreria si caricano correttamente (mancavano le intestazioni di autenticazione). * I menu a discesa non vengono più tagliati nelle tabelle delle impostazioni Persone e Team. * Percentuale di confronto delle dimensioni nascosta sugli strumenti non di compressione. * Rimosso il link duplicato alla privacy policy. * Aggiunta la traduzione italiana per le impostazioni delle funzionalità AI. * Aggiornate le icone Lucide rinominate (Wand2, Columns). ### Infrastruttura {#infrastructure} * OpenSSF Scorecard rafforzato da 4.3 a ~7.0. * Test CI parallelizzati in 4 shard con fixture ridimensionate. * 41 aggiornamenti delle dipendenze. ### Aggiornamento {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Oppure con Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo su GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Cinque nuovi strumenti, un editor di immagini completo, login SSO, 20 lingue. Probabilmente avrebbero dovuto essere tre release separate, ma eccoci qui. ### Nuove funzionalità {#new-features-3} * **Editor di immagini** - Livelli, pennelli, forme, regolazioni, filtri, curve, scorciatoie da tastiera. Gira nel tuo browser, elabora sul tuo hardware. * **Autenticazione OIDC / SSO** - Accedi con Google, GitHub, Okta o qualsiasi provider OpenID Connect. Imposta qualche variabile d'ambiente e il tuo team usa gli account esistenti. * **Generatore di meme** - 100 modelli integrati con rendering del testo tramite opentype.js. Oppure carica la tua immagine. * **Beautify** - Trascina uno screenshot, ottieni un'immagine rifinita. Cornici del dispositivo (macOS, Windows, browser), ombre, gradienti, preset per i social media. * **Simulazione del daltonismo** - Anteprima di come appaiono le immagini con protanopia, deuteranopia, tritanopia e altre deficienze della visione dei colori. * **Correttore di trasparenza PNG** - Rileva i PNG con falsa trasparenza e li corregge con il matting HR di BiRefNet. Rimozione opzionale del watermark tramite inpainting LaMa. * **Espansione AI del canvas** - Estende i confini dell'immagine con riempimento AI. Tre livelli di qualità (veloce, bilanciato, qualità) a seconda di quanto tempo GPU vuoi scambiare. * **20 lingue** - Arabo, Cinese (Semplificato/Tradizionale), Ceco, Olandese, Francese, Tedesco, Hindi, Indonesiano, Italiano, Giapponese, Coreano, Polacco, Portoghese, Russo, Spagnolo, Thai, Turco, Ucraino, Vietnamita. RTL funziona per l'arabo. * **Importazione da URL** - Incolla gli URL nella dropzone o importa in blocco da una lista. Fetch lato server con protezione SSRF. * **Gomma multi-file** - Disegna maschere di cancellazione su più immagini, elaborale tutte con un clic. I tratti persistono per singola immagine. * **Importazione/esportazione delle pipeline** - Salva le catene di strumenti come JSON, condividile con altri. * **17 nuovi formati RAW di fotocamera** tramite exiftool, più input QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ e APNG. Nuovi codec di output per BMP, ICO, JP2, QOI. Esportazione AVIF, TIFF, GIF, JXL e PSD recuperata da un branch precedentemente perso. ### Miglioramenti {#improvements-2} * **Miglioramento delle immagini** - Sostituita la vecchia pipeline con CLAHE + normalise + gamma. Il nuovo toggle Deep Enhance usa il modello AI per risultati più aggressivi. * **Restauro foto** - Rilevamento dei graffi riscritto con filtraggio Otsu a 8 angoli. L'inpainting LaMa ora gira a risoluzione nativa. * **Formati esotici ovunque** - OCR, image-to-PDF, generatore di favicon, composizione, stitch e vettorizzazione ora decodificano tutti HEIC, RAW, PSD. * **Compressione** - Tolleranza sulla dimensione target ridotta dal 5% all'1%. La dimensione target è la modalità predefinita. Aggiunti pulsanti di incremento e selettore di unità KB/MB. * **Pulizia Sentry** - 644 eventi non azionabili filtrati. Gli errori reali ora vengono gestiti correttamente. * **Rilevamento GPU** - Diagnostica migliore per i container dove CUDA è presente ma nvidia-smi no. * **Modalità con autenticazione disattivata** - Un utente anonimo viene inserito nel DB con ruolo admin. Chiavi API, pipeline e file utente non si rompono più sui vincoli FK. * **2.705+ nuovi test** tra unit, integrazione ed E2E. ### Correzioni di bug {#bug-fixes-3} * L'upscale su CPU non va più in timeout sui box NAS e sull'hardware a basso consumo. * Il logo del codice QR non fa più sparire l'anteprima in modo permanente. * Corretto l'overflow del ritaglio per le immagini in ritratto verticali. * I file TIFF con alfa forzano correttamente l'output PNG invece di produrre corruzione. * La decodifica HDR/EXR converte a 8 bit prima di CLAHE, correggendo i fallimenti di decodifica. * I buffer di input dei landmark facciali vengono convertiti in PNG prima del sidecar Python, correggendo i crash. * La ricerca dei duplicati gestisce i batch a formato misto e gli errori di rete. * L'anteprima di Beautify si aggiorna in tempo reale. * Barre di avanzamento per stitch e vettorizzazione. * SVGZ gestito da SVG-a-raster. * Nomi di file non ASCII corretti tramite l'intestazione X-File-Results codificata in percent-encoding. ### Aggiornamento {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Oppure con Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo su GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Immagine Docker unificata con rilevamento automatico della GPU. Un'unica immagine gestisce i carichi di lavoro sia CPU sia GPU. Compose semplificato in un singolo file con rotazione dei log. I pre-download dei modelli ora includono la verifica e uno smoke test. *** ## v1.13.0 {#v1-13-0} Controllo degli accessi basato sui ruoli (RBAC). 14 permessi granulari, tre ruoli integrati (admin, editor, user), supporto per ruoli personalizzati. Controlli dei permessi su tutte le route API. Schede del frontend filtrate in base ai permessi dell'utente. *** ## v1.12.0 {#v1-12-0} Strumento PDF a Immagine. Converti le pagine PDF in PNG, JPEG, WebP o TIFF a DPI personalizzato. Immagine Docker unificata con rilevamento automatico della GPU. *** ## v1.11.0 {#v1-11-0} llms.txt auto-generato tramite vitepress-plugin-llms per una documentazione a misura di AI. *** ## v1.10.0 {#v1-10-0} Ridimensionamento content-aware (seam carving) con protezione dei volti. Ridimensiona le immagini preservando i contenuti importanti. *** ## v1.9.0 {#v1-9-0} Strumento Stitch / Combina. Unisci le immagini fianco a fianco, impilate verticalmente o in una griglia personalizzata. *** ## v1.8.0 {#v1-8-0} Strumento Modifica metadati. Visualizza e modifica i metadati EXIF, IPTC e XMP con un'interfaccia granulare di rimozione/conservazione. *** ## Release meno recenti {#older-releases} Per il changelog completo a livello di commit, incluse le release di patch, consulta le [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/nl/changelog.md description: >- Release notes en versiegeschiedenis voor SnapOtter. Bekijk wat er nieuw, verbeterd en opgelost is in elke release. --- # Changelog {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 maakt van de beeldtoolkit een volledige suite voor bestandsbewerking: 200+ tools verdeeld over vijf modaliteiten (Image, Video, Audio, PDF en Files), herbouwd op Postgres 17 en een op Redis gebaseerde taakwachtrij, met een `docker run` die je met één commando start. Dit is een grote release; lees Ingrijpende wijzigingen voordat je vanaf 1.x upgradet. ### Nieuwe functies {#new-features} * **Vier nieuwe toolmodaliteiten**: Video, Audio, PDF en Files komen naast Image, waarmee de catalogus op 200+ tools komt. * **Duurzame achtergrondtaken**: Een op Redis gebaseerde wachtrij (BullMQ) voert elke tool uit als een gevolgde taak met live SSE-voortgang. * **All-in-one modus met één container**: Eén `docker run` start een complete instance met ingebedde Postgres en Redis. * **AI-bundels op aanvraag**: Achtergrondverwijdering, OCR, transcriptie, upscaling, gezichtsdetectie en -verbetering, objectgum, inkleuren en fotorestauratie installeren vanuit de UI. GPU-acceleratie wordt per framework gedetecteerd. * **PDF ondertekenen**: Teken, typ of upload een handtekening en plaats deze op een PDF in de browser. * **Automate**: Een visuele pijplijnbouwer die tools aan elkaar koppelt, met negen kant-en-klare templates. * **83 conversiepresets met één klik**: Speciale converters voor JPG-naar-PNG, MP4-naar-GIF en dergelijke met fuzzy zoeken. * **Op lagen gebaseerde beeldeditor**: Een door Konva aangedreven editor op `/editor` met penselen, vormen, aanpassingen, filters en curves. * **Files-bibliotheek**: Sla elk resultaat op en gebruik het opnieuw als invoer voor een andere tool. * Vastgemaakte tools, in-canvas zoomen en pannen, 21 talen en enterprisemogelijkheden (OIDC/SSO, SAML, SCIM, S3-opslag, permissies per tool, audit-export, distributed tracing). ### Verbeteringen {#improvements} * Een lopend proces annuleren. (#137) * RAW-decodering op volledige resolutie via LibRaw, inclusief DNG. (#289) * Deployments zonder root en met vreemde UID (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Nauwkeurige detectie van AI-installaties en een gehard installatieproces. (#214, #352) * Privacyversterking: geen automatische egress naar derden, plus een optionele strikte offline modus. * Altijd zichtbare feedbackknop, ook als analytics uit staat. ### Opgeloste fouten {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` schakelt rate limiting voor toolroutes weer uit. (#271) * AI-virtualenv-paden binnen de Docker-image hersteld. (#390) * Compatibiliteit met sharp 0.35.2+. (#362) * Lay-outfixes voor de beeldeditor: linialen, vulgedrag, zijbalk en canvasformaat. (#258, #259) * Italiaanse vertaling voltooid. (#231, #206, #425) * Audio normalize en loudnorm behouden de samplerate van de bron. * SSRF-versterking: numerieke IPv6 CIDR-matching en een verbrede URL-voorscan. (#287) * Gegenereerde PDF's krijgen SnapOtter als Producer gestempeld. * mediapipe installeert op Python 3.13 en Debian 13. ### Ingrijpende wijzigingen {#breaking-changes} 2.0 vervangt de ingebedde SQLite-database door Postgres 17 en voegt Redis 8 toe voor de taakwachtrij. Je 1.x-gegevens migreren automatisch bij de eerste keer opstarten, maar de containerstack is veranderd, dus maak eerst een back-up van je volledige `/data`-volume (1.x draait SQLite in WAL-modus, dus de vastgelegde gegevens staan meestal in `snapotter.db-wal`). Kies vervolgens de single-container image (ingebedde Postgres en Redis, alleen als root) of de Compose-stack (app plus Postgres 17 en Redis 8). Zie de [migratiegids](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) en de [upgradegids](/nl/guide/upgrading). ### Upgraden {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Of met Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Volledige diff op GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Nieuwe HTML-naar-Image-tool, WCAG 2.2 AA-toegankelijkheid, beveiligingsversterking op basis van penetratietests en 5 kritieke Docker-fixes. ### Nieuwe functies {#new-features-1} * **HTML naar Image**: Maak schermafbeeldingen van URL's of ruwe HTML als PNG/JPEG/WebP. Vastleggingen van volledige pagina's, aangepaste viewports, donkere modus. * **Docker \_FILE-secretconventie**: Koppel gevoelige env-variabelen als bestanden in plaats van als platte tekst. (#205) * **Enterprise-licentie en S3-opslag**: Optionele commerciële licentiesleutel en S3-compatibele objectopslag. * **Verbeteringen aan de vormeditor**: Transparantie voor vulling/lijn, RGBA-kleurkiezer, streepjeslijnstijlen. * **Kant-en-klare release-archieven**: Download tarballs van GitHub Releases voor installaties zonder Docker (Proxmox, bare metal, LXC). (#202) ### Verbeteringen {#improvements-1} * **WCAG 2.2 AA-toegankelijkheid**: Navigatie overslaan, focus-trapping, aria-live-regio's, ondersteuning voor beperkte beweging, correcte contrastverhoudingen. (#209) * **Mobiele responsiviteit**: Responsieve instellingen, automatische SSE-reconnect bij het wisselen van mobiele tabbladen. (#203, #204) * **Kwaliteit van achtergrondverwijdering**: Randverzachting, kleurdecontaminatie, keuze van uitvoerformaat. * **Italiaanse vertaling**: ~145 nieuwe strings door @albanobattistella. (#206) * **API-documentatie per tool**: 53 documentatiepagina's met parameters, voorbeelden en responsformaten. * **AI-modeldownloads**: Retry-logica met exponentiële backoff voor HuggingFace. (#201) ### Opgeloste fouten {#bug-fixes-1} * Verse Docker-containers waren volledig onbruikbaar (rate limit blokkeerde alle verzoeken). * AI-tools voor gezichtsdetectie (blur-faces, red-eye-removal, enhance-faces, passport-photo) faalden op alle platforms. * HEIC-bestanden kapot op ARM (libheif-symboolmismatch). * AI-bundels voor upscale en restore-photo faalden bij de installatie op ARM. * OCR gebruikte de verkeerde CUDA-versie op GPU-containers. * Bypass van de SSRF-bescherming via hex IPv4-mapped IPv6-adressen. (Met dank aan: @tonghuaroot) * iPhone-HEIC-decodering met hulpafbeeldingen. (#183, #199) * Real-ESRGAN CUDA OOM op 8 GB-GPU's. (#200) * 6 Sentry-fouten in productie en 7 QA-bugs. (#208) ### Beveiliging {#security} * 10 bevindingen uit de penetratietest aangepakt (XFF-bypass, crashes door misvormde JSON, ongelimiteerde pijplijnen, XSS in de auditlog, TRACE-methode en meer). (#207) * SSRF hex IPv6-bypass geblokkeerd. (Met dank aan: @tonghuaroot) * Dockerfile-basisimages vastgezet per digest. ### Upgraden {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Of met Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Volledige diff op GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Live demo, landingspagina's per tool en een reeks poetsfixes. ### Nieuwe functies {#new-features-2} * **Live demo** - [demo.snapotter.com](https://demo.snapotter.com) laat mensen SnapOtter proberen zonder iets te installeren. * **Tools-indexpagina** - Blader door alle 50+ tools op `/tools` met zoeken en categoriefilters. * **50+ SEO-landingspagina's** - Elke tool heeft nu een eigen landingspagina met FAQ's, use cases en vergelijkingstabellen. * **Achtergrondvoorbeeld** - Een voor-na-schuifregelaar toont een geblokte achtergrond achter transparante afbeeldingen. * **Generator voor sterke wachtwoorden** - Knop met één klik in het formulier Leden toevoegen. ### Opgeloste fouten {#bug-fixes-2} * De HEIC/HEIF-infotool faalt niet meer (pre-decode toegevoegd). * De installatie van AI-modelbundels toont betere foutmeldingen en respecteert resourcelimieten. * Bibliotheekminiaturen laden correct (auth-headers ontbraken). * Dropdown-menu's worden niet meer afgeknipt in de instellingentabellen van Mensen en Teams. * Percentage voor formaatvergelijking verborgen bij tools zonder compressie. * Dubbele link naar het privacybeleid verwijderd. * Italiaanse vertaling toegevoegd voor de instellingen van AI-functies. * Hernoemde Lucide-iconen bijgewerkt (Wand2, Columns). ### Infrastructuur {#infrastructure} * OpenSSF Scorecard verhard van 4.3 naar ~7.0. * CI-tests geparallelliseerd in 4 shards met verkleinde fixtures. * 41 dependency-updates. ### Upgraden {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Of met Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Volledige diff op GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Vijf nieuwe tools, een volledige beeldeditor, SSO-login, 20 talen. Waarschijnlijk hadden dit drie afzonderlijke releases moeten zijn, maar zo is het nu eenmaal. ### Nieuwe functies {#new-features-3} * **Beeldeditor** - Lagen, penselen, vormen, aanpassingen, filters, curves, sneltoetsen. Draait in je browser, verwerkt op je eigen hardware. * **OIDC / SSO-authenticatie** - Log in met Google, GitHub, Okta of een willekeurige OpenID Connect-provider. Stel een paar env-variabelen in en je team gebruikt zijn bestaande accounts. * **Meme-generator** - 100 ingebouwde templates met tekstweergave via opentype.js. Of upload je eigen afbeelding. * **Beautify** - Zet een schermafbeelding erin, krijg een verzorgde afbeelding eruit. Apparaatframes (macOS, Windows, browser), schaduwen, gradiënten, presets voor social media. * **Simulatie van kleurenblindheid** - Bekijk hoe afbeeldingen eruitzien bij protanopie, deuteranopie, tritanopie en andere afwijkingen in het kleurenzien. * **Fixer voor PNG-transparantie** - Detecteert nep-transparante PNG's en repareert ze met BiRefNet HR-matting. Optionele watermerkverwijdering via LaMa-inpainting. * **AI-canvasuitbreiding** - Breid de grenzen van een afbeelding uit met AI-vulling. Drie kwaliteitsniveaus (snel, gebalanceerd, kwaliteit) afhankelijk van hoeveel GPU-tijd je ervoor over hebt. * **20 talen** - Arabisch, Chinees (vereenvoudigd/traditioneel), Tsjechisch, Nederlands, Frans, Duits, Hindi, Indonesisch, Italiaans, Japans, Koreaans, Pools, Portugees, Russisch, Spaans, Thais, Turks, Oekraïens, Vietnamees. RTL werkt voor Arabisch. * **URL-import** - Plak URL's in de dropzone of importeer in bulk vanuit een lijst. Server-side ophalen met SSRF-bescherming. * **Multi-file gum** - Teken gummaskers over meerdere afbeeldingen, verwerk ze allemaal met één klik. Streken blijven per afbeelding behouden. * **Pijplijn import/export** - Sla toolketens op als JSON en deel ze met anderen. * **17 nieuwe camera-RAW-formaten** via exiftool, plus QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ en APNG als invoer. Nieuwe uitvoercodecs voor BMP, ICO, JP2, QOI. AVIF-, TIFF-, GIF-, JXL- en PSD-export teruggehaald uit een eerder verloren branch. ### Verbeteringen {#improvements-2} * **Beeldverbetering** - De oude pijplijn vervangen door CLAHE + normalise + gamma. Een nieuwe Deep Enhance-schakelaar gebruikt het AI-model voor agressievere resultaten. * **Foto herstellen** - Krasdetectie herschreven met Otsu-filtering onder 8 hoeken. LaMa-inpainting draait nu op de oorspronkelijke resolutie. * **Exotische formaten overal** - OCR, image-to-PDF, favicon-generator, compositie, stitch en vectorize decoderen nu allemaal HEIC, RAW en PSD. * **Comprimeren** - Tolerantie voor de doelgrootte aangescherpt van 5% naar 1%. Doelgrootte is de standaardmodus. Stepper-knoppen en een KB/MB-eenheidskiezer toegevoegd. * **Sentry-opschoning** - 644 niet-actiegerichte events gefilterd. Echte fouten worden nu correct afgehandeld. * **GPU-detectie** - Betere diagnostiek voor containers waar CUDA aanwezig is maar nvidia-smi niet. * **Modus met uitgeschakelde authenticatie** - Een anonieme gebruiker wordt in de DB aangemaakt met de admin-rol. API-sleutels, pijplijnen en gebruikersbestanden breken niet langer op FK-constraints. * **2.705+ nieuwe tests** verdeeld over unit-, integratie- en E2E-tests. ### Opgeloste fouten {#bug-fixes-3} * Upscale op CPU loopt niet meer af op een timeout op NAS-apparaten en hardware met weinig vermogen. * Het logo op een QR-code laat het voorbeeld niet meer permanent verdwijnen. * Crop-overflow opgelost voor hoge portretafbeeldingen. * TIFF-alpha-bestanden forceren nu correct PNG-uitvoer in plaats van corruptie te produceren. * HDR/EXR-decodering converteert naar 8-bit vóór CLAHE, waarmee decodeerfouten worden opgelost. * Invoerbuffers voor gezichtslandmarks worden naar PNG geconverteerd vóór de Python-sidecar, waarmee crashes worden opgelost. * Duplicaten zoeken verwerkt batches met gemengde formaten en netwerkfouten. * Het Beautify-voorbeeld werkt in realtime bij. * Voortgangsbalken voor stitch en vectorize. * SVGZ afgehandeld door SVG-naar-raster. * Niet-ASCII-bestandsnamen opgelost via een percent-gecodeerde X-File-Results-header. ### Upgraden {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Of met Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Volledige diff op GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Geünificeerde Docker-image met automatische GPU-detectie. Eén image handelt zowel CPU- als GPU-workloads af. Compose vereenvoudigd tot één bestand met logrotatie. Model-pre-downloads bevatten nu verificatie en een smoke test. *** ## v1.13.0 {#v1-13-0} Rolgebaseerde toegangscontrole (RBAC). 14 granulaire permissies, drie ingebouwde rollen (admin, editor, user), ondersteuning voor aangepaste rollen. Permissiecontroles op alle API-routes. Frontend-tabbladen gefilterd op basis van gebruikerspermissies. *** ## v1.12.0 {#v1-12-0} PDF-naar-Image-tool. Zet PDF-pagina's om naar PNG, JPEG, WebP of TIFF op een aangepaste DPI. Geünificeerde Docker-image met automatische GPU-detectie. *** ## v1.11.0 {#v1-11-0} Automatisch gegenereerde llms.txt via vitepress-plugin-llms voor AI-vriendelijke documentatie. *** ## v1.10.0 {#v1-10-0} Contentbewust vergroten/verkleinen (seam carving) met gezichtsbescherming. Verklein afbeeldingen terwijl belangrijke content behouden blijft. *** ## v1.9.0 {#v1-9-0} Stitch / Combine-tool. Voeg afbeeldingen naast elkaar, verticaal gestapeld of in een aangepast raster samen. *** ## v1.8.0 {#v1-8-0} Metadata bewerken-tool. Bekijk en bewerk EXIF-, IPTC- en XMP-metadata met een granulaire interface voor verwijderen/behouden. *** ## Oudere releases {#older-releases} Voor de volledige changelog op commit-niveau, inclusief patch-releases, zie [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/pt-BR/changelog.md description: >- Notas de versão e histórico de versões do SnapOtter. Veja o que há de novo, o que foi melhorado e o que foi corrigido em cada versão. --- # Changelog {#changelog} ## v2.0.0 {#v2-0-0} O SnapOtter 2.0 transforma o kit de ferramentas de imagem em uma suíte completa de manipulação de arquivos: mais de 200 ferramentas em cinco modalidades (Image, Video, Audio, PDF e Files), reconstruída sobre Postgres 17 e uma fila de jobs baseada em Redis, com um `docker run` de um único comando. Esta é uma versão importante; leia Mudanças incompatíveis antes de atualizar a partir da 1.x. ### Novos recursos {#new-features} * **Quatro novas modalidades de ferramentas**: Video, Audio, PDF e Files juntam-se a Image, elevando o catálogo para mais de 200 ferramentas. * **Jobs em segundo plano duráveis**: Uma fila baseada em Redis (BullMQ) executa cada ferramenta como um job rastreado, com progresso ao vivo via SSE. * **Modo tudo-em-um de contêiner único**: Um único `docker run` inicia uma instância completa com Postgres e Redis embutidos. * **Pacotes de IA sob demanda**: Remoção de fundo, OCR, transcrição, upscaling, detecção e aprimoramento de rostos, apagador de objetos, colorização e restauração de fotos são instalados pela interface. A aceleração por GPU é detectada por framework. * **Sign PDF**: Desenhe, digite ou envie uma assinatura e posicione-a em um PDF no navegador. * **Automate**: Um construtor visual de pipelines que encadeia ferramentas, com nove modelos pré-configurados. * **83 predefinições de conversão com um clique**: Conversores dedicados de JPG para PNG, MP4 para GIF e semelhantes, com busca aproximada. * **Editor de imagem baseado em camadas**: Um editor com tecnologia Konva em `/editor` com pincéis, formas, ajustes, filtros e curvas. * **Biblioteca Files**: Salve qualquer resultado e reutilize-o como entrada de outra ferramenta. * Ferramentas fixadas, zoom e panorâmica no canvas, 21 idiomas e recursos corporativos (OIDC/SSO, SAML, SCIM, armazenamento S3, permissões por ferramenta, exportação de auditoria, rastreamento distribuído). ### Melhorias {#improvements} * Cancele um processo em execução. (#137) * Decodificação RAW em resolução total via LibRaw, incluindo DNG. (#289) * Implantações não-root e com UID estrangeiro (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Detecção precisa de instalação de IA e um fluxo de instalação reforçado. (#214, #352) * Reforço de privacidade: nenhum tráfego automático para terceiros, além de um modo estritamente offline opcional. * Botão de feedback sempre visível, mesmo com a análise de dados desativada. ### Correções de bugs {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` desativa novamente a limitação de taxa para as rotas de ferramentas. (#271) * Corrigidos os caminhos do virtualenv de IA dentro da imagem Docker. (#390) * Compatibilidade com sharp 0.35.2+. (#362) * Correções de layout do editor de imagem: réguas, comportamento de preenchimento, barra lateral e dimensionamento do canvas. (#258, #259) * Concluída a tradução para o italiano. (#231, #206, #425) * As ferramentas de normalização e loudnorm de áudio preservam a taxa de amostragem original. * Reforço contra SSRF: correspondência numérica de CIDR IPv6 e uma pré-varredura de URL ampliada. (#287) * Os PDFs gerados são marcados com SnapOtter como Producer. * O mediapipe é instalado no Python 3.13 e no Debian 13. ### Mudanças incompatíveis {#breaking-changes} A 2.0 substitui o banco de dados SQLite embutido por Postgres 17 e adiciona o Redis 8 para a fila de jobs. Seus dados da 1.x são migrados automaticamente no primeiro boot, mas a pilha de contêineres mudou, então faça backup de todo o seu volume `/data` primeiro (a 1.x roda o SQLite no modo WAL, então os dados confirmados normalmente ficam em `snapotter.db-wal`). Depois escolha a imagem de contêiner único (Postgres e Redis embutidos, apenas root) ou a pilha do Compose (app mais Postgres 17 e Redis 8). Consulte o [guia de migração](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) e o [guia de atualização](/pt-BR/guide/upgrading). ### Atualização {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Ou com o Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo no GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Nova ferramenta HTML to Image, acessibilidade WCAG 2.2 AA, reforço de segurança a partir de testes de penetração e 5 correções críticas de Docker. ### Novos recursos {#new-features-1} * **HTML to Image**: Capture screenshots de URLs ou de HTML bruto como PNG/JPEG/WebP. Capturas de página inteira, viewports personalizados, modo escuro. * **Convenção de segredos \_FILE do Docker**: Monte variáveis de ambiente sensíveis como arquivos em vez de texto puro. (#205) * **Licenciamento corporativo e armazenamento S3**: Chave de licença comercial opcional e armazenamento de objetos compatível com S3. * **Melhorias no editor de formas**: Transparência de preenchimento/traço, seletor de cor RGBA, estilos de linha tracejada. * **Arquivos de versão pré-compilados**: Baixe tarballs das GitHub Releases para instalações sem Docker (Proxmox, bare metal, LXC). (#202) ### Melhorias {#improvements-1} * **Acessibilidade WCAG 2.2 AA**: Pular navegação, aprisionamento de foco, regiões aria-live, suporte a movimento reduzido, taxas de contraste corretas. (#209) * **Responsividade em dispositivos móveis**: Configurações responsivas, reconexão automática de SSE ao alternar de aba no celular. (#203, #204) * **Qualidade da remoção de fundo**: Suavização de bordas, descontaminação de cores, seleção do formato de saída. * **Tradução para o italiano**: cerca de 145 novas strings por @albanobattistella. (#206) * **Documentação de API por ferramenta**: 53 páginas de documentação com parâmetros, exemplos e formatos de resposta. * **Downloads de modelos de IA**: Lógica de repetição com recuo exponencial para o HuggingFace. (#201) ### Correções de bugs {#bug-fixes-1} * Contêineres Docker recém-criados ficavam completamente inutilizáveis (a limitação de taxa bloqueava todas as requisições). * As ferramentas de IA de detecção de rostos (blur-faces, red-eye-removal, enhance-faces, passport-photo) falhavam em todas as plataformas. * Arquivos HEIC quebrados no ARM (incompatibilidade de símbolos do libheif). * Os pacotes de IA de upscale e restore-photo falhavam na instalação no ARM. * O OCR usava a versão errada do CUDA em contêineres de GPU. * Contorno do guard contra SSRF via endereços IPv6 mapeados para IPv4 em hexadecimal. (Crédito: @tonghuaroot) * Decodificação de HEIC do iPhone com imagens auxiliares. (#183, #199) * Real-ESRGAN com OOM de CUDA em GPUs de 8GB. (#200) * 6 erros de produção no Sentry e 7 bugs de QA. (#208) ### Segurança {#security} * 10 descobertas de teste de penetração corrigidas (contorno de XFF, travamentos por JSON malformado, pipelines sem limite, XSS no log de auditoria, método TRACE e outras). (#207) * Bloqueado o contorno de SSRF via IPv6 em hexadecimal. (Crédito: @tonghuaroot) * Imagens base do Dockerfile fixadas por digest. ### Atualização {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Ou com o Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo no GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Demonstração ao vivo, páginas de destino por ferramenta e um lote de correções de refinamento. ### Novos recursos {#new-features-2} * **Demonstração ao vivo** - [demo.snapotter.com](https://demo.snapotter.com) permite que as pessoas experimentem o SnapOtter sem instalar nada. * **Página índice de ferramentas** - Navegue por todas as 50+ ferramentas em `/tools` com busca e filtros por categoria. * **50+ páginas de destino de SEO** - Cada ferramenta agora tem uma página de destino dedicada com FAQs, casos de uso e tabelas comparativas. * **Prévia de fundo** - Um controle deslizante de antes e depois exibe um fundo quadriculado atrás de imagens transparentes. * **Gerador de senhas fortes** - Botão de um clique no formulário Adicionar Membros. ### Correções de bugs {#bug-fixes-2} * A ferramenta de informações de HEIC/HEIF não falha mais (pré-decodificação adicionada). * A instalação de pacotes de modelos de IA mostra mensagens de erro melhores e respeita os limites de recursos. * As miniaturas da biblioteca carregam corretamente (os cabeçalhos de autenticação estavam ausentes). * Os menus suspensos não são mais cortados nas tabelas de configurações de Pessoas e Equipes. * Percentual de comparação de tamanho oculto em ferramentas que não são de compressão. * Link duplicado da política de privacidade removido. * Tradução para o italiano adicionada às configurações de recursos de IA. * Ícones renomeados do Lucide atualizados (Wand2, Columns). ### Infraestrutura {#infrastructure} * OpenSSF Scorecard reforçado de 4.3 para cerca de 7.0. * Testes de CI paralelizados em 4 shards com fixtures reduzidos. * 41 atualizações de dependências. ### Atualização {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Ou com o Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo no GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Cinco novas ferramentas, um editor de imagem completo, login por SSO, 20 idiomas. Provavelmente deveriam ter sido três versões separadas, mas aqui estamos. ### Novos recursos {#new-features-3} * **Editor de imagem** - Camadas, pincéis, formas, ajustes, filtros, curvas, atalhos de teclado. Roda no seu navegador, processa no seu hardware. * **Autenticação OIDC / SSO** - Faça login com Google, GitHub, Okta ou qualquer provedor OpenID Connect. Defina algumas variáveis de ambiente e sua equipe usa as contas que já possui. * **Gerador de memes** - 100 modelos integrados com renderização de texto via opentype.js. Ou envie a sua própria imagem. * **Beautify** - Solte uma captura de tela e obtenha uma imagem sofisticada. Molduras de dispositivo (macOS, Windows, navegador), sombras, gradientes, predefinições para redes sociais. * **Simulação de daltonismo** - Veja como as imagens aparecem com protanopia, deuteranopia, tritanopia e outras deficiências de visão de cores. * **Corretor de transparência de PNG** - Detecta PNGs com transparência falsa e os corrige com HR-matting do BiRefNet. Remoção opcional de marca d'água via inpainting com LaMa. * **Expansão de canvas por IA** - Estenda os limites da imagem com preenchimento por IA. Três níveis de qualidade (rápido, equilibrado, qualidade) dependendo de quanto tempo de GPU você quer trocar. * **20 idiomas** - Árabe, chinês (simplificado/tradicional), tcheco, holandês, francês, alemão, hindi, indonésio, italiano, japonês, coreano, polonês, português, russo, espanhol, tailandês, turco, ucraniano, vietnamita. RTL funciona para o árabe. * **Importação por URL** - Cole URLs no dropzone ou importe em massa a partir de uma lista. Busca no lado do servidor com proteção contra SSRF. * **Apagador multiarquivo** - Desenhe máscaras de apagamento em várias imagens e processe todas com um clique. Os traços persistem por imagem. * **Importação/exportação de pipelines** - Salve cadeias de ferramentas como JSON e compartilhe-as com outras pessoas. * **17 novos formatos RAW de câmera** via exiftool, mais entrada de QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ e APNG. Novos codecs de saída para BMP, ICO, JP2, QOI. Exportação de AVIF, TIFF, GIF, JXL e PSD recuperada de um branch anteriormente perdido. ### Melhorias {#improvements-2} * **Aprimoramento de imagem** - Substituímos o pipeline antigo por CLAHE + normalise + gamma. O novo botão Deep Enhance usa o modelo de IA para resultados mais agressivos. * **Restauração de foto** - Detecção de arranhões reescrita com filtragem Otsu de 8 ângulos. O inpainting com LaMa agora roda em resolução nativa. * **Formatos exóticos em toda parte** - OCR, image-to-PDF, gerador de favicon, composição, stitch e vetorização agora decodificam HEIC, RAW e PSD. * **Compress** - Tolerância de tamanho-alvo apertada de 5% para 1%. O tamanho-alvo é o modo padrão. Adicionados botões de incremento e seletor de unidade KB/MB. * **Limpeza do Sentry** - 644 eventos sem ação filtrados. Erros reais agora tratados corretamente. * **Detecção de GPU** - Melhor diagnóstico para contêineres onde o CUDA está presente mas o nvidia-smi não está. * **Modo com autenticação desativada** - Um usuário anônimo é semeado no banco de dados com a função admin. Chaves de API, pipelines e arquivos de usuário não quebram mais em restrições de FK. * **Mais de 2.705 novos testes** entre unitários, de integração e E2E. ### Correções de bugs {#bug-fixes-3} * O upscale em CPU não excede mais o tempo limite em servidores NAS e hardware de baixa potência. * O logotipo do QR code não faz mais a prévia desaparecer permanentemente. * Estouro de recorte corrigido para imagens de retrato altas. * Arquivos TIFF com alfa forçam corretamente a saída PNG em vez de produzir corrupção. * A decodificação de HDR/EXR converte para 8 bits antes do CLAHE, corrigindo falhas de decodificação. * Buffers de entrada de pontos de referência facial convertidos para PNG antes do sidecar Python, corrigindo travamentos. * Find duplicates lida com lotes de formatos mistos e erros de rede. * A prévia do Beautify atualiza em tempo real. * Barras de progresso para stitch e vetorização. * SVGZ tratado pelo SVG-to-raster. * Nomes de arquivo não-ASCII corrigidos via cabeçalho X-File-Results codificado em percent-encoding. ### Atualização {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Ou com o Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Diff completo no GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Imagem Docker unificada com detecção automática de GPU. Uma única imagem lida com cargas de trabalho tanto de CPU quanto de GPU. Compose simplificado para um único arquivo com rotação de logs. Os pré-downloads de modelos agora incluem verificação e um teste de fumaça. *** ## v1.13.0 {#v1-13-0} Controle de acesso baseado em funções (RBAC). 14 permissões granulares, três funções integradas (admin, editor, user), suporte a funções personalizadas. Verificações de permissão em todas as rotas de API. Abas do frontend filtradas pelas permissões do usuário. *** ## v1.12.0 {#v1-12-0} Ferramenta PDF to Image. Converta páginas de PDF para PNG, JPEG, WebP ou TIFF em DPI personalizado. Imagem Docker unificada com detecção automática de GPU. *** ## v1.11.0 {#v1-11-0} llms.txt gerado automaticamente via vitepress-plugin-llms para documentação amigável a IA. *** ## v1.10.0 {#v1-10-0} Redimensionamento com reconhecimento de conteúdo (seam carving) com proteção de rostos. Redimensione imagens preservando o conteúdo importante. *** ## v1.9.0 {#v1-9-0} Ferramenta Stitch / Combine. Una imagens lado a lado, empilhadas verticalmente ou em uma grade personalizada. *** ## v1.8.0 {#v1-8-0} Ferramenta Edit Metadata. Visualize e edite metadados EXIF, IPTC e XMP com uma interface granular para remover/manter. *** ## Versões mais antigas {#older-releases} Para o changelog completo em nível de commit, incluindo versões de correção, consulte as [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/th/changelog.md description: >- บันทึกการเผยแพร่และประวัติเวอร์ชันของ SnapOtter ดูสิ่งที่เพิ่มใหม่ ปรับปรุง และแก้ไขในแต่ละรุ่น --- # Changelog {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 เปลี่ยนชุดเครื่องมือรูปภาพให้กลายเป็นชุดเครื่องมือจัดการไฟล์แบบครบวงจร: เครื่องมือมากกว่า 200 รายการครอบคลุมห้ารูปแบบ (Image, Video, Audio, PDF และ Files) สร้างขึ้นใหม่บน Postgres 17 และคิวงานที่ใช้ Redis พร้อม `docker run` ด้วยคำสั่งเดียว นี่คือรุ่นใหญ่ อ่านหัวข้อ Breaking changes ก่อนอัปเกรดจาก 1.x ### New features {#new-features} * **รูปแบบเครื่องมือใหม่สี่ประเภท**: Video, Audio, PDF และ Files เข้าร่วมกับ Image ทำให้แคตตาล็อกมีเครื่องมือมากกว่า 200 รายการ * **งานเบื้องหลังที่คงทน**: คิวที่ใช้ Redis (BullMQ) รันเครื่องมือทุกตัวเป็นงานที่ติดตามได้ พร้อมความคืบหน้าแบบสด SSE * **โหมดคอนเทนเนอร์เดียวแบบครบวงจร**: `docker run` เพียงคำสั่งเดียวบูตอินสแตนซ์ที่สมบูรณ์พร้อม Postgres และ Redis แบบฝังในตัว * **ชุด AI แบบติดตั้งเมื่อต้องการ**: การลบพื้นหลัง, OCR, การถอดเสียง, การขยายภาพ, การตรวจจับและเพิ่มความคมชัดใบหน้า, ยางลบวัตถุ, การลงสี และการฟื้นฟูภาพถ่าย ติดตั้งได้จาก UI ตรวจจับการเร่งความเร็ว GPU แยกตามเฟรมเวิร์ก * **Sign PDF**: วาด พิมพ์ หรืออัปโหลดลายเซ็นแล้ววางลงบน PDF ในเบราว์เซอร์ * **Automate**: ตัวสร้างไปป์ไลน์แบบภาพที่เชื่อมโยงเครื่องมือเข้าด้วยกัน พร้อมเทมเพลตสำเร็จรูปเก้าแบบ * **พรีเซ็ตการแปลงแบบคลิกเดียว 83 รายการ**: ตัวแปลง JPG-to-PNG, MP4-to-GIF และอื่น ๆ ที่คล้ายกันโดยเฉพาะ พร้อมการค้นหาแบบคลุมเครือ * **โปรแกรมแก้ไขรูปภาพแบบเลเยอร์**: โปรแกรมแก้ไขที่ขับเคลื่อนด้วย Konva ที่ `/editor` พร้อมพู่กัน รูปทรง การปรับแต่ง ฟิลเตอร์ และเส้นโค้ง * **คลังไฟล์ Files**: บันทึกผลลัพธ์ใด ๆ แล้วนำกลับมาใช้เป็นอินพุตของเครื่องมืออื่น * เครื่องมือที่ปักหมุด, การซูมและเลื่อนในแคนวาส, 21 ภาษา และความสามารถระดับองค์กร (OIDC/SSO, SAML, SCIM, ที่จัดเก็บ S3, สิทธิ์แยกตามเครื่องมือ, การส่งออก audit, distributed tracing) ### Improvements {#improvements} * ยกเลิกกระบวนการที่กำลังทำงานอยู่ได้ (#137) * ถอดรหัส RAW ความละเอียดเต็มผ่าน LibRaw รวมถึง DNG (#289) * การปรับใช้แบบไม่ใช่ root และ UID ต่างเจ้าของ (TrueNAS, Unraid, OpenShift, PUID/PGID) (#230, #127) * การตรวจจับการติดตั้ง AI ที่แม่นยำและขั้นตอนการติดตั้งที่แข็งแรงขึ้น (#214, #352) * การเสริมความเป็นส่วนตัว: ไม่มีการส่งข้อมูลออกไปยังบุคคลที่สามโดยอัตโนมัติ พร้อมโหมดออฟไลน์เข้มงวดที่เลือกได้ * ปุ่มให้ข้อเสนอแนะที่แสดงตลอดเวลา แม้จะปิดการวิเคราะห์ข้อมูลก็ตาม ### Bug fixes {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` ปิดการจำกัดอัตราสำหรับเส้นทางเครื่องมืออีกครั้ง (#271) * ซ่อมแซมเส้นทาง virtualenv ของ AI ภายในอิมเมจ Docker (#390) * ความเข้ากันได้กับ sharp 0.35.2+ (#362) * แก้ไขเลย์เอาต์โปรแกรมแก้ไขรูปภาพ: ไม้บรรทัด, พฤติกรรมการเติมสี, แถบด้านข้าง และการกำหนดขนาดแคนวาส (#258, #259) * แปลภาษาอิตาลีเสร็จสมบูรณ์ (#231, #206, #425) * Audio normalize และ loudnorm รักษาอัตราการสุ่มตัวอย่างของต้นฉบับ * การเสริมความแข็งแกร่ง SSRF: การจับคู่ CIDR ของ IPv6 แบบตัวเลขและการสแกน URL ล่วงหน้าที่ครอบคลุมมากขึ้น (#287) * PDF ที่สร้างขึ้นจะประทับ SnapOtter เป็น Producer * mediapipe ติดตั้งได้บน Python 3.13 และ Debian 13 ### Breaking changes {#breaking-changes} 2.0 แทนที่ฐานข้อมูล SQLite แบบฝังในตัวด้วย Postgres 17 และเพิ่ม Redis 8 สำหรับคิวงาน ข้อมูล 1.x ของคุณจะย้ายโดยอัตโนมัติเมื่อบูตครั้งแรก แต่สแตกคอนเทนเนอร์เปลี่ยนไปแล้ว ดังนั้นให้สำรองข้อมูลทั้งวอลุ่ม `/data` ของคุณก่อน (1.x รัน SQLite ในโหมด WAL ดังนั้นข้อมูลที่คอมมิตแล้วมักจะอยู่ใน `snapotter.db-wal`) จากนั้นเลือกอิมเมจคอนเทนเนอร์เดียว (Postgres และ Redis แบบฝังในตัว เฉพาะ root) หรือสแตก Compose (แอปพลิเคชันพร้อม Postgres 17 และ Redis 8) ดู [migration guide](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) และ [upgrade guide](/th/guide/upgrading) ### Upgrade {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` หรือด้วย Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} เครื่องมือ HTML to Image ใหม่, การเข้าถึง WCAG 2.2 AA, การเสริมความแข็งแกร่งด้านความปลอดภัยจากการทดสอบการเจาะระบบ และแก้ไข Docker ที่สำคัญ 5 รายการ ### New features {#new-features-1} * **HTML to Image**: จับภาพหน้าจอของ URL หรือ HTML ดิบเป็น PNG/JPEG/WebP รองรับการจับภาพทั้งหน้า, viewport กำหนดเอง, โหมดมืด * **แบบแผน \_FILE secret ของ Docker**: เมานต์ตัวแปรสภาพแวดล้อมที่ละเอียดอ่อนเป็นไฟล์แทนข้อความธรรมดา (#205) * **การออกใบอนุญาตระดับองค์กรและที่จัดเก็บ S3**: คีย์ใบอนุญาตเชิงพาณิชย์ที่เลือกได้และที่จัดเก็บออบเจกต์ที่เข้ากันได้กับ S3 * **การปรับปรุงโปรแกรมแก้ไขรูปทรง**: ความโปร่งใสของการเติมสี/เส้นขอบ, ตัวเลือกสี RGBA, สไตล์เส้นประ * **ไฟล์เก็บถาวรของรุ่นที่สร้างไว้ล่วงหน้า**: ดาวน์โหลด tarball จาก GitHub Releases สำหรับการติดตั้งที่ไม่ใช่ Docker (Proxmox, bare metal, LXC) (#202) ### Improvements {#improvements-1} * **การเข้าถึง WCAG 2.2 AA**: ข้ามการนำทาง, การกักโฟกัส, พื้นที่ aria-live, การรองรับการลดการเคลื่อนไหว, อัตราส่วนความคมชัดที่ถูกต้อง (#209) * **การตอบสนองบนมือถือ**: การตั้งค่าที่ปรับตามหน้าจอ, SSE เชื่อมต่อใหม่อัตโนมัติเมื่อสลับแท็บบนมือถือ (#203, #204) * **คุณภาพการลบพื้นหลัง**: การปรับขอบให้เรียบ, การขจัดสีปนเปื้อน, การเลือกรูปแบบเอาต์พุต * **แปลภาษาอิตาลี**: ~145 สตริงใหม่โดย @albanobattistella (#206) * **เอกสาร API แยกตามเครื่องมือ**: 53 หน้าเอกสารพร้อมพารามิเตอร์ ตัวอย่าง และรูปแบบการตอบกลับ * **การดาวน์โหลดโมเดล AI**: ตรรกะการลองใหม่ด้วย exponential backoff สำหรับ HuggingFace (#201) ### Bug fixes {#bug-fixes-1} * คอนเทนเนอร์ Docker ที่สร้างใหม่ใช้งานไม่ได้เลย (การจำกัดอัตราบล็อกทุกคำขอ) * เครื่องมือ AI ตรวจจับใบหน้า (blur-faces, red-eye-removal, enhance-faces, passport-photo) ล้มเหลวบนทุกแพลตฟอร์ม * ไฟล์ HEIC เสียหายบน ARM (libheif symbol ไม่ตรงกัน) * ชุด AI Upscale และ restore-photo ติดตั้งไม่สำเร็จบน ARM * OCR ใช้เวอร์ชัน CUDA ผิดบนคอนเทนเนอร์ GPU * การเลี่ยงการป้องกัน SSRF ผ่านที่อยู่ IPv6 ที่จับคู่ IPv4 แบบเลขฐานสิบหก (เครดิต: @tonghuaroot) * การถอดรหัส HEIC ของ iPhone พร้อมภาพเสริม (#183, #199) * Real-ESRGAN CUDA OOM บน GPU 8GB (#200) * ข้อผิดพลาด Sentry ในการใช้งานจริง 6 รายการ และบั๊ก QA 7 รายการ (#208) ### Security {#security} * แก้ไขผลการทดสอบการเจาะระบบ 10 รายการ (การเลี่ยง XFF, การขัดข้องจาก JSON ที่ผิดรูปแบบ, ไปป์ไลน์ที่ไม่มีขอบเขต, audit log XSS, เมท็อด TRACE และอื่น ๆ) (#207) * ปิดกั้นการเลี่ยง SSRF IPv6 แบบเลขฐานสิบหก (เครดิต: @tonghuaroot) * ปักหมุดอิมเมจฐาน Dockerfile ด้วย digest ### Upgrade {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` หรือด้วย Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} การสาธิตสด, หน้าแลนดิงแยกตามเครื่องมือ และชุดการแก้ไขเพื่อความเรียบร้อย ### New features {#new-features-2} * **การสาธิตสด** - [demo.snapotter.com](https://demo.snapotter.com) ให้ผู้คนลองใช้ SnapOtter โดยไม่ต้องติดตั้งอะไรเลย * **หน้าดัชนีเครื่องมือ** - เรียกดูเครื่องมือทั้งหมดกว่า 50 รายการที่ `/tools` พร้อมการค้นหาและตัวกรองหมวดหมู่ * **หน้าแลนดิง SEO กว่า 50 หน้า** - ทุกเครื่องมือมีหน้าแลนดิงเฉพาะพร้อมคำถามที่พบบ่อย กรณีการใช้งาน และตารางเปรียบเทียบ * **การแสดงตัวอย่างพื้นหลัง** - แถบเลื่อน before-after แสดงพื้นหลังลายตารางหมากรุกด้านหลังภาพโปร่งใส * **ตัวสร้างรหัสผ่านที่แข็งแรง** - ปุ่มคลิกเดียวในฟอร์ม Add Members ### Bug fixes {#bug-fixes-2} * เครื่องมือข้อมูล HEIC/HEIF ไม่ล้มเหลวอีกต่อไป (เพิ่มการถอดรหัสล่วงหน้า) * การติดตั้งชุดโมเดล AI แสดงข้อความแสดงข้อผิดพลาดที่ดีขึ้นและเคารพขีดจำกัดทรัพยากร * ภาพขนาดย่อของคลังโหลดได้ถูกต้อง (ส่วนหัวการยืนยันตัวตนขาดหายไป) * เมนูแบบดรอปดาวน์ไม่ถูกตัดในตารางการตั้งค่า People และ Teams อีกต่อไป * ซ่อนเปอร์เซ็นต์การเปรียบเทียบขนาดบนเครื่องมือที่ไม่ใช่การบีบอัด * ลบลิงก์นโยบายความเป็นส่วนตัวที่ซ้ำกันออก * เพิ่มการแปลภาษาอิตาลีสำหรับการตั้งค่าฟีเจอร์ AI * อัปเดตไอคอน Lucide ที่เปลี่ยนชื่อ (Wand2, Columns) ### Infrastructure {#infrastructure} * เสริมความแข็งแกร่ง OpenSSF Scorecard จาก 4.3 เป็น ~7.0 * ทดสอบ CI แบบขนานเป็น 4 shard พร้อม fixture ที่ลดขนาดลง * อัปเดต dependency 41 รายการ ### Upgrade {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` หรือด้วย Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} เครื่องมือใหม่ห้ารายการ, โปรแกรมแก้ไขรูปภาพแบบเต็ม, การเข้าสู่ระบบ SSO, 20 ภาษา น่าจะควรแยกเป็นสามรุ่นต่างหาก แต่ก็เป็นแบบนี้แหละ ### New features {#new-features-3} * **โปรแกรมแก้ไขรูปภาพ** - เลเยอร์, พู่กัน, รูปทรง, การปรับแต่ง, ฟิลเตอร์, เส้นโค้ง, แป้นพิมพ์ลัด ทำงานในเบราว์เซอร์ของคุณ ประมวลผลบนฮาร์ดแวร์ของคุณ * **การยืนยันตัวตน OIDC / SSO** - เข้าสู่ระบบด้วย Google, GitHub, Okta หรือผู้ให้บริการ OpenID Connect ใด ๆ ตั้งค่าตัวแปรสภาพแวดล้อมสองสามตัวแล้วทีมของคุณใช้บัญชีที่มีอยู่แล้ว * **ตัวสร้างมีม** - เทมเพลตในตัว 100 แบบพร้อมการเรนเดอร์ข้อความผ่าน opentype.js หรืออัปโหลดรูปภาพของคุณเอง * **Beautify** - วางภาพหน้าจอเข้าไป ได้ภาพที่ขัดเกลาออกมา กรอบอุปกรณ์ (macOS, Windows, เบราว์เซอร์), เงา, การไล่ระดับสี, พรีเซ็ตโซเชียลมีเดีย * **การจำลองภาวะตาบอดสี** - ดูตัวอย่างว่าภาพจะดูเป็นอย่างไรกับ protanopia, deuteranopia, tritanopia และภาวะการมองเห็นสีบกพร่องอื่น ๆ * **ตัวแก้ความโปร่งใส PNG** - ตรวจจับ PNG ที่โปร่งใสปลอมและแก้ไขด้วย BiRefNet HR-matting ลบลายน้ำที่เลือกได้ผ่าน LaMa inpainting * **การขยายแคนวาสด้วย AI** - ขยายขอบเขตของภาพด้วยการเติมด้วย AI สามระดับคุณภาพ (fast, balanced, quality) ขึ้นอยู่กับปริมาณเวลา GPU ที่คุณต้องการแลกเปลี่ยน * **20 ภาษา** - อาหรับ, จีน (ตัวย่อ/ตัวเต็ม), เช็ก, ดัตช์, ฝรั่งเศส, เยอรมัน, ฮินดี, อินโดนีเซีย, อิตาลี, ญี่ปุ่น, เกาหลี, โปแลนด์, โปรตุเกส, รัสเซีย, สเปน, ไทย, ตุรกี, ยูเครน, เวียดนาม RTL ใช้งานได้สำหรับภาษาอาหรับ * **การนำเข้า URL** - วาง URL ลงในพื้นที่วางไฟล์หรือนำเข้าจากรายการเป็นชุด การดึงข้อมูลฝั่งเซิร์ฟเวอร์พร้อมการป้องกัน SSRF * **ยางลบหลายไฟล์** - วาดมาสก์การลบข้ามหลายภาพ ประมวลผลทั้งหมดด้วยคลิกเดียว เส้นวาดคงอยู่แยกตามภาพ * **การนำเข้า/ส่งออกไปป์ไลน์** - บันทึกห่วงโซ่เครื่องมือเป็น JSON แล้วแบ่งปันกับผู้อื่น * **รูปแบบ RAW ของกล้องใหม่ 17 รูปแบบ** ผ่าน exiftool รวมถึง QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ และอินพุต APNG โคเดกเอาต์พุตใหม่สำหรับ BMP, ICO, JP2, QOI กู้คืนการส่งออก AVIF, TIFF, GIF, JXL และ PSD จากสาขาที่เคยสูญหาย ### Improvements {#improvements-2} * **การเพิ่มความคมชัดภาพ** - แทนที่ไปป์ไลน์เดิมด้วย CLAHE + normalise + gamma ปุ่ม Deep Enhance ใหม่ใช้โมเดล AI เพื่อผลลัพธ์ที่เข้มข้นขึ้น * **ฟื้นฟูภาพถ่าย** - เขียนการตรวจจับรอยขีดข่วนใหม่ด้วยการกรอง Otsu 8 มุม LaMa inpainting ทำงานที่ความละเอียดต้นฉบับแล้ว * **รูปแบบแปลกทุกที่** - OCR, image-to-PDF, ตัวสร้าง favicon, การจัดวาง, การต่อภาพ และการแปลงเป็นเวกเตอร์ ตอนนี้ถอดรหัส HEIC, RAW, PSD ได้ทั้งหมด * **บีบอัด** - เข้มความคลาดเคลื่อนของขนาดเป้าหมายจาก 5% เป็น 1% ขนาดเป้าหมายเป็นโหมดเริ่มต้น เพิ่มปุ่มปรับค่าและตัวเลือกหน่วย KB/MB * **การล้าง Sentry** - กรองเหตุการณ์ที่ไม่ต้องดำเนินการ 644 รายการ ข้อผิดพลาดจริงได้รับการจัดการอย่างถูกต้องแล้ว * **การตรวจจับ GPU** - การวินิจฉัยที่ดีขึ้นสำหรับคอนเทนเนอร์ที่มี CUDA แต่ไม่มี nvidia-smi * **โหมดปิดการยืนยันตัวตน** - เพาะผู้ใช้แบบไม่ระบุตัวตนใน DB ด้วยบทบาท admin คีย์ API, ไปป์ไลน์ และไฟล์ผู้ใช้ไม่พังจากข้อจำกัด FK อีกต่อไป * **การทดสอบใหม่กว่า 2,705 รายการ** ครอบคลุมทั้ง unit, integration และ E2E ### Bug fixes {#bug-fixes-3} * Upscale บน CPU ไม่หมดเวลาบนกล่อง NAS และฮาร์ดแวร์กำลังต่ำอีกต่อไป * โลโก้รหัส QR ไม่ทำให้ตัวอย่างหายไปอย่างถาวรอีกต่อไป * แก้ไขการล้นของ crop สำหรับภาพแนวตั้งสูง * ไฟล์ TIFF alpha บังคับเอาต์พุต PNG อย่างถูกต้องแทนที่จะทำให้เกิดความเสียหาย * การถอดรหัส HDR/EXR แปลงเป็น 8-bit ก่อน CLAHE แก้ไขความล้มเหลวในการถอดรหัส * บัฟเฟอร์อินพุตของจุดสังเกตใบหน้าถูกแปลงเป็น PNG ก่อนไปยัง Python sidecar แก้ไขการขัดข้อง * การหาไฟล์ซ้ำจัดการชุดที่มีรูปแบบผสมและข้อผิดพลาดของเครือข่ายได้ * ตัวอย่าง Beautify อัปเดตแบบเรียลไทม์ * แถบความคืบหน้าสำหรับการต่อภาพและการแปลงเป็นเวกเตอร์ * SVGZ จัดการโดย SVG-to-raster * แก้ไขชื่อไฟล์ที่ไม่ใช่ ASCII ผ่านส่วนหัว X-File-Results ที่เข้ารหัสแบบเปอร์เซ็นต์ ### Upgrade {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` หรือด้วย Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Full diff on GitHub](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} อิมเมจ Docker แบบรวมพร้อมการตรวจจับ GPU อัตโนมัติ อิมเมจเดียวจัดการทั้งงาน CPU และ GPU ทำให้ compose ง่ายขึ้นเป็นไฟล์เดียวพร้อมการหมุนเวียนบันทึก การดาวน์โหลดโมเดลล่วงหน้าตอนนี้รวมการตรวจสอบและการทดสอบแบบสโมกแล้ว *** ## v1.13.0 {#v1-13-0} การควบคุมการเข้าถึงตามบทบาท (RBAC) สิทธิ์แบบละเอียด 14 รายการ, สามบทบาทในตัว (admin, editor, user), รองรับบทบาทกำหนดเอง การตรวจสอบสิทธิ์บนเส้นทาง API ทั้งหมด แท็บส่วนหน้ากรองตามสิทธิ์ของผู้ใช้ *** ## v1.12.0 {#v1-12-0} เครื่องมือ PDF to Image แปลงหน้า PDF เป็น PNG, JPEG, WebP หรือ TIFF ที่ DPI กำหนดเอง อิมเมจ Docker แบบรวมพร้อมการตรวจจับ GPU อัตโนมัติ *** ## v1.11.0 {#v1-11-0} สร้าง llms.txt อัตโนมัติผ่าน vitepress-plugin-llms สำหรับเอกสารที่เป็นมิตรกับ AI *** ## v1.10.0 {#v1-10-0} การปรับขนาดที่คำนึงถึงเนื้อหา (seam carving) พร้อมการปกป้องใบหน้า ปรับขนาดภาพขณะที่รักษาเนื้อหาสำคัญไว้ *** ## v1.9.0 {#v1-9-0} เครื่องมือ Stitch / Combine ต่อภาพเรียงกันในแนวนอน ซ้อนกันในแนวตั้ง หรือในตารางกำหนดเอง *** ## v1.8.0 {#v1-8-0} เครื่องมือ Edit Metadata ดูและแก้ไขเมทาดาทา EXIF, IPTC และ XMP ด้วยอินเทอร์เฟซการลบ/คงไว้แบบละเอียด *** ## Older releases {#older-releases} สำหรับ changelog ระดับคอมมิตทั้งหมดรวมถึงรุ่นแพตช์ ดู [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases) --- --- url: https://docs.snapotter.com/de/tools/files/chart-maker.md description: Erstellt Balken-, Linien- oder Kreisdiagramme aus CSV- oder JSON-Daten. --- # Chart Maker {#chart-maker} Erstellt Balken-, Linien- oder Kreisdiagramme aus CSV- oder JSON-Daten. Gibt ein PNG-Bild des gerenderten Diagramms zurück. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Akzeptiert Multipart-Formulardaten mit einer CSV- oder JSON-Datei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | kind | string | Nein | `"bar"` | Diagrammtyp: `bar`, `line`, `pie` | | title | string | Nein | - | Diagrammtitel (max. 120 Zeichen) | | width | integer | Nein | `960` | Diagrammbreite in Pixeln (320-2048) | | height | integer | Nein | `540` | Diagrammhöhe in Pixeln (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Die Eingabe muss eine `.csv`- oder `.json`-Datei sein. CSV-Dateien sollten eine Kopfzeile mit Spaltennamen haben. * Die erste Spalte wird als Kategoriebezeichnung verwendet; die zweite Spalte muss numerisch sein und liefert die Datenwerte. Es werden nur zwei Spalten verwendet. * Die JSON-Eingabe sollte ein Array von `{label, value}`-Objekten sein oder ein einfaches Objekt, dessen Schlüssel zu Bezeichnungen und dessen Werte zu Datenpunkten werden. * Maximal 100 Datenpunkte. Alle Werte müssen null oder größer sein. * Die Ausgabe ist unabhängig vom Eingabeformat immer ein PNG-Bild. --- --- url: https://docs.snapotter.com/hi/tools/files/chart-maker.md description: CSV या JSON डेटा से बार, लाइन, या पाई चार्ट बनाएं। --- # Chart Maker {#chart-maker} CSV या JSON डेटा से बार, लाइन, या पाई चार्ट बनाएं। रेंडर किए गए चार्ट की एक PNG इमेज लौटाता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` एक CSV या JSON फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | चार्ट प्रकार: `bar`, `line`, `pie` | | title | string | No | - | चार्ट शीर्षक (अधिकतम 120 वर्ण) | | width | integer | No | `960` | पिक्सेल में चार्ट की चौड़ाई (320-2048) | | height | integer | No | `540` | पिक्सेल में चार्ट की ऊंचाई (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * इनपुट एक `.csv` या `.json` फ़ाइल होनी चाहिए। CSV फ़ाइलों में कॉलम नामों के साथ एक हेडर पंक्ति होनी चाहिए। * पहला कॉलम श्रेणी लेबल के रूप में उपयोग किया जाता है; दूसरा कॉलम संख्यात्मक होना चाहिए और डेटा मान प्रदान करता है। केवल दो कॉलम उपयोग किए जाते हैं। * JSON इनपुट `{label, value}` ऑब्जेक्ट्स का एक ऐरे होना चाहिए, या एक सादा ऑब्जेक्ट जिसकी कुंजियाँ लेबल बन जाती हैं और मान डेटा पॉइंट बन जाते हैं। * अधिकतम 100 डेटा पॉइंट। सभी मान शून्य या उससे अधिक होने चाहिए। * इनपुट फ़ॉर्मेट की परवाह किए बिना आउटपुट हमेशा एक PNG इमेज होता है। --- --- url: https://docs.snapotter.com/id/tools/files/chart-maker.md description: Buat grafik batang, garis, atau lingkaran dari data CSV atau JSON. --- # Chart Maker {#chart-maker} Buat grafik batang, garis, atau lingkaran dari data CSV atau JSON. Mengembalikan gambar PNG dari grafik yang dirender. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Menerima multipart form data berisi file CSV atau JSON dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Jenis grafik: `bar`, `line`, `pie` | | title | string | No | - | Judul grafik (maks 120 karakter) | | width | integer | No | `960` | Lebar grafik dalam piksel (320-2048) | | height | integer | No | `540` | Tinggi grafik dalam piksel (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Input harus berupa file `.csv` atau `.json`. File CSV sebaiknya memiliki baris header dengan nama kolom. * Kolom pertama digunakan sebagai label kategori; kolom kedua harus numerik dan menyediakan nilai data. Hanya dua kolom yang digunakan. * Input JSON harus berupa array objek `{label, value}`, atau objek biasa yang key-nya menjadi label dan value-nya menjadi titik data. * Maksimum 100 titik data. Semua nilai harus nol atau lebih besar. * Output selalu berupa gambar PNG terlepas dari format input. --- --- url: https://docs.snapotter.com/it/tools/files/chart-maker.md description: Crea grafici a barre, a linee o a torta da dati CSV o JSON. --- # Chart Maker {#chart-maker} Crea grafici a barre, a linee o a torta da dati CSV o JSON. Restituisce un'immagine PNG del grafico renderizzato. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Accetta dati form multipart con un file CSV o JSON e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Tipo di grafico: `bar`, `line`, `pie` | | title | string | No | - | Titolo del grafico (massimo 120 caratteri) | | width | integer | No | `960` | Larghezza del grafico in pixel (320-2048) | | height | integer | No | `540` | Altezza del grafico in pixel (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * L'input deve essere un file `.csv` o `.json`. I file CSV dovrebbero avere una riga di intestazione con i nomi delle colonne. * La prima colonna viene usata come etichetta di categoria; la seconda colonna deve essere numerica e fornisce i valori dei dati. Vengono usate solo due colonne. * L'input JSON dovrebbe essere un array di oggetti `{label, value}`, oppure un oggetto semplice le cui chiavi diventano etichette e i cui valori diventano punti dati. * Massimo 100 punti dati. Tutti i valori devono essere maggiori o uguali a zero. * L'output è sempre un'immagine PNG indipendentemente dal formato di input. --- --- url: https://docs.snapotter.com/ja/tools/files/chart-maker.md description: CSV または JSON データから棒グラフ、折れ線グラフ、円グラフを作成します。 --- # Chart Maker {#chart-maker} CSV または JSON データから棒グラフ、折れ線グラフ、円グラフを作成します。描画されたグラフの PNG 画像を返します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` CSV または JSON ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | グラフの種類: `bar`、`line`、`pie` | | title | string | No | - | グラフのタイトル(最大 120 文字) | | width | integer | No | `960` | グラフの幅(ピクセル、320〜2048) | | height | integer | No | `540` | グラフの高さ(ピクセル、240〜1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * 入力は `.csv` または `.json` ファイルである必要があります。CSV ファイルには列名を含むヘッダー行が必要です。 * 最初の列がカテゴリラベルとして使用され、2 番目の列は数値である必要があり、データ値を提供します。使用されるのは 2 列のみです。 * JSON 入力は `{label, value}` オブジェクトの配列、またはキーがラベルに、値がデータポイントになるプレーンオブジェクトである必要があります。 * データポイントは最大 100 個です。すべての値は 0 以上である必要があります。 * 入力形式にかかわらず、出力は常に PNG 画像です。 --- --- url: https://docs.snapotter.com/nl/tools/files/chart-maker.md description: Maak staaf-, lijn- of taartdiagrammen van CSV- of JSON-data. --- # Chart Maker {#chart-maker} Maak staaf-, lijn- of taartdiagrammen van CSV- of JSON-data. Retourneert een PNG-afbeelding van het weergegeven diagram. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Accepteert multipart-formulierdata met een CSV- of JSON-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | kind | string | Nee | `"bar"` | Diagramtype: `bar`, `line`, `pie` | | title | string | Nee | - | Diagramtitel (max. 120 tekens) | | width | integer | Nee | `960` | Diagrambreedte in pixels (320-2048) | | height | integer | Nee | `540` | Diagramhoogte in pixels (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * De invoer moet een `.csv`- of `.json`-bestand zijn. CSV-bestanden moeten een koprij met kolomnamen hebben. * De eerste kolom wordt gebruikt als categorielabel; de tweede kolom moet numeriek zijn en levert de datawaarden. Slechts twee kolommen worden gebruikt. * JSON-invoer moet een array van `{label, value}`-objecten zijn, of een gewoon object waarvan de sleutels labels worden en de waarden datapunten. * Maximaal 100 datapunten. Alle waarden moeten nul of groter zijn. * De uitvoer is altijd een PNG-afbeelding, ongeacht het invoerformaat. --- --- url: https://docs.snapotter.com/pl/tools/files/chart-maker.md description: Tworzy wykresy słupkowe, liniowe lub kołowe z danych CSV lub JSON. --- # Chart Maker {#chart-maker} Tworzy wykresy słupkowe, liniowe lub kołowe z danych CSV lub JSON. Zwraca obraz PNG z wyrenderowanym wykresem. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Przyjmuje dane formularza multipart z plikiem CSV lub JSON oraz polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | kind | string | Nie | `"bar"` | Typ wykresu: `bar`, `line`, `pie` | | title | string | Nie | - | Tytuł wykresu (maks. 120 znaków) | | width | integer | Nie | `960` | Szerokość wykresu w pikselach (320-2048) | | height | integer | Nie | `540` | Wysokość wykresu w pikselach (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Wejściem musi być plik `.csv` lub `.json`. Pliki CSV powinny mieć wiersz nagłówka z nazwami kolumn. * Pierwsza kolumna jest używana jako etykieta kategorii; druga kolumna musi być liczbowa i dostarcza wartości danych. Używane są tylko dwie kolumny. * Wejście JSON powinno być tablicą obiektów `{label, value}` lub zwykłym obiektem, którego klucze stają się etykietami, a wartości punktami danych. * Maksymalnie 100 punktów danych. Wszystkie wartości muszą być zerowe lub większe. * Wynikiem jest zawsze obraz PNG, niezależnie od formatu wejściowego. --- --- url: https://docs.snapotter.com/sv/tools/files/chart-maker.md description: Skapa stapel-, linje- eller cirkeldiagram från CSV- eller JSON-data. --- # Chart Maker {#chart-maker} Skapa stapel-, linje- eller cirkeldiagram från CSV- eller JSON-data. Returnerar en PNG-bild av det renderade diagrammet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Tar emot multipart-formulärdata med en CSV- eller JSON-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Diagramtyp: `bar`, `line`, `pie` | | title | string | No | - | Diagramtitel (max 120 tecken) | | width | integer | No | `960` | Diagrambredd i pixlar (320-2048) | | height | integer | No | `540` | Diagramhöjd i pixlar (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Indata måste vara en `.csv`- eller `.json`-fil. CSV-filer bör ha en rubrikrad med kolumnnamn. * Den första kolumnen används som kategorietikett; den andra kolumnen måste vara numerisk och tillhandahåller datavärdena. Endast två kolumner används. * JSON-indata bör vara en array av `{label, value}`-objekt, eller ett enkelt objekt vars nycklar blir etiketter och vars värden blir datapunkter. * Högst 100 datapunkter. Alla värden måste vara noll eller större. * Utdata är alltid en PNG-bild oavsett indataformat. --- --- url: https://docs.snapotter.com/th/tools/files/chart-maker.md description: สร้างแผนภูมิแท่ง เส้น หรือวงกลมจากข้อมูล CSV หรือ JSON --- # Chart Maker {#chart-maker} สร้างแผนภูมิแท่ง เส้น หรือวงกลมจากข้อมูล CSV หรือ JSON ส่งคืนภาพ PNG ของแผนภูมิที่เรนเดอร์แล้ว ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` รับข้อมูล multipart form ที่มีไฟล์ CSV หรือ JSON และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | ประเภทแผนภูมิ: `bar`, `line`, `pie` | | title | string | No | - | ชื่อแผนภูมิ (สูงสุด 120 อักขระ) | | width | integer | No | `960` | ความกว้างแผนภูมิเป็นพิกเซล (320-2048) | | height | integer | No | `540` | ความสูงแผนภูมิเป็นพิกเซล (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * อินพุตต้องเป็นไฟล์ `.csv` หรือ `.json` ไฟล์ CSV ควรมีแถวส่วนหัวพร้อมชื่อคอลัมน์ * คอลัมน์แรกใช้เป็นป้ายกำกับหมวดหมู่ คอลัมน์ที่สองต้องเป็นตัวเลขและให้ค่าข้อมูล ใช้เพียงสองคอลัมน์เท่านั้น * อินพุต JSON ควรเป็นอาร์เรย์ของออบเจกต์ `{label, value}` หรือออบเจกต์ธรรมดาที่คีย์กลายเป็นป้ายกำกับและค่ากลายเป็นจุดข้อมูล * จุดข้อมูลสูงสุด 100 จุด ค่าทั้งหมดต้องเป็นศูนย์หรือมากกว่า * ผลลัพธ์จะเป็นภาพ PNG เสมอ ไม่ว่ารูปแบบอินพุตจะเป็นอะไร --- --- url: https://docs.snapotter.com/tr/tools/files/chart-maker.md description: CSV veya JSON verilerinden çubuk, çizgi veya pasta grafikleri oluşturun. --- # Chart Maker {#chart-maker} CSV veya JSON verilerinden çubuk, çizgi veya pasta grafikleri oluşturun. İşlenmiş grafiğin PNG görüntüsünü döndürür. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Bir CSV veya JSON dosyası ve JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Grafik türü: `bar`, `line`, `pie` | | title | string | No | - | Grafik başlığı (maks. 120 karakter) | | width | integer | No | `960` | Piksel cinsinden grafik genişliği (320-2048) | | height | integer | No | `540` | Piksel cinsinden grafik yüksekliği (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Giriş bir `.csv` veya `.json` dosyası olmalıdır. CSV dosyalarında sütun adlarını içeren bir başlık satırı bulunmalıdır. * İlk sütun kategori etiketi olarak kullanılır; ikinci sütun sayısal olmalı ve veri değerlerini sağlamalıdır. Yalnızca iki sütun kullanılır. * JSON girişi bir `{label, value}` nesneleri dizisi veya anahtarları etiketlere ve değerleri veri noktalarına dönüşen düz bir nesne olmalıdır. * Maksimum 100 veri noktası. Tüm değerler sıfır veya daha büyük olmalıdır. * Giriş formatından bağımsız olarak çıktı her zaman bir PNG görüntüsüdür. --- --- url: https://docs.snapotter.com/uk/tools/files/chart-maker.md description: Створення стовпчастих, лінійних або кругових діаграм з даних CSV чи JSON. --- # Chart Maker {#chart-maker} Створення стовпчастих, лінійних або кругових діаграм з даних CSV чи JSON. Повертає зображення PNG відрендереної діаграми. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Приймає дані форми multipart з файлом CSV чи JSON та JSON-полем `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Тип діаграми: `bar`, `line`, `pie` | | title | string | No | - | Заголовок діаграми (максимум 120 символів) | | width | integer | No | `960` | Ширина діаграми в пікселях (320-2048) | | height | integer | No | `540` | Висота діаграми в пікселях (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Вхідними даними має бути файл `.csv` або `.json`. Файли CSV повинні мати рядок заголовків з іменами стовпців. * Перший стовпець використовується як мітка категорії; другий стовпець має бути числовим і надає значення даних. Використовуються лише два стовпці. * Вхідні дані JSON мають бути масивом об'єктів `{label, value}` або простим об'єктом, ключі якого стають мітками, а значення - точками даних. * Максимум 100 точок даних. Усі значення мають бути нуль або більше. * Вивід завжди є зображенням PNG незалежно від вхідного формату. --- --- url: https://docs.snapotter.com/vi/tools/files/chart-maker.md description: Tạo biểu đồ cột, đường hoặc tròn từ dữ liệu CSV hoặc JSON. --- # Chart Maker {#chart-maker} Tạo biểu đồ cột, đường hoặc tròn từ dữ liệu CSV hoặc JSON. Trả về một ảnh PNG của biểu đồ đã kết xuất. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Nhận dữ liệu multipart form với một tệp CSV hoặc JSON và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Loại biểu đồ: `bar`, `line`, `pie` | | title | string | No | - | Tiêu đề biểu đồ (tối đa 120 ký tự) | | width | integer | No | `960` | Chiều rộng biểu đồ tính bằng pixel (320-2048) | | height | integer | No | `540` | Chiều cao biểu đồ tính bằng pixel (240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * Đầu vào phải là một tệp `.csv` hoặc `.json`. Tệp CSV nên có một hàng tiêu đề chứa tên cột. * Cột đầu tiên được dùng làm nhãn danh mục; cột thứ hai phải là số và cung cấp các giá trị dữ liệu. Chỉ hai cột được dùng. * Đầu vào JSON nên là một mảng các đối tượng `{label, value}`, hoặc một đối tượng thuần túy mà các khóa trở thành nhãn và các giá trị trở thành điểm dữ liệu. * Tối đa 100 điểm dữ liệu. Tất cả giá trị phải bằng 0 hoặc lớn hơn. * Đầu ra luôn là một ảnh PNG bất kể định dạng đầu vào. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/chart-maker.md description: 根据 CSV 或 JSON 数据创建柱状图、折线图或饼图。 --- # Chart Maker {#chart-maker} 根据 CSV 或 JSON 数据创建柱状图、折线图或饼图。返回渲染图表的 PNG 图片。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` 接受包含 CSV 或 JSON 文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | 图表类型:`bar`、`line`、`pie` | | title | string | No | - | 图表标题(最多 120 个字符) | | width | integer | No | `960` | 图表宽度(单位像素,320-2048) | | height | integer | No | `540` | 图表高度(单位像素,240-1536) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notes {#notes} * 输入必须是 `.csv` 或 `.json` 文件。CSV 文件应带有包含列名的表头行。 * 第一列用作类别标签;第二列必须为数值,用于提供数据值。只使用两列。 * JSON 输入应为一组 `{label, value}` 对象,或一个普通对象,其键成为标签、值成为数据点。 * 最多 100 个数据点。所有值必须大于或等于零。 * 无论输入格式如何,输出始终是 PNG 图片。 --- --- url: https://docs.snapotter.com/vi/tools/image/edit-metadata.md description: >- Chỉnh sửa các trường metadata EXIF, IPTC, GPS và XMP trong ảnh mà không mã hóa lại pixel. --- # Chỉnh sửa siêu dữ liệu ảnh {#edit-metadata} Chỉnh sửa các trường metadata của ảnh bao gồm EXIF, IPTC, tọa độ GPS, ngày tháng và từ khóa. Sử dụng ExifTool bên dưới, nên metadata được ghi tại chỗ mà không mã hóa lại pixel, giữ nguyên chất lượng ảnh đầy đủ. ## API Endpoints {#api-endpoints} ### Chỉnh sửa metadata {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Ghi các trường metadata vào ảnh và trả về tệp đã sửa đổi. ### Kiểm tra metadata {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Trả về toàn bộ metadata từ ảnh qua ExifTool dưới dạng JSON. Không sửa đổi ảnh. ## Tham số (Chỉnh sửa) {#parameters-edit} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | title | string | Không | - | Tiêu đề ảnh (XMP/EXIF) | | author | string | Không | - | Tên tác giả | | artist | string | Không | - | Tên nghệ sĩ (thẻ EXIF Artist) | | copyright | string | Không | - | Thông báo bản quyền | | imageDescription | string | Không | - | Mô tả ảnh (EXIF) | | software | string | Không | - | Thẻ phần mềm | | dateTime | string | Không | - | Giá trị EXIF DateTime | | dateTimeOriginal | string | Không | - | Giá trị EXIF DateTimeOriginal | | setAllDates | string | Không | - | Đặt tất cả các trường ngày cùng lúc | | dateShift | string | Không | - | Dịch tất cả các ngày theo độ lệch (định dạng: `+HH:MM` hoặc `-HH:MM`) | | clearGps | boolean | Không | `false` | Xóa toàn bộ dữ liệu GPS | | gpsLatitude | number | Không | - | Đặt vĩ độ GPS (-90 đến 90) | | gpsLongitude | number | Không | - | Đặt kinh độ GPS (-180 đến 180) | | gpsAltitude | number | Không | - | Đặt độ cao GPS tính bằng mét | | keywords | string\[] | Không | - | Từ khóa/thẻ cần thêm hoặc đặt | | keywordsMode | string | Không | `"add"` | Cách xử lý từ khóa: `add` (thêm vào) hoặc `set` (thay thế) | | fieldsToRemove | string\[] | Không | `[]` | Danh sách tên các trường metadata cụ thể cần xóa | | iptcTitle | string | Không | - | IPTC Object Name | | iptcHeadline | string | Không | - | IPTC Headline | | iptcCity | string | Không | - | IPTC City | | iptcState | string | Không | - | IPTC Province/State | | iptcCountry | string | Không | - | IPTC Country | ## Ví dụ yêu cầu {#example-request} Đặt tác giả và bản quyền: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` Đặt tọa độ GPS: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` Xóa GPS và thêm từ khóa: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Kiểm tra metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Ví dụ phản hồi (Chỉnh sửa) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Ghi chú {#notes} * Công cụ này yêu cầu cài đặt ExifTool trên máy chủ. Nó đã được bao gồm trong image Docker. * Metadata được ghi tại chỗ, nên không có việc mã hóa lại pixel. Thay đổi kích thước tệp là tối thiểu (chỉ các byte metadata). * Tham số `dateShift` dịch tất cả các trường ngày theo độ lệch chỉ định, hữu ích để sửa lỗi múi giờ (ví dụ `+02:00` hoặc `-05:30`). * Nếu không yêu cầu thay đổi nào (tất cả tham số bị bỏ hoặc để trống), tệp gốc được trả về không thay đổi. * Định dạng được hỗ trợ: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * Với các định dạng không xem trước được trên trình duyệt (HEIF, TIFF), phản hồi bao gồm một trường `previewUrl` với bản xem trước WebP. --- --- url: https://docs.snapotter.com/vi/tools/audio/normalize-audio.md description: Cân bằng độ lớn về mức chuẩn phát sóng (EBU R128). --- # Chuẩn hóa âm thanh {#normalize-audio} Cân bằng độ lớn âm thanh về mức chuẩn phát sóng bằng chuẩn hóa EBU R128 (-16 LUFS). ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/normalize-audio` Chấp nhận dữ liệu form multipart với một tệp âm thanh và một trường JSON `settings`. ## Tham số {#parameters} Công cụ này không có tham số cấu hình. Nó tự động áp dụng chuẩn hóa độ lớn EBU R128. ## Yêu cầu ví dụ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/normalize-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" ``` ## Phản hồi ví dụ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Ghi chú {#notes} * Dùng chuẩn độ lớn EBU R128, nhắm mục tiêu -16 LUFS. * Lý tưởng cho podcast, sách nói và nội dung phát sóng, nơi độ lớn nhất quán là quan trọng. * Tần số lấy mẫu nguồn được giữ nguyên trong đầu ra. * Đầu ra thường giữ container đầu vào. Đầu vào AAC được ghi thành M4A, và các đầu vào chỉ giải mã không được hỗ trợ sẽ chuyển về MP3. --- --- url: https://docs.snapotter.com/vi/tools/video/video-loudnorm.md description: Chuẩn hóa âm lượng của video theo tiêu chuẩn phát sóng. --- # Chuẩn hóa âm thanh video {#normalize-audio} Chuẩn hóa âm lượng âm thanh của video theo tiêu chuẩn độ ồn phát sóng EBU R128. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-loudnorm` Nhận multipart form data gồm một file video. Công cụ này không có cài đặt nào có thể cấu hình. ## Parameters {#parameters} Công cụ này không có tham số nào. Nó áp dụng chuẩn hóa độ ồn EBU R128 cho track âm thanh. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-loudnorm \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12500000 } ``` ## Notes {#notes} * Dùng bộ lọc `loudnorm` của FFmpeg nhắm tới độ ồn tích hợp -16 LUFS với đỉnh thực -1.5 dBTP và dải độ ồn 11 LU (tiêu chuẩn phát sóng EBU R128). * Tốc độ lấy mẫu âm thanh nguồn được giữ nguyên ở đầu ra. * Nếu video không có track âm thanh, yêu cầu trả về lỗi 400. --- --- url: https://docs.snapotter.com/vi/tools/audio/convert-audio.md description: Chuyển đổi âm thanh giữa các định dạng MP3, WAV, OGG, FLAC và M4A. --- # Chuyển đổi âm thanh {#convert-audio} Chuyển đổi tệp âm thanh giữa các định dạng phổ biến gồm MP3, WAV, OGG, FLAC và M4A, với bitrate và tần số lấy mẫu đầu ra có thể cấu hình. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Chấp nhận dữ liệu form multipart với một tệp âm thanh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | format | string | Không | `"mp3"` | Định dạng đầu ra: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Không | `192` | Bitrate đầu ra tính bằng kbps (32 đến 320) | | sampleRate | integer | Không | tần số gốc | Tần số lấy mẫu đầu ra tính bằng Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` hoặc `96000`. Bỏ qua để giữ nguyên tần số gốc | ## Yêu cầu ví dụ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Phản hồi ví dụ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Ghi chú {#notes} * Các định dạng đầu vào được hỗ trợ gồm MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF và OPUS. * Bitrate chỉ áp dụng cho các định dạng mất dữ liệu (MP3, OGG, M4A). Các định dạng không mất dữ liệu như WAV và FLAC bỏ qua cài đặt này. * Đầu ra MP3 hỗ trợ tần số lấy mẫu tối đa 48000 Hz. Tùy chọn 96000 Hz chỉ áp dụng cho WAV, OGG, FLAC và M4A. * Bitrate MP3 bị giới hạn bởi tần số lấy mẫu: tối đa 64 kbps ở 8000 Hz và 160 kbps ở 16000 hoặc 22050 Hz. Các yêu cầu vượt quá giới hạn sẽ bị từ chối thay vì bị âm thầm hạ xuống. * Tên tệp đầu ra giữ tên gốc với phần mở rộng mới. --- --- url: https://docs.snapotter.com/vi/tools/image/convert.md description: >- Chuyển đổi ảnh giữa các định dạng bao gồm các định dạng hiện đại như AVIF, JXL và HEIC. --- # Chuyển đổi ảnh {#convert} Chuyển đổi ảnh giữa các định dạng. Hỗ trợ các định dạng web phổ biến cũng như các định dạng chuyên biệt như HEIC, JXL, BMP, ICO, JP2, QOI và PSD. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/convert` Chấp nhận dữ liệu form multipart với một tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | format | string | Có | - | Định dạng mục tiêu: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | Không | - | Chất lượng đầu ra (1-100). Áp dụng cho các định dạng có mất dữ liệu như jpg, webp, avif, heic. | ## Các định dạng đầu ra được hỗ trợ {#supported-output-formats} | Định dạng | Kiểu | Ghi chú | |--------|------|-------| | jpg | Mất dữ liệu | JPEG, tương thích tốt nhất | | png | Không mất dữ liệu | Hỗ trợ trong suốt | | webp | Cả hai | Định dạng web hiện đại, nén tốt | | avif | Mất dữ liệu | Định dạng thế hệ mới, nén xuất sắc | | tiff | Cả hai | Quy trình in ấn/xuất bản | | gif | Không mất dữ liệu | Giới hạn 256 màu | | heic / heif | Mất dữ liệu | Định dạng hệ sinh thái Apple | | jxl | Cả hai | JPEG XL, định dạng thế hệ mới | | bmp | Không mất dữ liệu | Bitmap không nén | | ico | Không mất dữ liệu | Định dạng biểu tượng Windows | | jp2 | Mất dữ liệu | JPEG 2000 | | qoi | Không mất dữ liệu | Định dạng Quite OK Image | | psd | Có lớp | Adobe Photoshop (cần ImageMagick) | | ppm | Không mất dữ liệu | Portable Pixmap (PPM/PGM/PBM) | | eps | Vector | Encapsulated PostScript | | tga | Không mất dữ liệu | Định dạng ảnh Targa | ## Ví dụ yêu cầu {#example-request} Chuyển đổi sang WebP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` Chuyển đổi sang PNG (không mất dữ liệu): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Ghi chú {#notes} * Phần mở rộng tên tệp đầu ra được tự động cập nhật để khớp với định dạng mục tiêu. * Đầu vào SVG được rasterize ở 300 DPI trước khi chuyển đổi. * Chuyển đổi PSD cần cài đặt ImageMagick trên máy chủ. * BMP, EPS, ICO, JP2, JXL, PPM, QOI và TGA dùng các bộ mã hóa CLI chuyên biệt và bỏ qua xử lý Sharp. * Mã hóa HEIC/HEIF sử dụng thư viện mã hóa HEIC của hệ thống. * Các định dạng đầu vào rất rộng: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, v.v.), PSD, SVG, BMP và nhiều hơn nữa. --- --- url: https://docs.snapotter.com/vi/tools/files/epub-convert.md description: Chuyển đổi một EPUB sang PDF, DOCX, HTML hoặc Markdown. --- # Chuyển đổi từ EPUB {#convert-epub} Chuyển đổi một sách điện tử EPUB sang PDF, Word (DOCX), HTML hoặc Markdown. Các tài nguyên từ xa bên trong sách không được tải về. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Nhận dữ liệu multipart form với một tệp EPUB và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Định dạng đầu ra: `pdf`, `docx`, `html`, `md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} Trả về `202 Accepted`. Theo dõi tiến trình qua SSE tại `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Định dạng đầu vào được chấp nhận: `.epub`. * Các tài nguyên từ xa nhúng trong EPUB (ảnh, phông chữ bên ngoài) không được tải về vì lý do bảo mật. * Độ trung thực của hình ảnh trong đầu ra đã chuyển đổi có thể khác nhau tùy theo cấu trúc EPUB. * Việc chuyển đổi được xử lý bởi Pandoc trên máy chủ. --- --- url: https://docs.snapotter.com/vi/tools/files/yaml-json.md description: Chuyển đổi giữa YAML và JSON, cả hai chiều. --- # Chuyển đổi YAML / JSON {#yaml-json} Chuyển đổi giữa các định dạng YAML và JSON theo cả hai chiều. Tải lên một tệp YAML để nhận JSON, hoặc tải lên một tệp JSON để nhận YAML. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/yaml-json` Chấp nhận dữ liệu biểu mẫu multipart với một tệp YAML hoặc JSON. Không cần trường settings. ## Parameters {#parameters} Công cụ này không có tham số nào có thể cấu hình. Chiều chuyển đổi được xác định bởi phần mở rộng của tệp đầu vào. ## Example Request {#example-request} YAML sang JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.yaml" ``` JSON sang YAML: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.json" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.json", "originalSize": 620, "processedSize": 780 } ``` ## Notes {#notes} * Chiều chuyển đổi được tự động phát hiện từ phần mở rộng của tệp đầu vào: `.yaml` hoặc `.yml` tạo ra `.json`, và `.json` tạo ra `.yaml`. * Cả hai phần mở rộng `.yaml` và `.yml` đều được chấp nhận. * Chỉ tài liệu đầu tiên trong một tệp YAML nhiều tài liệu được chuyển đổi; các tài liệu bổ sung được phân tách bởi `---` sẽ bị bỏ qua. --- --- url: https://docs.snapotter.com/hi/tools/image/circle-crop.md description: किसी छवि को पारदर्शी कोनों के साथ एक केंद्रित वृत्त में क्रॉप करें। --- # Circle Crop {#circle-crop} किसी छवि को पारदर्शी कोनों के साथ एक केंद्रित वृत्त में क्रॉप करें। समायोज्य ज़ूम, ऑफसेट, बॉर्डर, और आउटपुट आकार का समर्थन करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` एक छवि फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | zoom | number | No | `1` | ज़ूम कारक (1-5); उच्च मान अधिक कसकर क्रॉप करते हैं | | offsetX | number | No | `0.5` | क्षैतिज केंद्र स्थिति (0-1) | | offsetY | number | No | `0.5` | ऊर्ध्वाधर केंद्र स्थिति (0-1) | | borderWidth | integer | No | `0` | पिक्सेल में बॉर्डर चौड़ाई (0-200) | | borderColor | string | No | `"#ffffff"` | बॉर्डर हेक्स रंग | | background | string | No | `"transparent"` | कोना फिल: `"transparent"` या एक हेक्स रंग | | outputSize | integer | No | - | पिक्सेल में अंतिम वर्गाकार आयाम (16-4096) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notes {#notes} * पारदर्शी कोनों को संरक्षित करने के लिए आउटपुट हमेशा PNG होता है (जब तक `background` को एक ठोस रंग पर सेट न किया गया हो)। * वृत्त छवि के छोटे आयाम के भीतर अंकित होता है। अधिक कसकर क्रॉप करने के लिए `zoom` का उपयोग करें और दृश्य क्षेत्र को स्थानांतरित करने के लिए `offsetX`/`offsetY` का उपयोग करें। * जब `outputSize` प्रदान किया जाता है, तो क्रॉप करने के बाद परिणाम को उस वर्गाकार आयाम पर आकार बदला जाता है। * HEIC, RAW, PSD, और SVG इनपुट को प्रोसेसिंग से पहले स्वचालित रूप से डिकोड किया जाता है। --- --- url: https://docs.snapotter.com/ja/tools/image/circle-crop.md description: 画像を中央揃えの円形に切り抜き、四隅を透明にします。 --- # Circle Crop {#circle-crop} 画像を中央揃えの円形に切り抜き、四隅を透明にします。ズーム、オフセット、ボーダー、出力サイズを調整できます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` 画像ファイルと JSON の `settings` フィールドを含むマルチパートフォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | zoom | number | No | `1` | ズーム係数 (1 ~ 5)。値が大きいほど切り抜きが狭くなります | | offsetX | number | No | `0.5` | 中心の水平位置 (0 ~ 1) | | offsetY | number | No | `0.5` | 中心の垂直位置 (0 ~ 1) | | borderWidth | integer | No | `0` | ボーダーの幅 (ピクセル) (0 ~ 200) | | borderColor | string | No | `"#ffffff"` | ボーダーの 16 進カラー | | background | string | No | `"transparent"` | 四隅の塗りつぶし: `"transparent"` または 16 進カラー | | outputSize | integer | No | - | 最終的な正方形のサイズ (ピクセル) (16 ~ 4096) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notes {#notes} * 透明な四隅を保持するため、出力は常に PNG です (`background` が単色に設定されている場合を除く)。 * 円は画像の短い辺の内側に収まります。より狭く切り抜くには `zoom` を、表示領域をずらすには `offsetX`/`offsetY` を使用してください。 * `outputSize` を指定すると、切り抜き後にその正方形のサイズにリサイズされます。 * HEIC、RAW、PSD、SVG の入力は処理前に自動的にデコードされます。 --- --- url: https://docs.snapotter.com/ko/tools/image/circle-crop.md description: 이미지를 투명한 모서리를 가진 중앙 정렬된 원으로 자릅니다. --- # Circle Crop {#circle-crop} 이미지를 투명한 모서리를 가진 중앙 정렬된 원으로 자릅니다. 조정 가능한 확대/축소, 오프셋, 테두리, 출력 크기를 지원합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/circle-crop` 이미지 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | zoom | number | 아니요 | `1` | 확대 계수 (1-5); 값이 높을수록 더 좁게 자름 | | offsetX | number | 아니요 | `0.5` | 수평 중심 위치 (0-1) | | offsetY | number | 아니요 | `0.5` | 수직 중심 위치 (0-1) | | borderWidth | integer | 아니요 | `0` | 테두리 너비 픽셀 (0-200) | | borderColor | string | 아니요 | `"#ffffff"` | 테두리 16진수 색상 | | background | string | 아니요 | `"transparent"` | 모서리 채우기: `"transparent"` 또는 16진수 색상 | | outputSize | integer | 아니요 | - | 최종 정사각형 크기 픽셀 (16-4096) | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## 참고 사항 {#notes} * 투명한 모서리를 유지하기 위해 출력은 항상 PNG입니다(`background`이(가) 단색으로 설정된 경우 제외). * 원은 이미지의 짧은 쪽 안에 내접합니다. 더 좁게 자르려면 `zoom`을(를) 사용하고, 보이는 영역을 이동하려면 `offsetX`/`offsetY`을(를) 사용하세요. * `outputSize`이(가) 제공되면, 자르기 후 결과가 해당 정사각형 크기로 조정됩니다. * HEIC, RAW, PSD, SVG 입력은 처리 전에 자동으로 디코딩됩니다. --- --- url: https://docs.snapotter.com/th/tools/image/circle-crop.md description: ครอบตัดรูปภาพเป็นวงกลมที่อยู่กึ่งกลางพร้อมมุมโปร่งใส --- # Circle Crop {#circle-crop} ครอบตัดรูปภาพเป็นวงกลมที่อยู่กึ่งกลางพร้อมมุมโปร่งใส รองรับการปรับซูม, ระยะเยื้อง, ขอบ และขนาดเอาต์พุต ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` รับข้อมูลแบบ multipart form data พร้อมไฟล์รูปภาพและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | zoom | number | No | `1` | ปัจจัยการซูม (1-5); ค่าที่สูงกว่าจะครอบตัดแน่นขึ้น | | offsetX | number | No | `0.5` | ตำแหน่งกึ่งกลางแนวนอน (0-1) | | offsetY | number | No | `0.5` | ตำแหน่งกึ่งกลางแนวตั้ง (0-1) | | borderWidth | integer | No | `0` | ความกว้างของขอบเป็นพิกเซล (0-200) | | borderColor | string | No | `"#ffffff"` | สีขอบเป็น hex | | background | string | No | `"transparent"` | การเติมมุม: `"transparent"` หรือสี hex | | outputSize | integer | No | - | มิติสี่เหลี่ยมจัตุรัสสุดท้ายเป็นพิกเซล (16-4096) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notes {#notes} * เอาต์พุตเป็น PNG เสมอเพื่อรักษามุมโปร่งใส (เว้นแต่ `background` ถูกตั้งเป็นสีทึบ) * วงกลมถูกจารึกภายในมิติที่สั้นกว่าของรูปภาพ ใช้ `zoom` เพื่อครอบตัดแน่นขึ้น และ `offsetX`/`offsetY` เพื่อเลื่อนพื้นที่ที่มองเห็น * เมื่อระบุ `outputSize` ผลลัพธ์จะถูกปรับขนาดเป็นมิติสี่เหลี่ยมจัตุรัสนั้นหลังการครอบตัด * อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนประมวลผล --- --- url: https://docs.snapotter.com/vi/tools/image/circle-crop.md description: Cắt một hình ảnh thành một hình tròn được căn giữa với các góc trong suốt. --- # Circle Crop {#circle-crop} Cắt một hình ảnh thành một hình tròn được căn giữa với các góc trong suốt. Hỗ trợ thu phóng, độ lệch, viền và kích thước đầu ra có thể điều chỉnh. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` Chấp nhận dữ liệu biểu mẫu multipart với một tệp hình ảnh và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | zoom | number | No | `1` | Hệ số thu phóng (1-5); giá trị cao hơn cắt sát hơn | | offsetX | number | No | `0.5` | Vị trí tâm theo chiều ngang (0-1) | | offsetY | number | No | `0.5` | Vị trí tâm theo chiều dọc (0-1) | | borderWidth | integer | No | `0` | Độ rộng viền tính bằng pixel (0-200) | | borderColor | string | No | `"#ffffff"` | Màu hex của viền | | background | string | No | `"transparent"` | Lấp góc: `"transparent"` hoặc một màu hex | | outputSize | integer | No | - | Kích thước vuông cuối cùng tính bằng pixel (16-4096) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notes {#notes} * Đầu ra luôn là PNG để giữ các góc trong suốt (trừ khi `background` được đặt thành một màu đơn sắc). * Hình tròn được nội tiếp trong chiều ngắn hơn của hình ảnh. Dùng `zoom` để cắt sát hơn và `offsetX`/`offsetY` để dịch chuyển vùng hiển thị. * Khi `outputSize` được cung cấp, kết quả được đổi kích thước thành kích thước vuông đó sau khi cắt. * Các đầu vào HEIC, RAW, PSD và SVG được tự động giải mã trước khi xử lý. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/circle-crop.md description: 将图像裁剪为居中的圆形,四角透明。 --- # Circle Crop {#circle-crop} 将图像裁剪为居中的圆形,四角透明。支持可调的缩放、偏移、边框和输出尺寸。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` 接受包含图像文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | zoom | number | 否 | `1` | 缩放系数(1-5);值越高裁剪越紧 | | offsetX | number | 否 | `0.5` | 水平中心位置(0-1) | | offsetY | number | 否 | `0.5` | 垂直中心位置(0-1) | | borderWidth | integer | 否 | `0` | 边框宽度(像素,0-200) | | borderColor | string | 否 | `"#ffffff"` | 边框十六进制颜色 | | background | string | 否 | `"transparent"` | 四角填充:`"transparent"` 或十六进制颜色 | | outputSize | integer | 否 | - | 最终正方形尺寸(像素,16-4096) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notes {#notes} * 输出始终为 PNG 以保留透明的四角(除非 `background` 被设为纯色)。 * 圆形内切于图像较短的一边。使用 `zoom` 裁剪更紧,使用 `offsetX`/`offsetY` 平移可见区域。 * 当提供 `outputSize` 时,结果会在裁剪后调整为该正方形尺寸。 * HEIC、RAW、PSD 和 SVG 输入在处理前会自动解码。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/circle-crop.md description: 將影像裁切為置中的圓形,並讓四角透明。 --- # Circle Crop {#circle-crop} 將影像裁切為置中的圓形,並讓四角透明。支援可調整的縮放、偏移、邊框及輸出尺寸。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` 接受包含影像檔案及 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | zoom | number | No | `1` | 縮放係數(1-5);數值越高裁切越緊 | | offsetX | number | No | `0.5` | 水平中心位置(0-1) | | offsetY | number | No | `0.5` | 垂直中心位置(0-1) | | borderWidth | integer | No | `0` | 邊框寬度,以像素為單位(0-200) | | borderColor | string | No | `"#ffffff"` | 邊框十六進位色碼 | | background | string | No | `"transparent"` | 四角填充:`"transparent"` 或十六進位色碼 | | outputSize | integer | No | - | 最終方形尺寸,以像素為單位(16-4096) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notes {#notes} * 輸出一律為 PNG 以保留透明的四角(除非 `background` 設為純色)。 * 圓形會內接於影像較短的一邊。使用 `zoom` 裁切得更緊,並使用 `offsetX`/`offsetY` 移動可見區域。 * 當提供 `outputSize` 時,結果會在裁切後調整為該方形尺寸。 * HEIC、RAW、PSD 及 SVG 輸入會在處理前自動解碼。 --- --- url: https://docs.snapotter.com/sv/tools/image/circle-crop.md description: Beskär en bild till en centrerad cirkel med transparenta hörn. --- # Cirkelbeskärning {#circle-crop} Beskär en bild till en centrerad cirkel med transparenta hörn. Stöder justerbar zoom, förskjutning, kant och utdatastorlek. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/circle-crop` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | zoom | tal | Nej | `1` | Zoomfaktor (1-5); högre värden beskär tätare | | offsetX | tal | Nej | `0.5` | Horisontell mittposition (0-1) | | offsetY | tal | Nej | `0.5` | Vertikal mittposition (0-1) | | borderWidth | heltal | Nej | `0` | Kantbredd i pixlar (0-200) | | borderColor | sträng | Nej | `"#ffffff"` | Kantfärg i hex | | background | sträng | Nej | `"transparent"` | Hörnfyllnad: `"transparent"` eller en hex-färg | | outputSize | heltal | Nej | - | Slutlig kvadratisk dimension i pixlar (16-4096) | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Anteckningar {#notes} * Utdata är alltid PNG för att bevara de transparenta hörnen (om inte `background` är satt till en enfärgad färg). * Cirkeln inskrivs i bildens kortare dimension. Använd `zoom` för att beskära tätare och `offsetX`/`offsetY` för att flytta det synliga området. * När `outputSize` anges storleksanpassas resultatet till den kvadratiska dimensionen efter beskärningen. * HEIC-, RAW-, PSD- och SVG-indata avkodas automatiskt före bearbetning. --- --- url: https://docs.snapotter.com/nl/tools/image/circle-crop.md description: Snijd een afbeelding bij tot een gecentreerde cirkel met transparante hoeken. --- # Cirkelvormig bijsnijden {#circle-crop} Snijd een afbeelding bij tot een gecentreerde cirkel met transparante hoeken. Ondersteunt instelbare zoom, verschuiving, rand en uitvoergrootte. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/circle-crop` Accepteert multipart form data met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | zoom | number | Nee | `1` | Zoomfactor (1-5); hogere waarden snijden strakker bij | | offsetX | number | Nee | `0.5` | Horizontale middenpositie (0-1) | | offsetY | number | Nee | `0.5` | Verticale middenpositie (0-1) | | borderWidth | integer | Nee | `0` | Randbreedte in pixels (0-200) | | borderColor | string | Nee | `"#ffffff"` | Hex-kleur van de rand | | background | string | Nee | `"transparent"` | Hoekopvulling: `"transparent"` of een hex-kleur | | outputSize | integer | Nee | - | Uiteindelijke vierkante afmeting in pixels (16-4096) | ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Opmerkingen {#notes} * De uitvoer is altijd PNG om de transparante hoeken te behouden (tenzij `background` is ingesteld op een effen kleur). * De cirkel wordt ingeschreven binnen de kortste afmeting van de afbeelding. Gebruik `zoom` om strakker bij te snijden en `offsetX`/`offsetY` om het zichtbare gebied te verschuiven. * Wanneer `outputSize` is opgegeven, wordt het resultaat na het bijsnijden naar die vierkante afmeting geschaald. * HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór de verwerking. --- --- url: https://docs.snapotter.com/ar/tools/video/video-metadata.md description: إزالة البيانات الوصفية من الفيديو والإبلاغ عما عُثر عليه. --- # Clean Video Metadata {#clean-video-metadata} إزالة البيانات الوصفية (تاريخ الإنشاء، إحداثيات GPS، طراز الكاميرا، وسوم البرامج، إلخ) من الفيديو والإبلاغ عما أُزيل. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو. لا توجد إعدادات قابلة للتهيئة لهذه الأداة. ## Parameters {#parameters} لا توجد معلمات لهذه الأداة. تزيل جميع البيانات الوصفية من حاوية الفيديو. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * تشمل البيانات الوصفية المُزالة طوابع وقت الإنشاء، وبيانات GPS/الموقع، ومعلومات الكاميرا/الجهاز، ووسوم البرامج. * يُنسَخ تدفقا الفيديو والصوت دون إعادة ترميز، لذا لا يوجد فقد في الجودة. * مفيدة للخصوصية قبل مشاركة مقاطع الفيديو علناً. --- --- url: https://docs.snapotter.com/de/tools/video/video-metadata.md description: Metadaten aus einem Video entfernen und melden, was gefunden wurde. --- # Clean Video Metadata {#clean-video-metadata} Metadaten (Erstellungsdatum, GPS-Koordinaten, Kameramodell, Software-Tags usw.) aus einem Video entfernen und melden, was entfernt wurde. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Nimmt Multipart-Formulardaten mit einer Videodatei entgegen. Dieses Tool hat keine konfigurierbaren Einstellungen. ## Parameters {#parameters} Dieses Tool hat keine Parameter. Es entfernt alle Metadaten aus dem Videocontainer. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Zu den entfernten Metadaten gehören Erstellungszeitstempel, GPS-/Standortdaten, Kamera-/Geräteinformationen und Software-Tags. * Die Video- und Audiostreams werden ohne Neukodierung kopiert, sodass kein Qualitätsverlust auftritt. * Nützlich für den Datenschutz, bevor Videos öffentlich geteilt werden. --- --- url: https://docs.snapotter.com/es/tools/video/video-metadata.md description: Elimina los metadatos de un vídeo e informa de lo que se encontró. --- # Clean Video Metadata {#clean-video-metadata} Elimina los metadatos (fecha de creación, coordenadas GPS, modelo de cámara, etiquetas de software, etc.) de un vídeo e informa de lo que se eliminó. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Acepta datos de formulario multipart con un archivo de vídeo. Esta herramienta no tiene ajustes configurables. ## Parameters {#parameters} Esta herramienta no tiene parámetros. Elimina todos los metadatos del contenedor de vídeo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Los metadatos eliminados incluyen marcas de tiempo de creación, datos de GPS/ubicación, información de cámara/dispositivo y etiquetas de software. * Los flujos de vídeo y audio se copian sin recodificar, por lo que no hay pérdida de calidad. * Útil para la privacidad antes de compartir vídeos públicamente. --- --- url: https://docs.snapotter.com/fr/tools/video/video-metadata.md description: Supprime les métadonnées d'une vidéo et signale ce qui a été trouvé. --- # Clean Video Metadata {#clean-video-metadata} Supprime les métadonnées (date de création, coordonnées GPS, modèle d'appareil, balises logicielles, etc.) d'une vidéo et signale ce qui a été supprimé. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Accepte des données de formulaire multipart avec un fichier vidéo. Cet outil n'a aucun réglage configurable. ## Parameters {#parameters} Cet outil n'a aucun paramètre. Il supprime toutes les métadonnées du conteneur vidéo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Les métadonnées supprimées incluent les horodatages de création, les données GPS/de localisation, les informations sur l'appareil/le périphérique et les balises logicielles. * Les flux vidéo et audio sont copiés sans réencodage, il n'y a donc aucune perte de qualité. * Utile pour la confidentialité avant de partager des vidéos publiquement. --- --- url: https://docs.snapotter.com/hi/tools/video/video-metadata.md description: किसी वीडियो से मेटाडेटा हटाएँ और जो मिला उसकी रिपोर्ट दें। --- # Clean Video Metadata {#clean-video-metadata} किसी वीडियो से मेटाडेटा (निर्माण तिथि, GPS निर्देशांक, कैमरा मॉडल, सॉफ़्टवेयर टैग, आदि) हटाएँ और जो हटाया गया उसकी रिपोर्ट दें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` एक वीडियो फ़ाइल के साथ multipart form data स्वीकार करता है। इस टूल में कोई समायोज्य सेटिंग नहीं है। ## Parameters {#parameters} इस टूल में कोई पैरामीटर नहीं है। यह वीडियो कंटेनर से सभी मेटाडेटा हटा देता है। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * हटाए गए मेटाडेटा में निर्माण टाइमस्टैम्प, GPS/स्थान डेटा, कैमरा/डिवाइस जानकारी, और सॉफ़्टवेयर टैग शामिल हैं। * वीडियो और ऑडियो स्ट्रीम को फिर से एन्कोड किए बिना कॉपी किया जाता है, इसलिए कोई गुणवत्ता हानि नहीं होती। * वीडियो सार्वजनिक रूप से साझा करने से पहले गोपनीयता के लिए उपयोगी। --- --- url: https://docs.snapotter.com/id/tools/video/video-metadata.md description: Menghapus metadata dari sebuah video dan melaporkan apa yang ditemukan. --- # Clean Video Metadata {#clean-video-metadata} Menghapus metadata (tanggal pembuatan, koordinat GPS, model kamera, tag perangkat lunak, dll.) dari sebuah video dan melaporkan apa yang dihapus. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Menerima multipart form data dengan file video. Alat ini tidak memiliki pengaturan yang dapat dikonfigurasi. ## Parameters {#parameters} Alat ini tidak memiliki parameter. Ia menghapus semua metadata dari kontainer video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Metadata yang dihapus mencakup stempel waktu pembuatan, data GPS/lokasi, info kamera/perangkat, dan tag perangkat lunak. * Aliran video dan audio disalin tanpa enkoding ulang, jadi tidak ada kehilangan kualitas. * Berguna untuk privasi sebelum membagikan video secara publik. --- --- url: https://docs.snapotter.com/it/tools/video/video-metadata.md description: Rimuovi i metadati da un video e riporta cosa è stato trovato. --- # Clean Video Metadata {#clean-video-metadata} Rimuovi i metadati (data di creazione, coordinate GPS, modello della camera, tag software, ecc.) da un video e riporta cosa è stato rimosso. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Accetta dati form multipart con un file video. Questo strumento non ha impostazioni configurabili. ## Parameters {#parameters} Questo strumento non ha parametri. Rimuove tutti i metadati dal contenitore video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * I metadati rimossi includono i timestamp di creazione, i dati GPS/di posizione, le informazioni sulla camera/dispositivo e i tag software. * I flussi video e audio vengono copiati senza ricodifica, quindi non c'è perdita di qualità. * Utile per la privacy prima di condividere pubblicamente i video. --- --- url: https://docs.snapotter.com/ja/tools/video/video-metadata.md description: 動画からメタデータを取り除き、見つかった内容を報告します。 --- # Clean Video Metadata {#clean-video-metadata} 動画からメタデータ(作成日、GPS 座標、カメラモデル、ソフトウェアタグなど)を取り除き、削除された内容を報告します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` 動画ファイルを含む multipart フォームデータを受け付けます。このツールに設定可能な項目はありません。 ## Parameters {#parameters} このツールにパラメータはありません。動画コンテナからすべてのメタデータを取り除きます。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * 取り除かれるメタデータには、作成タイムスタンプ、GPS/位置情報、カメラ/デバイス情報、ソフトウェアタグが含まれます。 * 映像と音声のストリームは再エンコードせずにコピーされるため、品質の低下はありません。 * 動画を公開する前のプライバシー保護に役立ちます。 --- --- url: https://docs.snapotter.com/ko/tools/video/video-metadata.md description: 비디오에서 메타데이터를 제거하고 발견된 내용을 보고합니다. --- # Clean Video Metadata {#clean-video-metadata} 비디오에서 메타데이터(생성 날짜, GPS 좌표, 카메라 모델, 소프트웨어 태그 등)를 제거하고 제거된 내용을 보고합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` 비디오 파일이 담긴 multipart form data를 받습니다. 이 도구에는 구성 가능한 설정이 없습니다. ## Parameters {#parameters} 이 도구에는 매개변수가 없습니다. 비디오 컨테이너에서 모든 메타데이터를 제거합니다. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * 제거되는 메타데이터에는 생성 타임스탬프, GPS/위치 데이터, 카메라/기기 정보, 소프트웨어 태그가 포함됩니다. * 비디오와 오디오 스트림은 재인코딩 없이 복사되므로 품질 손실이 없습니다. * 비디오를 공개적으로 공유하기 전 개인정보 보호에 유용합니다. --- --- url: https://docs.snapotter.com/nl/tools/video/video-metadata.md description: Metadata uit een video verwijderen en rapporteren wat er is gevonden. --- # Clean Video Metadata {#clean-video-metadata} Verwijder metadata (aanmaakdatum, GPS-coördinaten, cameramodel, softwaretags, enz.) uit een video en rapporteer wat er is verwijderd. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Accepteert multipart form data met een videobestand. Deze tool heeft geen instelbare opties. ## Parameters {#parameters} Deze tool heeft geen parameters. Het verwijdert alle metadata uit de videocontainer. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Verwijderde metadata omvat aanmaaktijdstempels, GPS-/locatiegegevens, camera-/apparaatinfo en softwaretags. * Het beeld- en audiospoor worden gekopieerd zonder opnieuw te encoderen, dus er is geen kwaliteitsverlies. * Handig voor privacy voordat je video's openbaar deelt. --- --- url: https://docs.snapotter.com/pl/tools/video/video-metadata.md description: Usunięcie metadanych z wideo i raport, co zostało znalezione. --- # Clean Video Metadata {#clean-video-metadata} Usuwa metadane (datę utworzenia, współrzędne GPS, model kamery, znaczniki oprogramowania itp.) z wideo i raportuje, co zostało usunięte. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Przyjmuje dane formularza multipart z plikiem wideo. To narzędzie nie ma konfigurowalnych ustawień. ## Parameters {#parameters} To narzędzie nie ma parametrów. Usuwa wszystkie metadane z kontenera wideo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Usuwane metadane obejmują znaczniki czasu utworzenia, dane GPS/lokalizacji, informacje o kamerze/urządzeniu oraz znaczniki oprogramowania. * Strumienie wideo i audio są kopiowane bez ponownego kodowania, więc nie ma utraty jakości. * Przydatne do ochrony prywatności przed publicznym udostępnianiem filmów. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/video-metadata.md description: Remove metadados de um vídeo e informa o que foi encontrado. --- # Clean Video Metadata {#clean-video-metadata} Remove metadados (data de criação, coordenadas GPS, modelo da câmera, tags de software, etc.) de um vídeo e informa o que foi removido. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Aceita dados de formulário multipart com um arquivo de vídeo. Esta ferramenta não tem configurações ajustáveis. ## Parameters {#parameters} Esta ferramenta não tem parâmetros. Ela remove todos os metadados do contêiner do vídeo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Os metadados removidos incluem carimbos de data/hora de criação, dados de GPS/localização, informações da câmera/dispositivo e tags de software. * Os streams de vídeo e áudio são copiados sem recodificação, então não há perda de qualidade. * Útil para privacidade antes de compartilhar vídeos publicamente. --- --- url: https://docs.snapotter.com/ru/tools/video/video-metadata.md description: Удаление метаданных из видео и отчёт о найденном. --- # Clean Video Metadata {#clean-video-metadata} Удаление метаданных (даты создания, координат GPS, модели камеры, тегов программного обеспечения и т. д.) из видео и отчёт о том, что было удалено. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Принимает multipart form data с файлом видео. У этого инструмента нет настраиваемых параметров. ## Parameters {#parameters} У этого инструмента нет параметров. Он удаляет все метаданные из контейнера видео. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Удаляемые метаданные включают отметки времени создания, данные GPS/местоположения, сведения о камере/устройстве и теги программного обеспечения. * Видео- и аудиопотоки копируются без перекодирования, поэтому потери качества нет. * Полезно для конфиденциальности перед публичным распространением видео. --- --- url: https://docs.snapotter.com/th/tools/video/video-metadata.md description: ลบเมทาดาทาออกจากวิดีโอและรายงานสิ่งที่พบ --- # Clean Video Metadata {#clean-video-metadata} ลบเมทาดาทา (วันที่สร้าง พิกัด GPS รุ่นกล้อง แท็กซอฟต์แวร์ ฯลฯ) ออกจากวิดีโอและรายงานสิ่งที่ถูกลบ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอ เครื่องมือนี้ไม่มีการตั้งค่าที่กำหนดค่าได้ ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์ โดยจะลบเมทาดาทาทั้งหมดออกจากคอนเทนเนอร์วิดีโอ ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * เมทาดาทาที่ถูกลบรวมถึงเวลาที่สร้าง ข้อมูล GPS/ตำแหน่ง ข้อมูลกล้อง/อุปกรณ์ และแท็กซอฟต์แวร์ * สตรีมวิดีโอและเสียงจะถูกคัดลอกโดยไม่เข้ารหัสใหม่ จึงไม่มีการสูญเสียคุณภาพ * มีประโยชน์ต่อความเป็นส่วนตัวก่อนแชร์วิดีโอสู่สาธารณะ --- --- url: https://docs.snapotter.com/tr/tools/video/video-metadata.md description: Bir videodan meta verileri temizleyin ve neler bulunduğunu raporlayın. --- # Clean Video Metadata {#clean-video-metadata} Bir videodan meta verileri (oluşturma tarihi, GPS koordinatları, kamera modeli, yazılım etiketleri vb.) temizleyin ve nelerin kaldırıldığını raporlayın. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Bir video dosyası içeren multipart form data kabul eder. Bu aracın yapılandırılabilir ayarı yoktur. ## Parameters {#parameters} Bu aracın parametresi yoktur. Video konteynerinden tüm meta verileri temizler. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Temizlenen meta veriler; oluşturma zaman damgalarını, GPS/konum verilerini, kamera/cihaz bilgilerini ve yazılım etiketlerini içerir. * Video ve ses akışları yeniden kodlanmadan kopyalanır, bu yüzden kalite kaybı olmaz. * Videoları herkese açık paylaşmadan önce gizlilik için kullanışlıdır. --- --- url: https://docs.snapotter.com/uk/tools/video/video-metadata.md description: Видаляє метадані з відео та повідомляє, що було знайдено. --- # Clean Video Metadata {#clean-video-metadata} Видаляє метадані (дата створення, GPS-координати, модель камери, теги програмного забезпечення тощо) з відео та повідомляє, що було видалено. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Приймає дані форми multipart із відеофайлом. Цей інструмент не має налаштувань. ## Parameters {#parameters} Цей інструмент не має параметрів. Він видаляє всі метадані з відеоконтейнера. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Видалені метадані включають мітки часу створення, дані GPS/розташування, інформацію про камеру/пристрій і теги програмного забезпечення. * Відео- та аудіопотоки копіюються без перекодування, тому втрати якості немає. * Корисно для приватності перед публічним поширенням відео. --- --- url: https://docs.snapotter.com/vi/tools/video/video-metadata.md description: Xóa metadata khỏi video và báo cáo những gì đã tìm thấy. --- # Clean Video Metadata {#clean-video-metadata} Xóa metadata (ngày tạo, tọa độ GPS, model máy quay, thẻ phần mềm, v.v.) khỏi video và báo cáo những gì đã được xóa. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` Nhận multipart form data gồm một file video. Công cụ này không có cài đặt nào có thể cấu hình. ## Parameters {#parameters} Công cụ này không có tham số nào. Nó xóa toàn bộ metadata khỏi container video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * Metadata bị xóa bao gồm dấu thời gian tạo, dữ liệu GPS/vị trí, thông tin máy quay/thiết bị và thẻ phần mềm. * Các luồng video và âm thanh được sao chép mà không mã hóa lại, nên không có mất mát chất lượng. * Hữu ích cho quyền riêng tư trước khi chia sẻ video công khai. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/video-metadata.md description: 从视频中剥离元数据并报告发现的内容。 --- # Clean Video Metadata {#clean-video-metadata} 从视频中剥离元数据(创建日期、GPS 坐标、相机型号、软件标记等)并报告已移除的内容。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` 接受包含视频文件的 multipart 表单数据。此工具没有可配置的设置。 ## Parameters {#parameters} 此工具没有参数。它会从视频容器中剥离所有元数据。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * 被剥离的元数据包括创建时间戳、GPS/位置数据、相机/设备信息和软件标记。 * 视频流和音频流会被直接复制而不重新编码,因此没有质量损失。 * 在公开分享视频前有助于保护隐私。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/video-metadata.md description: 從影片中移除中繼資料,並回報找到的內容。 --- # Clean Video Metadata {#clean-video-metadata} 從影片中移除中繼資料(建立日期、GPS 座標、相機型號、軟體標籤等),並回報移除了哪些內容。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/video-metadata` 接受包含一個影片檔案的 multipart form data。此工具沒有可設定的選項。 ## Parameters {#parameters} 此工具沒有參數。它會移除影片容器中的所有中繼資料。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/video-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip_clean.mp4", "originalSize": 12500000, "processedSize": 12480000, "metadata": { "container": "mov,mp4,m4a,3gp,3g2,mj2", "durationS": 42.5, "bitrateKbps": 2350, "streams": [ { "type": "video", "codec": "h264", "width": 1920, "height": 1080 }, { "type": "audio", "codec": "aac", "sampleRate": 48000 } ] } } ``` ## Notes {#notes} * 移除的中繼資料包括建立時間戳記、GPS/位置資料、相機/裝置資訊和軟體標籤。 * 影片和音訊串流會直接複製而不重新編碼,因此不會有品質損失。 * 適用於在公開分享影片前保護隱私。 --- --- url: https://docs.snapotter.com/vi/guide/database.md description: >- Lược đồ cơ sở dữ liệu PostgreSQL, bảng, di trú và quy trình sao lưu cho SnapOtter. --- # Cơ sở dữ liệu {#database} SnapOtter sử dụng PostgreSQL 17 với [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) để lưu trữ dữ liệu bền vững. Lược đồ được định nghĩa trong `apps/api/src/db/schema.ts`. Kết nối được cấu hình qua biến môi trường `DATABASE_URL` (mặc định `postgres://snapotter:snapotter@postgres:5432/snapotter`). Trong Docker Compose, container Postgres lưu dữ liệu của nó trong volume có tên `SnapOtter-pgdata`. ## Bảng {#tables} ### users {#users} Lưu trữ các tài khoản người dùng. Được tạo tự động ở lần chạy đầu tiên từ `DEFAULT_USERNAME` và `DEFAULT_PASSWORD`. | Cột | Kiểu | Ghi chú | |---|---|---| | `id` | uuid | Khóa chính | | `username` | varchar | Duy nhất, bắt buộc | | `passwordHash` | varchar | Băm scrypt | | `role` | varchar | `admin`, `editor`, hoặc `user` | | `mustChangePassword` | boolean | Cờ buộc đặt lại mật khẩu | | `createdAt` | timestamp | Thời điểm tạo | | `updatedAt` | timestamp | Thời điểm cập nhật gần nhất | ### sessions {#sessions} Các phiên đăng nhập đang hoạt động. Mỗi hàng liên kết một token phiên với một người dùng. | Cột | Kiểu | Ghi chú | |---|---|---| | `id` | varchar | Khóa chính (token phiên) | | `userId` | uuid | Khóa ngoại tới `users.id` | | `expiresAt` | timestamp | Thời điểm hết hạn | | `createdAt` | timestamp | Thời điểm tạo | ### teams {#teams} Các nhóm để tổ chức người dùng. Quản trị viên có thể gán người dùng vào các nhóm. | Cột | Kiểu | Mô tả | |--------|------|-------------| | `id` | uuid | Khóa chính | | `name` | varchar (duy nhất, tối đa 50 ký tự) | Tên nhóm | | `createdAt` | timestamp | Thời điểm tạo | ### api\_keys {#api-keys} Các khóa API để truy cập lập trình. Khóa thô chỉ được hiển thị một lần khi tạo; chỉ giá trị băm được lưu trữ. | Cột | Kiểu | Ghi chú | |---|---|---| | `id` | uuid | Khóa chính | | `userId` | uuid | Khóa ngoại tới `users.id` | | `keyHash` | varchar | Băm scrypt của khóa | | `name` | varchar | Nhãn do người dùng cung cấp | | `createdAt` | timestamp | Thời điểm tạo | | `lastUsedAt` | timestamp | Được cập nhật ở mỗi yêu cầu đã xác thực | Các khóa có tiền tố `si_` theo sau bởi 96 ký tự hex (48 byte ngẫu nhiên). ### pipelines {#pipelines} Các chuỗi công cụ đã lưu mà người dùng tạo trong giao diện. | Cột | Kiểu | Ghi chú | |---|---|---| | `id` | uuid | Khóa chính | | `name` | varchar | Tên pipeline | | `description` | varchar | Mô tả tùy chọn | | `steps` | jsonb | Mảng các đối tượng `{ toolId, settings }` | | `createdAt` | timestamp | Thời điểm tạo | ### user\_files {#user-files} Thư viện tệp bền vững. Theo mặc định, một chỉnh sửa đã lưu được chèn vào như một hàng gốc độc lập («lưu thành tệp mới»: `version` 1, `parentId` null, nên tệp gốc vẫn được liệt kê), hoặc như một phiên bản liên kết với tệp cha khi bạn ghi đè lên tệp gốc (`parentId` được đặt, `version` tăng lên, thay thế nó). Cột `toolChain` ghi lại các công cụ đã áp dụng. | Cột | Kiểu | Mô tả | |--------|------|-------------| | `id` | uuid | Khóa chính | | `userId` | uuid | FK tới users (CASCADE DELETE) | | `originalName` | varchar | Tên tệp tải lên gốc | | `storedName` | varchar | Tên tệp trên đĩa | | `mimeType` | varchar | Kiểu MIME | | `size` | integer | Kích thước tệp tính bằng byte | | `width` | integer | Chiều rộng ảnh tính bằng px | | `height` | integer | Chiều cao ảnh tính bằng px | | `version` | integer | Số phiên bản (1 = bản gốc) | | `parentId` | uuid hoặc null | FK tới user\_files (phiên bản cha) | | `toolChain` | jsonb | Các ID công cụ được áp dụng theo thứ tự để tạo ra phiên bản này | | `createdAt` | timestamp | Thời điểm tạo | ### jobs {#jobs} Theo dõi các tác vụ xử lý để báo cáo tiến độ và dọn dẹp. | Cột | Kiểu | Ghi chú | |---|---|---| | `id` | uuid | Khóa chính | | `type` | varchar | Định danh công cụ hoặc pipeline | | `status` | varchar | `queued`, `processing`, `completed`, hoặc `failed` | | `progress` | real | Phân số 0.0-1.0 | | `inputFiles` | jsonb | Mảng các đường dẫn tệp đầu vào | | `outputPath` | varchar | Đường dẫn tới tệp kết quả | | `settings` | jsonb | Các thiết lập công cụ đã sử dụng | | `error` | varchar | Thông báo lỗi nếu thất bại | | `createdAt` | timestamp | Thời điểm tạo | | `completedAt` | timestamp | Thời điểm hoàn thành | ### settings {#settings} Kho lưu trữ khóa-giá trị cho các thiết lập phạm vi toàn máy chủ mà quản trị viên có thể thay đổi từ giao diện. | Cột | Kiểu | Ghi chú | |---|---|---| | `key` | varchar | Khóa chính | | `value` | varchar | Giá trị thiết lập | | `updatedAt` | timestamp | Thời điểm cập nhật gần nhất | ### roles {#roles} Các vai trò tùy chỉnh với quyền chi tiết. | Cột | Kiểu | Ghi chú | |---|---|---| | `id` | uuid | Khóa chính | | `name` | varchar | Tên vai trò duy nhất | | `description` | varchar | Mô tả tùy chọn | | `permissions` | jsonb | Mảng các chuỗi quyền | | `createdAt` | timestamp | Thời điểm tạo | ### audit\_log {#audit-log} Nhật ký các hành động liên quan đến bảo mật. | Cột | Kiểu | Ghi chú | |---|---|---| | `id` | uuid | Khóa chính | | `userId` | uuid | FK tới users | | `action` | varchar | Loại hành động | | `details` | jsonb | Dữ liệu riêng cho hành động | | `createdAt` | timestamp | Thời điểm hành động | ### user\_preferences {#user-preferences} Trạng thái giao diện của từng người dùng, lấy tên thiết lập làm khóa. Lưu các công cụ đã ghim trên trang chủ, được ghi qua `PUT /api/v1/preferences`. | Cột | Kiểu | Ghi chú | |---|---|---| | `userId` | text | FK tới users, xóa theo tầng. Khóa chính cùng với `key` | | `key` | text | Tên thiết lập. Khóa chính cùng với `userId` | | `value` | jsonb | Nội dung thiết lập | | `updatedAt` | timestamp | Lần ghi gần nhất | ## Di trú {#migrations} Drizzle xử lý việc di trú lược đồ. Các tệp di trú nằm trong `apps/api/drizzle/`. Trong quá trình phát triển: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Trong môi trường sản xuất, các di trú đang chờ được áp dụng tự động khi khởi động. ## Sao lưu và khôi phục {#backup-and-restore} Cơ sở dữ liệu quan hệ nằm trong ổ `SnapOtter-pgdata` của vùng chứa Postgres chứ không phải ổ `/data` của ứng dụng. **Sao lưu hợp lý có xác thực (được khuyến nghị)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Kết xuất cơ sở dữ liệu này không chứa các đối tượng thư viện đã lưu ở `/data/files` hoặc trạng thái BullMQ bền vững trong Redis. Sao lưu và khôi phục chúng bằng quy trình phối hợp trong [Bảo mật & tăng cường](/vi/guide/security#backup-and-recovery). **Ảnh chụp nhanh khối lượng lạnh** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Không sao chép thư mục dữ liệu PostgreSQL trực tiếp bằng `tar`. Soạn tiền tố tên tập đĩa theo dự án, do đó hãy phân giải ID tập đĩa được gắn từ `docker inspect` hoặc nền tảng lưu trữ của bạn thay vì giả định nhãn bằng chữ `SnapOtter-pgdata`. ### Di trú từ 1.x (SQLite) {#migrating-from-1-x-sqlite} Nâng cấp từ SnapOtter 1.x có hướng dẫn riêng: xem [Nâng cấp từ 1.x lên 2.0](./upgrading). Nói ngắn gọn, hãy tái sử dụng volume `/data` hiện có của bạn và 2.0 sẽ tự động phát hiện và nhập `/data/snapotter.db` ở lần khởi động đầu tiên (hoặc đặt `SQLITE_MIGRATE_PATH` để trỏ tới nó một cách tường minh). Hãy sao lưu toàn bộ volume `/data` trước, không chỉ `snapotter.db`: 1.x dùng chế độ SQLite WAL, nên một container đã dừng thường để lại phần lớn dữ liệu của nó trong `snapotter.db-wal` bên cạnh một `snapotter.db` gần như rỗng. --- --- url: https://docs.snapotter.com/pl/guide/telemetry.md description: >- Jakie anonimowe dane o użyciu zbiera SnapOtter, kiedy są wysyłane i jak wyłączyć analitykę produktową dla całej instancji. --- # Co zbiera SnapOtter {#what-snapotter-collects} Anonimowa analityka produktowa jest domyślnie włączona i ustawiana dla całej instancji przez administratora. Wyłącz ją w Ustawienia > System > Prywatność. ## Zdarzenia, które wysyłamy (gdy włączone) {#events-we-send-when-enabled} * tool\_used: id narzędzia, status, czas trwania, kategoria, czy jest to narzędzie AI, kod błędu przy niepowodzeniu. * pipeline\_executed: liczba kroków, id narzędzi, flaga wsadu, liczba plików, czas trwania, status. * ai\_bundle\_action: id pakietu, akcja, czas trwania. * Użycie frontendu: które strony narzędzi się otwierają, dodane pliki (tylko liczby), uruchomione narzędzie, pobrania, zapisy, wyszukiwanie (tylko liczba wyników), przetwarzanie wsadowe. * Raporty o awariach: typ błędu i stos źródłowy zawierający wyłącznie podstawowe nazwy plików. ## Czego nigdy nie zbieramy {#what-we-never-collect} * Nazw ani ścieżek plików * Zawartości plików * Tekstu wyjściowego OCR * Metadanych obrazów (EXIF) * Wyodrębnionego tekstu dokumentów * Twojego adresu IP ani tożsamości konta ## Wyłączanie {#turning-it-off} Administratorzy: Ustawienia > System > Prywatność, przełącz "Anonimowa analityka produktowa" na wyłączone. Zatrzymuje się natychmiast, dla całej instancji. Aby zbudować obraz, który nigdy nie może niczego wysyłać, ustaw argument budowania `SNAPOTTER_ANALYTICS=off`. --- --- url: https://docs.snapotter.com/de/tools/image/collage.md description: >- Kombiniert mehrere Bilder zu Rastercollagen mit über 25 Vorlagen, einstellbaren Abständen und Ecken sowie Schwenken und Zoomen pro Zelle. --- # Collage & Raster {#collage-grid} Kombiniert mehrere Bilder zu ansprechenden Rastercollagen mit über 25 Vorlagen. Unterstützt Layouts für 2 bis 9 Bilder mit anpassbarem Abstand, Eckenradius, Hintergrundfarbe sowie Schwenk-/Zoom-Steuerung pro Zelle. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | templateId | string | Ja | - | ID des Vorlagenlayouts (z. B. `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | Nein | - | Array mit Einstellungen pro Zelle mit `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Ja | - | Index des Bildes, das in diese Zelle platziert wird (0-basiert) | | cells\[].panX | number | Nein | 0 | Horizontaler Schwenkversatz (-100 bis 100) | | cells\[].panY | number | Nein | 0 | Vertikaler Schwenkversatz (-100 bis 100) | | cells\[].zoom | number | Nein | 1 | Zoomstufe (1 bis 10) | | cells\[].objectFit | string | Nein | `"cover"` | Wie das Bild die Zelle ausfüllt: `cover` oder `contain` | | gap | number | Nein | 8 | Abstand zwischen den Zellen in Pixeln (0 bis 500) | | cornerRadius | number | Nein | 0 | Eckenradius jeder Zelle in Pixeln (0 bis 500) | | backgroundColor | string | Nein | `"#FFFFFF"` | Hintergrundfarbe als Hex-Wert oder `"transparent"` | | aspectRatio | string | Nein | `"free"` | Seitenverhältnis der Leinwand: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | Nein | `"png"` | Ausgabeformat: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Nein | 90 | Ausgabequalität (1 bis 100) | ## Verfügbare Vorlagen {#available-templates} | Vorlagen-ID | Bilder | Layout | |-------------|--------|--------| | `2-h-equal` | 2 | Zwei gleich große Spalten | | `2-v-equal` | 2 | Zwei gleich große Zeilen | | `2-h-left-large` | 2 | Links 2/3, rechts 1/3 | | `2-h-right-large` | 2 | Links 1/3, rechts 2/3 | | `3-left-large` | 3 | Groß links, zwei gestapelt rechts | | `3-right-large` | 3 | Zwei gestapelt links, groß rechts | | `3-top-large` | 3 | Groß oben, zwei Spalten unten | | `3-h-equal` | 3 | Drei gleich große Spalten | | `3-v-equal` | 3 | Drei gleich große Zeilen | | `4-grid` | 4 | 2x2-Raster | | `4-left-large` | 4 | Groß links, drei gestapelt rechts | | `4-top-large` | 4 | Groß oben, drei Spalten unten | | `4-bottom-large` | 4 | Drei Spalten oben, groß unten | | `5-top2-bottom3` | 5 | Zwei oben, drei unten | | `5-top3-bottom2` | 5 | Drei oben, zwei unten | | `5-left-large` | 5 | Groß links, vier gestapelt rechts | | `5-center-large` | 5 | Groß in der Mitte, vier Ecken | | `6-grid-2x3` | 6 | 2 Spalten x 3 Zeilen | | `6-grid-3x2` | 6 | 3 Spalten x 2 Zeilen | | `6-top-large` | 6 | Groß oben, fünf Spalten unten | | `7-mosaic` | 7 | Mosaiklayout | | `8-mosaic` | 8 | Mosaiklayout | | `9-grid` | 9 | 3x3-Raster | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Hinweise {#notes} * Laden Sie mehrere Bilddateien in der Multipart-Anfrage hoch. Die Bilder werden den Vorlagenzellen in der Reihenfolge des Hochladens zugewiesen. * Werden mehr Bilder hochgeladen, als die Vorlage unterstützt, werden die überzähligen Bilder ignoriert. * Unterstützt HEIC-, RAW-, PSD- und SVG-Eingabeformate (werden automatisch dekodiert). * Die Basisgröße der Leinwand beträgt 2400 px an der längsten Seite und wird anhand des gewählten Seitenverhältnisses skaliert. * Wenn `aspectRatio` `"free"` ist, verwendet die Leinwand standardmäßig 4:3 (2400x1800). * Die Werte `panX`/`panY` pro Zelle verschieben das Zuschneidefenster innerhalb der Zelle. Ein Wert von 100 verschiebt vollständig zu einer Kante, -100 zur anderen. * Die Hintergrundfarbe `"transparent"` bleibt nur bei den Ausgabeformaten `png`, `webp` oder `avif` erhalten. --- --- url: https://docs.snapotter.com/nl/tools/image/collage.md description: >- Combineer meerdere afbeeldingen tot rastercollages met meer dan 25 sjablonen, aanpasbare tussenruimtes en hoeken, en pannen en zoomen per cel. --- # Collage & Raster {#collage-grid} Combineer meerdere afbeeldingen tot fraaie rastercollages met meer dan 25 sjablonen. Ondersteunt lay-outs van 2 tot 9 afbeeldingen met aanpasbare tussenruimte, hoekstraal, achtergrondkleur en pan/zoom-instellingen per cel. ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | templateId | string | Ja | - | Sjabloonlay-out-ID (bijv. `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | Nee | - | Array met instellingen per cel met `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Ja | - | Index van de afbeelding die in deze cel wordt geplaatst (0-gebaseerd) | | cells\[].panX | number | Nee | 0 | Horizontale pan-offset (-100 tot 100) | | cells\[].panY | number | Nee | 0 | Verticale pan-offset (-100 tot 100) | | cells\[].zoom | number | Nee | 1 | Zoomniveau (1 tot 10) | | cells\[].objectFit | string | Nee | `"cover"` | Hoe de afbeelding de cel vult: `cover` of `contain` | | gap | number | Nee | 8 | Tussenruimte tussen cellen in pixels (0 tot 500) | | cornerRadius | number | Nee | 0 | Hoekstraal voor elke cel in pixels (0 tot 500) | | backgroundColor | string | Nee | `"#FFFFFF"` | Achtergrondkleur als hex of `"transparent"` | | aspectRatio | string | Nee | `"free"` | Beeldverhouding van het canvas: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | Nee | `"png"` | Uitvoerformaat: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Nee | 90 | Uitvoerkwaliteit (1 tot 100) | ## Beschikbare sjablonen {#available-templates} | Sjabloon-ID | Afbeeldingen | Lay-out | |-------------|--------|--------| | `2-h-equal` | 2 | Twee gelijke kolommen | | `2-v-equal` | 2 | Twee gelijke rijen | | `2-h-left-large` | 2 | Links 2/3, rechts 1/3 | | `2-h-right-large` | 2 | Links 1/3, rechts 2/3 | | `3-left-large` | 3 | Groot links, twee gestapeld rechts | | `3-right-large` | 3 | Twee gestapeld links, groot rechts | | `3-top-large` | 3 | Groot boven, twee kolommen onder | | `3-h-equal` | 3 | Drie gelijke kolommen | | `3-v-equal` | 3 | Drie gelijke rijen | | `4-grid` | 4 | 2x2-raster | | `4-left-large` | 4 | Groot links, drie gestapeld rechts | | `4-top-large` | 4 | Groot boven, drie kolommen onder | | `4-bottom-large` | 4 | Drie kolommen boven, groot onder | | `5-top2-bottom3` | 5 | Twee boven, drie onder | | `5-top3-bottom2` | 5 | Drie boven, twee onder | | `5-left-large` | 5 | Groot links, vier gestapeld rechts | | `5-center-large` | 5 | Groot in het midden, vier hoeken | | `6-grid-2x3` | 6 | 2 kolommen x 3 rijen | | `6-grid-3x2` | 6 | 3 kolommen x 2 rijen | | `6-top-large` | 6 | Groot boven, vijf kolommen onder | | `7-mosaic` | 7 | Mozaïeklay-out | | `8-mosaic` | 8 | Mozaïeklay-out | | `9-grid` | 9 | 3x3-raster | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Opmerkingen {#notes} * Upload meerdere afbeeldingsbestanden in het multipart-verzoek. De afbeeldingen worden in uploadvolgorde aan de sjablooncellen toegewezen. * Als er meer afbeeldingen worden geüpload dan het sjabloon ondersteunt, worden de extra afbeeldingen genegeerd. * Ondersteunt HEIC-, RAW-, PSD- en SVG-invoerformaten (automatisch gedecodeerd). * De basisgrootte van het canvas is 2400px aan de langste zijde, geschaald op basis van de gekozen beeldverhouding. * Als `aspectRatio` `"free"` is, staat het canvas standaard op 4:3 (2400x1800). * De `panX`/`panY`-waarden per cel verschuiven het uitsnijvenster binnen de cel. Een waarde van 100 verplaatst volledig naar de ene rand, -100 naar de andere. * De `"transparent"`-achtergrondkleur blijft alleen behouden bij de uitvoerformaten `png`, `webp` of `avif`. --- --- url: https://docs.snapotter.com/sv/tools/image/collage.md description: >- Kombinera flera bilder till rutnätscollage med 25+ mallar, justerbara mellanrum och hörn samt panorering och zoom per cell. --- # Collage & Rutnät {#collage-grid} Kombinera flera bilder till snygga rutnätscollage med 25+ mallar. Stöder layouter för 2-9 bilder med anpassningsbart mellanrum, hörnradie, bakgrundsfärg och kontroller för panorering/zoom per cell. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | templateId | string | Ja | - | Mallens layout-ID (t.ex. `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | Nej | - | Array med inställningar per cell med `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Ja | - | Index för bilden som ska placeras i denna cell (0-baserat) | | cells\[].panX | number | Nej | 0 | Horisontell panoreringsförskjutning (-100 till 100) | | cells\[].panY | number | Nej | 0 | Vertikal panoreringsförskjutning (-100 till 100) | | cells\[].zoom | number | Nej | 1 | Zoomnivå (1 till 10) | | cells\[].objectFit | string | Nej | `"cover"` | Hur bilden fyller cellen: `cover` eller `contain` | | gap | number | Nej | 8 | Mellanrum mellan celler i pixlar (0 till 500) | | cornerRadius | number | Nej | 0 | Hörnradie för varje cell i pixlar (0 till 500) | | backgroundColor | string | Nej | `"#FFFFFF"` | Bakgrundsfärg som hex eller `"transparent"` | | aspectRatio | string | Nej | `"free"` | Ritytans bildförhållande: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | Nej | `"png"` | Utdataformat: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Nej | 90 | Utdatakvalitet (1 till 100) | ## Tillgängliga mallar {#available-templates} | Mall-ID | Bilder | Layout | |-------------|--------|--------| | `2-h-equal` | 2 | Två lika kolumner | | `2-v-equal` | 2 | Två lika rader | | `2-h-left-large` | 2 | Vänster 2/3, höger 1/3 | | `2-h-right-large` | 2 | Vänster 1/3, höger 2/3 | | `3-left-large` | 3 | Stor till vänster, två staplade till höger | | `3-right-large` | 3 | Två staplade till vänster, stor till höger | | `3-top-large` | 3 | Stor upptill, två kolumner nedtill | | `3-h-equal` | 3 | Tre lika kolumner | | `3-v-equal` | 3 | Tre lika rader | | `4-grid` | 4 | 2x2-rutnät | | `4-left-large` | 4 | Stor till vänster, tre staplade till höger | | `4-top-large` | 4 | Stor upptill, tre kolumner nedtill | | `4-bottom-large` | 4 | Tre kolumner upptill, stor nedtill | | `5-top2-bottom3` | 5 | Två upptill, tre nedtill | | `5-top3-bottom2` | 5 | Tre upptill, två nedtill | | `5-left-large` | 5 | Stor till vänster, fyra staplade till höger | | `5-center-large` | 5 | Stor i mitten, fyra i hörnen | | `6-grid-2x3` | 6 | 2 kolumner x 3 rader | | `6-grid-3x2` | 6 | 3 kolumner x 2 rader | | `6-top-large` | 6 | Stor upptill, fem kolumner nedtill | | `7-mosaic` | 7 | Mosaiklayout | | `8-mosaic` | 8 | Mosaiklayout | | `9-grid` | 9 | 3x3-rutnät | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Anteckningar {#notes} * Ladda upp flera bildfiler i multipart-begäran. Bilderna tilldelas mallcellerna i uppladdningsordning. * Om fler bilder laddas upp än vad mallen stöder ignoreras de extra bilderna. * Stöder indataformaten HEIC, RAW, PSD och SVG (avkodas automatiskt). * Ritytans basstorlek är 2400px på den längsta sidan, skalad efter valt bildförhållande. * När `aspectRatio` är `"free"` blir ritytan som standard 4:3 (2400x1800). * Värden för `panX`/`panY` per cell förskjuter beskärningsfönstret inom cellen. Värdet 100 flyttar helt till en kant, -100 till den andra. * Bakgrundsfärgen `"transparent"` bevaras endast med utdataformaten `png`, `webp` eller `avif`. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/collage.md description: >- Combine várias imagens em colagens em grade com mais de 25 modelos, espaçamentos e cantos ajustáveis, além de deslocamento e zoom por célula. --- # Collage e Grade {#collage-grid} Combine várias imagens em colagens em grade com mais de 25 modelos. Suporta layouts de 2 a 9 imagens com espaçamento, raio de canto, cor de fundo e controles de deslocamento/zoom por célula personalizáveis. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | templateId | string | Sim | - | ID do layout do modelo (ex.: `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | Não | - | Array de configurações por célula com `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Sim | - | Índice da imagem a colocar nesta célula (baseado em 0) | | cells\[].panX | number | Não | 0 | Deslocamento horizontal (-100 a 100) | | cells\[].panY | number | Não | 0 | Deslocamento vertical (-100 a 100) | | cells\[].zoom | number | Não | 1 | Nível de zoom (1 a 10) | | cells\[].objectFit | string | Não | `"cover"` | Como a imagem preenche a célula: `cover` ou `contain` | | gap | number | Não | 8 | Espaçamento entre células em pixels (0 a 500) | | cornerRadius | number | Não | 0 | Raio de canto de cada célula em pixels (0 a 500) | | backgroundColor | string | Não | `"#FFFFFF"` | Cor de fundo em hexadecimal ou `"transparent"` | | aspectRatio | string | Não | `"free"` | Proporção do canvas: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | Não | `"png"` | Formato de saída: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Não | 90 | Qualidade de saída (1 a 100) | ## Modelos Disponíveis {#available-templates} | ID do Modelo | Imagens | Layout | |-------------|--------|--------| | `2-h-equal` | 2 | Duas colunas iguais | | `2-v-equal` | 2 | Duas linhas iguais | | `2-h-left-large` | 2 | Esquerda 2/3, direita 1/3 | | `2-h-right-large` | 2 | Esquerda 1/3, direita 2/3 | | `3-left-large` | 3 | Grande à esquerda, duas empilhadas à direita | | `3-right-large` | 3 | Duas empilhadas à esquerda, grande à direita | | `3-top-large` | 3 | Grande no topo, duas colunas embaixo | | `3-h-equal` | 3 | Três colunas iguais | | `3-v-equal` | 3 | Três linhas iguais | | `4-grid` | 4 | Grade 2x2 | | `4-left-large` | 4 | Grande à esquerda, três empilhadas à direita | | `4-top-large` | 4 | Grande no topo, três colunas embaixo | | `4-bottom-large` | 4 | Três colunas no topo, grande embaixo | | `5-top2-bottom3` | 5 | Duas no topo, três embaixo | | `5-top3-bottom2` | 5 | Três no topo, duas embaixo | | `5-left-large` | 5 | Grande à esquerda, quatro empilhadas à direita | | `5-center-large` | 5 | Grande ao centro, quatro nos cantos | | `6-grid-2x3` | 6 | 2 colunas x 3 linhas | | `6-grid-3x2` | 6 | 3 colunas x 2 linhas | | `6-top-large` | 6 | Grande no topo, cinco colunas embaixo | | `7-mosaic` | 7 | Layout mosaico | | `8-mosaic` | 8 | Layout mosaico | | `9-grid` | 9 | Grade 3x3 | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Notas {#notes} * Envie vários arquivos de imagem na requisição multipart. As imagens são atribuídas às células do modelo na ordem de upload. * Se forem enviadas mais imagens do que o modelo suporta, as imagens extras são ignoradas. * Suporta os formatos de entrada HEIC, RAW, PSD e SVG (decodificados automaticamente). * O tamanho base do canvas é de 2400px no lado mais longo, escalado conforme a proporção escolhida. * Quando `aspectRatio` é `"free"`, o canvas assume 4:3 por padrão (2400x1800). * Os valores de `panX`/`panY` por célula deslocam a janela de recorte dentro da célula. Um valor de 100 move totalmente para uma borda, -100 para a outra. * A cor de fundo `"transparent"` só é preservada com os formatos de saída `png`, `webp` ou `avif`. --- --- url: https://docs.snapotter.com/it/tools/image/collage.md description: >- Combina più immagini in collage a griglia con oltre 25 modelli, spazi e angoli regolabili e pan e zoom per singola cella. --- # Collage e griglia {#collage-grid} Combina più immagini in bellissimi collage a griglia con oltre 25 modelli. Supporta layout da 2 a 9 immagini con spazio, raggio degli angoli, colore di sfondo e controlli di pan/zoom per singola cella personalizzabili. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | templateId | string | Sì | - | ID del layout del modello (es. `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | No | - | Array di impostazioni per singola cella con `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Sì | - | Indice dell'immagine da inserire in questa cella (in base 0) | | cells\[].panX | number | No | 0 | Offset di pan orizzontale (da -100 a 100) | | cells\[].panY | number | No | 0 | Offset di pan verticale (da -100 a 100) | | cells\[].zoom | number | No | 1 | Livello di zoom (da 1 a 10) | | cells\[].objectFit | string | No | `"cover"` | Come l'immagine riempie la cella: `cover` o `contain` | | gap | number | No | 8 | Spazio tra le celle in pixel (da 0 a 500) | | cornerRadius | number | No | 0 | Raggio degli angoli per ogni cella in pixel (da 0 a 500) | | backgroundColor | string | No | `"#FFFFFF"` | Colore di sfondo come esadecimale o `"transparent"` | | aspectRatio | string | No | `"free"` | Proporzioni della tela: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | No | `"png"` | Formato di output: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Qualità di output (da 1 a 100) | ## Modelli disponibili {#available-templates} | ID modello | Immagini | Layout | |-------------|--------|--------| | `2-h-equal` | 2 | Due colonne uguali | | `2-v-equal` | 2 | Due righe uguali | | `2-h-left-large` | 2 | Sinistra 2/3, destra 1/3 | | `2-h-right-large` | 2 | Sinistra 1/3, destra 2/3 | | `3-left-large` | 3 | Grande a sinistra, due impilate a destra | | `3-right-large` | 3 | Due impilate a sinistra, grande a destra | | `3-top-large` | 3 | Grande in alto, due colonne in basso | | `3-h-equal` | 3 | Tre colonne uguali | | `3-v-equal` | 3 | Tre righe uguali | | `4-grid` | 4 | Griglia 2x2 | | `4-left-large` | 4 | Grande a sinistra, tre impilate a destra | | `4-top-large` | 4 | Grande in alto, tre colonne in basso | | `4-bottom-large` | 4 | Tre colonne in alto, grande in basso | | `5-top2-bottom3` | 5 | Due in alto, tre in basso | | `5-top3-bottom2` | 5 | Tre in alto, due in basso | | `5-left-large` | 5 | Grande a sinistra, quattro impilate a destra | | `5-center-large` | 5 | Grande al centro, quattro agli angoli | | `6-grid-2x3` | 6 | 2 colonne x 3 righe | | `6-grid-3x2` | 6 | 3 colonne x 2 righe | | `6-top-large` | 6 | Grande in alto, cinque colonne in basso | | `7-mosaic` | 7 | Layout a mosaico | | `8-mosaic` | 8 | Layout a mosaico | | `9-grid` | 9 | Griglia 3x3 | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Note {#notes} * Carica più file immagine nella richiesta multipart. Le immagini vengono assegnate alle celle del modello nell'ordine di caricamento. * Se vengono caricate più immagini di quante il modello ne supporti, le immagini in eccesso vengono ignorate. * Supporta i formati di input HEIC, RAW, PSD e SVG (decodificati automaticamente). * La dimensione base della tela è di 2400px sul lato più lungo, scalata in base alle proporzioni scelte. * Quando `aspectRatio` è `"free"`, la tela usa come predefinito 4:3 (2400x1800). * I valori `panX`/`panY` per singola cella spostano la finestra di ritaglio all'interno della cella. Un valore di 100 sposta completamente verso un bordo, -100 verso l'altro. * Il colore di sfondo `"transparent"` viene preservato solo con i formati di output `png`, `webp` o `avif`. --- --- url: https://docs.snapotter.com/fr/tools/image/collage.md description: >- Combinez plusieurs images en collages en grille avec plus de 25 modèles, des espacements et coins réglables, ainsi qu'un panoramique et un zoom par cellule. --- # Collage et grille {#collage-grid} Combinez plusieurs images en superbes collages en grille avec plus de 25 modèles. Prend en charge les dispositions de 2 à 9 images avec espacement, rayon des coins, couleur d'arrière-plan et contrôles de panoramique/zoom par cellule personnalisables. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | templateId | string | Oui | - | ID de la disposition du modèle (par ex. `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | Non | - | Tableau de réglages par cellule avec `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Oui | - | Index de l'image à placer dans cette cellule (base 0) | | cells\[].panX | number | Non | 0 | Décalage de panoramique horizontal (-100 à 100) | | cells\[].panY | number | Non | 0 | Décalage de panoramique vertical (-100 à 100) | | cells\[].zoom | number | Non | 1 | Niveau de zoom (1 à 10) | | cells\[].objectFit | string | Non | `"cover"` | Comment l'image remplit la cellule : `cover` ou `contain` | | gap | number | Non | 8 | Espacement entre cellules en pixels (0 à 500) | | cornerRadius | number | Non | 0 | Rayon des coins de chaque cellule en pixels (0 à 500) | | backgroundColor | string | Non | `"#FFFFFF"` | Couleur d'arrière-plan en hexadécimal ou `"transparent"` | | aspectRatio | string | Non | `"free"` | Rapport d'aspect du canevas : `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | Non | `"png"` | Format de sortie : `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Non | 90 | Qualité de sortie (1 à 100) | ## Available Templates {#available-templates} | ID du modèle | Images | Disposition | |-------------|--------|--------| | `2-h-equal` | 2 | Deux colonnes égales | | `2-v-equal` | 2 | Deux rangées égales | | `2-h-left-large` | 2 | Gauche 2/3, droite 1/3 | | `2-h-right-large` | 2 | Gauche 1/3, droite 2/3 | | `3-left-large` | 3 | Grande à gauche, deux empilées à droite | | `3-right-large` | 3 | Deux empilées à gauche, grande à droite | | `3-top-large` | 3 | Grande en haut, deux colonnes en bas | | `3-h-equal` | 3 | Trois colonnes égales | | `3-v-equal` | 3 | Trois rangées égales | | `4-grid` | 4 | Grille 2x2 | | `4-left-large` | 4 | Grande à gauche, trois empilées à droite | | `4-top-large` | 4 | Grande en haut, trois colonnes en bas | | `4-bottom-large` | 4 | Trois colonnes en haut, grande en bas | | `5-top2-bottom3` | 5 | Deux en haut, trois en bas | | `5-top3-bottom2` | 5 | Trois en haut, deux en bas | | `5-left-large` | 5 | Grande à gauche, quatre empilées à droite | | `5-center-large` | 5 | Grande au centre, quatre aux coins | | `6-grid-2x3` | 6 | 2 colonnes x 3 rangées | | `6-grid-3x2` | 6 | 3 colonnes x 2 rangées | | `6-top-large` | 6 | Grande en haut, cinq colonnes en bas | | `7-mosaic` | 7 | Disposition en mosaïque | | `8-mosaic` | 8 | Disposition en mosaïque | | `9-grid` | 9 | Grille 3x3 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Notes {#notes} * Téléversez plusieurs fichiers image dans la requête multipart. Les images sont attribuées aux cellules du modèle dans l'ordre de téléversement. * Si plus d'images sont téléversées que le modèle n'en accepte, les images supplémentaires sont ignorées. * Prend en charge les formats d'entrée HEIC, RAW, PSD et SVG (décodés automatiquement). * La taille de base du canevas est de 2400 px sur le côté le plus long, mise à l'échelle selon le rapport d'aspect choisi. * Lorsque `aspectRatio` vaut `"free"`, le canevas prend par défaut le rapport 4:3 (2400x1800). * Les valeurs `panX`/`panY` par cellule décalent la fenêtre de recadrage à l'intérieur de la cellule. Une valeur de 100 déplace entièrement vers un bord, -100 vers l'autre. * La couleur d'arrière-plan `"transparent"` n'est conservée qu'avec les formats de sortie `png`, `webp` ou `avif`. --- --- url: https://docs.snapotter.com/es/tools/image/collage.md description: >- Combina varias imágenes en collages de cuadrícula con más de 25 plantillas, espacios y esquinas ajustables, y desplazamiento y zoom por celda. --- # Collage y cuadrícula {#collage-grid} Combina varias imágenes en collages de cuadrícula atractivos con más de 25 plantillas. Admite diseños de 2 a 9 imágenes con espacio, radio de esquina, color de fondo y controles de desplazamiento/zoom por celda personalizables. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/collage` ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | templateId | string | Sí | - | ID del diseño de plantilla (p. ej. `2-h-equal`, `3-left-large`, `4-grid`, `9-grid`) | | cells | array | No | - | Array de ajustes por celda con `imageIndex`, `panX`, `panY`, `zoom`, `objectFit` | | cells\[].imageIndex | integer | Sí | - | Índice de la imagen que se coloca en esta celda (basado en 0) | | cells\[].panX | number | No | 0 | Desplazamiento horizontal (-100 a 100) | | cells\[].panY | number | No | 0 | Desplazamiento vertical (-100 a 100) | | cells\[].zoom | number | No | 1 | Nivel de zoom (1 a 10) | | cells\[].objectFit | string | No | `"cover"` | Cómo llena la imagen la celda: `cover` o `contain` | | gap | number | No | 8 | Espacio entre celdas en píxeles (0 a 500) | | cornerRadius | number | No | 0 | Radio de esquina para cada celda en píxeles (0 a 500) | | backgroundColor | string | No | `"#FFFFFF"` | Color de fondo como hex o `"transparent"` | | aspectRatio | string | No | `"free"` | Relación de aspecto del lienzo: `free`, `1:1`, `4:3`, `3:2`, `16:9`, `9:16`, `4:5` | | outputFormat | string | No | `"png"` | Formato de salida: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Calidad de salida (1 a 100) | ## Plantillas disponibles {#available-templates} | ID de plantilla | Imágenes | Diseño | |-------------|--------|--------| | `2-h-equal` | 2 | Dos columnas iguales | | `2-v-equal` | 2 | Dos filas iguales | | `2-h-left-large` | 2 | Izquierda 2/3, derecha 1/3 | | `2-h-right-large` | 2 | Izquierda 1/3, derecha 2/3 | | `3-left-large` | 3 | Grande a la izquierda, dos apiladas a la derecha | | `3-right-large` | 3 | Dos apiladas a la izquierda, grande a la derecha | | `3-top-large` | 3 | Grande arriba, dos columnas abajo | | `3-h-equal` | 3 | Tres columnas iguales | | `3-v-equal` | 3 | Tres filas iguales | | `4-grid` | 4 | Cuadrícula 2x2 | | `4-left-large` | 4 | Grande a la izquierda, tres apiladas a la derecha | | `4-top-large` | 4 | Grande arriba, tres columnas abajo | | `4-bottom-large` | 4 | Tres columnas arriba, grande abajo | | `5-top2-bottom3` | 5 | Dos arriba, tres abajo | | `5-top3-bottom2` | 5 | Tres arriba, dos abajo | | `5-left-large` | 5 | Grande a la izquierda, cuatro apiladas a la derecha | | `5-center-large` | 5 | Grande al centro, cuatro en las esquinas | | `6-grid-2x3` | 6 | 2 columnas x 3 filas | | `6-grid-3x2` | 6 | 3 columnas x 2 filas | | `6-top-large` | 6 | Grande arriba, cinco columnas abajo | | `7-mosaic` | 7 | Diseño de mosaico | | `8-mosaic` | 8 | Diseño de mosaico | | `9-grid` | 9 | Cuadrícula 3x3 | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/collage \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"templateId":"4-grid","gap":12,"cornerRadius":8,"backgroundColor":"#F5F5F5","outputFormat":"png","quality":90}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/collage.png", "originalSize": 2456789, "processedSize": 1823456 } ``` ## Notas {#notes} * Sube varios archivos de imagen en la solicitud multipart. Las imágenes se asignan a las celdas de la plantilla en el orden de carga. * Si se suben más imágenes de las que admite la plantilla, las imágenes sobrantes se ignoran. * Admite los formatos de entrada HEIC, RAW, PSD y SVG (decodificados automáticamente). * El tamaño base del lienzo es de 2400 px en el lado más largo, escalado según la relación de aspecto elegida. * Cuando `aspectRatio` es `"free"`, el lienzo usa de forma predeterminada 4:3 (2400x1800). * Los valores de `panX`/`panY` por celda desplazan la ventana de recorte dentro de la celda. Un valor de 100 la mueve por completo hacia un borde, y -100 hacia el otro. * El color de fondo `"transparent"` solo se conserva con los formatos de salida `png`, `webp` o `avif`. --- --- url: https://docs.snapotter.com/ar/tools/image/color-blindness.md description: محاكاة كيفية ظهور الصور للأشخاص المصابين بأنواع مختلفة من قصور رؤية الألوان. --- # Color Blindness Simulation {#color-blindness-simulation} حاكِ قصور رؤية الألوان (CVD) لمعاينة كيفية ظهور الصور للأشخاص المصابين بأنواع مختلفة من عمى الألوان. مفيد لاختبار إمكانية الوصول للتصاميم والمخططات وواجهات المستخدم. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-blindness` يقبل بيانات نموذج multipart تحتوي على ملف صورة وحقل JSON باسم `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | simulationType | string | No | `"deuteranomaly"` | نوع قصور رؤية الألوان المراد محاكاته | ### Simulation Types {#simulation-types} | Value | Condition | Description | |-------|-----------|-------------| | `protanopia` | عمى اللون الأحمر | غياب كامل للخلايا المخروطية الحمراء | | `deuteranopia` | عمى اللون الأخضر | غياب كامل للخلايا المخروطية الخضراء | | `tritanopia` | عمى اللون الأزرق | غياب كامل للخلايا المخروطية الزرقاء | | `protanomaly` | ضعف اللون الأحمر | انخفاض حساسية الخلايا المخروطية الحمراء | | `deuteranomaly` | ضعف اللون الأخضر | انخفاض حساسية الخلايا المخروطية الخضراء (الأكثر شيوعًا) | | `tritanomaly` | ضعف اللون الأزرق | انخفاض حساسية الخلايا المخروطية الزرقاء | | `achromatopsia` | عمى ألوان كامل | غياب كامل لرؤية الألوان | | `blueConeMonochromacy` | مخاريط زرقاء فقط | المخاريط الزرقاء فقط تعمل | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-blindness \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@design.png" \ -F 'settings={"simulationType": "deuteranopia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/design.png", "originalSize": 1850000, "processedSize": 1820000 } ``` ## Notes {#notes} * ضعف اللون الأخضر (Deuteranomaly) هو الافتراضي لأنه أكثر أشكال قصور رؤية الألوان شيوعًا، ويصيب نحو 6% من الذكور. * تستخدم المحاكاة مصفوفات تحويل ألوان تُنمذج كيف تغيّر المستقبلات الضوئية المخروطية المنخفضة أو الغائبة الألوان المُدرَكة. * هذه الأداة غير متلفة وتنتج معاينة فقط. لا تعدّل الصورة الأصلية لأغراض إمكانية الوصول. * صيغة الإخراج تطابق صيغة الإدخال. تُفَكّ شفرة مدخلات HEIC وRAW وPSD وSVG تلقائيًا قبل المعالجة. --- --- url: https://docs.snapotter.com/hi/tools/image/color-blindness.md description: >- अनुकरण करें कि विभिन्न प्रकार की रंग दृष्टि कमी वाले लोगों को छवियाँ कैसी दिखती हैं। --- # Color Blindness Simulation {#color-blindness-simulation} रंग दृष्टि कमी (CVD) का अनुकरण करें ताकि यह पूर्वावलोकन किया जा सके कि विभिन्न प्रकार के रंग अंधत्व वाले लोगों को छवियाँ कैसी दिखती हैं। डिज़ाइन, चार्ट, और UI के अभिगम्यता परीक्षण के लिए उपयोगी। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-blindness` एक छवि फ़ाइल और एक JSON `settings` फ़ील्ड के साथ मल्टीपार्ट फ़ॉर्म डेटा स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | simulationType | string | No | `"deuteranomaly"` | अनुकरण करने के लिए रंग दृष्टि कमी का प्रकार | ### Simulation Types {#simulation-types} | Value | Condition | Description | |-------|-----------|-------------| | `protanopia` | लाल-अंध | लाल शंकु कोशिकाओं की पूर्ण अनुपस्थिति | | `deuteranopia` | हरा-अंध | हरी शंकु कोशिकाओं की पूर्ण अनुपस्थिति | | `tritanopia` | नीला-अंध | नीली शंकु कोशिकाओं की पूर्ण अनुपस्थिति | | `protanomaly` | लाल-कमज़ोर | घटी हुई लाल शंकु संवेदनशीलता | | `deuteranomaly` | हरा-कमज़ोर | घटी हुई हरी शंकु संवेदनशीलता (सबसे सामान्य) | | `tritanomaly` | नीला-कमज़ोर | घटी हुई नीली शंकु संवेदनशीलता | | `achromatopsia` | पूर्ण रंग अंध | रंग दृष्टि की पूर्ण अनुपस्थिति | | `blueConeMonochromacy` | केवल नीला-शंकु | केवल नीले शंकु कार्यशील | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-blindness \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@design.png" \ -F 'settings={"simulationType": "deuteranopia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/design.png", "originalSize": 1850000, "processedSize": 1820000 } ``` ## Notes {#notes} * Deuteranomaly (हरा-कमज़ोर) डिफ़ॉल्ट है क्योंकि यह रंग दृष्टि कमी का सबसे सामान्य रूप है, जो लगभग 6% पुरुषों को प्रभावित करता है। * यह अनुकरण रंग परिवर्तन मैट्रिक्स का उपयोग करता है जो यह मॉडल करते हैं कि घटे हुए या अनुपस्थित शंकु प्रकाशग्राही अनुभव किए गए रंगों को कैसे बदलते हैं। * यह टूल गैर-विनाशकारी है और केवल एक पूर्वावलोकन उत्पन्न करता है। यह अभिगम्यता के लिए मूल छवि को संशोधित नहीं करता। * आउटपुट फ़ॉर्मेट इनपुट फ़ॉर्मेट से मेल खाता है। HEIC, RAW, PSD, और SVG इनपुट प्रोसेसिंग से पहले स्वचालित रूप से डिकोड किए जाते हैं। --- --- url: https://docs.snapotter.com/th/tools/image/color-blindness.md description: จำลองว่าภาพปรากฏอย่างไรต่อผู้ที่มีภาวะบกพร่องในการมองเห็นสีประเภทต่าง ๆ --- # Color Blindness Simulation {#color-blindness-simulation} จำลองภาวะบกพร่องในการมองเห็นสี (CVD) เพื่อดูตัวอย่างว่าภาพปรากฏอย่างไรต่อผู้ที่มีภาวะตาบอดสีประเภทต่าง ๆ มีประโยชน์สำหรับการทดสอบการเข้าถึงของงานออกแบบ แผนภูมิ และ UI ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-blindness` รับข้อมูลฟอร์ม multipart พร้อมไฟล์ภาพและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | simulationType | string | No | `"deuteranomaly"` | ประเภทของภาวะบกพร่องในการมองเห็นสีที่จะจำลอง | ### Simulation Types {#simulation-types} | Value | Condition | Description | |-------|-----------|-------------| | `protanopia` | ตาบอดสีแดง | ไม่มีเซลล์รูปกรวยสีแดงเลย | | `deuteranopia` | ตาบอดสีเขียว | ไม่มีเซลล์รูปกรวยสีเขียวเลย | | `tritanopia` | ตาบอดสีน้ำเงิน | ไม่มีเซลล์รูปกรวยสีน้ำเงินเลย | | `protanomaly` | มองเห็นสีแดงอ่อน | ความไวต่อเซลล์รูปกรวยสีแดงลดลง | | `deuteranomaly` | มองเห็นสีเขียวอ่อน | ความไวต่อเซลล์รูปกรวยสีเขียวลดลง (พบบ่อยที่สุด) | | `tritanomaly` | มองเห็นสีน้ำเงินอ่อน | ความไวต่อเซลล์รูปกรวยสีน้ำเงินลดลง | | `achromatopsia` | ตาบอดสีทั้งหมด | ไม่มีการมองเห็นสีเลย | | `blueConeMonochromacy` | มีเฉพาะเซลล์รูปกรวยสีน้ำเงิน | มีเฉพาะเซลล์รูปกรวยสีน้ำเงินที่ทำงานได้ | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-blindness \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@design.png" \ -F 'settings={"simulationType": "deuteranopia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/design.png", "originalSize": 1850000, "processedSize": 1820000 } ``` ## Notes {#notes} * Deuteranomaly (มองเห็นสีเขียวอ่อน) เป็นค่าเริ่มต้นเพราะเป็นรูปแบบภาวะบกพร่องในการมองเห็นสีที่พบบ่อยที่สุด ส่งผลต่อผู้ชายประมาณ 6% * การจำลองใช้เมทริกซ์การแปลงสีที่จำลองว่าการที่เซลล์รับแสงรูปกรวยลดลงหรือขาดหายไปเปลี่ยนแปลงการรับรู้สีอย่างไร * เครื่องมือนี้ไม่ทำลายข้อมูลและสร้างเป็นเพียงตัวอย่างเท่านั้น ไม่ได้แก้ไขภาพต้นฉบับเพื่อการเข้าถึง * รูปแบบเอาต์พุตตรงกับรูปแบบอินพุต อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนประมวลผล --- --- url: https://docs.snapotter.com/uk/tools/image/color-blindness.md description: >- Симулюйте, як зображення виглядають для людей із різними типами порушення колірного зору. --- # Color Blindness Simulation {#color-blindness-simulation} Симулюйте порушення колірного зору (CVD), щоб побачити, як зображення виглядають для людей із різними типами дальтонізму. Корисно для тестування доступності дизайнів, діаграм та інтерфейсів. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-blindness` Приймає дані форми multipart із файлом зображення та полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | simulationType | string | No | `"deuteranomaly"` | Тип порушення колірного зору для симуляції | ### Simulation Types {#simulation-types} | Value | Condition | Description | |-------|-----------|-------------| | `protanopia` | Червоносліпота | Повна відсутність червоних колбочок | | `deuteranopia` | Зеленосліпота | Повна відсутність зелених колбочок | | `tritanopia` | Синьосліпота | Повна відсутність синіх колбочок | | `protanomaly` | Ослаблення червоного | Знижена чутливість червоних колбочок | | `deuteranomaly` | Ослаблення зеленого | Знижена чутливість зелених колбочок (найпоширеніше) | | `tritanomaly` | Ослаблення синього | Знижена чутливість синіх колбочок | | `achromatopsia` | Повний дальтонізм | Повна відсутність колірного зору | | `blueConeMonochromacy` | Лише синій конус | Функціонують лише сині колбочки | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-blindness \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@design.png" \ -F 'settings={"simulationType": "deuteranopia"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/design.png", "originalSize": 1850000, "processedSize": 1820000 } ``` ## Notes {#notes} * Дейтераномалія (ослаблення зеленого) використовується за замовчуванням, оскільки це найпоширеніша форма порушення колірного зору, що вражає приблизно 6% чоловіків. * Симуляція використовує матриці колірного перетворення, які моделюють, як знижена або відсутня чутливість колбочок-фоторецепторів змінює сприйняття кольорів. * Цей інструмент неруйнівний і створює лише попередній перегляд. Він не змінює оригінальне зображення для доступності. * Вихідний формат збігається з вхідним. Вхідні дані HEIC, RAW, PSD та SVG автоматично декодуються перед обробкою. --- --- url: https://docs.snapotter.com/ar/tools/image/color-palette.md description: استخراج الألوان السائدة من صورة كلوحة ألوان. --- # Color Palette {#color-palette} استخرج الألوان السائدة من صورة وأعِدها كقيم ألوان hex. يستخدم تحليل التردد المُكمّم لتحديد الألوان الأكثر بروزًا وتمايزًا بصريًا. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-palette` يقبل بيانات نموذج multipart تحتوي على ملف صورة وحقل JSON اختياري باسم `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | count | integer | No | `8` | عدد الألوان المراد استخراجها (2-16) | | format | string | No | `"hex"` | صيغة اللون: `hex`، `rgb`، `hsl` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Example Response {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | اسم الملف المُنقّى | | colors | array | مصفوفة سلاسل الألوان بالصيغة المطلوبة، مرتّبة حسب الهيمنة (الأكثر تكرارًا أولًا) | | hex | array | مصفوفة سلاسل ألوان hex (دائمًا hex بغض النظر عن إعداد `format`) | | count | number | عدد الألوان المستخرَجة | ## Notes {#notes} * يُعيد حتى `count` لونًا سائدًا (الافتراضي 8، المدى 2-16)، مرتّبة حسب التردد (الأكثر شيوعًا أولًا). * يُعاد تحجيم الصورة داخليًا إلى 100x100 بكسل للتحليل، لذا تمثّل اللوحة توزيع الألوان العام بدلًا من التفاصيل الصغيرة. * تُستخرَج الألوان باستخدام تكميم median-cut، الذي يقسّم مجموعات البكسل بشكل متكرر على طول القناة ذات المدى الأوسع. * تُزال قناة الشفافية قبل التحليل، لذا لا تُؤخَذ المناطق الشفافة في الاعتبار. * هذه نقطة نهاية للقراءة فقط. لا تنتج ملف إخراج قابل للتنزيل ولا `jobId`. * تُفَكّ شفرة مدخلات HEIC وRAW وPSD وSVG تلقائيًا قبل التحليل. --- --- url: https://docs.snapotter.com/hi/tools/image/color-palette.md description: किसी छवि से प्रमुख रंगों को एक रंग पैलेट के रूप में निकालें। --- # Color Palette {#color-palette} किसी छवि से प्रमुख रंगों को निकालें और उन्हें हेक्स रंग मानों के रूप में लौटाएँ। सबसे प्रमुख और दृश्य रूप से विशिष्ट रंगों की पहचान के लिए क्वांटाइज़्ड आवृत्ति विश्लेषण का उपयोग करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-palette` एक छवि फ़ाइल और एक वैकल्पिक JSON `settings` फ़ील्ड के साथ मल्टीपार्ट फ़ॉर्म डेटा स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | count | integer | No | `8` | निकालने के लिए रंगों की संख्या (2-16) | | format | string | No | `"hex"` | रंग फ़ॉर्मेट: `hex`, `rgb`, `hsl` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Example Response {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | स्वच्छ किया गया फ़ाइलनाम | | colors | array | अनुरोधित फ़ॉर्मेट में रंग स्ट्रिंग्स की सरणी, प्रभुत्व के क्रम में (सबसे अधिक बारंबार पहले) | | hex | array | हेक्स रंग स्ट्रिंग्स की सरणी (हमेशा हेक्स, `format` सेटिंग की परवाह किए बिना) | | count | number | निकाले गए रंगों की संख्या | ## Notes {#notes} * अधिकतम `count` प्रमुख रंग लौटाता है (डिफ़ॉल्ट 8, सीमा 2-16), आवृत्ति के अनुसार क्रमबद्ध (सबसे सामान्य पहले)। * छवि का आंतरिक रूप से विश्लेषण के लिए 100x100 पिक्सेल में आकार बदला जाता है, इसलिए पैलेट छोटे विवरणों के बजाय समग्र रंग वितरण का प्रतिनिधित्व करता है। * रंग मीडियन-कट क्वांटाइज़ेशन का उपयोग करके निकाले जाते हैं, जो सबसे व्यापक सीमा वाले चैनल के साथ पिक्सेल समूहों को पुनरावर्ती रूप से विभाजित करता है। * विश्लेषण से पहले अल्फा चैनल हटा दिया जाता है, इसलिए पारदर्शी क्षेत्रों पर विचार नहीं किया जाता। * यह एक केवल-पढ़ने योग्य एंडपॉइंट है। यह डाउनलोड करने योग्य आउटपुट फ़ाइल या `jobId` उत्पन्न नहीं करता। * HEIC, RAW, PSD, और SVG इनपुट विश्लेषण से पहले स्वचालित रूप से डिकोड किए जाते हैं। --- --- url: https://docs.snapotter.com/th/tools/image/color-palette.md description: สกัดสีเด่นจากภาพออกมาเป็นชุดสี --- # Color Palette {#color-palette} สกัดสีเด่นจากภาพและส่งคืนเป็นค่าสี hex ใช้การวิเคราะห์ความถี่แบบควอนไทซ์เพื่อระบุสีที่โดดเด่นที่สุดและแตกต่างกันชัดเจนที่สุดในเชิงสายตา ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-palette` รับข้อมูลฟอร์ม multipart พร้อมไฟล์ภาพและฟิลด์ JSON `settings` ที่ไม่บังคับ ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | count | integer | No | `8` | จำนวนสีที่จะสกัด (2-16) | | format | string | No | `"hex"` | รูปแบบสี: `hex`, `rgb`, `hsl` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Example Response {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | ชื่อไฟล์ที่ผ่านการทำความสะอาดแล้ว | | colors | array | อาร์เรย์ของสตริงสีในรูปแบบที่ร้องขอ เรียงตามความเด่น (พบบ่อยที่สุดก่อน) | | hex | array | อาร์เรย์ของสตริงสี hex (เป็น hex เสมอ ไม่ว่าการตั้งค่า `format` จะเป็นอะไร) | | count | number | จำนวนสีที่สกัดได้ | ## Notes {#notes} * ส่งคืนสีเด่นได้สูงสุด `count` สี (ค่าเริ่มต้น 8, ช่วง 2-16) เรียงตามความถี่ (พบบ่อยที่สุดก่อน) * ภาพจะถูกปรับขนาดภายในเป็น 100x100 พิกเซลเพื่อการวิเคราะห์ ดังนั้นชุดสีจึงแทนการกระจายตัวของสีโดยรวมมากกว่ารายละเอียดเล็ก ๆ * สีถูกสกัดโดยใช้ median-cut quantization ซึ่งแบ่งกลุ่มพิกเซลแบบเรียกซ้ำตามช่องสัญญาณที่มีช่วงกว้างที่สุด * ช่องสัญญาณอัลฟาจะถูกลบออกก่อนการวิเคราะห์ ดังนั้นบริเวณโปร่งใสจึงไม่ถูกนำมาพิจารณา * นี่เป็น endpoint แบบอ่านอย่างเดียว ไม่สร้างไฟล์เอาต์พุตที่ดาวน์โหลดได้หรือ `jobId` * อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนการวิเคราะห์ --- --- url: https://docs.snapotter.com/uk/tools/image/color-palette.md description: Витягуйте домінантні кольори із зображення у вигляді колірної палітри. --- # Color Palette {#color-palette} Витягуйте домінантні кольори із зображення та повертайте їх у вигляді hex-значень кольорів. Використовує квантований частотний аналіз для визначення найпомітніших і візуально відмінних кольорів. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/color-palette` Приймає дані форми multipart із файлом зображення та необов'язковим полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | count | integer | No | `8` | Кількість кольорів для витягування (2-16) | | format | string | No | `"hex"` | Формат кольору: `hex`, `rgb`, `hsl` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Example Response {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | filename | string | Очищена назва файлу | | colors | array | Масив рядків кольорів у запитаному форматі, впорядкований за домінантністю (найчастіший першим) | | hex | array | Масив hex-рядків кольорів (завжди hex, незалежно від налаштування `format`) | | count | number | Кількість витягнутих кольорів | ## Notes {#notes} * Повертає до `count` домінантних кольорів (за замовчуванням 8, діапазон 2-16), відсортованих за частотою (найпоширеніший першим). * Зображення внутрішньо зменшується до 100x100 пікселів для аналізу, тож палітра відображає загальний розподіл кольорів, а не дрібні деталі. * Кольори витягуються за допомогою квантування методом медіанного розрізу, який рекурсивно розділяє групи пікселів уздовж каналу з найширшим діапазоном. * Альфа-канал видаляється перед аналізом, тож прозорі області не враховуються. * Це кінцева точка лише для читання. Вона не створює вихідний файл для завантаження або `jobId`. * Вхідні дані HEIC, RAW, PSD та SVG автоматично декодуються перед аналізом. --- --- url: https://docs.snapotter.com/fr/tools/image/colorize.md description: >- Colorisez automatiquement les photos en noir et blanc ou en niveaux de gris avec le modèle d'IA DDColor. --- # Colorisation par IA {#ai-colorization} Convertissez les photos en noir et blanc ou en niveaux de gris en couleur complète à l'aide de l'IA (modèle DDColor avec repli sur OpenCV DNN). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/colorize` **Traitement :** asynchrone (renvoie 202, interrogez `/api/v1/jobs/{jobId}/progress` pour le statut via SSE) **Bundle de modèle :** `object-eraser-colorize` (1-2 Go) ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | file | file | Oui | - | Fichier image (multipart) | | intensity | number | Non | `1.0` | Intensité des couleurs (0-1). Les valeurs plus basses produisent une colorisation plus subtile | | model | string | Non | `"auto"` | Modèle à utiliser : `auto`, `ddcolor`, `opencv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notes {#notes} * Nécessite l'installation du bundle de modèle `object-eraser-colorize` (1-2 Go). * DDColor produit des résultats de meilleure qualité mais est plus lent ; OpenCV DNN est plus rapide avec une qualité légèrement inférieure. `auto` utilise DDColor lorsqu'il est disponible, avec un repli sur OpenCV. * Le paramètre `intensity` mélange l'original en niveaux de gris et le résultat colorisé par l'IA. Utilisez 1.0 pour une couleur complète, des valeurs plus basses pour un rendu vintage partiellement désaturé. * Le format de sortie correspond automatiquement au format d'entrée. * Pour les formats de sortie non prévisualisables dans le navigateur, un aperçu WebP est généré en parallèle de la sortie principale. * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR par décodage automatique. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/colorize.md description: >- Colorize fotos em preto e branco ou em tons de cinza automaticamente com o modelo de IA DDColor. --- # Colorização por IA {#ai-colorization} Converta fotos em preto e branco ou em tons de cinza para cores completas usando IA (modelo DDColor com fallback para OpenCV DNN). ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/colorize` **Processamento:** Assíncrono (retorna 202, consulte `/api/v1/jobs/{jobId}/progress` para o status via SSE) **Pacote do modelo:** `object-eraser-colorize` (1-2 GB) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | intensity | number | Não | `1.0` | Intensidade de cor (0-1). Valores menores produzem uma colorização mais sutil | | model | string | Não | `"auto"` | Modelo a usar: `auto`, `ddcolor`, `opencv` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Resposta {#response} ### Resposta Inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progresso (SSE em `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Resultado Final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notas {#notes} * Requer que o pacote do modelo `object-eraser-colorize` esteja instalado (1-2 GB). * O DDColor produz resultados de maior qualidade, mas é mais lento; o OpenCV DNN é mais rápido com qualidade ligeiramente inferior. `auto` usa o DDColor quando disponível com fallback para OpenCV. * O parâmetro `intensity` mescla entre o tom de cinza original e o resultado colorizado por IA. Use 1.0 para cor completa, valores menores para um visual vintage parcialmente dessaturado. * O formato de saída corresponde automaticamente ao formato de entrada. * Para formatos de saída não pré-visualizáveis no navegador, uma pré-visualização WebP é gerada junto com a saída principal. * Suporta os formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR via decodificação automática. --- --- url: https://docs.snapotter.com/es/tools/image/colorize.md description: >- Coloriza fotos en blanco y negro o en escala de grises automáticamente con el modelo de IA DDColor. --- # Colorización con IA {#ai-colorization} Convierte fotos en blanco y negro o en escala de grises a color completo usando IA (modelo DDColor con OpenCV DNN como alternativa). ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/colorize` **Procesamiento:** Asíncrono (devuelve 202, consulta `/api/v1/jobs/{jobId}/progress` para conocer el estado mediante SSE) **Paquete de modelo:** `object-eraser-colorize` (1-2 GB) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | intensity | number | No | `1.0` | Intensidad del color (0-1). Los valores más bajos producen una colorización más sutil | | model | string | No | `"auto"` | Modelo que se usa: `auto`, `ddcolor`, `opencv` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Respuesta {#response} ### Respuesta inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progreso (SSE en `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Resultado final (mediante SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Notas {#notes} * Requiere que el paquete de modelo `object-eraser-colorize` esté instalado (1-2 GB). * DDColor produce resultados de mayor calidad pero es más lento; OpenCV DNN es más rápido con una calidad ligeramente inferior. `auto` usa DDColor cuando está disponible, con OpenCV como alternativa. * El parámetro `intensity` mezcla la escala de grises original con el resultado colorizado por IA. Usa 1.0 para color completo, o valores más bajos para un aspecto vintage parcialmente desaturado. * El formato de salida coincide automáticamente con el formato de entrada. * Para los formatos de salida que no se pueden previsualizar en el navegador, se genera una vista previa WebP junto a la salida principal. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/it/tools/image/colorize.md description: >- Colora automaticamente foto in bianco e nero o in scala di grigi con il modello di IA DDColor. --- # Colorizzazione con IA {#ai-colorization} Converti foto in bianco e nero o in scala di grigi a colori pieni usando l'IA (modello DDColor con fallback OpenCV DNN). ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/colorize` **Elaborazione:** Asincrona (restituisce 202, esegui il polling di `/api/v1/jobs/{jobId}/progress` per lo stato tramite SSE) **Bundle del modello:** `object-eraser-colorize` (1-2 GB) ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | file | file | Sì | - | File immagine (multipart) | | intensity | number | No | `1.0` | Intensità del colore (0-1). Valori più bassi producono una colorizzazione più tenue | | model | string | No | `"auto"` | Modello da usare: `auto`, `ddcolor`, `opencv` | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/colorize \ -F "file=@old-bw-photo.jpg" \ -F 'settings={"intensity":0.9,"model":"auto"}' ``` ## Risposta {#response} ### Risposta iniziale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Avanzamento (SSE su `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Colorizing...","percent":55} ``` ### Risultato finale (tramite SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/old-bw-photo_colorized.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 180000, "processedSize": 210000, "width": 1920, "height": 1080, "method": "ddcolor" } } ``` ## Note {#notes} * Richiede l'installazione del bundle del modello `object-eraser-colorize` (1-2 GB). * DDColor produce risultati di qualità superiore ma è più lento; OpenCV DNN è più veloce con qualità leggermente inferiore. `auto` usa DDColor quando disponibile con fallback su OpenCV. * Il parametro `intensity` miscela tra la scala di grigi originale e il risultato colorizzato dall'IA. Usa 1.0 per il colore pieno, valori più bassi per un aspetto vintage parzialmente desaturato. * Il formato di output corrisponde automaticamente al formato di input. * Per i formati di output non visualizzabili in anteprima nel browser, viene generata un'anteprima WebP insieme all'output principale. * Supporta i formati di input HEIC/HEIF, RAW, TGA, PSD, EXR e HDR tramite decodifica automatica. --- --- url: https://docs.snapotter.com/es/tools/audio/merge-audio.md description: Combina varios archivos de audio en una sola pista secuencial. --- # Combinar audio {#merge-audio} Combina dos o más archivos de audio en una sola pista secuencial, concatenados en el orden en que se suben. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/audio/merge-audio` Acepta datos de formulario multipart con varios archivos de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Formato de salida: `mp3`, `wav`, `flac`, `m4a` | ## Solicitud de ejemplo {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/merge-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@intro.mp3" \ -F "file=@main.mp3" \ -F "file=@outro.mp3" \ -F 'settings={"format": "mp3"}' ``` ## Respuesta de ejemplo {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.mp3", "originalSize": 9500000, "processedSize": 9200000 } ``` ## Notas {#notes} * Acepta de 2 a 10 archivos de audio por solicitud. * Los archivos se concatenan en el orden de subida. * Todos los archivos de entrada se recodifican al formato de salida y la frecuencia de muestreo elegidos para una unión sin fisuras. * Se admiten formatos de entrada mixtos (por ejemplo, un WAV y un MP3). --- --- url: https://docs.snapotter.com/es/tools/files/merge-csvs.md description: Combina varios archivos CSV o TSV con columnas coincidentes en uno solo. --- # Combinar CSV {#merge-csvs} Combina varios archivos CSV o TSV con columnas coincidentes en un único archivo fusionado. Todos los archivos de entrada deben tener los mismos encabezados de columna. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/merge-csvs` Acepta datos de formulario multipart con dos o más archivos CSV. No se requiere ningún campo de configuración. ## Parameters {#parameters} Esta herramienta no tiene parámetros configurables. Sube de 2 a 20 archivos CSV o TSV con encabezados de columna coincidentes. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/merge-csvs \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@january.csv" \ -F "file=@february.csv" \ -F "file=@march.csv" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", "originalSize": 30000, "processedSize": 28500 } ``` ## Notes {#notes} * Requiere entre 2 y 20 archivos de entrada. * Todos los archivos deben compartir los mismos encabezados de columna. La combinación fallará si las columnas no coinciden. * La fila de encabezado se incluye una sola vez en la salida; las filas de datos de todos los archivos se concatenan en el orden de subida. * Se aceptan tanto archivos CSV como TSV, pero todos los archivos de una misma solicitud deben usar el mismo delimitador. --- --- url: https://docs.snapotter.com/es/tools/pdf/merge-pdf.md description: Combina varios PDF en un único documento. --- # Combinar PDF {#merge-pdfs} Combina dos o más archivos PDF en un único documento, conservando el orden de las páginas de cada archivo de entrada. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/merge-pdf` Acepta datos de formulario multipart con dos o más archivos PDF. No se requiere un campo `settings`. ## Parameters {#parameters} Esta herramienta no tiene parámetros de configuración. Simplemente sube dos o más archivos PDF. | Restricción | Valor | |------------|-------| | Archivos mínimos | 2 | | Archivos máximos | 20 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/merge-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document1.pdf" \ -F "file=@document2.pdf" \ -F "file=@document3.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.pdf", "originalSize": 4500000, "processedSize": 4200000 } ``` ## Notes {#notes} * Los archivos se combinan en el orden en que se suben. * Se requieren al menos dos archivos PDF; la solicitud fallará con un error 400 si se proporcionan menos. * El número máximo de archivos de entrada es 20. * Los PDF cifrados deben desbloquearse antes de combinarlos. --- --- url: https://docs.snapotter.com/fr/tools/image/compare.md description: >- Comparez deux images côte à côte avec une visualisation des différences au niveau du pixel et un score de similarité. --- # Comparaison d'images {#image-compare} Téléversez deux images pour calculer une carte des différences au niveau du pixel et un pourcentage de similarité numérique. La sortie est une image de différence mettant en évidence les régions modifiées en rouge. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compare` Accepte des données de formulaire multipart avec **deux** fichiers image. Aucun champ de réglages n'est nécessaire. ## Parameters {#parameters} Cet outil n'a aucun paramètre configurable. Téléversez exactement deux fichiers image. | Champ | Type | Requis | Description | |-------|------|----------|-------------| | file (premier) | file | Oui | La première image | | file (second) | file | Oui | La deuxième image | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Response Fields {#response-fields} | Champ | Type | Description | |-------|------|-------------| | jobId | string | Identifiant de tâche pour télécharger l'image de différence | | similarity | number | Pourcentage de similarité entre les deux images (0 à 100) | | dimensions | object | Largeur et hauteur utilisées pour la comparaison | | downloadUrl | string | URL pour télécharger l'image de différence générée | | originalSize | number | Taille combinée des deux images d'entrée en octets | | processedSize | number | Taille de l'image de différence en sortie en octets | ## Notes {#notes} * Les deux images sont redimensionnées aux mêmes dimensions (le maximum de chaque axe) avant la comparaison. * L'image de différence met en évidence les écarts en rouge avec une opacité proportionnelle à l'ampleur du changement. Les pixels identiques ou quasi identiques (différence < 10) sont affichés sous forme de versions semi-transparentes de l'original. * La similarité est calculée comme l'inverse de la différence moyenne des pixels sur l'ensemble des pixels, exprimée en pourcentage. * Une similarité de 100 % signifie que les images sont identiques au pixel près (à la résolution de comparaison). * La sortie de différence est toujours au format PNG, quels que soient les formats d'entrée. * Les deux images sont validées et décodées (HEIC, RAW, PSD, SVG pris en charge) avant la comparaison. * L'orientation EXIF est appliquée automatiquement sur les deux images avant le traitement. --- --- url: https://docs.snapotter.com/es/tools/image/compare.md description: >- Compara dos imágenes lado a lado con visualización de diferencias a nivel de píxel y puntuación de similitud. --- # Comparar imágenes {#image-compare} Sube dos imágenes para calcular un mapa de diferencias a nivel de píxel y un porcentaje numérico de similitud. La salida es una imagen de diferencias que resalta en rojo las regiones que cambiaron. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/compare` Acepta datos de formulario multipart con **dos** archivos de imagen. No se necesita ningún campo de ajustes. ## Parámetros {#parameters} Esta herramienta no tiene parámetros configurables. Sube exactamente dos archivos de imagen. | Campo | Tipo | Obligatorio | Descripción | |-------|------|----------|-------------| | file (primero) | file | Sí | La primera imagen | | file (segundo) | file | Sí | La segunda imagen | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Campos de respuesta {#response-fields} | Campo | Tipo | Descripción | |-------|------|-------------| | jobId | string | Identificador del trabajo para descargar la imagen de diferencias | | similarity | number | Porcentaje de similitud entre las dos imágenes (0 a 100) | | dimensions | object | Ancho y alto usados para la comparación | | downloadUrl | string | URL para descargar la imagen de diferencias generada | | originalSize | number | Tamaño combinado de ambas imágenes de entrada en bytes | | processedSize | number | Tamaño de la imagen de diferencias de salida en bytes | ## Notas {#notes} * Ambas imágenes se redimensionan a las mismas dimensiones (el máximo de cada eje) antes de la comparación. * La imagen de diferencias resalta las diferencias en rojo con una opacidad proporcional a la magnitud del cambio. Los píxeles idénticos o casi idénticos (diferencia < 10) se muestran como versiones semitransparentes del original. * La similitud se calcula como el inverso de la diferencia media de píxeles en todos los píxeles, expresada como porcentaje. * Una similitud del 100 % significa que las imágenes son idénticas píxel a píxel (a la resolución de comparación). * La salida de diferencias siempre está en formato PNG, sin importar los formatos de entrada. * Ambas imágenes se validan y decodifican (se admiten HEIC, RAW, PSD, SVG) antes de la comparación. * La orientación EXIF se aplica automáticamente a ambas imágenes antes del procesamiento. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/compare.md description: >- Compare duas imagens lado a lado com visualização de diferença em nível de pixel e pontuação de similaridade. --- # Comparar Imagens {#image-compare} Envie duas imagens para calcular um mapa de diferença em nível de pixel e uma porcentagem numérica de similaridade. A saída é uma imagem de diferença que destaca em vermelho as regiões alteradas. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/compare` Aceita dados de formulário multipart com **duas** imagens. Nenhum campo de configuração é necessário. ## Parâmetros {#parameters} Esta ferramenta não tem parâmetros configuráveis. Envie exatamente duas imagens. | Campo | Tipo | Obrigatório | Descrição | |-------|------|----------|-------------| | file (primeira) | file | Sim | A primeira imagem | | file (segunda) | file | Sim | A segunda imagem | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Campos da Resposta {#response-fields} | Campo | Tipo | Descrição | |-------|------|-------------| | jobId | string | Identificador do trabalho para baixar a imagem de diferença | | similarity | number | Porcentagem de similaridade entre as duas imagens (0 a 100) | | dimensions | object | Largura e altura usadas na comparação | | downloadUrl | string | URL para baixar a imagem de diferença gerada | | originalSize | number | Tamanho combinado de ambas as imagens de entrada em bytes | | processedSize | number | Tamanho da imagem de diferença de saída em bytes | ## Notas {#notes} * Ambas as imagens são redimensionadas para as mesmas dimensões (o máximo de cada eixo) antes da comparação. * A imagem de diferença destaca as diferenças em vermelho com opacidade proporcional à magnitude da mudança. Pixels idênticos ou quase idênticos (diferença < 10) são exibidos como versões semitransparentes do original. * A similaridade é calculada como o inverso da diferença média de pixels em todos os pixels, expressa como porcentagem. * Uma similaridade de 100% significa que as imagens são idênticas pixel a pixel (na resolução de comparação). * A saída de diferença é sempre no formato PNG, independentemente dos formatos de entrada. * Ambas as imagens são validadas e decodificadas (HEIC, RAW, PSD, SVG suportados) antes da comparação. * A orientação EXIF é aplicada automaticamente em ambas as imagens antes do processamento. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/compose.md description: >- Sobreponha imagens com posição, opacidade e modos de mesclagem para composição. --- # Composição de Imagens {#image-composition} Sobreponha uma imagem de sobreposição em cima de uma imagem base com posição, opacidade e modo de mesclagem configuráveis. Útil para compor logotipos, gráficos ou combinar várias imagens. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/compose` Aceita dados de formulário multipart com **duas** imagens e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | x | number | Não | `0` | Deslocamento horizontal da sobreposição a partir do canto superior esquerdo em pixels (mín. 0) | | y | number | Não | `0` | Deslocamento vertical da sobreposição a partir do canto superior esquerdo em pixels (mín. 0) | | opacity | number | Não | `100` | Porcentagem de opacidade da sobreposição (0 a 100) | | blendMode | string | Não | `"over"` | Modo de mesclagem da composição | ### Modos de Mesclagem {#blend-modes} | Valor | Descrição | |-------|-------------| | `over` | Sobreposição normal (padrão) | | `multiply` | Escurece multiplicando os valores dos pixels | | `screen` | Clareia invertendo, multiplicando e invertendo novamente | | `overlay` | Combina multiplicação e clareamento com base no brilho da base | | `darken` | Mantém o pixel mais escuro de cada camada | | `lighten` | Mantém o pixel mais claro de cada camada | | `hard-light` | Sobreposição de forte contraste | | `soft-light` | Sobreposição de contraste sutil | | `difference` | Diferença absoluta entre as camadas | | `exclusion` | Semelhante à diferença, mas com menor contraste | ### Campos de Arquivo {#file-fields} | Nome do Campo | Obrigatório | Descrição | |------------|----------|-------------| | file | Sim | A imagem base/de fundo | | overlay | Sim | A imagem de sobreposição/primeiro plano | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Usando o modo de mesclagem multiplicação: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Notas {#notes} * Ambas as imagens são validadas e decodificadas (HEIC, RAW, PSD, SVG suportados) antes da composição. * A sobreposição é posicionada nas coordenadas exatas de pixel especificadas por `x` e `y`. Ela não é redimensionada para caber. * Se a opacidade for menor que 100, uma máscara alfa é aplicada à sobreposição antes da mesclagem. * A sobreposição pode se estender além dos limites da imagem base (ela será recortada). * A orientação EXIF é aplicada automaticamente em ambas as imagens antes do processamento. * As dimensões de saída correspondem às dimensões da imagem base. --- --- url: https://docs.snapotter.com/es/tools/image/compose.md description: Superpone imágenes con posición, opacidad y modos de fusión para composición. --- # Composición de imágenes {#image-composition} Superpone una imagen sobre una imagen base con posición, opacidad y modo de fusión configurables. Útil para componer logotipos, gráficos o combinar varias imágenes. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/compose` Acepta datos de formulario multipart con **dos** archivos de imagen y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | x | number | No | `0` | Desplazamiento horizontal de la superposición desde la esquina superior izquierda en píxeles (mín. 0) | | y | number | No | `0` | Desplazamiento vertical de la superposición desde la esquina superior izquierda en píxeles (mín. 0) | | opacity | number | No | `100` | Porcentaje de opacidad de la superposición (0 a 100) | | blendMode | string | No | `"over"` | Modo de fusión de la composición | ### Modos de fusión {#blend-modes} | Valor | Descripción | |-------|-------------| | `over` | Superposición normal (predeterminado) | | `multiply` | Oscurece multiplicando los valores de los píxeles | | `screen` | Aclara invirtiendo, multiplicando e invirtiendo de nuevo | | `overlay` | Combina multiplicar y trama según el brillo de la base | | `darken` | Conserva el píxel más oscuro de cada capa | | `lighten` | Conserva el píxel más claro de cada capa | | `hard-light` | Superposición de contraste fuerte | | `soft-light` | Superposición de contraste sutil | | `difference` | Diferencia absoluta entre las capas | | `exclusion` | Similar a la diferencia pero con menor contraste | ### Campos de archivo {#file-fields} | Nombre del campo | Obligatorio | Descripción | |------------|----------|-------------| | file | Sí | La imagen base/de fondo | | overlay | Sí | La imagen superpuesta/de primer plano | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Usando el modo de fusión multiplicar: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Notas {#notes} * Ambas imágenes se validan y decodifican (se admiten HEIC, RAW, PSD, SVG) antes de la composición. * La superposición se coloca en las coordenadas exactas de píxel especificadas por `x` y `y`. No se redimensiona para ajustarse. * Si la opacidad es menor que 100, se aplica una máscara alfa a la superposición antes de la fusión. * La superposición puede extenderse más allá de los límites de la imagen base (se recortará). * La orientación EXIF se aplica automáticamente a ambas imágenes antes del procesamiento. * Las dimensiones de salida coinciden con las dimensiones de la imagen base. --- --- url: https://docs.snapotter.com/fr/tools/image/compose.md description: >- Superposez des images avec position, opacité et modes de fusion pour la composition. --- # Composition d'images {#image-composition} Superposez une image de recouvrement au-dessus d'une image de base avec une position, une opacité et un mode de fusion configurables. Utile pour composer des logos, des graphiques ou combiner plusieurs images. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compose` Accepte des données de formulaire multipart avec **deux** fichiers image et un champ JSON `settings`. ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | x | number | Non | `0` | Décalage horizontal du recouvrement par rapport au coin supérieur gauche en pixels (min 0) | | y | number | Non | `0` | Décalage vertical du recouvrement par rapport au coin supérieur gauche en pixels (min 0) | | opacity | number | Non | `100` | Pourcentage d'opacité du recouvrement (0 à 100) | | blendMode | string | Non | `"over"` | Mode de fusion de composition | ### Blend Modes {#blend-modes} | Valeur | Description | |-------|-------------| | `over` | Recouvrement normal (par défaut) | | `multiply` | Assombrit en multipliant les valeurs des pixels | | `screen` | Éclaircit en inversant, multipliant, puis inversant à nouveau | | `overlay` | Combine multiply et screen selon la luminosité de la base | | `darken` | Conserve le pixel le plus sombre de chaque calque | | `lighten` | Conserve le pixel le plus clair de chaque calque | | `hard-light` | Recouvrement à fort contraste | | `soft-light` | Recouvrement à contraste subtil | | `difference` | Différence absolue entre les calques | | `exclusion` | Similaire à difference mais avec un contraste plus faible | ### File Fields {#file-fields} | Nom du champ | Requis | Description | |------------|----------|-------------| | file | Oui | L'image de base/d'arrière-plan | | overlay | Oui | L'image de recouvrement/de premier plan | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Avec le mode de fusion multiply : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Notes {#notes} * Les deux images sont validées et décodées (HEIC, RAW, PSD, SVG pris en charge) avant la composition. * Le recouvrement est placé aux coordonnées exactes en pixels spécifiées par `x` et `y`. Il n'est pas redimensionné pour s'ajuster. * Si l'opacité est inférieure à 100, un masque alpha est appliqué au recouvrement avant la fusion. * Le recouvrement peut dépasser les limites de l'image de base (il sera rogné). * L'orientation EXIF est appliquée automatiquement sur les deux images avant le traitement. * Les dimensions de sortie correspondent aux dimensions de l'image de base. --- --- url: https://docs.snapotter.com/it/tools/image/compose.md description: >- Sovrapponi immagini con posizione, opacità e modalità di fusione per il compositing. --- # Composizione immagini {#image-composition} Sovrapponi un'immagine in overlay sopra un'immagine di base con posizione, opacità e modalità di fusione configurabili. Utile per comporre loghi, grafica o combinare più immagini. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/compose` Accetta dati di form multipart con **due** file immagine e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | x | number | No | `0` | Offset orizzontale dell'overlay dall'angolo in alto a sinistra in pixel (min 0) | | y | number | No | `0` | Offset verticale dell'overlay dall'angolo in alto a sinistra in pixel (min 0) | | opacity | number | No | `100` | Percentuale di opacità dell'overlay (da 0 a 100) | | blendMode | string | No | `"over"` | Modalità di fusione del compositing | ### Modalità di fusione {#blend-modes} | Valore | Descrizione | |-------|-------------| | `over` | Overlay normale (predefinito) | | `multiply` | Scurisci moltiplicando i valori dei pixel | | `screen` | Schiarisci invertendo, moltiplicando e invertendo di nuovo | | `overlay` | Combina multiply e screen in base alla luminosità della base | | `darken` | Mantieni il pixel più scuro di ciascun livello | | `lighten` | Mantieni il pixel più chiaro di ciascun livello | | `hard-light` | Overlay a forte contrasto | | `soft-light` | Overlay a contrasto tenue | | `difference` | Differenza assoluta tra i livelli | | `exclusion` | Simile a difference ma con contrasto minore | ### Campi dei file {#file-fields} | Nome del campo | Obbligatorio | Descrizione | |------------|----------|-------------| | file | Sì | L'immagine di base/sfondo | | overlay | Sì | L'immagine in overlay/primo piano | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Usando la modalità di fusione multiply: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Note {#notes} * Entrambe le immagini vengono validate e decodificate (HEIC, RAW, PSD, SVG supportati) prima del compositing. * L'overlay viene posizionato alle coordinate esatte in pixel specificate da `x` e `y`. Non viene ridimensionato per adattarsi. * Se l'opacità è inferiore a 100, una maschera alfa viene applicata all'overlay prima della fusione. * L'overlay può estendersi oltre i confini dell'immagine di base (verrà ritagliato). * L'orientamento EXIF viene applicato automaticamente su entrambe le immagini prima dell'elaborazione. * Le dimensioni di output corrispondono alle dimensioni dell'immagine di base. --- --- url: https://docs.snapotter.com/ar/tools/pdf/compress-pdf.md description: تقليل حجم ملف PDF عن طريق ضغط الصور المضمّنة. --- # Compress PDF {#compress-pdf} قلّل حجم ملف PDF عن طريق تقليل دقة الصور المضمّنة. اختر بين شريط تمرير للجودة أو حجم ملف مستهدف. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` يقبل بيانات نموذج multipart تحتوي على ملف PDF وحقل `settings` بصيغة JSON. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | وضع الضغط: `quality` أو `targetSize` | | quality | integer | No | `75` | جودة الضغط، من 1 إلى 100 (الأعلى = ضغط أقل). يُستخدم في وضع `quality` | | targetSizeKb | number | No | - | حجم الملف المستهدف بالكيلوبايت. يُستخدم في وضع `targetSize` | ## Example Request {#example-request} الضغط حسب الجودة: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` الضغط إلى حجم مستهدف: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * في وضع `quality`، تُنتج القيم الأقل ملفات أصغر مع تدهور أكبر في الصور. * في وضع `targetSize`، يعثر البحث الثنائي على أعلى قيمة DPI تناسب الحجم المطلوب. * إذا كان الضغط سيؤدي إلى تكبير الملف، تُعاد وحدات البايت الأصلية دون تغيير. * لا يتأثر المحتوى النصي والمتّجه؛ تُقلّل دقة الصور النقطية المضمّنة فقط. --- --- url: https://docs.snapotter.com/hi/tools/pdf/compress-pdf.md description: एम्बेडेड इमेज को कंप्रेस करके PDF फ़ाइल का आकार घटाएं। --- # Compress PDF {#compress-pdf} एम्बेडेड इमेज को डाउनसैंपल करके PDF फ़ाइल का आकार कम करें। क्वालिटी स्लाइडर या लक्षित फ़ाइल आकार में से किसी एक को चुनें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` एक PDF फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | कंप्रेशन मोड: `quality` या `targetSize` | | quality | integer | No | `75` | कंप्रेशन क्वालिटी, 1-100 (अधिक = कम कंप्रेशन)। `quality` मोड में उपयोग किया जाता है | | targetSizeKb | number | No | - | किलोबाइट में लक्षित फ़ाइल आकार। `targetSize` मोड में उपयोग किया जाता है | ## Example Request {#example-request} क्वालिटी के अनुसार कंप्रेस करें: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` एक लक्षित आकार तक कंप्रेस करें: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * `quality` मोड में, कम मान अधिक इमेज गिरावट के साथ छोटी फ़ाइलें बनाते हैं। * `targetSize` मोड में, एक बाइनरी सर्च वह उच्चतम DPI ढूँढता है जो अनुरोधित आकार में फिट होता है। * यदि कंप्रेशन फ़ाइल को बड़ा कर देगा, तो मूल बाइट्स अपरिवर्तित लौटाए जाते हैं। * टेक्स्ट और वेक्टर सामग्री प्रभावित नहीं होती; केवल एम्बेडेड रास्टर इमेज को डाउनसैंपल किया जाता है। --- --- url: https://docs.snapotter.com/id/tools/pdf/compress-pdf.md description: Perkecil ukuran file PDF dengan mengompresi gambar yang tertanam. --- # Compress PDF {#compress-pdf} Kurangi ukuran file PDF dengan menurunkan resolusi gambar yang tertanam. Pilih antara penggeser kualitas atau ukuran file target. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Menerima data form multipart berisi file PDF dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Mode kompresi: `quality` atau `targetSize` | | quality | integer | No | `75` | Kualitas kompresi, 1-100 (lebih tinggi = kompresi lebih sedikit). Digunakan dalam mode `quality` | | targetSizeKb | number | No | - | Ukuran file target dalam kilobyte. Digunakan dalam mode `targetSize` | ## Example Request {#example-request} Kompresi berdasarkan kualitas: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Kompresi ke ukuran target: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * Dalam mode `quality`, nilai yang lebih rendah menghasilkan file yang lebih kecil dengan degradasi gambar yang lebih besar. * Dalam mode `targetSize`, pencarian biner menemukan DPI tertinggi yang sesuai dengan ukuran yang diminta. * Jika kompresi malah memperbesar file, byte asli dikembalikan tanpa perubahan. * Konten teks dan vektor tidak terpengaruh; hanya gambar raster yang tertanam yang diturunkan resolusinya. --- --- url: https://docs.snapotter.com/ja/tools/pdf/compress-pdf.md description: 埋め込み画像を圧縮して PDF のファイルサイズを縮小します。 --- # Compress PDF {#compress-pdf} 埋め込み画像をダウンサンプリングして PDF のファイルサイズを削減します。品質スライダーと目標ファイルサイズのどちらかを選択できます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` PDF ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | 圧縮モード: `quality` または `targetSize` | | quality | integer | No | `75` | 圧縮品質、1〜100(高いほど圧縮が弱い)。`quality` モードで使用 | | targetSizeKb | number | No | - | 目標ファイルサイズ(キロバイト単位)。`targetSize` モードで使用 | ## Example Request {#example-request} 品質で圧縮する場合: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` 目標サイズまで圧縮する場合: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * `quality` モードでは、値を小さくするほどファイルは小さくなりますが、画像の劣化が大きくなります。 * `targetSize` モードでは、二分探索によって要求サイズに収まる最高の DPI を見つけます。 * 圧縮によってファイルが大きくなる場合は、元のバイト列がそのまま返されます。 * テキストやベクターコンテンツは影響を受けません。埋め込みラスター画像のみがダウンサンプリングされます。 --- --- url: https://docs.snapotter.com/ko/tools/pdf/compress-pdf.md description: 내장된 이미지를 압축하여 PDF 파일 크기를 줄입니다. --- # Compress PDF {#compress-pdf} 내장된 이미지를 다운샘플링하여 PDF 파일 크기를 줄입니다. 품질 슬라이더와 목표 파일 크기 중에서 선택할 수 있습니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` PDF 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | 압축 모드: `quality` 또는 `targetSize` | | quality | integer | No | `75` | 압축 품질, 1-100 (높을수록 압축이 적음). `quality` 모드에서 사용됨 | | targetSizeKb | number | No | - | 목표 파일 크기(킬로바이트). `targetSize` 모드에서 사용됨 | ## Example Request {#example-request} 품질로 압축: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` 목표 크기로 압축: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * `quality` 모드에서는 값이 낮을수록 파일이 작아지지만 이미지 열화가 심해집니다. * `targetSize` 모드에서는 이진 탐색으로 요청한 크기에 맞는 가장 높은 DPI를 찾습니다. * 압축이 오히려 파일을 키우게 되는 경우, 원본 바이트가 변경 없이 반환됩니다. * 텍스트와 벡터 콘텐츠는 영향을 받지 않으며, 내장된 래스터 이미지만 다운샘플링됩니다. --- --- url: https://docs.snapotter.com/nl/tools/pdf/compress-pdf.md description: >- Verklein de bestandsgrootte van een PDF door ingebedde afbeeldingen te comprimeren. --- # Compress PDF {#compress-pdf} Verklein de bestandsgrootte van een PDF door ingebedde afbeeldingen te downsamplen. Kies tussen een kwaliteitsschuif of een doelbestandsgrootte. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Accepteert multipart-formuliergegevens met een PDF-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | mode | string | Nee | `"quality"` | Compressiemodus: `quality` of `targetSize` | | quality | integer | Nee | `75` | Compressiekwaliteit, 1-100 (hoger = minder compressie). Gebruikt in de modus `quality` | | targetSizeKb | number | Nee | - | Doelbestandsgrootte in kilobytes. Gebruikt in de modus `targetSize` | ## Example Request {#example-request} Comprimeren op kwaliteit: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimeren naar een doelgrootte: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * In de modus `quality` produceren lagere waarden kleinere bestanden met meer beeldkwaliteitsverlies. * In de modus `targetSize` vindt een binaire zoekopdracht de hoogste DPI die binnen de gevraagde grootte past. * Als compressie het bestand zou vergroten, worden de originele bytes ongewijzigd teruggegeven. * Tekst en vectorinhoud worden niet beïnvloed; alleen ingebedde rasterafbeeldingen worden gedownsampled. --- --- url: https://docs.snapotter.com/pl/tools/pdf/compress-pdf.md description: Zmniejsz rozmiar pliku PDF przez kompresję osadzonych obrazów. --- # Compress PDF {#compress-pdf} Zmniejsz rozmiar pliku PDF przez zmniejszenie rozdzielczości osadzonych obrazów. Wybierz suwak jakości albo docelowy rozmiar pliku. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Przyjmuje dane formularza multipart z plikiem PDF oraz polem JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Tryb kompresji: `quality` lub `targetSize` | | quality | integer | No | `75` | Jakość kompresji, 1-100 (wyższa = mniejsza kompresja). Używane w trybie `quality` | | targetSizeKb | number | No | - | Docelowy rozmiar pliku w kilobajtach. Używane w trybie `targetSize` | ## Example Request {#example-request} Kompresja według jakości: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Kompresja do docelowego rozmiaru: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * W trybie `quality` niższe wartości dają mniejsze pliki z większą degradacją obrazu. * W trybie `targetSize` wyszukiwanie binarne znajduje najwyższe DPI mieszczące się w żądanym rozmiarze. * Jeśli kompresja miałaby powiększyć plik, zwracane są niezmienione oryginalne bajty. * Treść tekstowa i wektorowa nie jest zmieniana; zmniejszana jest tylko rozdzielczość osadzonych obrazów rastrowych. --- --- url: https://docs.snapotter.com/pt-BR/tools/pdf/compress-pdf.md description: Reduza o tamanho do arquivo PDF comprimindo as imagens incorporadas. --- # Compress PDF {#compress-pdf} Reduza o tamanho do arquivo PDF fazendo o downsampling das imagens incorporadas. Escolha entre um controle deslizante de qualidade ou um tamanho de arquivo alvo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Aceita dados de formulário multipart com um arquivo PDF e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | mode | string | Não | `"quality"` | Modo de compressão: `quality` ou `targetSize` | | quality | integer | Não | `75` | Qualidade da compressão, 1-100 (maior = menos compressão). Usado no modo `quality` | | targetSizeKb | number | Não | - | Tamanho de arquivo alvo em kilobytes. Usado no modo `targetSize` | ## Example Request {#example-request} Comprimir por qualidade: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimir para um tamanho alvo: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * No modo `quality`, valores mais baixos produzem arquivos menores com mais degradação da imagem. * No modo `targetSize`, uma busca binária encontra o maior DPI que cabe no tamanho solicitado. * Se a compressão aumentar o tamanho do arquivo, os bytes originais são retornados sem alteração. * O conteúdo de texto e vetorial não é afetado; apenas as imagens raster incorporadas passam por downsampling. --- --- url: https://docs.snapotter.com/ru/tools/pdf/compress-pdf.md description: Уменьшение размера PDF-файла за счёт сжатия встроенных изображений. --- # Compress PDF {#compress-pdf} Уменьшите размер PDF-файла за счёт понижения разрешения встроенных изображений. Выберите между ползунком качества и целевым размером файла. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Принимает данные multipart form с PDF-файлом и JSON-полем `settings`. ## Parameters {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | mode | string | Нет | `"quality"` | Режим сжатия: `quality` или `targetSize` | | quality | integer | Нет | `75` | Качество сжатия, 1-100 (выше = меньше сжатие). Используется в режиме `quality` | | targetSizeKb | number | Нет | - | Целевой размер файла в килобайтах. Используется в режиме `targetSize` | ## Example Request {#example-request} Сжатие по качеству: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Сжатие до целевого размера: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * В режиме `quality` более низкие значения дают меньшие файлы с большей потерей качества изображений. * В режиме `targetSize` бинарный поиск находит максимальное разрешение DPI, укладывающееся в запрошенный размер. * Если сжатие увеличило бы файл, исходные байты возвращаются без изменений. * Текст и векторное содержимое не затрагиваются; понижается разрешение только встроенных растровых изображений. --- --- url: https://docs.snapotter.com/sv/tools/pdf/compress-pdf.md description: Krymp PDF-filstorleken genom att komprimera inbäddade bilder. --- # Compress PDF {#compress-pdf} Minska PDF-filstorleken genom att nedsampla inbäddade bilder. Välj mellan ett kvalitetsreglage eller en målfilstorlek. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Tar emot multipart-formulärdata med en PDF-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | mode | string | Nej | `"quality"` | Komprimeringsläge: `quality` eller `targetSize` | | quality | integer | Nej | `75` | Komprimeringskvalitet, 1-100 (högre = mindre komprimering). Används i läget `quality` | | targetSizeKb | number | Nej | - | Målfilstorlek i kilobyte. Används i läget `targetSize` | ## Example Request {#example-request} Komprimera efter kvalitet: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Komprimera till en målstorlek: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * I läget `quality` ger lägre värden mindre filer med mer bildförsämring. * I läget `targetSize` hittar en binärsökning den högsta DPI som får plats inom den begärda storleken. * Om komprimeringen skulle förstora filen returneras originalbyten oförändrade. * Text och vektorinnehåll påverkas inte; endast inbäddade rasterbilder nedsamplas. --- --- url: https://docs.snapotter.com/th/tools/pdf/compress-pdf.md description: ลดขนาดไฟล์ PDF โดยการบีบอัดรูปภาพที่ฝังอยู่ --- # Compress PDF {#compress-pdf} ลดขนาดไฟล์ PDF ด้วยการลดความละเอียดของรูปภาพที่ฝังอยู่ เลือกได้ระหว่างแถบเลื่อนปรับคุณภาพหรือขนาดไฟล์เป้าหมาย ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` รับข้อมูลแบบ multipart form data พร้อมไฟล์ PDF และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | โหมดการบีบอัด: `quality` หรือ `targetSize` | | quality | integer | No | `75` | คุณภาพการบีบอัด 1-100 (ค่ายิ่งสูง = บีบอัดน้อยลง) ใช้ในโหมด `quality` | | targetSizeKb | number | No | - | ขนาดไฟล์เป้าหมายเป็นกิโลไบต์ ใช้ในโหมด `targetSize` | ## Example Request {#example-request} บีบอัดตามคุณภาพ: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` บีบอัดให้ได้ขนาดเป้าหมาย: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * ในโหมด `quality` ค่ายิ่งต่ำจะได้ไฟล์ที่เล็กลงแต่รูปภาพเสื่อมคุณภาพมากขึ้น * ในโหมด `targetSize` การค้นหาแบบไบนารีจะหาค่า DPI สูงสุดที่พอดีกับขนาดที่ต้องการ * หากการบีบอัดจะทำให้ไฟล์ใหญ่ขึ้น ระบบจะคืนไบต์ต้นฉบับกลับมาโดยไม่เปลี่ยนแปลง * เนื้อหาที่เป็นข้อความและเวกเตอร์จะไม่ได้รับผลกระทบ มีเพียงรูปภาพแรสเตอร์ที่ฝังอยู่เท่านั้นที่ถูกลดความละเอียด --- --- url: https://docs.snapotter.com/uk/tools/pdf/compress-pdf.md description: Зменшення розміру файлу PDF шляхом стиснення вбудованих зображень. --- # Compress PDF {#compress-pdf} Зменшуйте розмір файлу PDF шляхом зниження роздільної здатності вбудованих зображень. Оберіть повзунок якості або цільовий розмір файлу. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Приймає багаточастинні (multipart) дані форми з файлом PDF та полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Режим стиснення: `quality` або `targetSize` | | quality | integer | No | `75` | Якість стиснення, 1-100 (вище = менше стиснення). Використовується в режимі `quality` | | targetSizeKb | number | No | - | Цільовий розмір файлу в кілобайтах. Використовується в режимі `targetSize` | ## Example Request {#example-request} Стиснення за якістю: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Стиснення до цільового розміру: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * У режимі `quality` нижчі значення дають менші файли з більшою деградацією зображення. * У режимі `targetSize` двійковий пошук знаходить найвищий DPI, який вкладається в запитаний розмір. * Якщо стиснення збільшило б файл, повертаються вихідні байти без змін. * Текст і векторний вміст не зазнають впливу; знижується роздільна здатність лише вбудованих растрових зображень. --- --- url: https://docs.snapotter.com/vi/tools/pdf/compress-pdf.md description: Giảm kích thước tệp PDF bằng cách nén các hình ảnh nhúng. --- # Compress PDF {#compress-pdf} Giảm kích thước tệp PDF bằng cách hạ độ phân giải các hình ảnh nhúng. Chọn giữa thanh trượt chất lượng hoặc kích thước tệp mục tiêu. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Chấp nhận dữ liệu biểu mẫu multipart với một tệp PDF và một trường JSON `settings`. ## Parameters {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | mode | string | Không | `"quality"` | Chế độ nén: `quality` hoặc `targetSize` | | quality | integer | Không | `75` | Chất lượng nén, 1-100 (càng cao = nén càng ít). Dùng trong chế độ `quality` | | targetSizeKb | number | Không | - | Kích thước tệp mục tiêu tính bằng kilobyte. Dùng trong chế độ `targetSize` | ## Example Request {#example-request} Nén theo chất lượng: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Nén xuống kích thước mục tiêu: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * Ở chế độ `quality`, giá trị thấp hơn tạo ra tệp nhỏ hơn nhưng hình ảnh suy giảm nhiều hơn. * Ở chế độ `targetSize`, một tìm kiếm nhị phân tìm DPI cao nhất vừa với kích thước yêu cầu. * Nếu việc nén khiến tệp lớn hơn, dữ liệu byte gốc được trả về nguyên vẹn. * Nội dung văn bản và vector không bị ảnh hưởng; chỉ các hình ảnh raster nhúng mới bị hạ độ phân giải. --- --- url: https://docs.snapotter.com/zh-CN/tools/pdf/compress-pdf.md description: 通过压缩嵌入的图像来缩减 PDF 文件大小。 --- # Compress PDF {#compress-pdf} 通过对嵌入的图像进行降采样来缩减 PDF 文件大小。可在质量滑块和目标文件大小之间选择。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` 接受包含一个 PDF 文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | 压缩模式:`quality` 或 `targetSize` | | quality | integer | No | `75` | 压缩质量,1-100(值越高压缩越少)。在 `quality` 模式下使用 | | targetSizeKb | number | No | - | 以千字节为单位的目标文件大小。在 `targetSize` 模式下使用 | ## Example Request {#example-request} 按质量压缩: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` 压缩到目标大小: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * 在 `quality` 模式下,值越低生成的文件越小,但图像退化越严重。 * 在 `targetSize` 模式下,二分查找会找到能够容纳所请求大小的最高 DPI。 * 如果压缩会使文件变大,则原始字节将原样返回。 * 文本和矢量内容不受影响;只有嵌入的栅格图像会被降采样。 --- --- url: https://docs.snapotter.com/ar/tools/video/compress-video.md description: تقليص حجم ملف الفيديو مع التحكم في الجودة. --- # Compress Video {#compress-video} تقليص حجم ملف الفيديو باستخدام قوة ضغط قابلة للتهيئة وتخفيض اختياري للدقة. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو وحقل JSON `settings`. هذه نقطة نهاية غير متزامنة - تُرجع `202 Accepted` فوراً ويُبَثّ التقدم عبر SSE على `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | قوة الضغط: `light` أو `balanced` أو `strong` | | resolution | string | No | `"original"` | دقة الإخراج: `original` أو `1080p` أو `720p` أو `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * يحافظ الإعداد المسبق `light` على جودة قريبة من الأصل. يقلل الإعداد المسبق `strong` حجم الملف بقوة على حساب دقة الصورة. * تخفيض الدقة (مثلاً من 4K إلى 720p) يتضاعف مع الضغط لتقليل الحجم بشكل كبير. * تحديثات التقدم متاحة عبر SSE على `GET /api/v1/jobs/{jobId}/progress` حتى تكتمل المهمة. --- --- url: https://docs.snapotter.com/de/tools/video/compress-video.md description: Videodateigröße mit Qualitätssteuerung verringern. --- # Compress Video {#compress-video} Videodateigröße mit konfigurierbarer Kompressionsstärke und optionaler Auflösungsreduzierung verringern. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Nimmt Multipart-Formulardaten mit einer Videodatei und einem JSON-Feld `settings` entgegen. Dies ist ein asynchroner Endpunkt: Er gibt sofort `202 Accepted` zurück, und der Fortschritt wird per SSE unter `GET /api/v1/jobs/{jobId}/progress` gestreamt. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Kompressionsstärke: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Ausgabeauflösung: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Die Voreinstellung `light` bewahrt eine nahezu originalgetreue Qualität. Die Voreinstellung `strong` verringert die Dateigröße aggressiv auf Kosten der visuellen Wiedergabetreue. * Die Auflösungsreduzierung (z. B. von 4K auf 720p) verstärkt sich zusammen mit der Kompression für eine deutliche Größenreduzierung. * Fortschrittsaktualisierungen sind per SSE unter `GET /api/v1/jobs/{jobId}/progress` verfügbar, bis der Job abgeschlossen ist. --- --- url: https://docs.snapotter.com/es/tools/video/compress-video.md description: Reduce el tamaño de archivo del vídeo con control de calidad. --- # Compress Video {#compress-video} Reduce el tamaño de archivo del vídeo usando una intensidad de compresión configurable y un escalado de resolución opcional. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Acepta datos de formulario multipart con un archivo de vídeo y un campo JSON `settings`. Este es un endpoint asíncrono: devuelve `202 Accepted` de inmediato y el progreso se transmite vía SSE en `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Intensidad de compresión: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Resolución de salida: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * El preajuste `light` conserva una calidad casi original. El preajuste `strong` reduce el tamaño de archivo de forma agresiva a costa de la fidelidad visual. * Reducir la resolución (por ejemplo, de 4K a 720p) se combina con la compresión para lograr una reducción de tamaño considerable. * Las actualizaciones de progreso están disponibles vía SSE en `GET /api/v1/jobs/{jobId}/progress` hasta que el trabajo se completa. --- --- url: https://docs.snapotter.com/fr/tools/video/compress-video.md description: Réduit la taille du fichier vidéo avec un contrôle de la qualité. --- # Compress Video {#compress-video} Réduit la taille du fichier vidéo à l'aide d'une force de compression configurable et d'une réduction facultative de la résolution. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Accepte des données de formulaire multipart avec un fichier vidéo et un champ JSON `settings`. Il s'agit d'un point de terminaison asynchrone : il renvoie immédiatement `202 Accepted` et la progression est diffusée via SSE sur `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Force de compression : `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Résolution de sortie : `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Le préréglage `light` préserve une qualité proche de l'originale. Le préréglage `strong` réduit agressivement la taille du fichier au détriment de la fidélité visuelle. * La réduction de la résolution (par exemple de 4K à 720p) se cumule avec la compression pour une réduction de taille importante. * Les mises à jour de progression sont disponibles via SSE sur `GET /api/v1/jobs/{jobId}/progress` jusqu'à la fin de la tâche. --- --- url: https://docs.snapotter.com/hi/tools/video/compress-video.md description: गुणवत्ता नियंत्रण के साथ वीडियो फ़ाइल आकार सिकोड़ें। --- # Compress Video {#compress-video} समायोज्य संपीड़न सामर्थ्य और वैकल्पिक रिज़ॉल्यूशन डाउनस्केलिंग का उपयोग करके वीडियो फ़ाइल आकार सिकोड़ें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। यह एक async endpoint है - यह तुरंत `202 Accepted` लौटाता है और प्रगति `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से स्ट्रीम की जाती है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | संपीड़न सामर्थ्य: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | आउटपुट रिज़ॉल्यूशन: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `light` प्रीसेट लगभग मूल गुणवत्ता को बनाए रखता है। `strong` प्रीसेट दृश्य निष्ठा की कीमत पर फ़ाइल आकार को आक्रामक रूप से घटाता है। * रिज़ॉल्यूशन डाउनस्केल करना (जैसे 4K से 720p तक) महत्वपूर्ण आकार कमी के लिए संपीड़न के साथ मिलकर काम करता है। * जॉब पूरा होने तक `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति अपडेट उपलब्ध रहते हैं। --- --- url: https://docs.snapotter.com/id/tools/video/compress-video.md description: Memperkecil ukuran file video dengan kontrol kualitas. --- # Compress Video {#compress-video} Memperkecil ukuran file video menggunakan kekuatan kompresi yang dapat dikonfigurasi dan penurunan resolusi opsional. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Menerima multipart form data dengan file video dan field JSON `settings`. Ini adalah endpoint asinkron - ia langsung mengembalikan `202 Accepted` dan progres dialirkan melalui SSE di `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Kekuatan kompresi: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Resolusi keluaran: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Preset `light` mempertahankan kualitas mendekati aslinya. Preset `strong` mengurangi ukuran file secara agresif dengan mengorbankan ketepatan visual. * Menurunkan resolusi (mis. dari 4K ke 720p) berkombinasi dengan kompresi untuk pengurangan ukuran yang signifikan. * Pembaruan progres tersedia melalui SSE di `GET /api/v1/jobs/{jobId}/progress` hingga job selesai. --- --- url: https://docs.snapotter.com/it/tools/video/compress-video.md description: Riduci la dimensione del file video con il controllo della qualità. --- # Compress Video {#compress-video} Riduci la dimensione del file video usando una forza di compressione configurabile e un ridimensionamento opzionale della risoluzione. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Accetta dati form multipart con un file video e un campo JSON `settings`. Questo è un endpoint asincrono: restituisce `202 Accepted` immediatamente e l'avanzamento viene trasmesso tramite SSE su `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Forza di compressione: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Risoluzione di output: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Il preset `light` conserva una qualità quasi originale. Il preset `strong` riduce la dimensione del file in modo aggressivo a scapito della fedeltà visiva. * Ridurre la risoluzione (ad es. da 4K a 720p) si somma alla compressione per una riduzione significativa delle dimensioni. * Gli aggiornamenti sull'avanzamento sono disponibili tramite SSE su `GET /api/v1/jobs/{jobId}/progress` finché il job non è completato. --- --- url: https://docs.snapotter.com/ja/tools/video/compress-video.md description: 品質を制御しながら動画ファイルサイズを縮小します。 --- # Compress Video {#compress-video} 設定可能な圧縮強度とオプションの解像度ダウンスケールを使用して、動画ファイルサイズを縮小します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。これは非同期エンドポイントで、即座に `202 Accepted` を返し、進捗は `GET /api/v1/jobs/{jobId}/progress` の SSE でストリーミングされます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | 圧縮強度: `light`、`balanced`、`strong` | | resolution | string | No | `"original"` | 出力解像度: `original`、`1080p`、`720p`、`480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `light` プリセットはほぼ元のままの品質を保ちます。`strong` プリセットは視覚的な忠実度を犠牲にして積極的にファイルサイズを削減します。 * 解像度のダウンスケール(例: 4K から 720p)は圧縮と組み合わさり、大幅なサイズ削減につながります。 * ジョブが完了するまで、進捗の更新は `GET /api/v1/jobs/{jobId}/progress` の SSE で確認できます。 --- --- url: https://docs.snapotter.com/ko/tools/video/compress-video.md description: 품질 제어와 함께 비디오 파일 크기를 줄입니다. --- # Compress Video {#compress-video} 구성 가능한 압축 강도와 선택적 해상도 다운스케일링을 사용하여 비디오 파일 크기를 줄입니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` 비디오 파일과 JSON `settings` 필드가 담긴 multipart form data를 받습니다. 이 엔드포인트는 비동기입니다. 즉시 `202 Accepted`를 반환하고 진행 상황은 `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 스트리밍됩니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | 압축 강도: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | 출력 해상도: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `light` 프리셋은 원본에 가까운 품질을 유지합니다. `strong` 프리셋은 시각적 충실도를 희생하면서 파일 크기를 적극적으로 줄입니다. * 해상도 다운스케일링(예: 4K에서 720p로)은 압축과 결합되어 크기를 크게 줄입니다. * 작업이 완료될 때까지 진행 상황 업데이트는 `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 제공됩니다. --- --- url: https://docs.snapotter.com/nl/tools/video/compress-video.md description: Videobestandsgrootte verkleinen met kwaliteitscontrole. --- # Compress Video {#compress-video} Verklein de videobestandsgrootte met een instelbare compressiesterkte en optioneel het verlagen van de resolutie. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Accepteert multipart form data met een videobestand en een JSON-veld `settings`. Dit is een async endpoint: het retourneert direct `202 Accepted` en de voortgang wordt via SSE gestreamd op `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | quality | string | Nee | `"balanced"` | Compressiesterkte: `light`, `balanced`, `strong` | | resolution | string | Nee | `"original"` | Uitvoerresolutie: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * De preset `light` behoudt een kwaliteit die bijna gelijk is aan het origineel. De preset `strong` verkleint de bestandsgrootte agressief ten koste van de visuele getrouwheid. * Het verlagen van de resolutie (bijvoorbeeld van 4K naar 720p) versterkt in combinatie met compressie de vermindering van de bestandsgrootte aanzienlijk. * Voortgangsupdates zijn beschikbaar via SSE op `GET /api/v1/jobs/{jobId}/progress` totdat de taak is voltooid. --- --- url: https://docs.snapotter.com/pl/tools/video/compress-video.md description: Zmniejszenie rozmiaru pliku wideo z kontrolą jakości. --- # Compress Video {#compress-video} Zmniejsza rozmiar pliku wideo przy użyciu konfigurowalnej siły kompresji i opcjonalnego zmniejszenia rozdzielczości. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Przyjmuje dane formularza multipart z plikiem wideo i polem JSON `settings`. To jest endpoint asynchroniczny - zwraca `202 Accepted` natychmiast, a postęp jest przesyłany strumieniowo przez SSE pod `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | quality | string | Nie | `"balanced"` | Siła kompresji: `light`, `balanced`, `strong` | | resolution | string | Nie | `"original"` | Rozdzielczość wyjściowa: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Ustawienie wstępne `light` zachowuje jakość zbliżoną do oryginalnej. Ustawienie wstępne `strong` agresywnie zmniejsza rozmiar pliku kosztem wierności wizualnej. * Zmniejszenie rozdzielczości (np. z 4K do 720p) łączy się z kompresją, dając znaczną redukcję rozmiaru. * Aktualizacje postępu są dostępne przez SSE pod `GET /api/v1/jobs/{jobId}/progress` aż do zakończenia zadania. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/compress-video.md description: Reduz o tamanho do arquivo de vídeo com controle de qualidade. --- # Compress Video {#compress-video} Reduz o tamanho do arquivo de vídeo usando uma força de compressão configurável e redução opcional de resolução. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. Este é um endpoint assíncrono - ele retorna `202 Accepted` imediatamente e o progresso é transmitido via SSE em `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | quality | string | Não | `"balanced"` | Força de compressão: `light`, `balanced`, `strong` | | resolution | string | Não | `"original"` | Resolução de saída: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * O preset `light` preserva a qualidade quase original. O preset `strong` reduz o tamanho do arquivo de forma agressiva à custa da fidelidade visual. * Reduzir a resolução (por exemplo, de 4K para 720p) se soma à compressão para uma redução significativa de tamanho. * As atualizações de progresso ficam disponíveis via SSE em `GET /api/v1/jobs/{jobId}/progress` até que o job seja concluído. --- --- url: https://docs.snapotter.com/ru/tools/video/compress-video.md description: Уменьшение размера файла видео с контролем качества. --- # Compress Video {#compress-video} Уменьшение размера файла видео с помощью настраиваемой степени сжатия и необязательного понижения разрешения. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Принимает multipart form data с файлом видео и полем JSON `settings`. Это асинхронная конечная точка: она сразу возвращает `202 Accepted`, а прогресс передаётся через SSE по адресу `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Степень сжатия: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Выходное разрешение: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Пресет `light` сохраняет качество, близкое к исходному. Пресет `strong` агрессивно уменьшает размер файла за счёт визуальной точности. * Понижение разрешения (например, с 4K до 720p) в сочетании со сжатием даёт значительное сокращение размера. * Обновления прогресса доступны через SSE по адресу `GET /api/v1/jobs/{jobId}/progress` до завершения задания. --- --- url: https://docs.snapotter.com/th/tools/video/compress-video.md description: ลดขนาดไฟล์วิดีโอพร้อมควบคุมคุณภาพ --- # Compress Video {#compress-video} ลดขนาดไฟล์วิดีโอโดยใช้ระดับการบีบอัดที่กำหนดค่าได้ และการลดความละเอียดเสริม ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` นี่คือ endpoint แบบ async โดยจะคืนค่า `202 Accepted` ทันที และความคืบหน้าจะถูกสตรีมผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | ระดับการบีบอัด: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | ความละเอียดเอาต์พุต: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * พรีเซ็ต `light` คงคุณภาพให้ใกล้เคียงต้นฉบับ ส่วนพรีเซ็ต `strong` ลดขนาดไฟล์อย่างมากโดยแลกกับความคมชัดของภาพ * การลดความละเอียด (เช่น จาก 4K เป็น 720p) จะเสริมกับการบีบอัดเพื่อลดขนาดได้อย่างมีนัยสำคัญ * การอัปเดตความคืบหน้าดูได้ผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` จนกว่างานจะเสร็จสมบูรณ์ --- --- url: https://docs.snapotter.com/tr/tools/video/compress-video.md description: Kalite kontrolüyle video dosya boyutunu küçültün. --- # Compress Video {#compress-video} Yapılandırılabilir sıkıştırma gücü ve isteğe bağlı çözünürlük küçültmesi kullanarak video dosya boyutunu küçültün. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Bir video dosyası ve bir JSON `settings` alanı içeren multipart form data kabul eder. Bu asenkron bir uç noktadır; hemen `202 Accepted` döndürür ve ilerleme `GET /api/v1/jobs/{jobId}/progress` adresinde SSE ile aktarılır. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Sıkıştırma gücü: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Çıktı çözünürlüğü: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `light` ön ayarı neredeyse orijinal kaliteyi korur. `strong` ön ayarı ise görsel doğruluk pahasına dosya boyutunu agresif şekilde azaltır. * Çözünürlüğü küçültmek (örneğin 4K'dan 720p'ye) sıkıştırmayla birleşerek belirgin bir boyut azalması sağlar. * İş tamamlanana kadar ilerleme güncellemeleri `GET /api/v1/jobs/{jobId}/progress` adresinde SSE ile sunulur. --- --- url: https://docs.snapotter.com/uk/tools/video/compress-video.md description: Зменшує розмір відеофайлу з контролем якості. --- # Compress Video {#compress-video} Зменшує розмір відеофайлу за допомогою налаштовуваної сили стиснення та необов'язкового зменшення роздільної здатності. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Приймає дані форми multipart із відеофайлом і полем JSON `settings`. Це асинхронний ендпоінт: він одразу повертає `202 Accepted`, а прогрес передається через SSE за адресою `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Сила стиснення: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Вихідна роздільна здатність: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Пресет `light` зберігає якість, близьку до оригінальної. Пресет `strong` агресивно зменшує розмір файлу за рахунок візуальної точності. * Зменшення роздільної здатності (наприклад, з 4K до 720p) поєднується зі стисненням для значного зменшення розміру. * Оновлення прогресу доступні через SSE за адресою `GET /api/v1/jobs/{jobId}/progress` до завершення завдання. --- --- url: https://docs.snapotter.com/vi/tools/video/compress-video.md description: Giảm kích thước file video với khả năng kiểm soát chất lượng. --- # Compress Video {#compress-video} Giảm kích thước file video bằng cách sử dụng cường độ nén có thể cấu hình và tùy chọn giảm độ phân giải. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` Nhận multipart form data gồm một file video và một trường JSON `settings`. Đây là endpoint bất đồng bộ - nó trả về `202 Accepted` ngay lập tức và tiến độ được truyền qua SSE tại `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | Cường độ nén: `light`, `balanced`, `strong` | | resolution | string | No | `"original"` | Độ phân giải đầu ra: `original`, `1080p`, `720p`, `480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Preset `light` giữ chất lượng gần như gốc. Preset `strong` giảm kích thước file mạnh mẽ với cái giá là độ trung thực hình ảnh. * Giảm độ phân giải (ví dụ từ 4K xuống 720p) kết hợp với nén để giảm kích thước đáng kể. * Cập nhật tiến độ có sẵn qua SSE tại `GET /api/v1/jobs/{jobId}/progress` cho đến khi tác vụ hoàn tất. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/compress-video.md description: 通过质量控制减小视频文件大小。 --- # Compress Video {#compress-video} 使用可配置的压缩强度和可选的分辨率降采样来减小视频文件大小。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` 接受包含视频文件和 JSON `settings` 字段的 multipart 表单数据。这是一个异步端点:它会立即返回 `202 Accepted`,进度通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 处流式传输。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | 压缩强度:`light`、`balanced`、`strong` | | resolution | string | No | `"original"` | 输出分辨率:`original`、`1080p`、`720p`、`480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `light` 预设可保留接近原始的质量。`strong` 预设以牺牲视觉保真度为代价,激进地减小文件大小。 * 降低分辨率(例如从 4K 降到 720p)与压缩叠加,可显著减小文件大小。 * 在任务完成前,可通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 处获取进度更新。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/compress-video.md description: 透過品質控制縮小影片檔案大小。 --- # Compress Video {#compress-video} 使用可設定的壓縮強度和選用的解析度縮放,縮小影片檔案大小。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/compress-video` 接受包含一個影片檔案和一個 JSON `settings` 欄位的 multipart form data。這是一個非同步端點,它會立即回傳 `202 Accepted`,進度則透過 SSE 於 `GET /api/v1/jobs/{jobId}/progress` 串流傳送。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | string | No | `"balanced"` | 壓縮強度:`light`、`balanced`、`strong` | | resolution | string | No | `"original"` | 輸出解析度:`original`、`1080p`、`720p`、`480p` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/compress-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"quality": "strong", "resolution": "720p"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `light` 預設會保留接近原始的品質。`strong` 預設則會積極縮小檔案大小,代價是視覺保真度。 * 縮小解析度(例如從 4K 降到 720p)會與壓縮相互疊加,達到顯著的體積縮減。 * 在工作完成之前,可透過 SSE 於 `GET /api/v1/jobs/{jobId}/progress` 取得進度更新。 --- --- url: https://docs.snapotter.com/fr/tools/pdf/compress-pdf.md description: Réduire la taille d'un fichier PDF en compressant les images intégrées. --- # Compresser un PDF {#compress-pdf} Réduisez la taille d'un fichier PDF en sous-échantillonnant les images intégrées. Choisissez entre un curseur de qualité ou une taille de fichier cible. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Accepte des données de formulaire multipart avec un fichier PDF et un champ `settings` au format JSON. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | mode | string | Non | `"quality"` | Mode de compression : `quality` ou `targetSize` | | quality | integer | Non | `75` | Qualité de compression, 1-100 (plus élevé = moins de compression). Utilisé en mode `quality` | | targetSizeKb | number | Non | - | Taille de fichier cible en kilo-octets. Utilisé en mode `targetSize` | ## Exemple de requête {#example-request} Compresser par qualité : ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Compresser jusqu'à une taille cible : ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Remarques {#notes} * En mode `quality`, des valeurs plus basses produisent des fichiers plus petits avec une plus forte dégradation des images. * En mode `targetSize`, une recherche binaire trouve le DPI le plus élevé qui respecte la taille demandée. * Si la compression devait agrandir le fichier, les octets d'origine sont renvoyés inchangés. * Le texte et le contenu vectoriel ne sont pas affectés ; seules les images matricielles intégrées sont sous-échantillonnées. --- --- url: https://docs.snapotter.com/fr/tools/image/compress.md description: >- Réduisez la taille du fichier image par niveau de qualité ou vers une taille de fichier cible. --- # Compresser une image {#compress} Réduisez la taille du fichier image en spécifiant un niveau de qualité ou une taille de fichier cible en kilo-octets. L'outil utilise une recherche binaire itérative pour atteindre précisément les cibles de taille. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compress` Accepte des données de formulaire multipart avec un fichier image et un champ JSON `settings`. ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | mode | string | Non | `"quality"` | Mode de compression : `quality` ou `targetSize` | | quality | number | Non | `80` | Niveau de qualité (1-100). Utilisé lorsque mode vaut `quality`. | | targetSizeKb | number | Non | - | Taille de fichier cible en kilo-octets. Utilisée lorsque mode vaut `targetSize`. | ## Example Request {#example-request} Compresser à la qualité 60 : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Compresser vers une taille cible de 200 Ko : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Notes {#notes} * En mode `quality`, les valeurs plus basses produisent des fichiers plus petits avec davantage d'artefacts de compression. Une valeur de 80 est une bonne valeur par défaut pour le web. * En mode `targetSize`, le moteur effectue une compression itérative pour se rapprocher le plus possible de la cible sans la dépasser. * Le format de sortie correspond au format d'entrée. La compression s'applique à l'encodage natif du format (par ex. qualité JPEG pour les fichiers JPEG, qualité WebP pour les fichiers WebP). * Si la qualité par défaut (80) convient, vous pouvez omettre entièrement le paramètre `quality`. --- --- url: https://docs.snapotter.com/it/tools/image/compress.md description: >- Riduci la dimensione del file immagine per livello di qualità o verso una dimensione file di destinazione. --- # Comprimi Immagine {#compress} Riduci la dimensione del file immagine specificando un livello di qualità o una dimensione file di destinazione in kilobyte. Lo strumento usa una ricerca binaria iterativa per raggiungere con precisione le dimensioni di destinazione. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/compress` Accetta dati di form multipart con un file immagine e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Modalità di compressione: `quality` o `targetSize` | | quality | number | No | `80` | Livello di qualità (1-100). Usato quando la modalità è `quality`. | | targetSizeKb | number | No | - | Dimensione file di destinazione in kilobyte. Usata quando la modalità è `targetSize`. | ## Esempio di richiesta {#example-request} Comprimi a qualità 60: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimi a una dimensione di destinazione di 200 KB: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Note {#notes} * In modalità `quality`, valori più bassi producono file più piccoli con più artefatti di compressione. Un valore di 80 è un buon predefinito per l'uso web. * In modalità `targetSize`, il motore esegue una compressione iterativa per avvicinarsi il più possibile alla destinazione senza superarla. * Il formato di output corrisponde al formato di input. La compressione si applica alla codifica nativa del formato (es. qualità JPEG per i file JPEG, qualità WebP per i file WebP). * Se la qualità predefinita (80) è accettabile, puoi omettere completamente il parametro `quality`. --- --- url: https://docs.snapotter.com/it/tools/pdf/compress-pdf.md description: Riduci la dimensione del file PDF comprimendo le immagini incorporate. --- # Comprimi PDF {#compress-pdf} Riduci la dimensione del file PDF sottocampionando le immagini incorporate. Scegli tra un cursore di qualità o una dimensione file di destinazione. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Accetta dati di form multipart con un file PDF e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Modalità di compressione: `quality` o `targetSize` | | quality | integer | No | `75` | Qualità di compressione, 1-100 (più alto = meno compressione). Usato in modalità `quality` | | targetSizeKb | number | No | - | Dimensione file di destinazione in kilobyte. Usato in modalità `targetSize` | ## Example Request {#example-request} Comprimi per qualità: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimi a una dimensione di destinazione: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * In modalità `quality`, i valori più bassi producono file più piccoli con maggiore degrado delle immagini. * In modalità `targetSize`, una ricerca binaria trova il DPI più alto che rientra nella dimensione richiesta. * Se la compressione ingrandirebbe il file, i byte originali vengono restituiti invariati. * Il testo e i contenuti vettoriali non sono influenzati; vengono sottocampionate solo le immagini raster incorporate. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/compress.md description: >- Reduza o tamanho do arquivo de imagem por nível de qualidade ou para um tamanho de arquivo alvo. --- # Comprimir Imagem {#compress} Reduza o tamanho do arquivo de imagem especificando um nível de qualidade ou um tamanho de arquivo alvo em kilobytes. A ferramenta usa busca binária iterativa para atingir os tamanhos alvo com precisão. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/compress` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | mode | string | Não | `"quality"` | Modo de compressão: `quality` ou `targetSize` | | quality | number | Não | `80` | Nível de qualidade (1-100). Usado quando o modo é `quality`. | | targetSizeKb | number | Não | - | Tamanho de arquivo alvo em kilobytes. Usado quando o modo é `targetSize`. | ## Exemplo de Requisição {#example-request} Comprimir para qualidade 60: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimir para um tamanho alvo de 200 KB: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Notas {#notes} * No modo `quality`, valores menores produzem arquivos menores com mais artefatos de compressão. Um valor de 80 é um bom padrão para uso na web. * No modo `targetSize`, o mecanismo realiza compressão iterativa para chegar o mais perto possível do alvo sem excedê-lo. * O formato de saída corresponde ao formato de entrada. A compressão se aplica à codificação nativa do formato (por exemplo, qualidade JPEG para arquivos JPEG, qualidade WebP para arquivos WebP). * Se a qualidade padrão (80) for aceitável, você pode omitir o parâmetro `quality` inteiramente. --- --- url: https://docs.snapotter.com/es/tools/image/compress.md description: >- Reduce el tamaño del archivo de imagen por nivel de calidad o hasta un tamaño de archivo objetivo. --- # Comprimir imagen {#compress} Reduce el tamaño del archivo de imagen especificando un nivel de calidad o un tamaño de archivo objetivo en kilobytes. La herramienta usa búsqueda binaria iterativa para alcanzar los tamaños objetivo con precisión. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/compress` Acepta datos de formulario multipart con un archivo de imagen y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Modo de compresión: `quality` o `targetSize` | | quality | number | No | `80` | Nivel de calidad (1-100). Se usa cuando el modo es `quality`. | | targetSizeKb | number | No | - | Tamaño de archivo objetivo en kilobytes. Se usa cuando el modo es `targetSize`. | ## Ejemplo de solicitud {#example-request} Comprimir a calidad 60: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimir a un tamaño objetivo de 200 KB: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Notas {#notes} * En el modo `quality`, los valores más bajos producen archivos más pequeños con más artefactos de compresión. Un valor de 80 es un buen valor predeterminado para uso web. * En el modo `targetSize`, el motor realiza una compresión iterativa para acercarse lo máximo posible al objetivo sin superarlo. * El formato de salida coincide con el formato de entrada. La compresión se aplica a la codificación nativa del formato (p. ej. calidad JPEG para archivos JPEG, calidad WebP para archivos WebP). * Si la calidad predeterminada (80) es aceptable, puedes omitir por completo el parámetro `quality`. --- --- url: https://docs.snapotter.com/es/tools/pdf/compress-pdf.md description: Reduce el tamaño de un archivo PDF comprimiendo las imágenes incrustadas. --- # Comprimir PDF {#compress-pdf} Reduce el tamaño de un archivo PDF submuestreando las imágenes incrustadas. Elige entre un control deslizante de calidad o un tamaño de archivo objetivo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/compress-pdf` Acepta datos de formulario multipart con un archivo PDF y un campo JSON `settings`. ## Parameters {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | mode | string | No | `"quality"` | Modo de compresión: `quality` o `targetSize` | | quality | integer | No | `75` | Calidad de compresión, 1-100 (mayor = menos compresión). Se usa en el modo `quality` | | targetSizeKb | number | No | - | Tamaño de archivo objetivo en kilobytes. Se usa en el modo `targetSize` | ## Example Request {#example-request} Comprimir por calidad: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "quality", "quality": 60}' ``` Comprimir a un tamaño objetivo: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/compress-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 5200000, "processedSize": 1800000 } ``` ## Notes {#notes} * En el modo `quality`, los valores más bajos producen archivos más pequeños con mayor degradación de la imagen. * En el modo `targetSize`, una búsqueda binaria encuentra el DPI más alto que se ajusta al tamaño solicitado. * Si la compresión aumentara el tamaño del archivo, se devuelven los bytes originales sin cambios. * El contenido de texto y vectorial no se ve afectado; solo se submuestrean las imágenes rasterizadas incrustadas. --- --- url: https://docs.snapotter.com/pt-BR/guide/configuration.md description: >- Todas as variáveis de ambiente do SnapOtter com valores padrão. Configure autenticação, armazenamento, modelos de IA, análise de dados e muito mais. --- # Configuração {#configuration} Toda a configuração é feita por meio de variáveis de ambiente. Cada variável tem um padrão sensato, então o SnapOtter funciona imediatamente sem definir nenhuma delas. ## Variáveis de ambiente {#environment-variables} ### Servidor {#server} | Variável | Padrão | Descrição | |---|---|---| | `PORT` | `1349` | Porta em que o servidor escuta. | | `RATE_LIMIT_PER_MIN` | `1000` | Máximo de requisições por minuto por IP. Defina como 0 para desativar a limitação de taxa. | | `CORS_ORIGIN` | (vazio) | Origens permitidas para CORS, separadas por vírgula, ou vazio para apenas a mesma origem. | | `LOG_LEVEL` | `info` | Verbosidade do log. Um de: `fatal`, `error`, `warn`, `info`, `debug`, `trace`. | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Quais pares podem definir o IP do cliente por meio de `X-Forwarded-For`. O padrão acredita apenas em um par de rede privada, então um proxy reverso em uma rede Docker ou em uma LAN é confiável e o cabeçalho forjado de um cliente público não é. Defina `true` só quando um proxy sob seu controle estiver na frente, em um endereço público. | ### Autenticação {#authentication} Os dois booleanos abaixo aceitam apenas `true` e `false`. Qualquer outra coisa, `1` ou `yes` ou `on`, falha na validação e o servidor encerra antes de começar a escutar. | Variável | Padrão | Descrição | |---|---|---| | `AUTH_ENABLED` | `true` | Exige login. Defina como `false` para rodar sem conta nenhuma, o que dá direitos de admin a toda requisição, então mantenha isso em uma rede confiável. | | `DEFAULT_USERNAME` | `admin` | Nome de usuário da conta de admin inicial. Usado apenas na primeira execução. | | `DEFAULT_PASSWORD` | `admin` | Senha da conta de admin inicial. Altere-a após o primeiro login. | | `MAX_USERS` | `0` (ilimitado) | Número máximo de contas de usuário registradas. Defina como 0 para ilimitado. | | `SESSION_DURATION_HOURS` | `168` | Duração da sessão de login em horas (o padrão é 7 dias). | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Defina como `true` para pular o prompt de troca de senha forçada no primeiro login. | ### Armazenamento {#storage} | Variável | Padrão | Descrição | |---|---|---| | `STORAGE_MODE` | `local` | `local` ou `s3`. S3 e MinIO precisam de uma licença com o recurso s3\_storage, além das variáveis `S3_*` abaixo. | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | String de conexão do PostgreSQL. A pilha Compose aponta isso para o serviço `postgres` dela; deixe indefinido (junto com `REDIS_URL`) para obter o modo embutido. | | `REDIS_URL` | `redis://localhost:6379` | String de conexão do Redis (usada para as filas de jobs do BullMQ). O Compose aponta isso para o serviço `redis` dele. | | `WORKSPACE_PATH` | `./tmp/workspace` | Diretório para arquivos temporários durante o processamento. Limpo automaticamente. A imagem define `/tmp/workspace`. | | `FILES_STORAGE_PATH` | `./data/files` | Diretório para arquivos persistentes do usuário (imagens enviadas, resultados salvos). A imagem define `/data/files`. | ### Armazenamento de objetos S3 {#s3-object-storage} Lido apenas quando `STORAGE_MODE=s3`. Se faltar qualquer uma das três obrigatórias, a inicialização falha informando o nome da variável que você deixou de fora. | Variável | Padrão | Descrição | |---|---|---| | `S3_BUCKET` | (vazio) | Bucket que guarda os uploads e as saídas. Obrigatória. | | `S3_ACCESS_KEY_ID` | (vazio) | Chave de acesso. Obrigatória. No contêiner, você pode montá-la em vez disso, via `S3_ACCESS_KEY_ID_FILE`. | | `S3_SECRET_ACCESS_KEY` | (vazio) | Chave secreta. Obrigatória. Mesma convenção de arquivo: `S3_SECRET_ACCESS_KEY_FILE`. | | `S3_REGION` | `us-east-1` | Região do bucket. | | `S3_ENDPOINT` | (vazio) | Endpoint personalizado para MinIO, R2, Backblaze e outros armazenamentos compatíveis com S3. Vazio significa AWS. | | `S3_FORCE_PATH_STYLE` | `false` | Defina como `true` para o MinIO e qualquer outro que espere `endpoint/bucket/key` em vez de endereçamento por virtual host. | | `S3_PREFIX` | (vazio) | Prefixo de chave, para que um bucket possa guardar várias instâncias. | ### Criptografia em repouso {#encryption-at-rest} | Variável | Padrão | Descrição | |---|---|---| | `DATA_ENCRYPTION_KEY` | (vazio) | 64 caracteres hexadecimais (32 bytes). Criptografa as configurações sensíveis armazenadas no banco de dados. Qualquer coisa que não tenha 64 caracteres hexadecimais é rejeitada na inicialização. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (vazio) | A chave da qual você está saindo na rotação, no mesmo formato. Defina as duas durante uma rotação para que as linhas existentes ainda sejam descriptografadas e depois remova esta. | ### Modo embutido {#embedded-mode} Execute a imagem sem `DATABASE_URL` e sem `REDIS_URL` e ela inicia o seu próprio PostgreSQL 17 e Redis dentro do contêiner, vinculados ao loopback, com todos os dados no volume `/data`. Isso restaura a experiência de `docker run` de comando único para início rápido, homelab e atualizações a partir da 1.x. É um caminho de conveniência, não uma implantação de produção: para produção, execute a pilha Compose de 3 contêineres com PostgreSQL e Redis separados. O modo embutido requer executar o contêiner como root e é incompatível com runtimes de UID arbitrário (OpenShift, Kubernetes `runAsNonRoot`); use o Compose nesses casos. | Variável | Padrão | Descrição | |---|---|---| | `EMBEDDED` | `auto` | Ativado automaticamente quando tanto `DATABASE_URL` quanto `REDIS_URL` estão indefinidos. Defina como `0` para desativá-lo (o app então falha imediatamente se nenhum `DATABASE_URL`/`REDIS_URL` externo estiver definido, em vez de iniciar silenciosamente um banco de dados dentro do contêiner). | | `REDIS_MAXMEMORY` | `512mb` | Limite de memória para o Redis embutido (apenas no modo embutido). Reduza-o em hosts com restrição de memória, como um Raspberry Pi. | Atualização a partir da 1.x: coloque seu antigo `snapotter.db` em `/data/snapotter.db` no volume e o modo embutido o importa para o PostgreSQL embutido no primeiro boot. A importação roda uma vez; os boots posteriores a ignoram. Observação sobre telemetria: o modo embutido herda o padrão de análise de dados da imagem como qualquer outra configuração. A imagem publicada vem com a análise de dados ativada; compile com `--build-arg SNAPOTTER_ANALYTICS=off`, ou use a opção de desativação de admin dentro do app, para desligá-la. ### Limites de processamento {#processing-limits} | Variável | Padrão | Descrição | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (ilimitado) | Tamanho máximo de arquivo por upload em megabytes. Defina como 0 para ilimitado. A imagem publicada vem com `0`; uma compilação a partir do código-fonte começa em 100. | | `MAX_BATCH_SIZE` | `0` (ilimitado) | Número máximo de arquivos em uma única requisição em lote. Defina como 0 para ilimitado. A imagem publicada vem com `0`; uma compilação a partir do código-fonte começa em 100. | | `CONCURRENT_JOBS` | `0` (auto) | Número de jobs em lote que rodam em paralelo. Defina como 0 para detecção automática com base nos núcleos de CPU disponíveis. | | `MAX_MEGAPIXELS` | `0` (ilimitado) | Resolução máxima de imagem permitida em megapixels. Defina como 0 para ilimitado. | | `MAX_WORKER_THREADS` | `0` (auto) | Máximo de threads de trabalho para o processamento de imagem. Defina como 0 para detecção automática com base nos núcleos de CPU disponíveis. | | `PROCESSING_TIMEOUT_S` | `0` (sem limite) | Tempo máximo de processamento por requisição em segundos. Defina como 0 para sem tempo limite. | | `MAX_PIPELINE_STEPS` | `20` | Número máximo de etapas em um pipeline. Defina como 0 para sem limite. | | `MAX_CANVAS_PIXELS` | `0` (sem limite) | Tamanho máximo de canvas em pixels para as imagens de saída. Defina como 0 para sem limite. | | `MAX_SVG_SIZE_MB` | `50` | Maior SVG aceito antes da sanitização, em megabytes. `0` se comporta de forma diferente aqui em relação às linhas ao redor. Ele remove por completo o limite de tamanho aplicado antes da análise, em vez de aumentá-lo, então deixe esta definida. | | `MAX_PDF_PAGES` | `0` (ilimitado) | Número máximo de páginas de PDF para a conversão de PDF para imagem. Defina como 0 para ilimitado. | ### Limpeza {#cleanup} | Variável | Padrão | Descrição | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | Por quanto tempo os resultados de processamento não salvos (uploads brutos e saídas de ferramentas) são mantidos antes da exclusão automática. Os arquivos que você salva explicitamente na biblioteca Files não são afetados e persistem até você excluí-los. | | `CLEANUP_INTERVAL_MINUTES` | `60` | Com que frequência o job de limpeza roda. | ### Aparência {#appearance} | Variável | Padrão | Descrição | |---|---|---| | `DEFAULT_THEME` | `light` | Tema padrão para novas sessões. `light`, `dark` ou `system`. | | `DEFAULT_LOCALE` | `en` | Idioma padrão da interface. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Layout padrão das ferramentas. `sidebar` ou `fullscreen`. | ### Permissões do Docker {#docker-permissions} | Variável | Padrão | Descrição | |---|---|---| | `PUID` | `999` | Executa o processo do contêiner com este UID. Defina para corresponder ao seu usuário do host em bind mounts (`id -u`). | | `PGID` | `999` | Executa o processo do contêiner com este GID. Defina para corresponder ao seu grupo do host em bind mounts (`id -g`). | ## Exemplo de Docker {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Altere isso para implantações não locais POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volumes {#volumes} A pilha Docker Compose usa quatro volumes: * `/data` (app) - Modelos de IA, venv Python e arquivos do usuário. Monte-o para manter os arquivos enviados e os pacotes de IA instalados entre reinícios. * `/tmp/workspace` (app) - Armazenamento temporário para arquivos em processamento. Isso pode ser efêmero, mas montá-lo evita encher a camada gravável do contêiner. * `SnapOtter-pgdata` (postgres) - Diretório de dados do PostgreSQL. Isso guarda todos os dados relacionais (usuários, configurações, pipelines, jobs, log de auditoria). Faça backup via `pg_dump` ou snapshot de volume. * `SnapOtter-redisdata` (redis) - Arquivo append-only do Redis para filas de jobs duráveis. --- --- url: https://docs.snapotter.com/es/guide/configuration.md description: >- Todas las variables de entorno de SnapOtter con sus valores predeterminados. Configura autenticación, almacenamiento, modelos de IA, analítica y más. --- # Configuración {#configuration} Toda la configuración se realiza mediante variables de entorno. Cada variable tiene un valor predeterminado sensato, por lo que SnapOtter funciona de inmediato sin necesidad de establecer ninguna de ellas. ## Variables de entorno {#environment-variables} ### Servidor {#server} | Variable | Predeterminado | Descripción | |---|---|---| | `PORT` | `1349` | Puerto en el que escucha el servidor. | | `RATE_LIMIT_PER_MIN` | `1000` | Máximo de solicitudes por minuto por IP. Ponlo a 0 para desactivar la limitación de tasa. | | `CORS_ORIGIN` | (vacío) | Orígenes permitidos para CORS separados por comas, o vacío para solo el mismo origen. | | `LOG_LEVEL` | `info` | Verbosidad del registro. Uno de: `fatal`, `error`, `warn`, `info`, `debug`, `trace`. | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Qué pares pueden establecer la IP del cliente mediante `X-Forwarded-For`. El valor predeterminado solo cree a un par de una red privada, así que un proxy inverso en una red de Docker o en una LAN sí es de confianza y la cabecera falsificada de un cliente público no. Pon `true` solo cuando delante haya un proxy bajo tu control en una dirección pública. | ### Autenticación {#authentication} Los dos valores booleanos de abajo solo aceptan `true` y `false`. Cualquier otra cosa, ya sea `1`, `yes` u `on`, no supera la validación y el servidor termina antes de ponerse a escuchar. | Variable | Predeterminado | Descripción | |---|---|---| | `AUTH_ENABLED` | `true` | Exige un inicio de sesión. Ponlo a `false` para funcionar sin ninguna cuenta, lo que concede permisos de administrador a todas las solicitudes, así que resérvalo para una red de confianza. | | `DEFAULT_USERNAME` | `admin` | Nombre de usuario de la cuenta de administrador inicial. Solo se usa en la primera ejecución. | | `DEFAULT_PASSWORD` | `admin` | Contraseña de la cuenta de administrador inicial. Cámbiala tras el primer inicio de sesión. | | `MAX_USERS` | `0` (ilimitado) | Número máximo de cuentas de usuario registradas. Ponlo a 0 para ilimitado. | | `SESSION_DURATION_HOURS` | `168` | Duración de la sesión de inicio de sesión en horas (el valor predeterminado es 7 días). | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Ponlo a `true` para omitir el aviso obligatorio de cambio de contraseña en el primer inicio de sesión. | ### Almacenamiento {#storage} | Variable | Predeterminado | Descripción | |---|---|---| | `STORAGE_MODE` | `local` | `local` o `s3`. S3 y MinIO necesitan una licencia con la función s3\_storage, además de las variables `S3_*` de abajo. | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | Cadena de conexión de PostgreSQL. La pila de Compose la apunta a su servicio `postgres`; déjala sin establecer (junto con `REDIS_URL`) para obtener el modo embebido. | | `REDIS_URL` | `redis://localhost:6379` | Cadena de conexión de Redis (usada para las colas de tareas de BullMQ). Compose la apunta a su servicio `redis`. | | `WORKSPACE_PATH` | `./tmp/workspace` | Directorio para archivos temporales durante el procesamiento. Se limpia automáticamente. La imagen establece `/tmp/workspace`. | | `FILES_STORAGE_PATH` | `./data/files` | Directorio para archivos de usuario persistentes (imágenes subidas, resultados guardados). La imagen establece `/data/files`. | ### Almacenamiento de objetos S3 {#s3-object-storage} Solo se leen cuando `STORAGE_MODE=s3`. Si falta alguna de las tres obligatorias, el arranque falla indicando el nombre de la variable que omitiste. | Variable | Predeterminado | Descripción | |---|---|---| | `S3_BUCKET` | (vacío) | Bucket que contiene las subidas y las salidas. Obligatorio. | | `S3_ACCESS_KEY_ID` | (vacío) | Clave de acceso. Obligatoria. En el contenedor puedes montarla en su lugar, mediante `S3_ACCESS_KEY_ID_FILE`. | | `S3_SECRET_ACCESS_KEY` | (vacío) | Clave secreta. Obligatoria. Misma convención de archivo: `S3_SECRET_ACCESS_KEY_FILE`. | | `S3_REGION` | `us-east-1` | Región del bucket. | | `S3_ENDPOINT` | (vacío) | Endpoint personalizado para MinIO, R2, Backblaze y otros almacenes compatibles con S3. Vacío significa AWS. | | `S3_FORCE_PATH_STYLE` | `false` | Ponlo a `true` para MinIO y para cualquier otro que espere `endpoint/bucket/key` en lugar del direccionamiento por host virtual. | | `S3_PREFIX` | (vacío) | Prefijo de clave, para que un mismo bucket pueda alojar varias instancias. | ### Cifrado en reposo {#encryption-at-rest} | Variable | Predeterminado | Descripción | |---|---|---| | `DATA_ENCRYPTION_KEY` | (vacío) | 64 caracteres hexadecimales (32 bytes). Cifra los ajustes sensibles almacenados en la base de datos. Cualquier cosa que no sean 64 caracteres hexadecimales se rechaza al arrancar. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (vacío) | La clave que estás dejando atrás en una rotación, con el mismo formato. Establece ambas durante la rotación para que las filas existentes se sigan descifrando, y luego elimina esta. | ### Modo embebido {#embedded-mode} Ejecuta la imagen sin `DATABASE_URL` ni `REDIS_URL` y arrancará sus propios PostgreSQL 17 y Redis dentro del contenedor, enlazados a loopback, con todos los datos en el volumen `/data`. Esto restaura la experiencia de un solo comando `docker run` para el inicio rápido, el homelab y las actualizaciones desde la 1.x. Es una vía de conveniencia, no un despliegue de producción: para producción, ejecuta la pila de Compose de 3 contenedores con PostgreSQL y Redis separados. El modo embebido requiere ejecutar el contenedor como root y es incompatible con los tiempos de ejecución de UID arbitrario (OpenShift, Kubernetes `runAsNonRoot`); usa Compose en esos casos. | Variable | Predeterminado | Descripción | |---|---|---| | `EMBEDDED` | `auto` | Se activa automáticamente cuando tanto `DATABASE_URL` como `REDIS_URL` están sin establecer. Ponlo a `0` para desactivarlo (la app entonces falla rápido si no hay `DATABASE_URL`/`REDIS_URL` externo establecido, en lugar de arrancar silenciosamente una base de datos dentro del contenedor). | | `REDIS_MAXMEMORY` | `512mb` | Límite de memoria para el Redis embebido (solo en modo embebido). Redúcelo en hosts con memoria limitada, como una Raspberry Pi. | Actualizar desde la 1.x: coloca tu antiguo `snapotter.db` en `/data/snapotter.db` dentro del volumen y el modo embebido lo importa al PostgreSQL embebido en el primer arranque. La importación se ejecuta una vez; los arranques posteriores la omiten. Nota sobre telemetría: el modo embebido hereda el valor predeterminado de analítica de la imagen como cualquier otra configuración. La imagen publicada se distribuye con la analítica activada; compila con `--build-arg SNAPOTTER_ANALYTICS=off`, o usa la exclusión voluntaria de administrador dentro de la app, para desactivarla. ### Límites de procesamiento {#processing-limits} | Variable | Predeterminado | Descripción | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (ilimitado) | Tamaño máximo de archivo por subida en megabytes. Ponlo a 0 para ilimitado. La imagen publicada se distribuye con `0`; una compilación desde el código fuente empieza en 100. | | `MAX_BATCH_SIZE` | `0` (ilimitado) | Número máximo de archivos en una sola solicitud por lotes. Ponlo a 0 para ilimitado. La imagen publicada se distribuye con `0`; una compilación desde el código fuente empieza en 100. | | `CONCURRENT_JOBS` | `0` (automático) | Número de tareas por lotes que se ejecutan en paralelo. Ponlo a 0 para detectarlo automáticamente según los núcleos de CPU disponibles. | | `MAX_MEGAPIXELS` | `0` (ilimitado) | Resolución máxima de imagen permitida en megapíxeles. Ponlo a 0 para ilimitado. | | `MAX_WORKER_THREADS` | `0` (automático) | Máximo de hilos de trabajo para el procesamiento de imágenes. Ponlo a 0 para detectarlo automáticamente según los núcleos de CPU disponibles. | | `PROCESSING_TIMEOUT_S` | `0` (sin límite) | Tiempo máximo de procesamiento por solicitud en segundos. Ponlo a 0 para que no haya tiempo de espera. | | `MAX_PIPELINE_STEPS` | `20` | Número máximo de pasos en una canalización. Ponlo a 0 para que no haya límite. | | `MAX_CANVAS_PIXELS` | `0` (sin límite) | Tamaño máximo del lienzo en píxeles para las imágenes de salida. Ponlo a 0 para que no haya límite. | | `MAX_SVG_SIZE_MB` | `50` | El SVG más grande que se acepta antes de sanearlo, en megabytes. Aquí `0` se comporta de forma distinta que en las filas de alrededor. Elimina por completo el límite de tamaño previo al análisis en lugar de subirlo, así que deja esta variable con un valor. | | `MAX_PDF_PAGES` | `0` (ilimitado) | Número máximo de páginas de PDF para la conversión de PDF a imagen. Ponlo a 0 para ilimitado. | ### Limpieza {#cleanup} | Variable | Predeterminado | Descripción | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | Cuánto tiempo se conservan los resultados de procesamiento no guardados (subidas en bruto y salidas de herramientas) antes de su eliminación automática. Los archivos que guardas explícitamente en la biblioteca de Archivos no se ven afectados y persisten hasta que los eliminas. | | `CLEANUP_INTERVAL_MINUTES` | `60` | Con qué frecuencia se ejecuta la tarea de limpieza. | ### Apariencia {#appearance} | Variable | Predeterminado | Descripción | |---|---|---| | `DEFAULT_THEME` | `light` | Tema predeterminado para las sesiones nuevas. `light`, `dark` o `system`. | | `DEFAULT_LOCALE` | `en` | Idioma predeterminado de la interfaz. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Diseño de herramienta predeterminado. `sidebar` o `fullscreen`. | ### Permisos de Docker {#docker-permissions} | Variable | Predeterminado | Descripción | |---|---|---| | `PUID` | `999` | Ejecuta el proceso del contenedor con este UID. Ponlo para que coincida con tu usuario del host en los montajes de enlace (`id -u`). | | `PGID` | `999` | Ejecuta el proceso del contenedor con este GID. Ponlo para que coincida con tu grupo del host en los montajes de enlace (`id -g`). | ## Ejemplo de Docker {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Cambie esto para implementaciones no locales POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volúmenes {#volumes} La pila de Docker Compose usa cuatro volúmenes: * `/data` (app) - Modelos de IA, entorno virtual de Python y archivos de usuario. Móntalo para conservar los archivos subidos y los paquetes de IA instalados entre reinicios. * `/tmp/workspace` (app) - Almacenamiento temporal para los archivos que se están procesando. Puede ser efímero, pero montarlo evita llenar la capa escribible del contenedor. * `SnapOtter-pgdata` (postgres) - Directorio de datos de PostgreSQL. Contiene todos los datos relacionales (usuarios, ajustes, canalizaciones, tareas, registro de auditoría). Haz copia de seguridad mediante `pg_dump` o una instantánea del volumen. * `SnapOtter-redisdata` (redis) - Archivo de solo anexado de Redis para colas de tareas duraderas. --- --- url: https://docs.snapotter.com/es/guide/low-resource.md --- # Configuraciones con recursos limitados {#low-resource-setups} SnapOtter funciona bien en hardware modesto: una Raspberry Pi 4 o 5, un portátil viejo o un VPS de 2 GB. Esta página es la guía práctica para esas máquinas: qué esperar, una instalación de copiar y pegar con topes sensatos, y qué funciones conviene omitir. Los datos de benchmark completos detrás de estas cifras están en [Requisitos de hardware](/es/guide/deployment#hardware-requirements). Dos restricciones duras de entrada: * **Solo 64 bits.** La imagen se compila para `linux/amd64` y `linux/arm64`. ARM de 32 bits (`armv7`/`armhf`) no está soportado, así que las Pi de primera generación y la familia Pi Zero quedan fuera. * **Mínimo de 2 GB de memoria.** Con 512 MB la pila no arranca, y con 1 GB fallan los lotes de varios archivos. 2 GB con 2 núcleos es la configuración más pequeña que funciona con holgura. ## Qué funciona bien en hardware modesto {#what-runs-well} Todas las herramientas sin IA funcionan en una máquina de 2 GB y 2 núcleos: las secciones de Imagen y Archivos completas, las herramientas de PDF y las operaciones de vídeo y audio por copia de flujo (recortar, silenciar, cambiar de contenedor). La mayoría termina en menos de un segundo. Dos cargas de trabajo son la excepción: * **La recodificación de vídeo** (convertir entre códecs) está limitada por la CPU. Un clip 1080p que tarda ~40 s en una CPU de escritorio rápida puede tardar varios minutos en una CPU de clase Pi. Las operaciones por copia de flujo siguen siendo instantáneas. * **Las herramientas de IA** necesitan RAM (4 GB recomendados) y disco (los bundles más grandes ocupan 4-5 GB cada uno), y las pesadas (ampliación, restauración de fotos, eliminación de fondo) no son prácticas en CPUs de clase Pi. La IA ligera, como la detección de caras y el OCR, es usable si tienes memoria para ella. Nada de esto se instala ni se ejecuta a menos que lo uses: sin bundles de IA instalados, la aplicación consume en reposo unos 360 MB, y los bundles de IA solo se descargan cuando un administrador los habilita. ## Guía paso a paso: Raspberry Pi / portátil viejo {#walkthrough} Es la instalación estándar con Compose de [Primeros pasos](/es/guide/getting-started), más límites de recursos y topes conservadores. Supone un sistema operativo de 64 bits (en una Pi: Raspberry Pi OS de 64 bits o Ubuntu Server arm64). ```yaml services: snapotter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - ./snapotter-data:/data environment: - DATABASE_URL=postgres://snapotter:snapotter@db:5432/snapotter - REDIS_URL=redis://redis:6379 # Small-box profile: see the table below for what each cap does. - CONCURRENT_JOBS=1 - MAX_WORKER_THREADS=2 - MAX_BATCH_SIZE=5 - MAX_UPLOAD_SIZE_MB=100 - MAX_MEGAPIXELS=50 - MAX_VIDEO_DURATION_S=300 deploy: resources: limits: cpus: "2" memory: 2G depends_on: - db - redis restart: unless-stopped db: image: postgres:17-alpine environment: - POSTGRES_USER=snapotter - POSTGRES_PASSWORD=snapotter # Cambie esto para implementaciones no locales - POSTGRES_DB=snapotter volumes: - ./postgres-data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:8-alpine command: redis-server --maxmemory 256mb --maxmemory-policy noeviction restart: unless-stopped ``` Notas para máquinas de clase Pi: * **Prefiere un SSD USB antes que una tarjeta SD** para el volumen de datos y Postgres. Los espacios de trabajo de los jobs hacen E/S de disco real, y las tarjetas SD son lentas y se desgastan rápido. * **El contenedor único todo en uno también funciona aquí** (PostgreSQL y Redis embebidos cuando `DATABASE_URL`/`REDIS_URL` no están definidos), y en un host con poca memoria conviene bajar el tope de su Redis embebido con `REDIS_MAXMEMORY` (consulta [Configuración](/es/guide/configuration)). Compose te da un control más fino por servicio, y por eso esta guía lo usa. * **Añade swap en dispositivos de 2 GB.** Evita que el pico ocasional (un PDF grande, un lote que olvidaste limitar) acabe en un cierre por falta de memoria. zram es la opción que menos castiga la tarjeta SD. * La imagen arm64 es solo CPU; no hay CUDA en placas ARM. ## Los ajustes que importan {#tuning-knobs} Todos los topes son variables de entorno, documentadas al completo en [Configuración](/es/guide/configuration). `0` significa ilimitado o automático. Los que importan en hardware modesto: | Variable | Sugerencia para máquinas pequeñas | Qué protege | |---|---|---| | `CONCURRENT_JOBS` | `1` | Cuántos jobs se ejecutan en paralelo. La autodetección usa los núcleos de CPU menos uno, lo cual va bien en máquinas grandes y es demasiado agresivo en una máquina de 2 núcleos con presión de memoria. | | `MAX_WORKER_THREADS` | `2` | Grupo de hilos del procesamiento de imágenes. | | `MAX_BATCH_SIZE` | `5` | Los lotes son donde las máquinas de 1-2 GB se quedan sin memoria primero. | | `MAX_UPLOAD_SIZE_MB` | `100` | Evita que un solo archivo enorme ocupe todo el espacio de trabajo. | | `MAX_MEGAPIXELS` | `50` | Decodificar una imagen de más de 100 MP cuesta RAM sin importar el tamaño del archivo. | | `MAX_VIDEO_DURATION_S` | `300` | Las transcodificaciones largas monopolizan una CPU pequeña durante minutos u horas. | | `PROCESSING_TIMEOUT_S` | `600` | Techo duro para que un job descontrolado libere la máquina en algún momento. | Estos topes se aplican a lo que el servidor acepta, así que ajústalos a lo que realmente usas, no lo más bajo posible. Si nunca tocas vídeo, un tope de `MAX_VIDEO_DURATION_S` no cuesta nada; si escaneas documentos a diario, no limites `MAX_PDF_PAGES`. ## Qué omitir {#what-to-skip} * **Los bundles de IA pesados.** La ampliación, la restauración de fotos y la eliminación de fondo piden una GPU o una CPU rápida de muchos núcleos, y cada bundle cuesta 4-5 GB de disco. En una máquina pequeña, simplemente no los instales; las herramientas cuyo bundle falta muestran un aviso de instalación en lugar de ejecutarse. * **La recodificación de vídeo como carga habitual.** Las transcodificaciones ocasionales están bien (solo son lentas); una cola de transcodificación constante pide núcleos de CPU, no una Pi. * **Las herramientas sin uso, en general.** Un administrador puede desactivar herramientas individuales en Ajustes, lo que las quita de la interfaz y deja de registrar sus rutas de API. Eso por sí solo no ahorra memoria, pero evita que una instancia pequeña compartida se use justo para la carga que el hardware no aguanta. Si más adelante mueves la instancia a hardware más potente, quita los topes (devuélvelos a `0`) y el mismo volumen de datos se conserva tal cual. --- --- url: https://docs.snapotter.com/nl/guide/configuration.md description: >- Alle SnapOtter-omgevingsvariabelen met standaardwaarden. Configureer authenticatie, opslag, AI-modellen, analytics en meer. --- # Configuratie {#configuration} Alle configuratie gebeurt via omgevingsvariabelen. Elke variabele heeft een verstandige standaardwaarde, zodat SnapOtter direct werkt zonder er ook maar één in te stellen. ## Omgevingsvariabelen {#environment-variables} ### Server {#server} | Variabele | Standaard | Beschrijving | |---|---|---| | `PORT` | `1349` | Poort waarop de server luistert. | | `RATE_LIMIT_PER_MIN` | `1000` | Maximaal aantal verzoeken per minuut per IP. Stel in op 0 om rate limiting uit te schakelen. | | `CORS_ORIGIN` | (leeg) | Door komma's gescheiden toegestane origins voor CORS, of leeg voor alleen dezelfde origin. | | `LOG_LEVEL` | `info` | Uitgebreidheid van logging. Een van: `fatal`, `error`, `warn`, `info`, `debug`, `trace`. | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Welke peers het client-IP via `X-Forwarded-For` mogen zetten. De standaardwaarde gelooft alleen een peer uit een privénetwerk, dus een reverse proxy op een Docker-netwerk of in een LAN wordt vertrouwd en de vervalste header van een publieke client niet. Stel alleen `true` in wanneer er een proxy die jij beheert vóór zit op een openbaar adres. | ### Authenticatie {#authentication} De twee booleans hieronder accepteren alleen `true` en `false`. Al het andere, `1` of `yes` of `on`, komt niet door de validatie en de server stopt voordat hij begint te luisteren. | Variabele | Standaard | Beschrijving | |---|---|---| | `AUTH_ENABLED` | `true` | Vereist aanmelden. Stel in op `false` om helemaal zonder accounts te draaien, wat elk verzoek adminrechten geeft, dus houd dat op een vertrouwd netwerk. | | `DEFAULT_USERNAME` | `admin` | Gebruikersnaam voor het initiële adminaccount. Wordt alleen bij de eerste keer opstarten gebruikt. | | `DEFAULT_PASSWORD` | `admin` | Wachtwoord voor het initiële adminaccount. Wijzig dit na de eerste keer aanmelden. | | `MAX_USERS` | `0` (onbeperkt) | Maximaal aantal geregistreerde gebruikersaccounts. Stel in op 0 voor onbeperkt. | | `SESSION_DURATION_HOURS` | `168` | Levensduur van de aanmeldsessie in uren (standaard 7 dagen). | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Stel in op `true` om de verplichte wachtwoordwijzigingsprompt bij de eerste aanmelding over te slaan. | ### Opslag {#storage} | Variabele | Standaard | Beschrijving | |---|---|---| | `STORAGE_MODE` | `local` | `local` of `s3`. S3 en MinIO vereisen een licentie met de s3\_storage-functie plus de `S3_*`-variabelen hieronder. | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | PostgreSQL-connectiestring. De Compose-stack wijst deze naar zijn `postgres`-service; laat hem leeg (samen met `REDIS_URL`) om de ingebedde modus te krijgen. | | `REDIS_URL` | `redis://localhost:6379` | Redis-connectiestring (gebruikt voor BullMQ-taakwachtrijen). Compose wijst deze naar zijn `redis`-service. | | `WORKSPACE_PATH` | `./tmp/workspace` | Map voor tijdelijke bestanden tijdens de verwerking. Wordt automatisch opgeschoond. De image stelt `/tmp/workspace` in. | | `FILES_STORAGE_PATH` | `./data/files` | Map voor persistente gebruikersbestanden (geüploade afbeeldingen, opgeslagen resultaten). De image stelt `/data/files` in. | ### S3-objectopslag {#s3-object-storage} Wordt alleen gelezen wanneer `STORAGE_MODE=s3`. Ontbreekt een van de drie verplichte variabelen, dan mislukt het opstarten met de naam van de variabele die je hebt weggelaten. | Variabele | Standaard | Beschrijving | |---|---|---| | `S3_BUCKET` | (leeg) | Bucket die uploads en uitvoer bevat. Verplicht. | | `S3_ACCESS_KEY_ID` | (leeg) | Access key. Verplicht. In de container kun je hem in plaats daarvan koppelen, via `S3_ACCESS_KEY_ID_FILE`. | | `S3_SECRET_ACCESS_KEY` | (leeg) | Secret key. Verplicht. Dezelfde bestandsconventie: `S3_SECRET_ACCESS_KEY_FILE`. | | `S3_REGION` | `us-east-1` | Regio van de bucket. | | `S3_ENDPOINT` | (leeg) | Aangepast endpoint voor MinIO, R2, Backblaze en andere S3-compatibele opslag. Leeg betekent AWS. | | `S3_FORCE_PATH_STYLE` | `false` | Stel in op `true` voor MinIO en al het andere dat `endpoint/bucket/key` wil in plaats van virtual-hostadressering. | | `S3_PREFIX` | (leeg) | Sleutelprefix, zodat één bucket meerdere instanties kan bevatten. | ### Versleuteling in rust {#encryption-at-rest} | Variabele | Standaard | Beschrijving | |---|---|---| | `DATA_ENCRYPTION_KEY` | (leeg) | 64 hexadecimale tekens (32 bytes). Versleutelt gevoelige instellingen die in de database zijn opgeslagen. Alles wat geen 64 hexadecimale tekens is, wordt bij het opstarten geweigerd. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (leeg) | De sleutel waar je vanaf roteert, met dezelfde indeling. Stel beide in tijdens een rotatie zodat bestaande rijen nog steeds ontsleuteld worden, en verwijder deze daarna. | ### Ingebedde modus {#embedded-mode} Draai de image zonder `DATABASE_URL` en zonder `REDIS_URL` en hij start zijn eigen PostgreSQL 17 en Redis binnen de container, gebonden aan loopback, met alle gegevens op het `/data`-volume. Dit herstelt de `docker run`-ervaring met één commando voor snelle start, homelab en upgrades vanaf 1.x. Het is een gemakspad, geen productiedeployment: draai voor productie de Compose-stack met 3 containers met aparte PostgreSQL en Redis. De ingebedde modus vereist dat de container als root draait en is niet compatibel met runtimes met een willekeurige UID (OpenShift, Kubernetes `runAsNonRoot`); gebruik daar Compose. | Variabele | Standaard | Beschrijving | |---|---|---| | `EMBEDDED` | `auto` | Automatisch ingeschakeld wanneer zowel `DATABASE_URL` als `REDIS_URL` niet zijn ingesteld. Stel in op `0` om het uit te schakelen (de app faalt dan direct als er geen externe `DATABASE_URL`/`REDIS_URL` is ingesteld, in plaats van stilletjes een database binnen de container te starten). | | `REDIS_MAXMEMORY` | `512mb` | Geheugenlimiet voor de ingebedde Redis (alleen in de ingebedde modus). Verlaag deze op hosts met beperkt geheugen, zoals een Raspberry Pi. | Upgraden vanaf 1.x: plaats je oude `snapotter.db` op `/data/snapotter.db` in het volume en de ingebedde modus importeert het bij de eerste keer opstarten in de ingebedde PostgreSQL. De import draait één keer; latere opstarts slaan deze over. Opmerking over telemetrie: de ingebedde modus erft de analytics-standaard van de image net als elke andere configuratie. De gepubliceerde image wordt geleverd met analytics aan; bouw met `--build-arg SNAPOTTER_ANALYTICS=off`, of gebruik de admin-opt-out in de app, om het uit te schakelen. ### Verwerkingslimieten {#processing-limits} | Variabele | Standaard | Beschrijving | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (onbeperkt) | Maximale bestandsgrootte per upload in megabytes. Stel in op 0 voor onbeperkt. De gepubliceerde image wordt geleverd met `0`; een build vanaf de broncode begint op 100. | | `MAX_BATCH_SIZE` | `0` (onbeperkt) | Maximaal aantal bestanden in één batchverzoek. Stel in op 0 voor onbeperkt. De gepubliceerde image wordt geleverd met `0`; een build vanaf de broncode begint op 100. | | `CONCURRENT_JOBS` | `0` (auto) | Aantal batchtaken dat parallel draait. Stel in op 0 om automatisch te detecteren op basis van beschikbare CPU-cores. | | `MAX_MEGAPIXELS` | `0` (onbeperkt) | Maximaal toegestane beeldresolutie in megapixels. Stel in op 0 voor onbeperkt. | | `MAX_WORKER_THREADS` | `0` (auto) | Maximaal aantal worker-threads voor beeldverwerking. Stel in op 0 om automatisch te detecteren op basis van beschikbare CPU-cores. | | `PROCESSING_TIMEOUT_S` | `0` (geen limiet) | Maximale verwerkingstijd per verzoek in seconden. Stel in op 0 voor geen timeout. | | `MAX_PIPELINE_STEPS` | `20` | Maximaal aantal stappen in een pijplijn. Stel in op 0 voor geen limiet. | | `MAX_CANVAS_PIXELS` | `0` (geen limiet) | Maximale canvasgrootte in pixels voor uitvoerafbeeldingen. Stel in op 0 voor geen limiet. | | `MAX_SVG_SIZE_MB` | `50` | Grootste SVG die vóór het opschonen wordt geaccepteerd, in megabytes. `0` gedraagt zich hier anders dan in de rijen eromheen. Het verwijdert de groottelimiet vóór het parsen volledig in plaats van hem te verhogen, dus laat deze ingesteld staan. | | `MAX_PDF_PAGES` | `0` (onbeperkt) | Maximaal aantal PDF-pagina's voor PDF-naar-image-conversie. Stel in op 0 voor onbeperkt. | ### Opschoning {#cleanup} | Variabele | Standaard | Beschrijving | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | Hoe lang niet-opgeslagen verwerkingsresultaten (ruwe uploads en tooluitvoer) worden bewaard vóór automatische verwijdering. Bestanden die je expliciet opslaat in de Files-bibliotheek worden niet beïnvloed en blijven bestaan totdat je ze verwijdert. | | `CLEANUP_INTERVAL_MINUTES` | `60` | Hoe vaak de opschoontaak draait. | ### Weergave {#appearance} | Variabele | Standaard | Beschrijving | |---|---|---| | `DEFAULT_THEME` | `light` | Standaardthema voor nieuwe sessies. `light`, `dark` of `system`. | | `DEFAULT_LOCALE` | `en` | Standaardtaal van de interface. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Standaard toollay-out. `sidebar` of `fullscreen`. | ### Docker-permissies {#docker-permissions} | Variabele | Standaard | Beschrijving | |---|---|---| | `PUID` | `999` | Draai het containerproces als deze UID. Stel in om overeen te komen met je hostgebruiker voor bind mounts (`id -u`). | | `PGID` | `999` | Draai het containerproces als deze GID. Stel in om overeen te komen met je hostgroep voor bind mounts (`id -g`). | ## Docker-voorbeeld {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Wijzig dit voor niet-lokale implementaties POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volumes {#volumes} De Docker Compose-stack gebruikt vier volumes: * `/data` (app) - AI-modellen, Python-venv en gebruikersbestanden. Koppel dit om geüploade bestanden en geïnstalleerde AI-bundels te behouden bij herstarts. * `/tmp/workspace` (app) - Tijdelijke opslag voor bestanden die worden verwerkt. Dit mag vluchtig zijn, maar het koppelen ervan voorkomt dat de beschrijfbare laag van de container volloopt. * `SnapOtter-pgdata` (postgres) - PostgreSQL-datamap. Deze bevat alle relationele gegevens (gebruikers, instellingen, pijplijnen, taken, auditlog). Maak een back-up via `pg_dump` of een volumesnapshot. * `SnapOtter-redisdata` (redis) - Redis append-only-bestand voor duurzame taakwachtrijen. --- --- url: https://docs.snapotter.com/fr/guide/configuration.md description: >- Toutes les variables d'environnement de SnapOtter avec leurs valeurs par défaut. Configurez l'authentification, le stockage, les modèles d'IA, l'analytique et plus encore. --- # Configuration {#configuration} Toute la configuration se fait via des variables d'environnement. Chaque variable possède une valeur par défaut raisonnable, de sorte que SnapOtter fonctionne d'emblée sans qu'aucune d'elles ne soit définie. ## Variables d'environnement {#environment-variables} ### Serveur {#server} | Variable | Par défaut | Description | |---|---|---| | `PORT` | `1349` | Port sur lequel le serveur écoute. | | `RATE_LIMIT_PER_MIN` | `1000` | Nombre maximal de requêtes par minute par IP. Mettez 0 pour désactiver la limitation de débit. | | `CORS_ORIGIN` | (vide) | Origines autorisées pour le CORS, séparées par des virgules, ou vide pour la même origine uniquement. | | `LOG_LEVEL` | `info` | Verbosité des journaux. L'une des valeurs : `fatal`, `error`, `warn`, `info`, `debug`, `trace`. | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Quels pairs peuvent définir l'IP du client via `X-Forwarded-For`. La valeur par défaut ne croit qu'un pair d'un réseau privé : un reverse proxy sur un réseau Docker ou sur un LAN est donc digne de confiance, alors que l'en-tête falsifié d'un client public ne l'est pas. Ne mettez `true` que lorsqu'un proxy que vous contrôlez se trouve devant, sur une adresse publique. | ### Authentification {#authentication} Les deux booléens ci-dessous n'acceptent que `true` et `false`. Toute autre valeur, `1`, `yes` ou `on`, échoue à la validation et le serveur s'arrête avant de commencer à écouter. | Variable | Par défaut | Description | |---|---|---| | `AUTH_ENABLED` | `true` | Exige une connexion. Mettez `false` pour fonctionner sans aucun compte, ce qui accorde les droits admin à chaque requête ; réservez donc cela à un réseau de confiance. | | `DEFAULT_USERNAME` | `admin` | Nom d'utilisateur du compte admin initial. Utilisé uniquement au premier lancement. | | `DEFAULT_PASSWORD` | `admin` | Mot de passe du compte admin initial. Changez-le après la première connexion. | | `MAX_USERS` | `0` (illimité) | Nombre maximal de comptes utilisateur enregistrés. Mettez 0 pour illimité. | | `SESSION_DURATION_HOURS` | `168` | Durée de vie de la session de connexion en heures (par défaut 7 jours). | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Mettez `true` pour ignorer l'invite de changement de mot de passe forcé à la première connexion. | ### Stockage {#storage} | Variable | Par défaut | Description | |---|---|---| | `STORAGE_MODE` | `local` | `local` ou `s3`. S3 et MinIO nécessitent une licence avec la fonctionnalité s3\_storage, ainsi que les variables `S3_*` ci-dessous. | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | Chaîne de connexion PostgreSQL. La pile Compose la pointe vers son service `postgres` ; laissez-la non définie (avec `REDIS_URL`) pour obtenir le mode intégré. | | `REDIS_URL` | `redis://localhost:6379` | Chaîne de connexion Redis (utilisée pour les files d'attente de tâches BullMQ). Compose la pointe vers son service `redis`. | | `WORKSPACE_PATH` | `./tmp/workspace` | Répertoire des fichiers temporaires pendant le traitement. Nettoyé automatiquement. L'image définit `/tmp/workspace`. | | `FILES_STORAGE_PATH` | `./data/files` | Répertoire des fichiers utilisateur persistants (images téléversées, résultats enregistrés). L'image définit `/data/files`. | ### Stockage d'objets S3 {#s3-object-storage} Lues uniquement lorsque `STORAGE_MODE=s3`. S'il manque l'une des trois variables obligatoires, le démarrage échoue en indiquant le nom de celle que vous avez oubliée. | Variable | Par défaut | Description | |---|---|---| | `S3_BUCKET` | (vide) | Bucket qui contient les téléversements et les sorties. Obligatoire. | | `S3_ACCESS_KEY_ID` | (vide) | Clé d'accès. Obligatoire. Dans le conteneur, vous pouvez plutôt la monter, via `S3_ACCESS_KEY_ID_FILE`. | | `S3_SECRET_ACCESS_KEY` | (vide) | Clé secrète. Obligatoire. Même convention de fichier : `S3_SECRET_ACCESS_KEY_FILE`. | | `S3_REGION` | `us-east-1` | Région du bucket. | | `S3_ENDPOINT` | (vide) | Point de terminaison personnalisé pour MinIO, R2, Backblaze et les autres stockages compatibles S3. Vide signifie AWS. | | `S3_FORCE_PATH_STYLE` | `false` | Mettez `true` pour MinIO et tout autre service qui attend `endpoint/bucket/key` plutôt qu'un adressage par hôte virtuel. | | `S3_PREFIX` | (vide) | Préfixe de clé, pour qu'un même bucket puisse héberger plusieurs instances. | ### Chiffrement au repos {#encryption-at-rest} | Variable | Par défaut | Description | |---|---|---| | `DATA_ENCRYPTION_KEY` | (vide) | 64 caractères hexadécimaux (32 octets). Chiffre les paramètres sensibles stockés dans la base de données. Tout ce qui ne fait pas exactement 64 caractères hexadécimaux est rejeté au démarrage. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (vide) | La clé que vous abandonnez lors d'une rotation, au même format. Définissez les deux pendant la rotation pour que les lignes existantes restent déchiffrables, puis retirez celle-ci. | ### Mode intégré {#embedded-mode} Exécutez l'image sans `DATABASE_URL` et sans `REDIS_URL` et elle démarre ses propres PostgreSQL 17 et Redis à l'intérieur du conteneur, liés au loopback, avec toutes les données sur le volume `/data`. Cela restaure l'expérience `docker run` en une seule commande pour un démarrage rapide, un homelab et les mises à niveau depuis la version 1.x. C'est un chemin de commodité, pas un déploiement de production : pour la production, exécutez la pile Compose à 3 conteneurs avec PostgreSQL et Redis séparés. Le mode intégré nécessite d'exécuter le conteneur en tant que root et est incompatible avec les runtimes à UID arbitraire (OpenShift, Kubernetes `runAsNonRoot`) ; utilisez Compose dans ce cas. | Variable | Par défaut | Description | |---|---|---| | `EMBEDDED` | `auto` | Activé automatiquement lorsque `DATABASE_URL` et `REDIS_URL` sont tous deux non définis. Mettez `0` pour le désactiver (l'application échoue alors immédiatement si aucun `DATABASE_URL`/`REDIS_URL` externe n'est défini, plutôt que de démarrer silencieusement une base de données dans le conteneur). | | `REDIS_MAXMEMORY` | `512mb` | Plafond mémoire du Redis intégré (mode intégré uniquement). Abaissez-le sur les hôtes à mémoire limitée tels qu'un Raspberry Pi. | Mise à niveau depuis la version 1.x : placez votre ancien `snapotter.db` à `/data/snapotter.db` dans le volume et le mode intégré l'importe dans le PostgreSQL intégré au premier démarrage. L'import s'exécute une fois ; les démarrages suivants l'ignorent. Note sur la télémétrie : le mode intégré hérite de la valeur d'analytique par défaut de l'image comme toute autre configuration. L'image publiée est livrée avec l'analytique activée ; compilez avec `--build-arg SNAPOTTER_ANALYTICS=off`, ou utilisez la désactivation admin intégrée à l'application, pour la désactiver. ### Limites de traitement {#processing-limits} | Variable | Par défaut | Description | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (illimité) | Taille maximale de fichier par téléversement en mégaoctets. Mettez 0 pour illimité. L'image publiée est livrée avec `0` ; une compilation depuis les sources démarre à 100. | | `MAX_BATCH_SIZE` | `0` (illimité) | Nombre maximal de fichiers dans une seule requête par lots. Mettez 0 pour illimité. L'image publiée est livrée avec `0` ; une compilation depuis les sources démarre à 100. | | `CONCURRENT_JOBS` | `0` (auto) | Nombre de tâches par lots exécutées en parallèle. Mettez 0 pour détecter automatiquement selon les cœurs CPU disponibles. | | `MAX_MEGAPIXELS` | `0` (illimité) | Résolution d'image maximale autorisée en mégapixels. Mettez 0 pour illimité. | | `MAX_WORKER_THREADS` | `0` (auto) | Nombre maximal de threads de travail pour le traitement d'images. Mettez 0 pour détecter automatiquement selon les cœurs CPU disponibles. | | `PROCESSING_TIMEOUT_S` | `0` (aucune limite) | Temps de traitement maximal par requête en secondes. Mettez 0 pour aucun délai d'expiration. | | `MAX_PIPELINE_STEPS` | `20` | Nombre maximal d'étapes dans un pipeline. Mettez 0 pour aucune limite. | | `MAX_CANVAS_PIXELS` | `0` (aucune limite) | Taille de canevas maximale en pixels pour les images de sortie. Mettez 0 pour aucune limite. | | `MAX_SVG_SIZE_MB` | `50` | Plus grand SVG accepté avant l'assainissement, en mégaoctets. Ici, `0` se comporte différemment des lignes voisines. Il supprime entièrement le plafond de taille appliqué avant l'analyse au lieu de le relever, laissez donc cette valeur définie. | | `MAX_PDF_PAGES` | `0` (illimité) | Nombre maximal de pages PDF pour la conversion PDF-vers-image. Mettez 0 pour illimité. | ### Nettoyage {#cleanup} | Variable | Par défaut | Description | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | Durée de conservation des résultats de traitement non enregistrés (téléversements bruts et sorties d'outils) avant suppression automatique. Les fichiers que vous enregistrez explicitement dans la bibliothèque Fichiers ne sont pas affectés et persistent jusqu'à ce que vous les supprimiez. | | `CLEANUP_INTERVAL_MINUTES` | `60` | Fréquence d'exécution de la tâche de nettoyage. | ### Apparence {#appearance} | Variable | Par défaut | Description | |---|---|---| | `DEFAULT_THEME` | `light` | Thème par défaut pour les nouvelles sessions. `light`, `dark` ou `system`. | | `DEFAULT_LOCALE` | `en` | Langue d'interface par défaut. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Disposition d'outil par défaut. `sidebar` ou `fullscreen`. | ### Permissions Docker {#docker-permissions} | Variable | Par défaut | Description | |---|---|---| | `PUID` | `999` | Exécuter le processus du conteneur sous cet UID. Réglez-le pour correspondre à votre utilisateur hôte pour les bind mounts (`id -u`). | | `PGID` | `999` | Exécuter le processus du conteneur sous ce GID. Réglez-le pour correspondre à votre groupe hôte pour les bind mounts (`id -g`). | ## Exemple Docker {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Changez ceci pour les déploiements non locaux POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volumes {#volumes} La pile Docker Compose utilise quatre volumes : * `/data` (app) - Modèles d'IA, environnement virtuel Python et fichiers utilisateur. Montez-le pour conserver les fichiers téléversés et les modules d'IA installés entre les redémarrages. * `/tmp/workspace` (app) - Stockage temporaire des fichiers en cours de traitement. Il peut être éphémère, mais le monter évite de remplir la couche accessible en écriture du conteneur. * `SnapOtter-pgdata` (postgres) - Répertoire de données de PostgreSQL. Il contient toutes les données relationnelles (utilisateurs, paramètres, pipelines, tâches, journal d'audit). Sauvegardez-le via `pg_dump` ou un instantané de volume. * `SnapOtter-redisdata` (redis) - Fichier en écriture seule de Redis pour des files d'attente de tâches durables. --- --- url: https://docs.snapotter.com/hi/guide/configuration.md description: >- सभी SnapOtter एनवायरनमेंट वेरिएबल्स डिफ़ॉल्ट के साथ। auth, स्टोरेज, AI मॉडल, एनालिटिक्स, और अधिक कॉन्फ़िगर करें। --- # Configuration {#configuration} सभी कॉन्फ़िगरेशन एनवायरनमेंट वेरिएबल्स के माध्यम से किया जाता है। हर वेरिएबल का एक उचित डिफ़ॉल्ट होता है, इसलिए SnapOtter उनमें से किसी को सेट किए बिना बॉक्स से बाहर काम करता है। ## Environment variables {#environment-variables} ### Server {#server} | Variable | Default | Description | |---|---|---| | `PORT` | `1349` | सर्वर जिस पोर्ट पर सुनता है। | | `RATE_LIMIT_PER_MIN` | `1000` | प्रति IP प्रति मिनट अधिकतम अनुरोध। रेट लिमिटिंग अक्षम करने के लिए 0 पर सेट करें। | | `CORS_ORIGIN` | (empty) | CORS के लिए अल्पविराम-पृथक अनुमत मूल, या केवल-समान-मूल के लिए खाली। | | `LOG_LEVEL` | `info` | लॉग वर्बोसिटी। इनमें से एक: `fatal`, `error`, `warn`, `info`, `debug`, `trace`। | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | `X-Forwarded-For` के ज़रिए क्लाइंट IP कौन से पीयर सेट कर सकते हैं। डिफ़ॉल्ट केवल किसी निजी नेटवर्क के पीयर पर भरोसा करता है, इसलिए Docker नेटवर्क या LAN पर मौजूद रिवर्स प्रॉक्सी भरोसेमंद माना जाता है, जबकि किसी सार्वजनिक क्लाइंट का जाली हेडर नहीं। `true` तभी सेट करें जब आपके नियंत्रण वाला कोई प्रॉक्सी सार्वजनिक पते पर आगे लगा हो। | ### Authentication {#authentication} नीचे दिए गए दोनों बूलियन केवल `true` और `false` स्वीकार करते हैं। इसके अलावा कुछ और, जैसे `1` या `yes` या `on`, सत्यापन में विफल हो जाता है और सर्वर सुनना शुरू करने से पहले ही बाहर निकल जाता है। | Variable | Default | Description | |---|---|---| | `AUTH_ENABLED` | `true` | लॉगिन अनिवार्य करें। बिना किसी अकाउंट के चलाने के लिए `false` पर सेट करें, जो हर अनुरोध को admin अधिकार देता है, इसलिए इसे किसी भरोसेमंद नेटवर्क तक ही सीमित रखें। | | `DEFAULT_USERNAME` | `admin` | प्रारंभिक admin अकाउंट के लिए उपयोगकर्ता नाम। केवल पहली बार चलने पर उपयोग किया जाता है। | | `DEFAULT_PASSWORD` | `admin` | प्रारंभिक admin अकाउंट के लिए पासवर्ड। पहली बार लॉगिन के बाद इसे बदलें। | | `MAX_USERS` | `0` (unlimited) | पंजीकृत उपयोगकर्ता अकाउंट की अधिकतम संख्या। असीमित के लिए 0 पर सेट करें। | | `SESSION_DURATION_HOURS` | `168` | घंटों में लॉगिन सत्र जीवनकाल (डिफ़ॉल्ट 7 दिन है)। | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | पहली बार लॉगिन पर बाध्य पासवर्ड-परिवर्तन प्रॉम्प्ट को छोड़ने के लिए `true` पर सेट करें। | ### Storage {#storage} | Variable | Default | Description | |---|---|---| | `STORAGE_MODE` | `local` | `local` या `s3`। S3 और MinIO के लिए s3\_storage फ़ीचर वाले लाइसेंस के साथ नीचे दिए गए `S3_*` वेरिएबल्स की भी आवश्यकता होती है। | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | PostgreSQL कनेक्शन स्ट्रिंग। Compose स्टैक इसे अपनी `postgres` सेवा की ओर इंगित करता है; embedded मोड पाने के लिए इसे (`REDIS_URL` के साथ) अनसेट छोड़ दें। | | `REDIS_URL` | `redis://localhost:6379` | Redis कनेक्शन स्ट्रिंग (BullMQ जॉब क्यू के लिए उपयोग की जाती है)। Compose इसे अपनी `redis` सेवा की ओर इंगित करता है। | | `WORKSPACE_PATH` | `./tmp/workspace` | प्रोसेसिंग के दौरान अस्थायी फ़ाइलों के लिए डायरेक्टरी। स्वचालित रूप से साफ़ की जाती है। इमेज इसे `/tmp/workspace` पर सेट करती है। | | `FILES_STORAGE_PATH` | `./data/files` | स्थायी उपयोगकर्ता फ़ाइलों (अपलोड की गई इमेज, सहेजे गए परिणाम) के लिए डायरेक्टरी। इमेज इसे `/data/files` पर सेट करती है। | ### S3 object storage {#s3-object-storage} ये केवल तभी पढ़े जाते हैं जब `STORAGE_MODE=s3` हो। तीन आवश्यक वेरिएबल्स में से कोई भी छूट जाए तो स्टार्टअप विफल हो जाता है और जो वेरिएबल आपने छोड़ा उसका नाम बताता है। | Variable | Default | Description | |---|---|---| | `S3_BUCKET` | (empty) | वह बकेट जो अपलोड और आउटपुट रखता है। आवश्यक। | | `S3_ACCESS_KEY_ID` | (empty) | एक्सेस की। आवश्यक। कंटेनर में आप इसके बजाय इसे `S3_ACCESS_KEY_ID_FILE` के माध्यम से माउंट कर सकते हैं। | | `S3_SECRET_ACCESS_KEY` | (empty) | सीक्रेट की। आवश्यक। वही फ़ाइल परिपाटी: `S3_SECRET_ACCESS_KEY_FILE`। | | `S3_REGION` | `us-east-1` | बकेट का क्षेत्र। | | `S3_ENDPOINT` | (empty) | MinIO, R2, Backblaze, और अन्य S3-संगत स्टोर के लिए कस्टम एंडपॉइंट। खाली का अर्थ है AWS। | | `S3_FORCE_PATH_STYLE` | `false` | MinIO और ऐसी किसी भी अन्य चीज़ के लिए `true` पर सेट करें जो वर्चुअल-होस्ट एड्रेसिंग के बजाय `endpoint/bucket/key` चाहती है। | | `S3_PREFIX` | (empty) | की प्रीफ़िक्स, ताकि एक ही बकेट कई इंस्टेंस रख सके। | ### Encryption at rest {#encryption-at-rest} | Variable | Default | Description | |---|---|---| | `DATA_ENCRYPTION_KEY` | (empty) | 64 हेक्स वर्ण (32 बाइट)। डेटाबेस में संग्रहीत संवेदनशील सेटिंग्स को एन्क्रिप्ट करता है। जो कुछ भी 64 हेक्स वर्ण नहीं है उसे स्टार्टअप पर अस्वीकार कर दिया जाता है। | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (empty) | वह की जिससे आप रोटेट होकर दूर जा रहे हैं, वही फ़ॉर्मैट। रोटेशन के दौरान दोनों सेट करें ताकि मौजूदा पंक्तियाँ अब भी डिक्रिप्ट हों, फिर इसे हटा दें। | ### Embedded mode {#embedded-mode} इमेज को बिना किसी `DATABASE_URL` और बिना किसी `REDIS_URL` के चलाएँ और यह कंटेनर के अंदर अपना स्वयं का PostgreSQL 17 और Redis शुरू करता है, जो लूपबैक से बंधा हुआ है, सारा डेटा `/data` वॉल्यूम पर। यह त्वरित शुरुआत, होमलैब, और 1.x से अपग्रेड के लिए एकल-कमांड `docker run` अनुभव को बहाल करता है। यह एक सुविधा पथ है, न कि एक प्रोडक्शन परिनियोजन: प्रोडक्शन के लिए, अलग PostgreSQL और Redis के साथ 3-कंटेनर Compose स्टैक चलाएँ। Embedded मोड को कंटेनर को रूट के रूप में चलाने की आवश्यकता होती है और यह मनमाने-UID रनटाइम (OpenShift, Kubernetes `runAsNonRoot`) के साथ असंगत है; वहाँ Compose का उपयोग करें। | Variable | Default | Description | |---|---|---| | `EMBEDDED` | `auto` | तब स्वतः-सक्षम होता है जब `DATABASE_URL` और `REDIS_URL` दोनों अनसेट हों। इसे अक्षम करने के लिए `0` पर सेट करें (तब ऐप तेज़ी से विफल हो जाता है यदि कोई बाहरी `DATABASE_URL`/`REDIS_URL` सेट नहीं है, बजाय चुपचाप एक इन-कंटेनर डेटाबेस शुरू करने के)। | | `REDIS_MAXMEMORY` | `512mb` | एम्बेडेड Redis के लिए मेमोरी कैप (केवल embedded मोड)। Raspberry Pi जैसे मेमोरी-सीमित होस्ट पर इसे कम करें। | 1.x से अपग्रेड करना: अपनी पुरानी `snapotter.db` को वॉल्यूम में `/data/snapotter.db` पर रखें और embedded मोड इसे पहली बार बूट होने पर एम्बेडेड PostgreSQL में आयात करता है। आयात एक बार चलता है; बाद के बूट इसे छोड़ देते हैं। टेलीमेट्री नोट: embedded मोड किसी भी अन्य कॉन्फ़िगरेशन की तरह इमेज के एनालिटिक्स डिफ़ॉल्ट को विरासत में लेता है। प्रकाशित इमेज एनालिटिक्स चालू के साथ शिप होती है; इसे अक्षम करने के लिए `--build-arg SNAPOTTER_ANALYTICS=off` के साथ बिल्ड करें, या इन-ऐप admin ऑप्ट-आउट का उपयोग करें। ### Processing limits {#processing-limits} | Variable | Default | Description | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (unlimited) | मेगाबाइट में प्रति अपलोड अधिकतम फ़ाइल आकार। असीमित के लिए 0 पर सेट करें। प्रकाशित इमेज `0` के साथ शिप होती है; सोर्स से बिल्ड 100 से शुरू होता है। | | `MAX_BATCH_SIZE` | `0` (unlimited) | एकल बैच अनुरोध में फ़ाइलों की अधिकतम संख्या। असीमित के लिए 0 पर सेट करें। प्रकाशित इमेज `0` के साथ शिप होती है; सोर्स से बिल्ड 100 से शुरू होता है। | | `CONCURRENT_JOBS` | `0` (auto) | समानांतर में चलने वाले बैच जॉब की संख्या। उपलब्ध CPU कोर के आधार पर स्वतः-पहचान के लिए 0 पर सेट करें। | | `MAX_MEGAPIXELS` | `0` (unlimited) | मेगापिक्सेल में अनुमत अधिकतम इमेज रिज़ॉल्यूशन। असीमित के लिए 0 पर सेट करें। | | `MAX_WORKER_THREADS` | `0` (auto) | इमेज प्रोसेसिंग के लिए अधिकतम वर्कर थ्रेड। उपलब्ध CPU कोर के आधार पर स्वतः-पहचान के लिए 0 पर सेट करें। | | `PROCESSING_TIMEOUT_S` | `0` (no limit) | सेकंड में प्रति अनुरोध अधिकतम प्रोसेसिंग समय। बिना टाइमआउट के लिए 0 पर सेट करें। | | `MAX_PIPELINE_STEPS` | `20` | एक पाइपलाइन में अधिकतम चरणों की संख्या। बिना सीमा के लिए 0 पर सेट करें। | | `MAX_CANVAS_PIXELS` | `0` (no limit) | आउटपुट इमेज के लिए पिक्सेल में अधिकतम कैनवास आकार। बिना सीमा के लिए 0 पर सेट करें। | | `MAX_SVG_SIZE_MB` | `50` | सैनिटाइज़ करने से पहले स्वीकार किया जाने वाला सबसे बड़ा SVG, मेगाबाइट में। यहाँ `0` आसपास की पंक्तियों से अलग व्यवहार करता है। यह पार्स-पूर्व आकार सीमा को बढ़ाने के बजाय पूरी तरह हटा देता है, इसलिए इसे सेट ही रहने दें। | | `MAX_PDF_PAGES` | `0` (unlimited) | PDF-to-image रूपांतरण के लिए PDF पृष्ठों की अधिकतम संख्या। असीमित के लिए 0 पर सेट करें। | ### Cleanup {#cleanup} | Variable | Default | Description | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | बिना सहेजे प्रोसेसिंग परिणाम (कच्चे अपलोड और टूल आउटपुट) स्वचालित हटाने से पहले कितने समय तक रखे जाते हैं। जिन फ़ाइलों को आप स्पष्ट रूप से Files लाइब्रेरी में सहेजते हैं वे प्रभावित नहीं होतीं और तब तक बनी रहती हैं जब तक आप उन्हें हटा नहीं देते। | | `CLEANUP_INTERVAL_MINUTES` | `60` | क्लीनअप जॉब कितनी बार चलता है। | ### Appearance {#appearance} | Variable | Default | Description | |---|---|---| | `DEFAULT_THEME` | `light` | नए सत्रों के लिए डिफ़ॉल्ट थीम। `light`, `dark`, या `system`। | | `DEFAULT_LOCALE` | `en` | डिफ़ॉल्ट इंटरफ़ेस भाषा। | | `DEFAULT_TOOL_VIEW` | `sidebar` | डिफ़ॉल्ट टूल लेआउट। `sidebar` या `fullscreen`। | ### Docker permissions {#docker-permissions} | Variable | Default | Description | |---|---|---| | `PUID` | `999` | कंटेनर प्रक्रिया को इस UID के रूप में चलाएँ। बाइंड माउंट के लिए अपने होस्ट उपयोगकर्ता से मिलान करने के लिए सेट करें (`id -u`)। | | `PGID` | `999` | कंटेनर प्रक्रिया को इस GID के रूप में चलाएँ। बाइंड माउंट के लिए अपने होस्ट समूह से मिलान करने के लिए सेट करें (`id -g`)। | ## Docker example {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # गैर-स्थानीय तैनाती के लिए इसे बदलें POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volumes {#volumes} Docker Compose स्टैक चार वॉल्यूम का उपयोग करता है: * `/data` (app) - AI मॉडल, Python venv, और उपयोगकर्ता फ़ाइलें। अपलोड की गई फ़ाइलों और इंस्टॉल किए गए AI बंडलों को पुनरारंभ के दौरान रखने के लिए इसे माउंट करें। * `/tmp/workspace` (app) - प्रोसेस की जा रही फ़ाइलों के लिए अस्थायी स्टोरेज। यह क्षणिक हो सकता है, लेकिन इसे माउंट करने से कंटेनर की लिखने योग्य लेयर भरने से बचती है। * `SnapOtter-pgdata` (postgres) - PostgreSQL डेटा डायरेक्टरी। यह सभी रिलेशनल डेटा (users, settings, pipelines, jobs, audit log) रखती है। `pg_dump` या वॉल्यूम स्नैपशॉट के माध्यम से बैकअप लें। * `SnapOtter-redisdata` (redis) - टिकाऊ जॉब क्यू के लिए Redis append-only फ़ाइल। --- --- url: https://docs.snapotter.com/th/guide/configuration.md description: >- ตัวแปรสภาพแวดล้อมทั้งหมดของ SnapOtter พร้อมค่าเริ่มต้น กำหนดค่าการยืนยันตัวตน, ที่จัดเก็บ, โมเดล AI, การวิเคราะห์ข้อมูล และอื่น ๆ --- # Configuration {#configuration} การกำหนดค่าทั้งหมดทำผ่านตัวแปรสภาพแวดล้อม ทุกตัวแปรมีค่าเริ่มต้นที่เหมาะสม ดังนั้น SnapOtter จึงทำงานได้ทันทีโดยไม่ต้องตั้งค่าใด ๆ ## Environment variables {#environment-variables} ### Server {#server} | Variable | Default | Description | |---|---|---| | `PORT` | `1349` | พอร์ตที่เซิร์ฟเวอร์รับฟัง | | `RATE_LIMIT_PER_MIN` | `1000` | จำนวนคำขอสูงสุดต่อนาทีต่อ IP ตั้งเป็น 0 เพื่อปิดการจำกัดอัตรา | | `CORS_ORIGIN` | (ว่าง) | ต้นทางที่อนุญาตสำหรับ CORS คั่นด้วยเครื่องหมายจุลภาค หรือว่างไว้สำหรับต้นทางเดียวกันเท่านั้น | | `LOG_LEVEL` | `info` | ระดับความละเอียดของบันทึก หนึ่งใน: `fatal`, `error`, `warn`, `info`, `debug`, `trace` | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | เพียร์ใดบ้างที่ตั้งค่า IP ของไคลเอนต์ผ่าน `X-Forwarded-For` ได้ ค่าเริ่มต้นจะเชื่อเฉพาะเพียร์ในเครือข่ายส่วนตัว ดังนั้น reverse proxy บนเครือข่าย Docker หรือบน LAN จึงได้รับความเชื่อถือ ส่วนส่วนหัวที่ปลอมแปลงมาจากไคลเอนต์บนเครือข่ายสาธารณะจะไม่ได้รับ ตั้งเป็น `true` เฉพาะเมื่อมี proxy ที่คุณควบคุมเองวางอยู่ด้านหน้าบนที่อยู่สาธารณะ | ### Authentication {#authentication} บูลีนสองตัวด้านล่างรับเฉพาะ `true` และ `false` เท่านั้น ค่าอื่นใด เช่น `1` หรือ `yes` หรือ `on` จะไม่ผ่านการตรวจสอบ และเซิร์ฟเวอร์จะออกก่อนที่จะเริ่มรับฟัง | Variable | Default | Description | |---|---|---| | `AUTH_ENABLED` | `true` | บังคับให้เข้าสู่ระบบ ตั้งเป็น `false` เพื่อรันโดยไม่มีบัญชีใด ๆ เลย ซึ่งให้สิทธิ์ admin แก่ทุกคำขอ ดังนั้นควรจำกัดไว้เฉพาะเครือข่ายที่เชื่อถือได้ | | `DEFAULT_USERNAME` | `admin` | ชื่อผู้ใช้สำหรับบัญชี admin เริ่มต้น ใช้เฉพาะตอนรันครั้งแรก | | `DEFAULT_PASSWORD` | `admin` | รหัสผ่านสำหรับบัญชี admin เริ่มต้น เปลี่ยนหลังจากเข้าสู่ระบบครั้งแรก | | `MAX_USERS` | `0` (ไม่จำกัด) | จำนวนบัญชีผู้ใช้ที่ลงทะเบียนสูงสุด ตั้งเป็น 0 สำหรับไม่จำกัด | | `SESSION_DURATION_HOURS` | `168` | อายุของ session การเข้าสู่ระบบเป็นชั่วโมง (ค่าเริ่มต้นคือ 7 วัน) | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | ตั้งเป็น `true` เพื่อข้ามการแจ้งให้เปลี่ยนรหัสผ่านแบบบังคับตอนเข้าสู่ระบบครั้งแรก | ### Storage {#storage} | Variable | Default | Description | |---|---|---| | `STORAGE_MODE` | `local` | `local` หรือ `s3` S3 และ MinIO ต้องใช้ใบอนุญาตที่มีฟีเจอร์ s3\_storage พร้อมกับตัวแปร `S3_*` ด้านล่าง | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | สตริงการเชื่อมต่อ PostgreSQL สแตก Compose ชี้ค่านี้ไปยังบริการ `postgres` ของมัน ปล่อยไม่ตั้งค่า (พร้อมกับ `REDIS_URL`) เพื่อใช้โหมด embedded | | `REDIS_URL` | `redis://localhost:6379` | สตริงการเชื่อมต่อ Redis (ใช้สำหรับคิวงาน BullMQ) Compose ชี้ค่านี้ไปยังบริการ `redis` ของมัน | | `WORKSPACE_PATH` | `./tmp/workspace` | ไดเรกทอรีสำหรับไฟล์ชั่วคราวระหว่างการประมวลผล ล้างข้อมูลโดยอัตโนมัติ อิมเมจตั้งค่าเป็น `/tmp/workspace` | | `FILES_STORAGE_PATH` | `./data/files` | ไดเรกทอรีสำหรับไฟล์ผู้ใช้แบบถาวร (ภาพที่อัปโหลด, ผลลัพธ์ที่บันทึก) อิมเมจตั้งค่าเป็น `/data/files` | ### S3 object storage {#s3-object-storage} อ่านค่าเหล่านี้เฉพาะเมื่อ `STORAGE_MODE=s3` เท่านั้น หากขาดตัวใดตัวหนึ่งในสามตัวที่จำเป็น การเริ่มระบบจะล้มเหลวพร้อมบอกชื่อตัวแปรที่คุณละไว้ | Variable | Default | Description | |---|---|---| | `S3_BUCKET` | (ว่าง) | บักเก็ตที่เก็บไฟล์อัปโหลดและเอาต์พุต จำเป็น | | `S3_ACCESS_KEY_ID` | (ว่าง) | แอ็กเซสคีย์ จำเป็น ในคอนเทนเนอร์คุณสามารถเมานต์เป็นไฟล์แทนได้ ผ่าน `S3_ACCESS_KEY_ID_FILE` | | `S3_SECRET_ACCESS_KEY` | (ว่าง) | ซีเคร็ตคีย์ จำเป็น ใช้แบบแผนไฟล์เดียวกัน: `S3_SECRET_ACCESS_KEY_FILE` | | `S3_REGION` | `us-east-1` | ภูมิภาคของบักเก็ต | | `S3_ENDPOINT` | (ว่าง) | เอนด์พอยต์แบบกำหนดเองสำหรับ MinIO, R2, Backblaze และที่จัดเก็บอื่น ๆ ที่รองรับ S3 ค่าว่างหมายถึง AWS | | `S3_FORCE_PATH_STYLE` | `false` | ตั้งเป็น `true` สำหรับ MinIO และสิ่งอื่นใดที่ต้องการ `endpoint/bucket/key` แทนการระบุที่อยู่แบบ virtual-host | | `S3_PREFIX` | (ว่าง) | คำนำหน้าคีย์ เพื่อให้บักเก็ตเดียวเก็บได้หลายอินสแตนซ์ | ### Encryption at rest {#encryption-at-rest} | Variable | Default | Description | |---|---|---| | `DATA_ENCRYPTION_KEY` | (ว่าง) | อักขระเลขฐานสิบหก 64 ตัว (32 ไบต์) เข้ารหัสการตั้งค่าที่ละเอียดอ่อนซึ่งเก็บอยู่ในฐานข้อมูล สิ่งใดที่ไม่ใช่อักขระเลขฐานสิบหก 64 ตัวจะถูกปฏิเสธตอนเริ่มระบบ | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (ว่าง) | คีย์ที่คุณกำลังหมุนเปลี่ยนออกไป รูปแบบเดียวกัน ตั้งค่าทั้งสองตัวระหว่างการหมุนคีย์เพื่อให้แถวที่มีอยู่ยังถอดรหัสได้ แล้วจึงลบตัวนี้ออก | ### Embedded mode {#embedded-mode} รันอิมเมจโดยไม่มี `DATABASE_URL` และไม่มี `REDIS_URL` แล้วมันจะเริ่ม PostgreSQL 17 และ Redis ของตัวเองภายในคอนเทนเนอร์ ผูกกับ loopback โดยข้อมูลทั้งหมดอยู่บนวอลุ่ม `/data` สิ่งนี้ฟื้นฟูประสบการณ์ `docker run` ด้วยคำสั่งเดียวสำหรับการเริ่มต้นอย่างรวดเร็ว, homelab และการอัปเกรดจาก 1.x เป็นเส้นทางเพื่อความสะดวก ไม่ใช่การปรับใช้เพื่อการใช้งานจริง: สำหรับการใช้งานจริง ให้รันสแตก Compose 3 คอนเทนเนอร์พร้อม PostgreSQL และ Redis แยกต่างหาก โหมด embedded ต้องรันคอนเทนเนอร์เป็น root และเข้ากันไม่ได้กับรันไทม์ที่ใช้ UID ตามอำเภอใจ (OpenShift, Kubernetes `runAsNonRoot`) ให้ใช้ Compose ที่นั่น | Variable | Default | Description | |---|---|---| | `EMBEDDED` | `auto` | เปิดใช้อัตโนมัติเมื่อทั้ง `DATABASE_URL` และ `REDIS_URL` ไม่ได้ตั้งค่า ตั้งเป็น `0` เพื่อปิด (แอปจะล้มเหลวอย่างรวดเร็วหากไม่มี `DATABASE_URL`/`REDIS_URL` ภายนอกที่ตั้งค่าไว้ แทนที่จะเริ่มฐานข้อมูลในคอนเทนเนอร์อย่างเงียบ ๆ) | | `REDIS_MAXMEMORY` | `512mb` | ขีดจำกัดหน่วยความจำสำหรับ Redis แบบฝังในตัว (เฉพาะโหมด embedded) ลดค่านี้บนโฮสต์ที่มีหน่วยความจำจำกัด เช่น Raspberry Pi | การอัปเกรดจาก 1.x: วาง `snapotter.db` เก่าของคุณไว้ที่ `/data/snapotter.db` ในวอลุ่ม แล้วโหมด embedded จะนำเข้าไปยัง PostgreSQL แบบฝังในตัวเมื่อบูตครั้งแรก การนำเข้าทำงานครั้งเดียว การบูตครั้งต่อ ๆ ไปจะข้ามมัน หมายเหตุเกี่ยวกับ telemetry: โหมด embedded สืบทอดค่าเริ่มต้นการวิเคราะห์ข้อมูลของอิมเมจเหมือนการกำหนดค่าอื่น ๆ อิมเมจที่เผยแพร่มาพร้อมการวิเคราะห์ข้อมูลที่เปิดอยู่ สร้างด้วย `--build-arg SNAPOTTER_ANALYTICS=off` หรือใช้การเลือกไม่เข้าร่วมของ admin ในแอป เพื่อปิดใช้งาน ### Processing limits {#processing-limits} | Variable | Default | Description | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (ไม่จำกัด) | ขนาดไฟล์สูงสุดต่อการอัปโหลดเป็นเมกะไบต์ ตั้งเป็น 0 สำหรับไม่จำกัด อิมเมจที่เผยแพร่มาพร้อมค่า `0` ส่วนการบิลด์จากซอร์สเริ่มต้นที่ 100 | | `MAX_BATCH_SIZE` | `0` (ไม่จำกัด) | จำนวนไฟล์สูงสุดในคำขอชุดเดียว ตั้งเป็น 0 สำหรับไม่จำกัด อิมเมจที่เผยแพร่มาพร้อมค่า `0` ส่วนการบิลด์จากซอร์สเริ่มต้นที่ 100 | | `CONCURRENT_JOBS` | `0` (อัตโนมัติ) | จำนวนงานชุดที่รันแบบขนาน ตั้งเป็น 0 เพื่อตรวจจับอัตโนมัติตามแกน CPU ที่มีอยู่ | | `MAX_MEGAPIXELS` | `0` (ไม่จำกัด) | ความละเอียดภาพสูงสุดที่อนุญาตเป็นเมกะพิกเซล ตั้งเป็น 0 สำหรับไม่จำกัด | | `MAX_WORKER_THREADS` | `0` (อัตโนมัติ) | เธรด worker สูงสุดสำหรับการประมวลผลรูปภาพ ตั้งเป็น 0 เพื่อตรวจจับอัตโนมัติตามแกน CPU ที่มีอยู่ | | `PROCESSING_TIMEOUT_S` | `0` (ไม่มีขีดจำกัด) | เวลาการประมวลผลสูงสุดต่อคำขอเป็นวินาที ตั้งเป็น 0 สำหรับไม่มีการหมดเวลา | | `MAX_PIPELINE_STEPS` | `20` | จำนวนขั้นตอนสูงสุดในไปป์ไลน์ ตั้งเป็น 0 สำหรับไม่มีขีดจำกัด | | `MAX_CANVAS_PIXELS` | `0` (ไม่มีขีดจำกัด) | ขนาดแคนวาสสูงสุดเป็นพิกเซลสำหรับภาพเอาต์พุต ตั้งเป็น 0 สำหรับไม่มีขีดจำกัด | | `MAX_SVG_SIZE_MB` | `50` | ขนาด SVG ใหญ่ที่สุดที่รับได้ก่อนการทำ sanitize เป็นเมกะไบต์ ที่นี่ `0` ทำงานต่างจากแถวรอบ ๆ มัน โดยจะลบขีดจำกัดขนาดก่อนการแปลงออกทั้งหมดแทนที่จะเพิ่มขีดจำกัด ดังนั้นควรตั้งค่าตัวนี้ไว้เสมอ | | `MAX_PDF_PAGES` | `0` (ไม่จำกัด) | จำนวนหน้า PDF สูงสุดสำหรับการแปลง PDF-to-image ตั้งเป็น 0 สำหรับไม่จำกัด | ### Cleanup {#cleanup} | Variable | Default | Description | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | ระยะเวลาที่เก็บผลลัพธ์การประมวลผลที่ไม่ได้บันทึก (การอัปโหลดดิบและเอาต์พุตเครื่องมือ) ก่อนการลบอัตโนมัติ ไฟล์ที่คุณบันทึกลงคลัง Files อย่างชัดเจนจะไม่ได้รับผลกระทบและคงอยู่จนกว่าคุณจะลบ | | `CLEANUP_INTERVAL_MINUTES` | `60` | ความถี่ที่งานล้างข้อมูลทำงาน | ### Appearance {#appearance} | Variable | Default | Description | |---|---|---| | `DEFAULT_THEME` | `light` | ธีมเริ่มต้นสำหรับ session ใหม่ `light`, `dark` หรือ `system` | | `DEFAULT_LOCALE` | `en` | ภาษาอินเทอร์เฟซเริ่มต้น | | `DEFAULT_TOOL_VIEW` | `sidebar` | เลย์เอาต์เครื่องมือเริ่มต้น `sidebar` หรือ `fullscreen` | ### Docker permissions {#docker-permissions} | Variable | Default | Description | |---|---|---| | `PUID` | `999` | รันกระบวนการคอนเทนเนอร์เป็น UID นี้ ตั้งให้ตรงกับผู้ใช้โฮสต์ของคุณสำหรับ bind mount (`id -u`) | | `PGID` | `999` | รันกระบวนการคอนเทนเนอร์เป็น GID นี้ ตั้งให้ตรงกับกลุ่มโฮสต์ของคุณสำหรับ bind mount (`id -g`) | ## Docker example {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # เปลี่ยนสิ่งนี้สำหรับการปรับใช้ที่ไม่ใช่ภายในเครื่อง POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volumes {#volumes} สแตก Docker Compose ใช้สี่วอลุ่ม: * `/data` (app) - โมเดล AI, Python venv และไฟล์ผู้ใช้ เมานต์นี้เพื่อเก็บไฟล์ที่อัปโหลดและชุด AI ที่ติดตั้งไว้ข้ามการรีสตาร์ต * `/tmp/workspace` (app) - ที่จัดเก็บชั่วคราวสำหรับไฟล์ที่กำลังประมวลผล อาจเป็นแบบชั่วคราวได้ แต่การเมานต์ช่วยหลีกเลี่ยงการเติมเลเยอร์ที่เขียนได้ของคอนเทนเนอร์ * `SnapOtter-pgdata` (postgres) - ไดเรกทอรีข้อมูล PostgreSQL เก็บข้อมูลเชิงสัมพันธ์ทั้งหมด (users, settings, pipelines, jobs, audit log) สำรองข้อมูลผ่าน `pg_dump` หรือ snapshot ของวอลุ่ม * `SnapOtter-redisdata` (redis) - ไฟล์ append-only ของ Redis สำหรับคิวงานที่คงทน --- --- url: https://docs.snapotter.com/fr/guide/low-resource.md --- # Configurations à ressources limitées {#low-resource-setups} SnapOtter tourne bien sur du petit matériel : un Raspberry Pi 4 ou 5, un vieux portable ou un VPS de 2 Go. Cette page est le guide pratique pour ces machines : à quoi s'attendre, une installation à copier-coller avec des plafonds raisonnables, et quelles fonctionnalités laisser de côté. Les données de benchmark complètes derrière ces chiffres se trouvent dans [Exigences matérielles](/fr/guide/deployment#hardware-requirements). Deux contraintes strictes d'emblée : * **64 bits uniquement.** L'image est construite pour `linux/amd64` et `linux/arm64`. L'ARM 32 bits (`armv7`/`armhf`) n'est pas pris en charge : les Pi de première génération et la famille Pi Zero sont donc exclus. * **Plancher mémoire de 2 Go.** 512 Mo ne suffisent pas à démarrer la pile, et 1 Go échoue sur les lots multi-fichiers. 2 Go avec 2 cœurs est la plus petite configuration qui fonctionne confortablement. ## Ce qui tourne bien sur du petit matériel {#what-runs-well} Tous les outils non-IA fonctionnent sur une machine à 2 Go / 2 cœurs : l'intégralité des sections Image et Fichiers, les outils PDF et les opérations vidéo et audio en copie de flux (couper, couper le son, changer de conteneur). La plupart se terminent en moins d'une seconde. Deux charges de travail font exception : * **Le réencodage vidéo** (conversion entre codecs) est limité par le CPU. Un clip 1080p qui prend ~40 s sur un CPU de bureau rapide peut prendre plusieurs minutes sur un CPU de classe Pi. Les opérations en copie de flux restent instantanées. * **Les outils IA** demandent de la RAM (4 Go recommandés) et du disque (les bundles les plus gros font 4-5 Go chacun), et les plus lourds (mise à l'échelle, restauration de photos, suppression d'arrière-plan) ne sont pas utilisables en pratique sur des CPU de classe Pi. L'IA légère comme la détection de visages et l'OCR reste utilisable si vous avez la mémoire nécessaire. Rien de tout cela n'est installé ni actif tant que vous ne l'utilisez pas : sans bundle IA installé, l'application tourne au repos autour de 360 Mo, et les bundles IA ne se téléchargent que lorsqu'un admin les active. ## Pas à pas : Raspberry Pi / vieux portable {#walkthrough} C'est l'installation Compose standard de [Prise en main](/fr/guide/getting-started), plus des limites de ressources et des plafonds prudents. Elle suppose un OS 64 bits (sur un Pi : Raspberry Pi OS 64 bits ou Ubuntu Server arm64). ```yaml services: snapotter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - ./snapotter-data:/data environment: - DATABASE_URL=postgres://snapotter:snapotter@db:5432/snapotter - REDIS_URL=redis://redis:6379 # Small-box profile: see the table below for what each cap does. - CONCURRENT_JOBS=1 - MAX_WORKER_THREADS=2 - MAX_BATCH_SIZE=5 - MAX_UPLOAD_SIZE_MB=100 - MAX_MEGAPIXELS=50 - MAX_VIDEO_DURATION_S=300 deploy: resources: limits: cpus: "2" memory: 2G depends_on: - db - redis restart: unless-stopped db: image: postgres:17-alpine environment: - POSTGRES_USER=snapotter - POSTGRES_PASSWORD=snapotter # Changez ceci pour les déploiements non locaux - POSTGRES_DB=snapotter volumes: - ./postgres-data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:8-alpine command: redis-server --maxmemory 256mb --maxmemory-policy noeviction restart: unless-stopped ``` Remarques pour les machines de classe Pi : * **Préférez un SSD USB à une carte SD** pour le volume de données et Postgres. Les espaces de travail des jobs font de vraies E/S disque, et les cartes SD sont à la fois lentes et vite usées. * **Le conteneur unique tout-en-un fonctionne aussi ici** (PostgreSQL et Redis embarqués quand `DATABASE_URL`/`REDIS_URL` ne sont pas définis), et sur un hôte limité en mémoire, abaissez le plafond de son Redis embarqué avec `REDIS_MAXMEMORY` (voir [Configuration](/fr/guide/configuration)). Compose vous donne un contrôle plus fin par service, c'est pourquoi ce pas à pas l'utilise. * **Ajoutez du swap sur les appareils à 2 Go.** Cela évite qu'un pic occasionnel (un gros PDF, un lot que vous avez oublié de plafonner) se termine en arrêt pour manque de mémoire. zram est l'option qui ménage les cartes SD. * L'image arm64 est CPU uniquement ; il n'y a pas de CUDA sur les cartes ARM. ## Les leviers de réglage {#tuning-knobs} Tous les plafonds sont des variables d'environnement, documentées en détail dans [Configuration](/fr/guide/configuration). `0` signifie illimité ou automatique. Ceux qui comptent sur du petit matériel : | Variable | Suggestion petite machine | Ce que ce plafond protège | |---|---|---| | `CONCURRENT_JOBS` | `1` | Combien de jobs s'exécutent en parallèle. L'auto-détection prend les cœurs CPU moins un : très bien sur une grosse machine, trop gourmand sur une machine à 2 cœurs sous pression mémoire. | | `MAX_WORKER_THREADS` | `2` | Pool de threads du traitement d'image. | | `MAX_BATCH_SIZE` | `5` | Les lots sont le premier endroit où les machines à 1-2 Go manquent de mémoire. | | `MAX_UPLOAD_SIZE_MB` | `100` | Empêche un seul fichier énorme d'occuper tout l'espace de travail. | | `MAX_MEGAPIXELS` | `50` | Décoder une image de plus de 100 MP coûte de la RAM, quelle que soit la taille du fichier. | | `MAX_VIDEO_DURATION_S` | `300` | Les longs transcodages monopolisent un petit CPU pendant des minutes, voire des heures. | | `PROCESSING_TIMEOUT_S` | `600` | Plafond dur pour qu'un job hors de contrôle finisse par libérer la machine. | Ces plafonds s'appliquent à ce que le serveur accepte : réglez-les donc selon ce que vous utilisez réellement, pas au plus bas possible. Si vous ne touchez jamais à la vidéo, un plafond `MAX_VIDEO_DURATION_S` ne coûte rien ; si vous numérisez des documents tous les jours, ne plafonnez pas `MAX_PDF_PAGES`. ## Ce qu'il faut laisser de côté {#what-to-skip} * **Les bundles IA lourds.** La mise à l'échelle, la restauration de photos et la suppression d'arrière-plan demandent un GPU ou un CPU rapide à nombreux cœurs, et chaque bundle coûte 4-5 Go de disque. Sur une petite machine, ne les installez tout simplement pas ; les outils dont le bundle manque affichent une invite d'installation au lieu de s'exécuter. * **Le réencodage vidéo comme charge de travail régulière.** Des transcodages occasionnels ne posent pas de problème (ils sont juste lents) ; une file de transcodage continue demande des cœurs CPU, pas un Pi. * **Les outils inutilisés en général.** Un admin peut désactiver des outils individuels dans les Paramètres, ce qui les retire de l'interface et cesse d'enregistrer leurs routes API. Cela ne libère pas de mémoire en soi, mais évite qu'une petite instance partagée serve précisément à la charge de travail que le matériel ne peut pas encaisser. Si vous déplacez plus tard l'instance vers du matériel plus puissant, retirez les plafonds (remettez-les à `0`) et le même volume de données suit tel quel. --- --- url: https://docs.snapotter.com/it/guide/configuration.md description: >- Tutte le variabili d'ambiente di SnapOtter con i valori predefiniti. Configura autenticazione, archiviazione, modelli AI, analisi e altro. --- # Configurazione {#configuration} Tutta la configurazione avviene tramite variabili d'ambiente. Ogni variabile ha un valore predefinito sensato, quindi SnapOtter funziona out of the box senza impostarne nessuna. ## Variabili d'ambiente {#environment-variables} ### Server {#server} | Variabile | Predefinito | Descrizione | |---|---|---| | `PORT` | `1349` | Porta su cui il server è in ascolto. | | `RATE_LIMIT_PER_MIN` | `1000` | Numero massimo di richieste al minuto per IP. Imposta a 0 per disabilitare il rate limiting. | | `CORS_ORIGIN` | (vuoto) | Origini consentite per CORS separate da virgola, oppure vuoto per solo same-origin. | | `LOG_LEVEL` | `info` | Verbosità dei log. Uno tra: `fatal`, `error`, `warn`, `info`, `debug`, `trace`. | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Quali peer possono impostare l'IP del client tramite `X-Forwarded-For`. Il valore predefinito crede solo a un peer su rete privata, quindi un reverse proxy su una rete Docker o su una LAN è attendibile, mentre l'intestazione falsificata di un client pubblico non lo è. Imposta `true` solo quando davanti c'è un proxy che controlli tu, su un indirizzo pubblico. | ### Autenticazione {#authentication} I due booleani qui sotto accettano solo `true` e `false`. Qualsiasi altro valore, che sia `1`, `yes` oppure `on`, non supera la validazione e il server termina prima di mettersi in ascolto. | Variabile | Predefinito | Descrizione | |---|---|---| | `AUTH_ENABLED` | `true` | Richiede il login. Imposta a `false` per funzionare senza alcun account, il che concede a ogni richiesta i diritti di admin, quindi tienilo su una rete fidata. | | `DEFAULT_USERNAME` | `admin` | Nome utente per l'account admin iniziale. Usato solo alla prima esecuzione. | | `DEFAULT_PASSWORD` | `admin` | Password per l'account admin iniziale. Cambiala dopo il primo login. | | `MAX_USERS` | `0` (illimitato) | Numero massimo di account utente registrati. Imposta a 0 per illimitato. | | `SESSION_DURATION_HOURS` | `168` | Durata della sessione di login in ore (il predefinito è 7 giorni). | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Imposta a `true` per saltare la richiesta forzata di cambio password al primo login. | ### Archiviazione {#storage} | Variabile | Predefinito | Descrizione | |---|---|---| | `STORAGE_MODE` | `local` | `local` o `s3`. S3 e MinIO richiedono una licenza con la funzionalità s3\_storage, oltre alle variabili `S3_*` qui sotto. | | `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | Stringa di connessione PostgreSQL. Lo stack Compose la punta al suo servizio `postgres`; lasciala non impostata (insieme a `REDIS_URL`) per ottenere la modalità embedded. | | `REDIS_URL` | `redis://localhost:6379` | Stringa di connessione Redis (usata per le code di lavori BullMQ). Compose la punta al suo servizio `redis`. | | `WORKSPACE_PATH` | `./tmp/workspace` | Directory per i file temporanei durante l'elaborazione. Pulita automaticamente. L'immagine imposta `/tmp/workspace`. | | `FILES_STORAGE_PATH` | `./data/files` | Directory per i file utente persistenti (immagini caricate, risultati salvati). L'immagine imposta `/data/files`. | ### Archiviazione oggetti S3 {#s3-object-storage} Lette solo quando `STORAGE_MODE=s3`. Se manca una delle tre obbligatorie, l'avvio fallisce indicando il nome della variabile che hai tralasciato. | Variabile | Predefinito | Descrizione | |---|---|---| | `S3_BUCKET` | (vuoto) | Bucket che contiene upload e output. Obbligatorio. | | `S3_ACCESS_KEY_ID` | (vuoto) | Access key. Obbligatoria. Nel container puoi invece montarla, tramite `S3_ACCESS_KEY_ID_FILE`. | | `S3_SECRET_ACCESS_KEY` | (vuoto) | Secret key. Obbligatoria. Stessa convenzione per i file: `S3_SECRET_ACCESS_KEY_FILE`. | | `S3_REGION` | `us-east-1` | Regione del bucket. | | `S3_ENDPOINT` | (vuoto) | Endpoint personalizzato per MinIO, R2, Backblaze e altri store compatibili con S3. Vuoto significa AWS. | | `S3_FORCE_PATH_STYLE` | `false` | Imposta a `true` per MinIO e per qualsiasi altro servizio che si aspetta `endpoint/bucket/key` invece dell'indirizzamento virtual-host. | | `S3_PREFIX` | (vuoto) | Prefisso delle chiavi, così un solo bucket può ospitare più istanze. | ### Crittografia a riposo {#encryption-at-rest} | Variabile | Predefinito | Descrizione | |---|---|---| | `DATA_ENCRYPTION_KEY` | (vuoto) | 64 caratteri esadecimali (32 byte). Cifra le impostazioni sensibili salvate nel database. Qualsiasi cosa che non sia di 64 caratteri esadecimali viene rifiutata all'avvio. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (vuoto) | La chiave che stai abbandonando durante una rotazione, nello stesso formato. Impostale entrambe durante la rotazione così le righe esistenti restano decifrabili, poi rimuovi questa. | ### Modalità embedded {#embedded-mode} Esegui l'immagine senza `DATABASE_URL` e senza `REDIS_URL` e avvia il proprio PostgreSQL 17 e Redis all'interno del container, associati al loopback, con tutti i dati sul volume `/data`. Questo ripristina l'esperienza a comando singolo `docker run` per l'avvio rapido, l'homelab e gli aggiornamenti dalla 1.x. È un percorso di comodità, non un deployment di produzione: per la produzione, esegui lo stack Compose a 3 container con PostgreSQL e Redis separati. La modalità embedded richiede l'esecuzione del container come root ed è incompatibile con i runtime a UID arbitrario (OpenShift, Kubernetes `runAsNonRoot`); lì usa Compose. | Variabile | Predefinito | Descrizione | |---|---|---| | `EMBEDDED` | `auto` | Abilitata automaticamente quando sia `DATABASE_URL` sia `REDIS_URL` non sono impostate. Imposta a `0` per disabilitarla (l'app allora fallisce rapidamente se non è impostato alcun `DATABASE_URL`/`REDIS_URL` esterno, invece di avviare silenziosamente un database in-container). | | `REDIS_MAXMEMORY` | `512mb` | Limite di memoria per il Redis embedded (solo modalità embedded). Abbassalo su host con memoria limitata come un Raspberry Pi. | Aggiornamento dalla 1.x: metti il tuo vecchio `snapotter.db` in `/data/snapotter.db` nel volume e la modalità embedded lo importa nel PostgreSQL embedded al primo avvio. L'importazione avviene una volta sola; gli avvii successivi la saltano. Nota sulla telemetria: la modalità embedded eredita il valore predefinito delle analisi dell'immagine come qualsiasi altra configurazione. L'immagine pubblicata viene fornita con le analisi attive; compila con `--build-arg SNAPOTTER_ANALYTICS=off`, oppure usa l'opt-out admin in-app, per disabilitarla. ### Limiti di elaborazione {#processing-limits} | Variabile | Predefinito | Descrizione | |---|---|---| | `MAX_UPLOAD_SIZE_MB` | `0` (illimitato) | Dimensione massima del file per upload in megabyte. Imposta a 0 per illimitato. L'immagine pubblicata viene fornita con `0`; una build dai sorgenti parte da 100. | | `MAX_BATCH_SIZE` | `0` (illimitato) | Numero massimo di file in una singola richiesta batch. Imposta a 0 per illimitato. L'immagine pubblicata viene fornita con `0`; una build dai sorgenti parte da 100. | | `CONCURRENT_JOBS` | `0` (auto) | Numero di lavori batch che girano in parallelo. Imposta a 0 per rilevarlo automaticamente in base ai core CPU disponibili. | | `MAX_MEGAPIXELS` | `0` (illimitato) | Risoluzione massima dell'immagine consentita in megapixel. Imposta a 0 per illimitato. | | `MAX_WORKER_THREADS` | `0` (auto) | Numero massimo di thread worker per l'elaborazione delle immagini. Imposta a 0 per rilevarlo automaticamente in base ai core CPU disponibili. | | `PROCESSING_TIMEOUT_S` | `0` (nessun limite) | Tempo massimo di elaborazione per richiesta in secondi. Imposta a 0 per nessun timeout. | | `MAX_PIPELINE_STEPS` | `20` | Numero massimo di passaggi in una pipeline. Imposta a 0 per nessun limite. | | `MAX_CANVAS_PIXELS` | `0` (nessun limite) | Dimensione massima del canvas in pixel per le immagini di output. Imposta a 0 per nessun limite. | | `MAX_SVG_SIZE_MB` | `50` | Il più grande SVG accettato prima della sanificazione, in megabyte. Qui `0` si comporta diversamente rispetto alle righe vicine. Rimuove del tutto il limite di dimensione applicato prima del parsing invece di alzarlo, quindi lascia questo valore impostato. | | `MAX_PDF_PAGES` | `0` (illimitato) | Numero massimo di pagine PDF per la conversione PDF-a-immagine. Imposta a 0 per illimitato. | ### Pulizia {#cleanup} | Variabile | Predefinito | Descrizione | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | Per quanto tempo i risultati di elaborazione non salvati (upload grezzi e output degli strumenti) vengono conservati prima dell'eliminazione automatica. I file che salvi esplicitamente nella libreria File non sono interessati e persistono finché non li elimini. | | `CLEANUP_INTERVAL_MINUTES` | `60` | Con quale frequenza viene eseguito il lavoro di pulizia. | ### Aspetto {#appearance} | Variabile | Predefinito | Descrizione | |---|---|---| | `DEFAULT_THEME` | `light` | Tema predefinito per le nuove sessioni. `light`, `dark` o `system`. | | `DEFAULT_LOCALE` | `en` | Lingua predefinita dell'interfaccia. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Layout predefinito degli strumenti. `sidebar` o `fullscreen`. | ### Permessi Docker {#docker-permissions} | Variabile | Predefinito | Descrizione | |---|---|---| | `PUID` | `999` | Esegui il processo del container come questo UID. Imposta per corrispondere al tuo utente host per i bind mount (`id -u`). | | `PGID` | `999` | Esegui il processo del container come questo GID. Imposta per corrispondere al tuo gruppo host per i bind mount (`id -g`). | ## Esempio Docker {#docker-example} ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=changeme - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 - MAX_UPLOAD_SIZE_MB=200 - CONCURRENT_JOBS=4 - FILE_MAX_AGE_HOURS=12 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Modificarlo per distribuzioni non locali POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ## Volumi {#volumes} Lo stack Docker Compose usa quattro volumi: * `/data` (app) - Modelli AI, venv Python e file utente. Montalo per conservare i file caricati e i bundle AI installati tra i riavvii. * `/tmp/workspace` (app) - Archiviazione temporanea per i file in elaborazione. Può essere effimera, ma montarlo evita di riempire il livello scrivibile del container. * `SnapOtter-pgdata` (postgres) - Directory dati di PostgreSQL. Contiene tutti i dati relazionali (utenti, impostazioni, pipeline, lavori, log di audit). Esegui il backup tramite `pg_dump` o snapshot del volume. * `SnapOtter-redisdata` (redis) - File append-only di Redis per code di lavori durevoli. --- --- url: https://docs.snapotter.com/it/guide/low-resource.md --- # Configurazioni a basse risorse {#low-resource-setups} SnapOtter funziona bene su hardware modesto: un Raspberry Pi 4 o 5, un vecchio laptop o un VPS da 2 GB. Questa pagina è la guida pratica per quelle macchine: cosa aspettarsi, una configurazione copia-incolla con limiti ragionevoli e quali funzionalità saltare. I dati completi dei benchmark dietro questi numeri si trovano in [Requisiti hardware](/it/guide/deployment#hardware-requirements). Due vincoli rigidi da subito: * **Solo a 64 bit.** L'immagine viene creata per `linux/amd64` e `linux/arm64`. ARM a 32 bit (`armv7`/`armhf`) non è supportato, quindi i Pi di prima generazione e la famiglia Pi Zero sono esclusi. * **Soglia minima di memoria: 2 GB.** Con 512 MB lo stack non si avvia nemmeno, e 1 GB fallisce sui batch multi-file. 2 GB con 2 core è la configurazione più piccola che funziona comodamente. ## Cosa funziona bene su hardware modesto {#what-runs-well} Ogni strumento non AI funziona su una macchina da 2 GB / 2 core: le intere sezioni Immagine e File, gli strumenti PDF e le operazioni video e audio in stream-copy (taglio, silenziamento, remux del container). La maggior parte termina in meno di un secondo. Due carichi di lavoro fanno eccezione: * **La ricodifica video** (conversione tra codec) è vincolata alla CPU. Una clip 1080p che richiede ~40 s su una CPU desktop veloce può richiedere diversi minuti su una CPU di classe Pi. Le operazioni in stream-copy restano istantanee. * **Gli strumenti AI** hanno bisogno di RAM (4 GB consigliati) e di disco (i bundle più grandi pesano 4-5 GB ciascuno), e quelli pesanti (upscaling, ripristino foto, rimozione dello sfondo) non sono praticabili su CPU di classe Pi. L'AI leggera come il rilevamento dei volti e l'OCR è utilizzabile se hai la memoria necessaria. Nessuno dei due è installato o in esecuzione finché non lo usi: senza bundle AI installati l'app a riposo occupa circa 360 MB, e i bundle AI vengono scaricati solo quando un amministratore li abilita. ## Guida passo passo per Raspberry Pi / vecchio laptop {#walkthrough} Questa è l'installazione Compose standard di [Per iniziare](/it/guide/getting-started), più limiti di risorse e tetti prudenti. Presuppone un sistema operativo a 64 bit (su un Pi: Raspberry Pi OS 64-bit o Ubuntu Server arm64). ```yaml services: snapotter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - ./snapotter-data:/data environment: - DATABASE_URL=postgres://snapotter:snapotter@db:5432/snapotter - REDIS_URL=redis://redis:6379 # Small-box profile: see the table below for what each cap does. - CONCURRENT_JOBS=1 - MAX_WORKER_THREADS=2 - MAX_BATCH_SIZE=5 - MAX_UPLOAD_SIZE_MB=100 - MAX_MEGAPIXELS=50 - MAX_VIDEO_DURATION_S=300 deploy: resources: limits: cpus: "2" memory: 2G depends_on: - db - redis restart: unless-stopped db: image: postgres:17-alpine environment: - POSTGRES_USER=snapotter - POSTGRES_PASSWORD=snapotter # Modificarlo per distribuzioni non locali - POSTGRES_DB=snapotter volumes: - ./postgres-data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:8-alpine command: redis-server --maxmemory 256mb --maxmemory-policy noeviction restart: unless-stopped ``` Note per le macchine di classe Pi: * **Preferisci un SSD USB a una scheda SD** per il volume dei dati e Postgres. Gli spazi di lavoro dei job fanno vero IO su disco, e le schede SD sono lente e si usurano in fretta. * **Anche il container unico all-in-one funziona qui** (Postgres e Redis integrati quando `DATABASE_URL`/`REDIS_URL` non sono impostati), e su un host con poca memoria conviene abbassare il tetto del Redis integrato con `REDIS_MAXMEMORY` (vedi [Configurazione](/it/guide/configuration)). Compose offre un controllo più fine per singolo servizio, ed è per questo che questa guida lo usa. * **Aggiungi swap sui dispositivi da 2 GB.** Evita che il picco occasionale (un PDF enorme, un batch che hai dimenticato di limitare) finisca in un out-of-memory kill. zram è l'opzione più delicata con le schede SD. * L'immagine arm64 è solo CPU; non c'è CUDA sulle schede ARM. ## I parametri di regolazione {#tuning-knobs} Tutti i tetti sono variabili d'ambiente, documentate per esteso in [Configurazione](/it/guide/configuration). `0` significa illimitato o automatico. Quelli che contano su hardware modesto: | Variabile | Suggerimento per macchine piccole | Cosa protegge | |---|---|---| | `CONCURRENT_JOBS` | `1` | Quanti job girano in parallelo. Il rilevamento automatico usa i core della CPU meno uno, che va bene sulle macchine grandi ed è troppo aggressivo su una macchina a 2 core sotto pressione di memoria. | | `MAX_WORKER_THREADS` | `2` | Pool di thread per l'elaborazione delle immagini. | | `MAX_BATCH_SIZE` | `5` | I batch sono il punto in cui le macchine da 1-2 GB esauriscono la memoria per prime. | | `MAX_UPLOAD_SIZE_MB` | `100` | Impedisce che un singolo file enorme occupi l'intero spazio di lavoro. | | `MAX_MEGAPIXELS` | `50` | Decodificare un'immagine da 100+ MP costa RAM a prescindere dalla dimensione del file. | | `MAX_VIDEO_DURATION_S` | `300` | Le transcodifiche lunghe monopolizzano una CPU piccola per minuti o ore. | | `PROCESSING_TIMEOUT_S` | `600` | Tetto rigido perché un job fuori controllo liberi comunque la macchina, prima o poi. | Questi tetti si applicano a ciò che il server accetta, quindi impostali in base a ciò che usi davvero, non al minimo possibile. Se non tocchi mai i video, un tetto su `MAX_VIDEO_DURATION_S` non costa nulla; se digitalizzi documenti ogni giorno, non mettere un tetto a `MAX_PDF_PAGES`. ## Cosa saltare {#what-to-skip} * **I bundle AI pesanti.** Upscaling, ripristino foto e rimozione dello sfondo vogliono una GPU o una CPU veloce con molti core, e ogni bundle costa 4-5 GB di disco. Su una macchina piccola, semplicemente non installarli; gli strumenti il cui bundle manca mostrano un invito all'installazione invece di essere eseguiti. * **La ricodifica video come carico di lavoro abituale.** Le transcodifiche occasionali vanno bene (sono solo lente); una coda di transcodifica costante vuole core CPU, non un Pi. * **Gli strumenti inutilizzati in generale.** Un amministratore può disattivare i singoli strumenti nelle Impostazioni, il che li rimuove dall'interfaccia e smette di registrare le loro rotte API. Di per sé non fa risparmiare memoria, ma evita che una piccola istanza condivisa venga usata proprio per l'unico carico di lavoro che l'hardware non può reggere. Se in seguito sposti l'istanza su hardware più potente, rimuovi i tetti (riportali a `0`) e lo stesso volume dei dati si trasferisce così com'è. --- --- url: https://docs.snapotter.com/it/tools/image/compare.md description: >- Confronta due immagini fianco a fianco con visualizzazione delle differenze a livello di pixel e punteggio di somiglianza. --- # Confronto immagini {#image-compare} Carica due immagini per calcolare una mappa delle differenze a livello di pixel e una percentuale numerica di somiglianza. L'output è un'immagine delle differenze che evidenzia in rosso le regioni cambiate. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/compare` Accetta dati di form multipart con **due** file immagine. Non è necessario alcun campo di impostazioni. ## Parametri {#parameters} Questo strumento non ha parametri configurabili. Carica esattamente due file immagine. | Campo | Tipo | Obbligatorio | Descrizione | |-------|------|----------|-------------| | file (primo) | file | Sì | La prima immagine | | file (secondo) | file | Sì | La seconda immagine | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Campi della risposta {#response-fields} | Campo | Tipo | Descrizione | |-------|------|-------------| | jobId | string | Identificatore del job per scaricare l'immagine delle differenze | | similarity | number | Percentuale di somiglianza tra le due immagini (da 0 a 100) | | dimensions | object | Larghezza e altezza usate per il confronto | | downloadUrl | string | URL per scaricare l'immagine delle differenze generata | | originalSize | number | Dimensione combinata di entrambe le immagini di input in byte | | processedSize | number | Dimensione dell'immagine di output delle differenze in byte | ## Note {#notes} * Entrambe le immagini vengono ridimensionate alle stesse dimensioni (il massimo di ciascun asse) prima del confronto. * L'immagine delle differenze evidenzia le differenze in rosso con opacità proporzionale all'entità del cambiamento. I pixel identici o quasi identici (differenza < 10) vengono mostrati come versioni semitrasparenti dell'originale. * La somiglianza è calcolata come l'inverso della differenza media dei pixel su tutti i pixel, espressa in percentuale. * Una somiglianza del 100% significa che le immagini sono identiche a livello di pixel (alla risoluzione di confronto). * L'output delle differenze è sempre in formato PNG indipendentemente dai formati di input. * Entrambe le immagini vengono validate e decodificate (HEIC, RAW, PSD, SVG supportati) prima del confronto. * L'orientamento EXIF viene applicato automaticamente su entrambe le immagini prima dell'elaborazione. --- --- url: https://docs.snapotter.com/vi/tools/image/gif-tools.md description: >- Thay đổi kích thước, tối ưu hóa, đổi tốc độ, đảo ngược, xoay và trích xuất khung hình từ GIF động trong một công cụ duy nhất. --- # Công cụ GIF {#gif-tools} Thay đổi kích thước, tối ưu hóa, đổi tốc độ, đảo ngược, trích xuất khung hình và xoay GIF động. Cung cấp nhiều chế độ thao tác trong một công cụ duy nhất. ## Điểm cuối API {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Tham số {#parameters} ### Tham số chung {#common-parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | mode | string | Không | `"resize"` | Chế độ thao tác: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | Không | 0 | Số lần lặp cho GIF đầu ra (0 = vô hạn, 1-100 = số lần lặp hữu hạn) | ### Tham số chế độ Resize {#resize-mode-parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | width | integer | Không | - | Chiều rộng đích tính bằng pixel (1 đến 16384) | | height | integer | Không | - | Chiều cao đích tính bằng pixel (1 đến 16384) | | percentage | number | Không | - | Thu phóng theo phần trăm (1 đến 500). Ghi đè width/height nếu được đặt. | ### Tham số chế độ Optimize {#optimize-mode-parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | colors | number | Không | 256 | Số màu tối đa trong bảng màu (2 đến 256) | | dither | number | Không | 1.0 | Cường độ khử răng cưa màu (0 đến 1, trong đó 0 tắt dithering) | | effort | number | Không | 7 | Mức nỗ lực tối ưu hóa (1 đến 10, cao hơn = chậm hơn nhưng nhỏ hơn) | ### Tham số chế độ Speed {#speed-mode-parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | speedFactor | number | Không | 1.0 | Hệ số nhân tốc độ (0.1 đến 10). Giá trị > 1 tăng tốc, < 1 làm chậm. | ### Tham số chế độ Extract {#extract-mode-parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | extractMode | string | Không | `"single"` | Chế độ trích xuất: `single`, `range`, `all` | | frameNumber | number | Không | 0 | Chỉ số khung hình cần trích xuất trong chế độ `single` (bắt đầu từ 0) | | frameStart | number | Không | 0 | Chỉ số khung hình bắt đầu cho chế độ `range` (bắt đầu từ 0) | | frameEnd | number | Không | - | Chỉ số khung hình kết thúc cho chế độ `range` (bắt đầu từ 0, bao gồm cả chỉ số này) | | extractFormat | string | Không | `"png"` | Định dạng cho khung hình được trích xuất: `png`, `webp` | ### Tham số chế độ Rotate {#rotate-mode-parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | angle | number | Không | - | Góc xoay: `90`, `180`, hoặc `270` độ | | flipH | boolean | Không | `false` | Lật ngang | | flipV | boolean | Không | `false` | Lật dọc | ## Ví dụ yêu cầu {#example-requests} ### Resize {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimize {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Tăng tốc {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Trích xuất một khung hình đơn {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Tuyến con Info {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Trả về siêu dữ liệu về một GIF động mà không xử lý nó. ### Yêu cầu Info {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Phản hồi Info {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Ghi chú {#notes} * Sử dụng factory `createToolRoute` tiêu chuẩn cho điểm cuối xử lý chính. * Điểm cuối info chỉ cần tải lên một tệp (không cần cài đặt). * Ở chế độ `resize`, nếu `percentage` được cung cấp thì nó được ưu tiên hơn `width`/`height`. Việc thay đổi kích thước dùng `fit: inside` để giữ tỷ lệ khung hình. * Ở chế độ `speed`, độ trễ khung hình được chia cho hệ số tốc độ. Độ trễ tối thiểu mỗi khung hình là 20ms (giới hạn của đặc tả GIF). * Ở chế độ `reverse`, tham số `speedFactor` cũng khả dụng để đồng thời điều chỉnh tốc độ trong khi đảo ngược. * Ở chế độ `extract` với `range` hoặc `all`, đầu ra là một tệp ZIP chứa từng khung hình riêng lẻ. * Ở chế độ `rotate`, mỗi khung hình được xử lý riêng và lắp ghép lại thành một hoạt ảnh. * Tham số `loop` kiểm soát số lần lặp của GIF đầu ra. Dùng 0 để lặp vô hạn. * Trường `duration` trong phản hồi info là tổng thời lượng hoạt ảnh tính bằng mili-giây. --- --- url: https://docs.snapotter.com/ar/tools/image/content-aware-resize.md description: >- إعادة تحجيم بنحت الشقوق تضيف أو تزيل بكسلات على طول المسارات الأقل أهمية للحفاظ على المحتوى الأساسي والوجوه. --- # Content-Aware Resize {#content-aware-resize} إعادة تحجيم بنحت الشقوق تزيل أو تضيف البكسلات بذكاء على طول المسارات الأقل أهمية بصريًا، مع الحفاظ على المحتوى المهم وحماية الوجوه اختياريًا. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/content-aware-resize` **المعالجة:** متزامنة (تُعيد النتيجة مباشرة) **حزمة النموذج:** لا حاجة إليها للتشغيل الأساسي. تستخدم حماية الوجوه حزمة `face-detection` (200-300 ميغابايت) إذا كانت مفعّلة. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | ملف الصورة (multipart) | | width | number | No | - | العرض المستهدف بالبكسل | | height | number | No | - | الارتفاع المستهدف بالبكسل | | protectFaces | boolean | No | `false` | اكتشاف الوجوه وحمايتها من إزالة الشقوق | | blurRadius | number | No | `4` | نصف قطر التمويه للمعالجة المسبقة لحساب الطاقة (0-20) | | sobelThreshold | number | No | `2` | عتبة اكتشاف حواف Sobel (1-20). القيم الأعلى تجعل الخوارزمية أكثر حدّة | | square | boolean | No | `false` | إعادة التحجيم إلى مربع (يستخدم البُعد الأصغر) | يجب تحديد واحد على الأقل من `width` أو `height` أو `square`. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/content-aware-resize \ -F "file=@landscape.jpg" \ -F 'settings={"width":800,"protectFaces":true}' ``` ## Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/landscape_seam.png", "originalSize": 450000, "processedSize": 380000, "width": 800, "height": 600 } ``` ## Notes {#notes} * يُعيد هذا المسار المخصص حاليًا استجابة 200 متزامنة. * يستخدم مكتبة نحت الشقوق `caire` لإعادة التحجيم المدركة للمحتوى. * يقلّل الأبعاد فقط (يزيل الشقوق). لا يمكنه توسيع الصورة إلى ما وراء حجمها الأصلي. * يستخدم خيار `protectFaces` اكتشاف الوجوه بالذكاء الاصطناعي لتحديد مناطق الوجه كذات طاقة عالية، مما يمنع مرور الشقوق عبر الوجوه. * يتحكّم `blurRadius` في التنعيم قبل حساب خريطة الطاقة. القيم الأعلى تجعل خريطة الطاقة أكثر تجانسًا، مما قد يساعد مع الصور المشوّشة. * يؤثّر `sobelThreshold` في مدى حدّة اكتشاف الحواف. القيم الأقل تحافظ على مزيد من الحواف الخفيفة. * الإخراج دائمًا بصيغة PNG. * يدعم صيغ الإدخال HEIC/HEIF وRAW وTGA وPSD وEXR وHDR عبر فكّ الشفرة التلقائي. --- --- url: https://docs.snapotter.com/hi/tools/image/content-aware-resize.md description: >- सीम-कार्विंग आकार बदलना जो प्रमुख सामग्री और चेहरों को संरक्षित करने के लिए कम-महत्व वाले पथों के साथ पिक्सेल जोड़ता या हटाता है। --- # Content-Aware Resize {#content-aware-resize} सीम कार्विंग आकार बदलना जो न्यूनतम दृश्य महत्व वाले पथों के साथ बुद्धिमानी से पिक्सेल हटाता या जोड़ता है, महत्वपूर्ण सामग्री को संरक्षित करता है और वैकल्पिक रूप से चेहरों की रक्षा करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/content-aware-resize` **Processing:** तुल्यकालिक (परिणाम सीधे लौटाता है) **Model bundle:** बुनियादी संचालन के लिए कोई आवश्यक नहीं। सक्षम होने पर चेहरा सुरक्षा `face-detection` बंडल (200-300 MB) का उपयोग करती है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | छवि फ़ाइल (मल्टीपार्ट) | | width | number | No | - | पिक्सेल में लक्षित चौड़ाई | | height | number | No | - | पिक्सेल में लक्षित ऊँचाई | | protectFaces | boolean | No | `false` | सीम हटाने से चेहरों का पता लगाएँ और उन्हें सुरक्षित रखें | | blurRadius | number | No | `4` | ऊर्जा गणना के लिए पूर्व-प्रसंस्करण ब्लर त्रिज्या (0-20) | | sobelThreshold | number | No | `2` | Sobel किनारा पहचान सीमा (1-20)। उच्च मान एल्गोरिथ्म को अधिक आक्रामक बनाते हैं | | square | boolean | No | `false` | वर्ग में आकार बदलें (छोटे आयाम का उपयोग करता है) | `width`, `height`, या `square` में से कम से कम एक निर्दिष्ट किया जाना चाहिए। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/content-aware-resize \ -F "file=@landscape.jpg" \ -F 'settings={"width":800,"protectFaces":true}' ``` ## Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/landscape_seam.png", "originalSize": 450000, "processedSize": 380000, "width": 800, "height": 600 } ``` ## Notes {#notes} * यह कस्टम रूट वर्तमान में एक तुल्यकालिक 200 प्रतिक्रिया लौटाता है। * सामग्री-जागरूक आकार बदलने के लिए `caire` सीम कार्विंग लाइब्रेरी का उपयोग करता है। * केवल आयाम घटाता है (सीम हटाता है)। किसी छवि को उसके मूल आकार से आगे विस्तारित नहीं कर सकता। * `protectFaces` विकल्प चेहरा क्षेत्रों को उच्च-ऊर्जा के रूप में चिह्नित करने के लिए AI चेहरा पहचान का उपयोग करता है, जिससे सीम को चेहरों से गुज़रने से रोका जाता है। * `blurRadius` ऊर्जा मानचित्र गणना से पहले चौरसाई को नियंत्रित करता है। उच्च मान ऊर्जा मानचित्र को अधिक एकसमान बनाते हैं, जो शोरयुक्त छवियों के साथ मदद कर सकता है। * `sobelThreshold` प्रभावित करता है कि किनारों का पता कितनी आक्रामकता से लगाया जाता है। कम मान अधिक सूक्ष्म किनारों को संरक्षित करते हैं। * आउटपुट हमेशा PNG फ़ॉर्मेट होता है। * स्वचालित डिकोडिंग के माध्यम से HEIC/HEIF, RAW, TGA, PSD, EXR, और HDR इनपुट फ़ॉर्मेट का समर्थन करता है। --- --- url: https://docs.snapotter.com/th/tools/image/content-aware-resize.md description: >- การปรับขนาดแบบ seam-carving ที่เพิ่มหรือลบพิกเซลตามเส้นทางที่มีความสำคัญต่ำ เพื่อรักษาเนื้อหาหลักและใบหน้าเอาไว้ --- # Content-Aware Resize {#content-aware-resize} การปรับขนาดแบบ seam carving ที่ลบหรือเพิ่มพิกเซลอย่างชาญฉลาดตามเส้นทางที่มีความสำคัญเชิงสายตาน้อยที่สุด รักษาเนื้อหาสำคัญและปกป้องใบหน้าเป็นทางเลือก ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/content-aware-resize` **การประมวลผล:** แบบซิงโครนัส (ส่งคืนผลลัพธ์โดยตรง) **ชุดโมเดล:** ไม่จำเป็นสำหรับการทำงานพื้นฐาน การปกป้องใบหน้าใช้ชุด `face-detection` (200-300 MB) หากเปิดใช้งาน ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | ไฟล์ภาพ (multipart) | | width | number | No | - | ความกว้างเป้าหมายเป็นพิกเซล | | height | number | No | - | ความสูงเป้าหมายเป็นพิกเซล | | protectFaces | boolean | No | `false` | ตรวจจับและปกป้องใบหน้าจากการลบ seam | | blurRadius | number | No | `4` | รัศมีเบลอก่อนประมวลผลสำหรับการคำนวณพลังงาน (0-20) | | sobelThreshold | number | No | `2` | ค่าเทรชโฮลด์การตรวจจับขอบแบบ Sobel (1-20) ค่าที่สูงกว่าจะทำให้อัลกอริทึมทำงานเชิงรุกมากขึ้น | | square | boolean | No | `false` | ปรับขนาดให้เป็นสี่เหลี่ยมจัตุรัส (ใช้ด้านที่เล็กกว่า) | ต้องระบุอย่างน้อยหนึ่งค่าจาก `width`, `height` หรือ `square` ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/content-aware-resize \ -F "file=@landscape.jpg" \ -F 'settings={"width":800,"protectFaces":true}' ``` ## Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/landscape_seam.png", "originalSize": 450000, "processedSize": 380000, "width": 800, "height": 600 } ``` ## Notes {#notes} * เส้นทางแบบกำหนดเองนี้ปัจจุบันส่งคืนการตอบสนอง 200 แบบซิงโครนัส * ใช้ไลบรารี seam carving `caire` สำหรับการปรับขนาดแบบคำนึงถึงเนื้อหา * ลดขนาดได้เท่านั้น (ลบ seam) ไม่สามารถขยายภาพเกินขนาดต้นฉบับได้ * ตัวเลือก `protectFaces` ใช้การตรวจจับใบหน้าด้วย AI เพื่อทำเครื่องหมายบริเวณใบหน้าเป็นพลังงานสูง ป้องกันไม่ให้ seam ผ่านใบหน้า * `blurRadius` ควบคุมการทำให้เรียบก่อนการคำนวณแผนที่พลังงาน ค่าที่สูงกว่าจะทำให้แผนที่พลังงานสม่ำเสมอมากขึ้น ซึ่งช่วยได้กับภาพที่มีสัญญาณรบกวน * `sobelThreshold` ส่งผลต่อความเชิงรุกในการตรวจจับขอบ ค่าที่ต่ำกว่าจะรักษาขอบที่ละเอียดอ่อนกว่าเอาไว้ * เอาต์พุตเป็นรูปแบบ PNG เสมอ * รองรับรูปแบบอินพุต HEIC/HEIF, RAW, TGA, PSD, EXR และ HDR ผ่านการถอดรหัสอัตโนมัติ --- --- url: https://docs.snapotter.com/uk/tools/image/content-aware-resize.md description: >- Зміна розміру методом швів, що додає або видаляє пікселі вздовж малозначущих шляхів для збереження ключового вмісту та облич. --- # Content-Aware Resize {#content-aware-resize} Зміна розміру методом швів, що інтелектуально видаляє або додає пікселі вздовж шляхів найменшої візуальної значущості, зберігаючи важливий вміст і за бажанням захищаючи обличчя. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/content-aware-resize` **Processing:** Синхронна (повертає результат напряму) **Model bundle:** Не потрібен для базової роботи. Захист облич використовує пакет `face-detection` (200-300 MB), якщо увімкнено. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Файл зображення (multipart) | | width | number | No | - | Цільова ширина в пікселях | | height | number | No | - | Цільова висота в пікселях | | protectFaces | boolean | No | `false` | Виявляти та захищати обличчя від видалення швів | | blurRadius | number | No | `4` | Радіус попереднього розмиття для розрахунку енергії (0-20) | | sobelThreshold | number | No | `2` | Поріг виявлення країв за методом Собеля (1-20). Вищі значення роблять алгоритм агресивнішим | | square | boolean | No | `false` | Змінити розмір до квадрата (використовує меншу сторону) | Потрібно вказати принаймні один із `width`, `height` або `square`. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/content-aware-resize \ -F "file=@landscape.jpg" \ -F 'settings={"width":800,"protectFaces":true}' ``` ## Response (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/landscape_seam.png", "originalSize": 450000, "processedSize": 380000, "width": 800, "height": 600 } ``` ## Notes {#notes} * Цей власний маршрут наразі повертає синхронну відповідь 200. * Використовує бібліотеку швів `caire` для зміни розміру з урахуванням вмісту. * Лише зменшує розміри (видаляє шви). Не може розширити зображення понад його оригінальний розмір. * Параметр `protectFaces` використовує AI-виявлення облич, щоб позначити області облич як високоенергетичні, запобігаючи проходженню швів через обличчя. * `blurRadius` керує згладжуванням перед розрахунком мапи енергії. Вищі значення роблять мапу енергії одноріднішою, що може допомогти із зашумленими зображеннями. * `sobelThreshold` впливає на те, наскільки агресивно виявляються краї. Нижчі значення зберігають більше тонких країв. * Вивід завжди у форматі PNG. * Підтримує вхідні формати HEIC/HEIF, RAW, TGA, PSD, EXR та HDR через автоматичне декодування. --- --- url: https://docs.snapotter.com/fr/guide/contributing.md description: >- Comment contribuer à SnapOtter. Rapports de bugs, demandes de fonctionnalités, pull requests et exigences du CLA. --- # Contribuer {#contributing} Merci de l'intérêt que vous portez à contribuer. Ce guide explique comment participer, ce que nous acceptons et comment démarrer. ## Façons de contribuer {#ways-to-contribute} ### Tickets (aucune configuration requise) {#issues-no-setup-required} * **Rapports de bugs** - Quelque chose est cassé ? Ouvrez un [rapport de bug](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) avec les étapes de reproduction. * **Demandes de fonctionnalités** - Vous avez une idée ? Lancez une [discussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) pour que la communauté puisse donner son avis et voter pour elle. * **Problèmes de traduction** - Vous repérez une traduction erronée ou manquante ? Ouvrez un [ticket de traduction](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Problèmes de documentation** - Quelque chose cloche dans la documentation ? Ouvrez un [ticket de documentation](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Code (nécessite le CLA) {#code-requires-cla} Nous acceptons les pull requests pour : | Type | Processus | |------|---------| | Corrections de bugs | Ouvrez une PR directement (liez le ticket s'il en existe un) | | Nouvelles traductions | Ouvrez une PR directement (voir le [Guide de traduction](/fr/guide/translations)) | | Améliorations de la documentation | Ouvrez une PR directement | | Améliorations de la couverture de tests | Ouvrez une PR directement | | Nouveaux outils ou fonctionnalités | Lancez d'abord une [discussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) ; un mainteneur convertit les idées approuvées en un ticket suivi avant que vous n'écriviez du code | | Refactorisations ou changements d'architecture | Lancez d'abord une [discussion](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) et attendez la validation d'un mainteneur avant d'écrire du code | ### Ce que nous n'accepterons pas {#what-we-will-not-accept} * Les modifications des workflows CI/CD, de la configuration de release ou de la configuration du linter/compilateur * Les PR sans [Accord de licence de contributeur](#contributor-license-agreement) signé * Les PR de plus de 400 lignes de changement (découpez les gros travaux en PR plus petites) * Les fonctionnalités qui n'ont pas été discutées et approuvées au préalable * Les modifications de `packages/ai/` sans discussion préalable ## Accord de licence de contributeur {#contributor-license-agreement} Avant que nous puissions fusionner votre première PR, vous devez signer notre [CLA individuel](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md). C'est une exigence à faire une seule fois. **Pourquoi :** SnapOtter est sous double licence (AGPLv3 + commerciale). Le CLA nous accorde le droit de distribuer vos contributions sous les deux licences. Vous conservez la pleine propriété du droit d'auteur sur votre travail. **Comment :** Lorsque vous ouvrez votre première PR, le bot CLA Assistant publie un commentaire avec un lien. Cliquez dessus, relisez l'accord et signez avec votre compte GitHub. Cela prend 30 secondes. Si vous contribuez pour le compte de votre employeur et que celui-ci conserve les droits de propriété intellectuelle sur votre travail, contactez contact@snapotter.com pour mettre en place un CLA d'entreprise avant de soumettre. ## Démarrage {#getting-started} ### Prérequis {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (uniquement pour les outils d'IA) * Docker (facultatif, pour les tests d'intégration complets) ### Configuration {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Exécuter les vérifications {#running-checks} Avant de soumettre une PR, assurez-vous que toutes les vérifications passent en local : ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Processus de pull request {#pull-request-process} 1. Forkez le dépôt et créez une branche à partir de `main` (`feat/my-feature` ou `fix/issue-123`) 2. Effectuez vos modifications dans des commits ciblés et relisibles en utilisant les [commits conventionnels](https://www.conventionalcommits.org/) 3. Ajoutez ou mettez à jour les tests pour vos modifications 4. Exécutez `pnpm lint && pnpm typecheck && pnpm test` en local 5. Ouvrez une PR contre `main` et remplissez le modèle 6. Signez le CLA si on vous le demande 7. Attendez que la CI passe et qu'un mainteneur fasse sa relecture ### Attentes concernant la relecture {#review-expectations} * Nous visons à répondre aux PR sous 7 jours * Les PR petites et ciblées sont relues plus rapidement * Si vous n'avez pas de nouvelles sous 7 jours, laissez un commentaire pour relancer le fil * Nous pouvons demander des modifications, suggérer une approche différente ou fermer la PR si elle ne correspond pas à la direction du projet ### Une fois votre PR fusionnée {#after-your-pr-is-merged} Votre contribution sera incluse dans la prochaine release et créditée dans le changelog. ## Bons premiers tickets {#good-first-issues} Vous cherchez quelque chose sur quoi travailler ? Consultez nos [bons premiers tickets](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) pour des tâches adaptées aux débutants, ou [aide recherchée](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) pour des chantiers plus importants où l'aide de la communauté serait appréciée. ## Style de code {#code-style} * Biome gère le formatage et le linting (guillemets doubles, points-virgules, indentation de 2 espaces) * Le hook de pré-commit exécute automatiquement `biome check --write` sur les fichiers indexés * Si le linter se plaint, corrigez le code (ne modifiez pas la configuration de Biome) * Modules ES partout (`import`/`export`) * Commits conventionnels : `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` Pour tous les détails d'architecture, consultez le [Guide du développeur](/fr/guide/developer). ## Sécurité {#security} **N'ouvrez pas de PR ou de ticket public pour les vulnérabilités de sécurité.** Signalez-les de manière privée via les [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) ou par e-mail à contact@snapotter.com. Consultez [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) pour tous les détails. ## Des questions ? {#questions} * [Documentation](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/pt-BR/guide/contributing.md description: >- Como contribuir com o SnapOtter. Relatórios de bugs, solicitações de recursos, pull requests e requisitos do CLA. --- # Contribuindo {#contributing} Obrigado pelo seu interesse em contribuir. Este guia cobre como participar, o que aceitamos e como começar. ## Formas de contribuir {#ways-to-contribute} ### Issues (sem configuração necessária) {#issues-no-setup-required} * **Relatórios de bugs** - Algo quebrado? Abra um [relatório de bug](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) com passos de reprodução. * **Solicitações de recursos** - Tem uma ideia? Comece uma [discussão](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) para que a comunidade possa opinar e votar nela. * **Problemas de tradução** - Encontrou uma tradução errada ou faltando? Abra uma [issue de tradução](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Problemas de documentação** - Algo errado na documentação? Abra uma [issue de documentação](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Código (requer CLA) {#code-requires-cla} Aceitamos pull requests para: | Tipo | Processo | |------|---------| | Correções de bugs | Abra um PR diretamente (referencie a issue, se houver) | | Novas traduções | Abra um PR diretamente (veja o [Guia de Tradução](/pt-BR/guide/translations)) | | Melhorias na documentação | Abra um PR diretamente | | Melhorias na cobertura de testes | Abra um PR diretamente | | Novas ferramentas ou recursos | Comece uma [discussão](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) primeiro; um mantenedor converte ideias aprovadas em uma issue rastreada antes de você escrever código | | Refatorações ou mudanças de arquitetura | Comece uma [discussão](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) primeiro e aguarde a aprovação de um mantenedor antes de escrever código | ### O que não aceitamos {#what-we-will-not-accept} * Mudanças em workflows de CI/CD, configuração de release ou configuração do linter/compilador * PRs sem um [Contributor License Agreement](#contributor-license-agreement) assinado * PRs com mais de 400 linhas de alteração (divida trabalhos grandes em PRs menores) * Recursos que não foram discutidos e aprovados antes * Mudanças em `packages/ai/` sem discussão prévia ## Contributor License Agreement {#contributor-license-agreement} Antes de podermos fazer merge do seu primeiro PR, você precisa assinar nosso [CLA Individual](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md). Este é um requisito único. **Por quê:** O SnapOtter tem licença dupla (AGPLv3 + comercial). O CLA nos concede o direito de distribuir suas contribuições sob ambas as licenças. Você mantém a titularidade total dos direitos autorais do seu trabalho. **Como:** Quando você abrir seu primeiro PR, o bot CLA Assistant comentará com um link. Clique nele, revise o acordo e assine com sua conta do GitHub. Leva 30 segundos. Se você está contribuindo em nome do seu empregador e ele detém os direitos de propriedade intelectual sobre seu trabalho, entre em contato com contact@snapotter.com para providenciar um CLA Corporativo antes de enviar. ## Começando {#getting-started} ### Pré-requisitos {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (apenas para ferramentas de IA) * Docker (opcional, para testes de integração completos) ### Configuração {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Executando as verificações {#running-checks} Antes de enviar um PR, garanta que todas as verificações passem localmente: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Processo de pull request {#pull-request-process} 1. Faça um fork do repositório e crie um branch a partir de `main` (`feat/my-feature` ou `fix/issue-123`) 2. Faça suas mudanças em commits focados e revisáveis usando [conventional commits](https://www.conventionalcommits.org/) 3. Adicione ou atualize testes para suas mudanças 4. Execute `pnpm lint && pnpm typecheck && pnpm test` localmente 5. Abra um PR contra `main` e preencha o template 6. Assine o CLA se solicitado 7. Aguarde o CI passar e um mantenedor revisar ### Expectativas de revisão {#review-expectations} * Buscamos responder a PRs em até 7 dias * PRs pequenos e focados são revisados mais rápido * Se você não tiver retorno em 7 dias, deixe um comentário marcando a thread * Podemos solicitar mudanças, sugerir uma abordagem diferente ou fechar o PR se ele não estiver alinhado com a direção do projeto ### Depois que seu PR for mesclado {#after-your-pr-is-merged} Sua contribuição será incluída no próximo release e creditada no changelog. ## Boas primeiras issues {#good-first-issues} Procurando algo para trabalhar? Veja nossas [boas primeiras issues](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) para tarefas amigáveis a iniciantes, ou [help wanted](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) para itens maiores em que agradeceríamos a ajuda da comunidade. ## Estilo de código {#code-style} * O Biome cuida da formatação e do linting (aspas duplas, ponto e vírgula, indentação de 2 espaços) * O hook de pre-commit executa `biome check --write` nos arquivos em stage automaticamente * Se o linter reclamar, corrija o código (não modifique a configuração do Biome) * Módulos ES em todos os lugares (`import`/`export`) * Conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` Para detalhes completos de arquitetura, veja o [Guia do Desenvolvedor](/pt-BR/guide/developer). ## Segurança {#security} **Não abra um PR ou issue público para vulnerabilidades de segurança.** Reporte-as em privado através dos [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) ou por e-mail para contact@snapotter.com. Veja [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) para detalhes completos. ## Dúvidas? {#questions} * [Documentação](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/es/guide/contributing.md description: >- Cómo contribuir a SnapOtter. Informes de errores, solicitudes de funciones, pull requests y requisitos del CLA. --- # Contribuir {#contributing} Gracias por tu interés en contribuir. Esta guía cubre cómo participar, qué aceptamos y cómo empezar. ## Formas de contribuir {#ways-to-contribute} ### Issues (sin configuración) {#issues-no-setup-required} * **Informes de errores** - ¿Algo no funciona? Abre un [informe de error](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) con los pasos para reproducirlo. * **Solicitudes de funciones** - ¿Tienes una idea? Inicia una [discusión](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) para que la comunidad opine y la vote. * **Problemas de traducción** - ¿Detectas una traducción incorrecta o faltante? Abre un [issue de traducción](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Problemas de documentación** - ¿Algo raro en la documentación? Abre un [issue de documentación](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Código (requiere CLA) {#code-requires-cla} Aceptamos pull requests para: | Tipo | Proceso | |------|---------| | Correcciones de errores | Abre un PR directamente (enlaza el issue si existe) | | Nuevas traducciones | Abre un PR directamente (consulta la [Guía de traducción](/es/guide/translations)) | | Mejoras de documentación | Abre un PR directamente | | Mejoras en la cobertura de pruebas | Abre un PR directamente | | Nuevas herramientas o funciones | Inicia primero una [discusión](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas); un mantenedor convierte las ideas aprobadas en un issue con seguimiento antes de que escribas código | | Refactorizaciones o cambios de arquitectura | Inicia primero una [discusión](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) y espera la aprobación de un mantenedor antes de escribir código | ### Lo que no aceptaremos {#what-we-will-not-accept} * Cambios en los flujos de trabajo de CI/CD, la configuración de release o la configuración del linter/compilador * PRs sin un [Acuerdo de Licencia de Contribuidor](#contributor-license-agreement) firmado * PRs con más de 400 líneas de cambios (divide el trabajo grande en PRs más pequeños) * Funciones que no se hayan discutido y aprobado antes * Cambios en `packages/ai/` sin discusión previa ## Acuerdo de Licencia de Contribuidor {#contributor-license-agreement} Antes de poder fusionar tu primer PR, debes firmar nuestro [CLA Individual](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md). Es un requisito único. **Por qué:** SnapOtter tiene licencia dual (AGPLv3 + comercial). El CLA nos otorga el derecho a distribuir tus contribuciones bajo ambas licencias. Conservas la plena titularidad de los derechos de autor sobre tu trabajo. **Cómo:** Cuando abras tu primer PR, el bot CLA Assistant comentará con un enlace. Haz clic en él, revisa el acuerdo y fírmalo con tu cuenta de GitHub. Tarda 30 segundos. Si contribuyes en nombre de tu empleador y este conserva los derechos de propiedad intelectual sobre tu trabajo, contacta con contact@snapotter.com para gestionar un CLA Corporativo antes de enviar tu contribución. ## Cómo empezar {#getting-started} ### Requisitos previos {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (solo para herramientas de IA) * Docker (opcional, para pruebas de integración completas) ### Configuración {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Ejecutar comprobaciones {#running-checks} Antes de enviar un PR, asegúrate de que todas las comprobaciones pasen localmente: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Proceso de pull request {#pull-request-process} 1. Haz un fork del repositorio y crea una rama a partir de `main` (`feat/my-feature` o `fix/issue-123`) 2. Realiza tus cambios en commits enfocados y revisables usando [conventional commits](https://www.conventionalcommits.org/) 3. Añade o actualiza pruebas para tus cambios 4. Ejecuta `pnpm lint && pnpm typecheck && pnpm test` localmente 5. Abre un PR contra `main` y rellena la plantilla 6. Firma el CLA si se te solicita 7. Espera a que CI pase y a que un mantenedor lo revise ### Qué esperar de la revisión {#review-expectations} * Intentamos responder a los PRs en un plazo de 7 días * Los PRs pequeños y enfocados se revisan más rápido * Si no recibes respuesta en 7 días, deja un comentario mencionando el hilo * Podemos solicitar cambios, sugerir un enfoque diferente o cerrar el PR si no encaja con la dirección del proyecto ### Después de que se fusione tu PR {#after-your-pr-is-merged} Tu contribución se incluirá en la siguiente versión y se acreditará en el changelog. ## Buenos primeros issues {#good-first-issues} ¿Buscas en qué trabajar? Revisa nuestros [good first issues](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) para tareas aptas para principiantes, o [help wanted](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) para tareas más grandes en las que agradeceríamos la ayuda de la comunidad. ## Estilo de código {#code-style} * Biome se encarga del formato y el linting (comillas dobles, punto y coma, indentación de 2 espacios) * El hook de pre-commit ejecuta `biome check --write` automáticamente sobre los archivos en staging * Si el linter se queja, corrige el código (no modifiques la configuración de Biome) * Módulos ES en todas partes (`import`/`export`) * Conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` Para los detalles completos de la arquitectura, consulta la [Guía del desarrollador](/es/guide/developer). ## Seguridad {#security} **No abras un PR o issue público para vulnerabilidades de seguridad.** Repórtalas de forma privada a través de [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) o por correo a contact@snapotter.com. Consulta [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) para todos los detalles. ## ¿Preguntas? {#questions} * [Documentación](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/it/guide/contributing.md description: >- Come contribuire a SnapOtter. Segnalazioni di bug, richieste di funzionalità, pull request e requisiti CLA. --- # Contribuire {#contributing} Grazie per il tuo interesse a contribuire. Questa guida spiega come partecipare, cosa accettiamo e come iniziare. ## Modi per contribuire {#ways-to-contribute} ### Issue (nessuna configurazione richiesta) {#issues-no-setup-required} * **Segnalazioni di bug** - Qualcosa non funziona? Apri una [segnalazione di bug](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) con i passaggi per riprodurlo. * **Richieste di funzionalità** - Hai un'idea? Avvia una [discussione](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) così la community può valutarla e votarla. * **Problemi di traduzione** - Hai notato una traduzione errata o mancante? Apri una [issue di traduzione](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Problemi nella documentazione** - Qualcosa non torna nella documentazione? Apri una [issue di documentazione](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Codice (richiede CLA) {#code-requires-cla} Accettiamo pull request per: | Tipo | Processo | |------|---------| | Correzioni di bug | Apri direttamente una PR (collega la issue se ne esiste una) | | Nuove traduzioni | Apri direttamente una PR (vedi la [Guida alla traduzione](/it/guide/translations)) | | Miglioramenti alla documentazione | Apri direttamente una PR | | Miglioramenti alla copertura dei test | Apri direttamente una PR | | Nuovi strumenti o funzionalità | Avvia prima una [discussione](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas); un manutentore converte le idee approvate in una issue tracciata prima che tu scriva il codice | | Refactor o modifiche all'architettura | Avvia prima una [discussione](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) e attendi l'approvazione di un manutentore prima di scrivere il codice | ### Cosa non accetteremo {#what-we-will-not-accept} * Modifiche ai workflow CI/CD, alla configurazione di rilascio o alla configurazione di linter/compilatore * PR senza un [Contributor License Agreement](#contributor-license-agreement) firmato * PR con oltre 400 righe di modifiche (suddividi il lavoro grande in PR più piccole) * Funzionalità che non sono state prima discusse e approvate * Modifiche a `packages/ai/` senza discussione preventiva ## Contributor License Agreement {#contributor-license-agreement} Prima di poter unire la tua prima PR, devi firmare il nostro [CLA individuale](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md). È un requisito una tantum. **Perché:** SnapOtter è a doppia licenza (AGPLv3 + commerciale). Il CLA ci concede il diritto di distribuire i tuoi contributi con entrambe le licenze. Mantieni la piena titolarità del copyright sul tuo lavoro. **Come:** Quando apri la tua prima PR, il bot CLA Assistant commenterà con un link. Fai clic, esamina l'accordo e firma con il tuo account GitHub. Bastano 30 secondi. Se stai contribuendo per conto del tuo datore di lavoro e questi mantiene i diritti di proprietà intellettuale sul tuo lavoro, contatta contact@snapotter.com per stipulare un CLA aziendale prima di inviare. ## Come iniziare {#getting-started} ### Prerequisiti {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (solo per gli strumenti AI) * Docker (facoltativo, per il test di integrazione completo) ### Configurazione {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Esecuzione dei controlli {#running-checks} Prima di inviare una PR, assicurati che tutti i controlli passino localmente: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Processo di pull request {#pull-request-process} 1. Effettua il fork del repo e crea un branch da `main` (`feat/my-feature` o `fix/issue-123`) 2. Apporta le tue modifiche in commit mirati e revisionabili usando i [conventional commit](https://www.conventionalcommits.org/) 3. Aggiungi o aggiorna i test per le tue modifiche 4. Esegui `pnpm lint && pnpm typecheck && pnpm test` localmente 5. Apri una PR verso `main` e compila il template 6. Firma il CLA se richiesto 7. Attendi che la CI passi e che un manutentore effettui la revisione ### Cosa aspettarsi dalla revisione {#review-expectations} * Puntiamo a rispondere alle PR entro 7 giorni * Le PR piccole e mirate vengono revisionate più velocemente * Se non ricevi risposta entro 7 giorni, lascia un commento per richiamare l'attenzione sul thread * Potremmo richiedere modifiche, suggerire un approccio diverso o chiudere la PR se non è in linea con la direzione del progetto ### Dopo che la tua PR è stata unita {#after-your-pr-is-merged} Il tuo contributo sarà incluso nella prossima release e accreditato nel changelog. ## Prime issue adatte ai principianti {#good-first-issues} Cerchi qualcosa su cui lavorare? Consulta le nostre [good first issue](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) per attività adatte ai principianti, oppure le [help wanted](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) per attività più grandi in cui apprezzeremmo l'aiuto della community. ## Stile del codice {#code-style} * Biome gestisce formattazione e linting (virgolette doppie, punto e virgola, indentazione di 2 spazi) * L'hook pre-commit esegue automaticamente `biome check --write` sui file in stage * Se il linter si lamenta, correggi il codice (non modificare la configurazione di Biome) * Moduli ES ovunque (`import`/`export`) * Conventional commit: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` Per i dettagli completi sull'architettura, consulta la [Guida per sviluppatori](/it/guide/developer). ## Sicurezza {#security} **Non aprire una PR o una issue pubblica per le vulnerabilità di sicurezza.** Segnalale privatamente tramite i [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) o via email a contact@snapotter.com. Vedi [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) per tutti i dettagli. ## Domande? {#questions} * [Documentazione](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/de/tools/conversion-presets.md description: >- Dedizierte Konvertierungs-Preset-Endpunkte, generiert aus dem SnapOtter-Tool-Katalog. --- # Conversion Presets {#conversion-presets} SnapOtter stellt zusätzlich zu den Basis-Konverter-Tools 83 dedizierte Konvertierungs-Preset-Endpunkte bereit. Jedes Preset legt das Ausgabeformat fest und delegiert an seine Basis-Verarbeitungspipeline, sodass Verhalten, Validierung und Ausgabekontrakt dem unten aufgeführten Basis-Tool entsprechen. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Sende `multipart/form-data` mit einem `file`-Teil und einem optionalen JSON-String `settings`. Presets folgen dem Antwortkontrakt des Basis-Tools. Schnelle Presets geben in der Regel `200` mit einer `downloadUrl` zurück, können aber `202` zurückgeben, wenn sie das synchrone Wartefenster überschreiten. Video-Presets und lange Datei-/Dokument-Presets geben `202` zurück und streamen den Fortschritt von `/api/v1/jobs//progress`. PDF-zu-Bild-Presets geben Download-URLs für die Seiten plus eine ZIP-URL zurück. ## Image Presets {#image-presets} | Preset-ID | Konvertiert | Route | Basis-Tool | Akzeptierte Eingaben | Optionale Einstellungen | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG zu PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG zu JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG zu WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG zu WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP zu JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP zu PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG zu AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG zu AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP zu AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC zu JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC zu PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC zu AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG zu GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG zu GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF zu JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF zu PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP zu GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG zu TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG zu TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF zu JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF zu PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD zu JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD zu PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG zu EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG zu EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS zu PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS zu JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG zu SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | keine | | `jpg-to-svg` | JPG zu SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | keine | | `tiff-to-svg` | TIFF zu SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | keine | | `psd-to-svg` | PSD zu SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | keine | | `eps-to-svg` | EPS zu SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | keine | | `svg-to-png` | SVG zu PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG zu JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG zu PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG zu PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC zu PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF zu PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP zu PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF zu PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS zu PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset-ID | Konvertiert | Route | Basis-Tool | Akzeptierte Eingaben | Optionale Einstellungen | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV zu MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM zu MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV zu MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI zu MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 zu MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 zu WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM zu MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV zu MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI zu MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 zu AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV zu AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV zu AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI zu MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 zu GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV zu GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV zu GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI zu GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF zu MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | keine | | `gif-to-webm` | GIF zu WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | keine | | `gif-to-mov` | GIF zu MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | keine | | `mp4-to-mp3` | MP4 zu MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | keine | | `mov-to-mp3` | MOV zu MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | keine | | `mkv-to-mp3` | MKV zu MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | keine | | `webm-to-mp3` | WEBM zu MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | keine | | `avi-to-mp3` | AVI zu MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | keine | | `mp4-to-wav` | MP4 zu WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | keine | | `mov-to-wav` | MOV zu WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | keine | | `mp4-to-ogg` | MP4 zu OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | keine | ## Audio Presets {#audio-presets} | Preset-ID | Konvertiert | Route | Basis-Tool | Akzeptierte Eingaben | Optionale Einstellungen | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A zu MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | keine | | `m4a-to-wav` | M4A zu WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | keine | | `aac-to-mp3` | AAC zu MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | keine | | `aac-to-wav` | AAC zu WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | keine | | `aac-to-flac` | AAC zu FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | keine | | `ogg-to-mp3` | OGG zu MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | keine | | `ogg-to-wav` | OGG zu WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | keine | | `wav-to-mp3` | WAV zu MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | keine | | `mp3-to-wav` | MP3 zu WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | keine | | `flac-to-mp3` | FLAC zu MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | keine | ## PDF Presets {#pdf-presets} | Preset-ID | Konvertiert | Route | Basis-Tool | Akzeptierte Eingaben | Optionale Einstellungen | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF zu JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF zu PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF zu TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset-ID | Konvertiert | Route | Basis-Tool | Akzeptierte Eingaben | Optionale Einstellungen | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel zu CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | keine | ## Notes {#notes} * Presets sind vollwertige API-Endpunkte und auch in Batch-Anfragen gültig, sofern ihre Basis-Route die Batch-Verarbeitung unterstützt. * Presets, die Videokonvertierung nutzen, können `202 Accepted` zurückgeben; verbinde dich mit dem SSE-Endpunkt für den Job-Fortschritt, bevor du das Ergebnis herunterlädst. * Für erweiterte Optionen, die ein Preset nicht bereitstellt, rufe das Basis-Konverter-Tool direkt auf und lege das Ausgabeformat in `settings` fest. --- --- url: https://docs.snapotter.com/hi/tools/conversion-presets.md description: SnapOtter टूल कैटलॉग से उत्पन्न समर्पित कन्वर्ज़न प्रीसेट एंडपॉइंट। --- # Conversion Presets {#conversion-presets} SnapOtter बेस कन्वर्टर टूल के अलावा 83 समर्पित कन्वर्ज़न प्रीसेट एंडपॉइंट प्रदान करता है। प्रत्येक प्रीसेट आउटपुट फ़ॉर्मेट को लॉक करता है और अपनी बेस प्रोसेसिंग पाइपलाइन को सौंप देता है, इसलिए व्यवहार, सत्यापन, और आउटपुट कॉन्ट्रैक्ट नीचे सूचीबद्ध बेस टूल से मेल खाता है। ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` एक `file` भाग और वैकल्पिक `settings` JSON स्ट्रिंग के साथ `multipart/form-data` भेजें। प्रीसेट बेस टूल के रिस्पॉन्स कॉन्ट्रैक्ट का पालन करते हैं। फ़ास्ट प्रीसेट आमतौर पर एक `downloadUrl` के साथ `200` लौटाते हैं, लेकिन यदि वे सिंक्रोनस प्रतीक्षा विंडो से अधिक हो जाते हैं तो `202` लौटा सकते हैं। वीडियो प्रीसेट और लंबे file/document प्रीसेट `202` और `/api/v1/jobs//progress` से प्रगति स्ट्रीम लौटाते हैं। PDF-to-image प्रीसेट पेज डाउनलोड URL के साथ एक ZIP URL लौटाते हैं। ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG to PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG to JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG to WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG to WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP to JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP to PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG to AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG to AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP to AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC to JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC to PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC to AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG to GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG to GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF to JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF to PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP to GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG to TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG to TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF to JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF to PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD to JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD to PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG to EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG to EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS to PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS to JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG to SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG to SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF to SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD to SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS to SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG to PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG to JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG to PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG to PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC to PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF to PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP to PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF to PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS to PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV to MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM to MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV to MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI to MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 to MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 to WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM to MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV to MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI to MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 to AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV to AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV to AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI to MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 to GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV to GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV to GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI to GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF to MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF to WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF to MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 to MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV to MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV to MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM to MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI to MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 to WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV to WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 to OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A to MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A to WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC to MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC to WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC to FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG to MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG to WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV to MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 to WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC to MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF to JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF to PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF to TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel to CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * प्रीसेट फ़र्स्ट-क्लास API एंडपॉइंट हैं और batch अनुरोधों में भी मान्य हैं जहां उनका बेस रूट batch प्रोसेसिंग का समर्थन करता है। * वीडियो कन्वर्ज़न का उपयोग करने वाले प्रीसेट `202 Accepted` लौटा सकते हैं; परिणाम डाउनलोड करने से पहले job प्रगति SSE एंडपॉइंट से कनेक्ट करें। * किसी प्रीसेट द्वारा उजागर न किए गए उन्नत विकल्पों के लिए, बेस कन्वर्टर टूल को सीधे कॉल करें और `settings` में आउटपुट फ़ॉर्मेट सेट करें। --- --- url: https://docs.snapotter.com/id/tools/conversion-presets.md description: Endpoint preset konversi khusus yang dihasilkan dari katalog tool SnapOtter. --- # Conversion Presets {#conversion-presets} SnapOtter menyediakan 83 endpoint preset konversi khusus selain tool konverter dasar. Setiap preset mengunci format output dan mendelegasikan ke pipeline pemrosesan dasarnya, sehingga perilaku, validasi, dan kontrak output-nya sesuai dengan tool dasar yang tercantum di bawah. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Kirim `multipart/form-data` dengan bagian `file` dan string JSON `settings` opsional. Preset mengikuti kontrak respons dari tool dasar. Preset cepat biasanya mengembalikan `200` dengan `downloadUrl`, tetapi dapat mengembalikan `202` jika melampaui jendela tunggu sinkron. Preset video dan preset file/dokumen yang berjalan lama mengembalikan `202` dan aliran progres dari `/api/v1/jobs//progress`. Preset PDF-ke-gambar mengembalikan URL unduhan halaman ditambah URL ZIP. ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG to PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG to JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG to WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG to WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP to JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP to PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG to AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG to AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP to AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC to JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC to PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC to AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG to GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG to GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF to JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF to PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP to GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG to TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG to TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF to JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF to PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD to JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD to PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG to EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG to EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS to PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS to JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG to SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG to SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF to SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD to SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS to SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG to PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG to JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG to PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG to PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC to PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF to PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP to PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF to PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS to PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV to MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM to MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV to MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI to MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 to MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 to WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM to MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV to MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI to MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 to AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV to AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV to AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI to MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 to GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV to GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV to GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI to GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF to MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF to WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF to MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 to MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV to MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV to MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM to MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI to MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 to WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV to WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 to OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A to MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A to WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC to MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC to WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC to FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG to MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG to WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV to MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 to WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC to MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF to JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF to PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF to TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel to CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * Preset adalah endpoint API kelas satu dan juga valid dalam permintaan batch di mana route dasarnya mendukung pemrosesan batch. * Preset yang menggunakan konversi video dapat mengembalikan `202 Accepted`; sambungkan ke endpoint SSE progres pekerjaan sebelum mengunduh hasilnya. * Untuk opsi lanjutan yang tidak diekspos oleh sebuah preset, panggil tool konverter dasar secara langsung dan atur format output di `settings`. --- --- url: https://docs.snapotter.com/it/tools/conversion-presets.md description: >- Endpoint di preset di conversione dedicati generati dal catalogo di strumenti di SnapOtter. --- # Conversion Presets {#conversion-presets} SnapOtter espone 83 endpoint di preset di conversione dedicati oltre agli strumenti di conversione di base. Ogni preset blocca il formato di output e delega alla propria pipeline di elaborazione di base, quindi il comportamento, la validazione e il contratto di output corrispondono allo strumento di base elencato di seguito. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Invia `multipart/form-data` con una parte `file` e una stringa JSON `settings` opzionale. I preset seguono il contratto di risposta dello strumento di base. I preset veloci di solito restituiscono `200` con un `downloadUrl`, ma possono restituire `202` se superano la finestra di attesa sincrona. I preset video e i preset lunghi per file/documenti restituiscono `202` e stream di avanzamento da `/api/v1/jobs//progress`. I preset PDF-to-image restituiscono gli URL di download delle pagine più un URL ZIP. ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG to PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG to JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG to WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG to WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP to JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP to PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG to AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG to AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP to AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC to JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC to PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC to AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG to GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG to GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF to JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF to PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP to GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG to TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG to TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF to JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF to PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD to JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD to PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG to EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG to EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS to PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS to JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG to SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG to SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF to SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD to SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS to SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG to PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG to JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG to PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG to PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC to PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF to PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP to PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF to PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS to PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV to MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM to MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV to MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI to MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 to MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 to WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM to MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV to MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI to MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 to AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV to AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV to AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI to MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 to GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV to GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV to GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI to GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF to MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF to WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF to MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 to MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV to MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV to MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM to MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI to MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 to WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV to WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 to OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A to MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A to WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC to MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC to WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC to FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG to MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG to WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV to MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 to WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC to MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF to JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF to PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF to TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel to CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * I preset sono endpoint API di prima classe e sono validi anche nelle richieste batch dove la loro route di base supporta l'elaborazione batch. * I preset che usano la conversione video possono restituire `202 Accepted`; connettiti all'endpoint SSE di avanzamento del job prima di scaricare il risultato. * Per le opzioni avanzate non esposte da un preset, chiama direttamente lo strumento di conversione di base e imposta il formato di output in `settings`. --- --- url: https://docs.snapotter.com/ja/tools/conversion-presets.md description: SnapOtter のツールカタログから生成された専用の変換プリセットエンドポイント。 --- # Conversion Presets {#conversion-presets} SnapOtter は、ベースとなるコンバーターツールに加えて、83 個の専用変換プリセットエンドポイントを公開しています。各プリセットは出力形式を固定し、ベースの処理パイプラインに委譲するため、動作、検証、出力の仕様は下記に挙げるベースツールと一致します。 ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` `file` パートと、任意の `settings` JSON 文字列を含む `multipart/form-data` を送信します。プリセットはベースツールのレスポンス仕様に従います。高速なプリセットは通常 `downloadUrl` とともに `200` を返しますが、同期待機ウィンドウを超えると `202` を返すことがあります。動画プリセットおよび実行時間の長いファイル/ドキュメントのプリセットは `202` を返し、`/api/v1/jobs//progress` から進捗をストリーミングします。PDF から画像へのプリセットは、ページのダウンロード URL と ZIP の URL を返します。 ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG から PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-jpg` | PNG から JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG から WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-webp` | PNG から WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP から JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP から PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG から AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-avif` | PNG から AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP から AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC から JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`、`.heif` | quality | | `heic-to-png` | HEIC から PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`、`.heif` | quality | | `heic-to-avif` | HEIC から AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`、`.heif` | quality | | `jpg-to-gif` | JPG から GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-gif` | PNG から GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF から JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF から PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP から GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG から TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-tiff` | PNG から TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF から JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`、`.tif` | quality | | `tiff-to-png` | TIFF から PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`、`.tif` | quality | | `psd-to-jpg` | PSD から JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD から PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG から EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG から EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`、`.jpeg` | quality | | `eps-to-png` | EPS から PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS から JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG から SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG から SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`、`.jpeg` | none | | `tiff-to-svg` | TIFF から SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`、`.tif` | none | | `psd-to-svg` | PSD から SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS から SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG から PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`、`.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG から JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`、`.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG から PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`、`.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG から PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC から PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`、`.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF から PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`、`.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP から PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF から PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS から PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV から MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM から MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV から MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI から MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 から MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 から WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM から MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV から MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI から MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 から AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV から AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV から AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI から MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 から GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV から GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV から GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI から GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF から MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF から WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF から MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 から MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV から MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV から MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM から MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI から MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 から WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV から WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 から OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A から MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A から WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC から MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC から WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC から FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG から MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG から WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV から MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 から WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC から MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF から JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF から PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF から TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel から CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`、`.xls` | none | ## Notes {#notes} * プリセットはファーストクラスの API エンドポイントであり、ベースルートがバッチ処理をサポートしている場合はバッチリクエストでも有効です。 * 動画変換を使用するプリセットは `202 Accepted` を返すことがあります。結果をダウンロードする前に、ジョブ進捗の SSE エンドポイントに接続してください。 * プリセットで公開されていない詳細オプションを利用するには、ベースのコンバーターツールを直接呼び出し、`settings` で出力形式を設定してください。 --- --- url: https://docs.snapotter.com/nl/tools/conversion-presets.md description: Speciale conversiepreset-endpoints gegenereerd uit de SnapOtter-toolcatalogus. --- # Conversion Presets {#conversion-presets} SnapOtter biedt naast de basisconvertertools 83 speciale conversiepreset-endpoints. Elke preset vergrendelt het uitvoerformaat en delegeert naar de bijbehorende basisverwerkingspijplijn, zodat het gedrag, de validatie en het uitvoercontract overeenkomen met de hieronder vermelde basistool. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Stuur `multipart/form-data` met een `file`-deel en een optionele `settings` JSON-string. Presets volgen het antwoordcontract van de basistool. Snelle presets retourneren meestal `200` met een `downloadUrl`, maar kunnen `202` retourneren als ze het synchrone wachtvenster overschrijden. Videopresets en langlopende bestands-/documentpresets retourneren `202` en voortgangsstreams van `/api/v1/jobs//progress`. PDF-naar-afbeeldingpresets retourneren download-URL's per pagina plus een ZIP-URL. ## Image Presets {#image-presets} | Preset-ID | Converteert | Route | Basistool | Geaccepteerde invoer | Optionele instellingen | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG naar PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG naar JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG naar WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG naar WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP naar JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP naar PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG naar AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG naar AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP naar AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC naar JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC naar PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC naar AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG naar GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG naar GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF naar JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF naar PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP naar GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG naar TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG naar TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF naar JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF naar PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD naar JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD naar PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG naar EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG naar EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS naar PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS naar JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG naar SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | geen | | `jpg-to-svg` | JPG naar SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | geen | | `tiff-to-svg` | TIFF naar SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | geen | | `psd-to-svg` | PSD naar SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | geen | | `eps-to-svg` | EPS naar SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | geen | | `svg-to-png` | SVG naar PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG naar JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG naar PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG naar PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC naar PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF naar PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP naar PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF naar PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS naar PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset-ID | Converteert | Route | Basistool | Geaccepteerde invoer | Optionele instellingen | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV naar MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM naar MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV naar MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI naar MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 naar MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 naar WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM naar MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV naar MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI naar MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 naar AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV naar AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV naar AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI naar MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 naar GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV naar GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV naar GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI naar GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF naar MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | geen | | `gif-to-webm` | GIF naar WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | geen | | `gif-to-mov` | GIF naar MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | geen | | `mp4-to-mp3` | MP4 naar MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | geen | | `mov-to-mp3` | MOV naar MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | geen | | `mkv-to-mp3` | MKV naar MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | geen | | `webm-to-mp3` | WEBM naar MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | geen | | `avi-to-mp3` | AVI naar MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | geen | | `mp4-to-wav` | MP4 naar WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | geen | | `mov-to-wav` | MOV naar WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | geen | | `mp4-to-ogg` | MP4 naar OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | geen | ## Audio Presets {#audio-presets} | Preset-ID | Converteert | Route | Basistool | Geaccepteerde invoer | Optionele instellingen | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A naar MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | geen | | `m4a-to-wav` | M4A naar WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | geen | | `aac-to-mp3` | AAC naar MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | geen | | `aac-to-wav` | AAC naar WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | geen | | `aac-to-flac` | AAC naar FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | geen | | `ogg-to-mp3` | OGG naar MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | geen | | `ogg-to-wav` | OGG naar WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | geen | | `wav-to-mp3` | WAV naar MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | geen | | `mp3-to-wav` | MP3 naar WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | geen | | `flac-to-mp3` | FLAC naar MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | geen | ## PDF Presets {#pdf-presets} | Preset-ID | Converteert | Route | Basistool | Geaccepteerde invoer | Optionele instellingen | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF naar JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF naar PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF naar TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset-ID | Converteert | Route | Basistool | Geaccepteerde invoer | Optionele instellingen | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel naar CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | geen | ## Notes {#notes} * Presets zijn eersteklas API-endpoints en zijn ook geldig in batchverzoeken waar hun basisroute batchverwerking ondersteunt. * Presets die videoconversie gebruiken, kunnen `202 Accepted` retourneren; maak verbinding met het SSE-endpoint voor taakvoortgang voordat je het resultaat downloadt. * Voor geavanceerde opties die niet door een preset worden aangeboden, roep je de basisconvertertool rechtstreeks aan en stel je het uitvoerformaat in via `settings`. --- --- url: https://docs.snapotter.com/pl/tools/conversion-presets.md description: >- Dedykowane endpointy predefiniowanych konwersji generowane z katalogu narzędzi SnapOtter. --- # Conversion Presets {#conversion-presets} SnapOtter udostępnia 83 dedykowane endpointy predefiniowanych konwersji oprócz podstawowych narzędzi konwertujących. Każdy preset blokuje format wyjściowy i deleguje do swojego podstawowego potoku przetwarzania, więc jego zachowanie, walidacja i kontrakt wyjściowy odpowiadają narzędziu podstawowemu wymienionemu poniżej. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Wyślij `multipart/form-data` z częścią `file` oraz opcjonalnym ciągiem JSON `settings`. Presety stosują kontrakt odpowiedzi narzędzia podstawowego. Szybkie presety zwykle zwracają `200` z `downloadUrl`, ale mogą zwrócić `202`, jeśli przekroczą synchroniczne okno oczekiwania. Presety wideo oraz długie presety plików/dokumentów zwracają `202` i strumienie postępu z `/api/v1/jobs//progress`. Presety PDF-do-obrazu zwracają adresy URL do pobrania stron oraz adres URL ZIP. ## Image Presets {#image-presets} | ID presetu | Konwertuje | Trasa | Narzędzie podstawowe | Akceptowane wejścia | Ustawienia opcjonalne | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG na PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG na JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG na WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG na WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP na JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP na PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG na AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG na AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP na AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC na JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC na PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC na AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG na GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG na GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF na JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF na PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP na GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG na TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG na TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF na JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF na PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD na JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD na PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG na EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG na EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS na PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS na JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG na SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | brak | | `jpg-to-svg` | JPG na SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | brak | | `tiff-to-svg` | TIFF na SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | brak | | `psd-to-svg` | PSD na SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | brak | | `eps-to-svg` | EPS na SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | brak | | `svg-to-png` | SVG na PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG na JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG na PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG na PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC na PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF na PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP na PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF na PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS na PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | ID presetu | Konwertuje | Trasa | Narzędzie podstawowe | Akceptowane wejścia | Ustawienia opcjonalne | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV na MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM na MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV na MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI na MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 na MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 na WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM na MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV na MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI na MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 na AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV na AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV na AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI na MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 na GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV na GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV na GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI na GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF na MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | brak | | `gif-to-webm` | GIF na WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | brak | | `gif-to-mov` | GIF na MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | brak | | `mp4-to-mp3` | MP4 na MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | brak | | `mov-to-mp3` | MOV na MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | brak | | `mkv-to-mp3` | MKV na MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | brak | | `webm-to-mp3` | WEBM na MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | brak | | `avi-to-mp3` | AVI na MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | brak | | `mp4-to-wav` | MP4 na WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | brak | | `mov-to-wav` | MOV na WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | brak | | `mp4-to-ogg` | MP4 na OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | brak | ## Audio Presets {#audio-presets} | ID presetu | Konwertuje | Trasa | Narzędzie podstawowe | Akceptowane wejścia | Ustawienia opcjonalne | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A na MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | brak | | `m4a-to-wav` | M4A na WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | brak | | `aac-to-mp3` | AAC na MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | brak | | `aac-to-wav` | AAC na WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | brak | | `aac-to-flac` | AAC na FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | brak | | `ogg-to-mp3` | OGG na MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | brak | | `ogg-to-wav` | OGG na WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | brak | | `wav-to-mp3` | WAV na MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | brak | | `mp3-to-wav` | MP3 na WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | brak | | `flac-to-mp3` | FLAC na MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | brak | ## PDF Presets {#pdf-presets} | ID presetu | Konwertuje | Trasa | Narzędzie podstawowe | Akceptowane wejścia | Ustawienia opcjonalne | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF na JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF na PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF na TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | ID presetu | Konwertuje | Trasa | Narzędzie podstawowe | Akceptowane wejścia | Ustawienia opcjonalne | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel na CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | brak | ## Notes {#notes} * Presety są pełnoprawnymi endpointami API i są też ważne w żądaniach wsadowych, o ile ich trasa podstawowa obsługuje przetwarzanie wsadowe. * Presety korzystające z konwersji wideo mogą zwrócić `202 Accepted`; połącz się z endpointem SSE postępu zadania przed pobraniem wyniku. * W przypadku opcji zaawansowanych nieudostępnianych przez preset wywołaj bezpośrednio podstawowe narzędzie konwertujące i ustaw format wyjściowy w `settings`. --- --- url: https://docs.snapotter.com/sv/tools/conversion-presets.md description: >- Dedikerade konverteringsförinställningsslutpunkter genererade från SnapOtters verktygskatalog. --- # Conversion Presets {#conversion-presets} SnapOtter exponerar 83 dedikerade konverteringsförinställningsslutpunkter utöver bas-konverteringsverktygen. Varje förinställning låser utdataformatet och delegerar till sin bas-bearbetningspipeline, så att beteendet, valideringen och utdatakontraktet matchar bas-verktyget som listas nedan. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Skicka `multipart/form-data` med en `file`-del och en valfri JSON-sträng `settings`. Förinställningar följer bas-verktygets svarskontrakt. Snabba förinställningar returnerar vanligtvis `200` med en `downloadUrl`, men kan returnera `202` om de överskrider det synkrona väntefönstret. Videoförinställningar och långa fil-/dokumentförinställningar returnerar `202` och förloppsströmmar från `/api/v1/jobs//progress`. PDF-till-bild-förinställningar returnerar nedladdnings-URL:er för sidorna plus en ZIP-URL. ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG till PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG till JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG till WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG till WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP till JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP till PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG till AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG till AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP till AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC till JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC till PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC till AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG till GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG till GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF till JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF till PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP till GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG till TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG till TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF till JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF till PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD till JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD till PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG till EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG till EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS till PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS till JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG till SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG till SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF till SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD till SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS till SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG till PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG till JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG till PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG till PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC till PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF till PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP till PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF till PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS till PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV till MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM till MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV till MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI till MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 till MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 till WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM till MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV till MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI till MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 till AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV till AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV till AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI till MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 till GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV till GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV till GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI till GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF till MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF till WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF till MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 till MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV till MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV till MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM till MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI till MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 till WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV till WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 till OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A till MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A till WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC till MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC till WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC till FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG till MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG till WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV till MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 till WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC till MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF till JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF till PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF till TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel till CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * Förinställningar är förstklassiga API-slutpunkter och är även giltiga i batch-förfrågningar där deras bas-route stöder batch-bearbetning. * Förinställningar som använder videokonvertering kan returnera `202 Accepted`; anslut till jobbets förlopps-SSE-slutpunkt innan du laddar ner resultatet. * För avancerade alternativ som inte exponeras av en förinställning, anropa bas-konverteringsverktyget direkt och ange utdataformatet i `settings`. --- --- url: https://docs.snapotter.com/th/tools/conversion-presets.md description: เอนด์พอยต์พรีเซ็ตการแปลงเฉพาะทางที่สร้างจากแคตตาล็อกเครื่องมือ SnapOtter --- # Conversion Presets {#conversion-presets} SnapOtter เปิดเผยเอนด์พอยต์พรีเซ็ตการแปลงเฉพาะทาง 83 รายการ นอกเหนือจากเครื่องมือแปลงพื้นฐาน แต่ละพรีเซ็ตจะล็อกรูปแบบผลลัพธ์และมอบหมายให้กับไปป์ไลน์การประมวลผลพื้นฐาน ดังนั้นพฤติกรรม การตรวจสอบความถูกต้อง และสัญญาผลลัพธ์จึงตรงกับเครื่องมือพื้นฐานที่แสดงไว้ด้านล่าง ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` ส่ง `multipart/form-data` พร้อมส่วน `file` และสตริง JSON `settings` ที่ไม่บังคับ พรีเซ็ตจะเป็นไปตามสัญญาการตอบสนองของเครื่องมือพื้นฐาน พรีเซ็ตแบบเร็วมักจะส่งคืน `200` พร้อม `downloadUrl` แต่สามารถส่งคืน `202` ได้หากเกินหน้าต่างการรอแบบซิงโครนัส พรีเซ็ตวิดีโอและพรีเซ็ตไฟล์/เอกสารที่ใช้เวลานานจะส่งคืน `202` และสตรีมความคืบหน้าจาก `/api/v1/jobs//progress` พรีเซ็ต PDF-to-image จะส่งคืน URL ดาวน์โหลดของหน้าพร้อม URL ของ ZIP ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG to PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG to JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG to WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG to WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP to JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP to PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG to AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG to AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP to AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC to JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC to PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC to AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG to GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG to GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF to JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF to PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP to GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG to TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG to TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF to JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF to PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD to JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD to PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG to EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG to EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS to PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS to JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG to SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG to SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF to SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD to SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS to SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG to PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG to JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG to PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG to PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC to PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF to PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP to PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF to PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS to PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV to MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM to MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV to MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI to MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 to MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 to WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM to MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV to MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI to MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 to AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV to AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV to AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI to MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 to GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV to GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV to GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI to GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF to MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF to WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF to MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 to MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV to MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV to MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM to MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI to MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 to WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV to WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 to OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A to MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A to WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC to MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC to WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC to FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG to MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG to WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV to MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 to WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC to MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF to JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF to PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF to TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel to CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * พรีเซ็ตเป็นเอนด์พอยต์ API ระดับเฟิร์สคลาส และยังใช้ได้ในคำขอแบบ batch ที่รูตพื้นฐานของมันรองรับการประมวลผลแบบ batch * พรีเซ็ตที่ใช้การแปลงวิดีโอสามารถส่งคืน `202 Accepted` ได้ ให้เชื่อมต่อกับเอนด์พอยต์ SSE ความคืบหน้าของงานก่อนดาวน์โหลดผลลัพธ์ * สำหรับตัวเลือกขั้นสูงที่พรีเซ็ตไม่ได้เปิดเผย ให้เรียกเครื่องมือแปลงพื้นฐานโดยตรงและตั้งรูปแบบผลลัพธ์ใน `settings` --- --- url: https://docs.snapotter.com/tr/tools/conversion-presets.md description: SnapOtter araç kataloğundan oluşturulan özel dönüştürme ön ayarı uç noktaları. --- # Conversion Presets {#conversion-presets} SnapOtter, temel dönüştürücü araçlarına ek olarak 83 özel dönüştürme ön ayarı uç noktası sunar. Her ön ayar çıktı formatını sabitler ve temel işleme hattına devreder, böylece davranış, doğrulama ve çıktı sözleşmesi aşağıda listelenen temel araçla eşleşir. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Bir `file` parçası ve isteğe bağlı `settings` JSON dizesi ile `multipart/form-data` gönderin. Ön ayarlar, temel aracın yanıt sözleşmesini takip eder. Hızlı ön ayarlar genellikle bir `downloadUrl` ile `200` döndürür, ancak senkron bekleme penceresini aşarlarsa `202` döndürebilirler. Video ön ayarları ve uzun dosya/belge ön ayarları `202` döndürür ve ilerleme akışlarını `/api/v1/jobs//progress` üzerinden yayınlar. PDF'ten görüntüye ön ayarları sayfa indirme URL'leri artı bir ZIP URL'si döndürür. ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG'den PNG'ye | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG'den JPG'ye | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG'den WebP'ye | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG'den WebP'ye | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP'den JPG'ye | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP'den PNG'ye | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG'den AVIF'e | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG'den AVIF'e | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP'den AVIF'e | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC'ten JPG'ye | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC'ten PNG'ye | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC'ten AVIF'e | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG'den GIF'e | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG'den GIF'e | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF'ten JPG'ye | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF'ten PNG'ye | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP'den GIF'e | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG'den TIFF'e | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG'den TIFF'e | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF'ten JPG'ye | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF'ten PNG'ye | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD'den JPG'ye | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD'den PNG'ye | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG'den EPS'e | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG'den EPS'e | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS'ten PNG'ye | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS'ten JPG'ye | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG'den SVG'ye | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG'den SVG'ye | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF'ten SVG'ye | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD'den SVG'ye | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS'ten SVG'ye | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG'den PNG'ye | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG'den JPG'ye | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG'den PDF'e | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG'den PDF'e | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC'ten PDF'e | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF'ten PDF'e | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP'den PDF'e | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF'ten PDF'e | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS'ten PDF'e | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV'dan MP4'e | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM'den MP4'e | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV'den MP4'e | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI'den MP4'e | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4'ten MOV'a | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4'ten WEBM'e | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM'den MOV'a | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV'den MOV'a | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI'den MOV'a | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4'ten AVI'ye | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV'dan AVI'ye | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV'den AVI'ye | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI'den MKV'ye | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4'ten GIF'e | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV'dan GIF'e | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV'den GIF'e | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI'den GIF'e | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF'ten MP4'e | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF'ten WEBM'e | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF'ten MOV'a | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4'ten MP3'e | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV'dan MP3'e | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV'den MP3'e | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM'den MP3'e | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI'den MP3'e | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4'ten WAV'a | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV'dan WAV'a | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4'ten OGG'ye | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A'dan MP3'e | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A'dan WAV'a | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC'den MP3'e | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC'den WAV'a | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC'den FLAC'e | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG'den MP3'e | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG'den WAV'a | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV'dan MP3'e | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3'ten WAV'a | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC'ten MP3'e | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF'ten JPG'ye | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF'ten PNG'ye | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF'ten TIFF'e | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel'den CSV'ye | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * Ön ayarlar birinci sınıf API uç noktalarıdır ve temel rotalarının toplu işlemeyi desteklediği toplu isteklerde de geçerlidir. * Video dönüştürmeyi kullanan ön ayarlar `202 Accepted` döndürebilir; sonucu indirmeden önce iş ilerleme SSE uç noktasına bağlanın. * Bir ön ayar tarafından sunulmayan gelişmiş seçenekler için, temel dönüştürücü aracı doğrudan çağırın ve çıktı formatını `settings` içinde ayarlayın. --- --- url: https://docs.snapotter.com/uk/tools/conversion-presets.md description: >- Спеціалізовані кінцеві точки пресетів конвертації, згенеровані з каталогу інструментів SnapOtter. --- # Conversion Presets {#conversion-presets} SnapOtter надає 83 спеціалізовані кінцеві точки пресетів конвертації на додаток до базових інструментів-конвертерів. Кожен пресет фіксує формат виводу та делегує обробку своєму базовому конвеєру, тому поведінка, валідація та контракт виводу відповідають базовому інструменту, зазначеному нижче. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Надсилайте `multipart/form-data` із частиною `file` та необов'язковим JSON-рядком `settings`. Пресети дотримуються контракту відповіді базового інструменту. Швидкі пресети зазвичай повертають `200` із `downloadUrl`, але можуть повернути `202`, якщо перевищать вікно синхронного очікування. Відеопресети та тривалі пресети для файлів/документів повертають `202` і потоки прогресу з `/api/v1/jobs//progress`. Пресети PDF-to-image повертають URL-адреси завантаження сторінок плюс URL-адресу ZIP. ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG у PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG у JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG у WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG у WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP у JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP у PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG у AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG у AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP у AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC у JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC у PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC у AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG у GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG у GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF у JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF у PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP у GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG у TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG у TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF у JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF у PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD у JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD у PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG у EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG у EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS у PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS у JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG у SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG у SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF у SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD у SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS у SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG у PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG у JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG у PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG у PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC у PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF у PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP у PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF у PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS у PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV у MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM у MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV у MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI у MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 у MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 у WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM у MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV у MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI у MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 у AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV у AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV у AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI у MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 у GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV у GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV у GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI у GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF у MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF у WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF у MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 у MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV у MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV у MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM у MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI у MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 у WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV у WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 у OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A у MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A у WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC у MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC у WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC у FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG у MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG у WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV у MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 у WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC у MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF у JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF у PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF у TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel у CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * Пресети є повноцінними кінцевими точками API і також дійсні в пакетних запитах, де їхній базовий маршрут підтримує пакетну обробку. * Пресети, що використовують відеоконвертацію, можуть повертати `202 Accepted`; під'єднайтеся до кінцевої точки SSE прогресу завдання перед завантаженням результату. * Для розширених опцій, не доступних через пресет, викличте базовий інструмент-конвертер безпосередньо та встановіть формат виводу в `settings`. --- --- url: https://docs.snapotter.com/vi/tools/conversion-presets.md description: >- Các endpoint cấu hình chuyển đổi chuyên dụng được tạo từ danh mục công cụ SnapOtter. --- # Conversion Presets {#conversion-presets} Ngoài các công cụ chuyển đổi gốc, SnapOtter cung cấp 83 endpoint cấu hình chuyển đổi chuyên dụng. Mỗi cấu hình khóa định dạng đầu ra và ủy quyền cho pipeline xử lý gốc của nó, nên hành vi, kiểm tra hợp lệ và hợp đồng đầu ra khớp với công cụ gốc được liệt kê bên dưới. ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` Gửi `multipart/form-data` với một phần `file` và một chuỗi JSON `settings` tùy chọn. Các cấu hình tuân theo hợp đồng phản hồi của công cụ gốc. Các cấu hình nhanh thường trả về `200` kèm một `downloadUrl`, nhưng có thể trả về `202` nếu vượt quá cửa sổ chờ đồng bộ. Các cấu hình video và các cấu hình tệp/tài liệu chạy lâu trả về `202` và luồng tiến trình từ `/api/v1/jobs//progress`. Các cấu hình PDF-to-image trả về URL tải xuống của từng trang cùng một URL ZIP. ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG to PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-jpg` | PNG to JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG to WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-webp` | PNG to WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP to JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP to PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG to AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-avif` | PNG to AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP to AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC to JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`, `.heif` | quality | | `heic-to-png` | HEIC to PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`, `.heif` | quality | | `heic-to-avif` | HEIC to AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`, `.heif` | quality | | `jpg-to-gif` | JPG to GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-gif` | PNG to GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF to JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF to PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP to GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG to TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`, `.jpeg` | quality | | `png-to-tiff` | PNG to TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF to JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`, `.tif` | quality | | `tiff-to-png` | TIFF to PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`, `.tif` | quality | | `psd-to-jpg` | PSD to JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD to PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG to EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG to EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`, `.jpeg` | quality | | `eps-to-png` | EPS to PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS to JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG to SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG to SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`, `.jpeg` | none | | `tiff-to-svg` | TIFF to SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`, `.tif` | none | | `psd-to-svg` | PSD to SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS to SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG to PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG to JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`, `.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG to PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`, `.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG to PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC to PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`, `.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF to PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`, `.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP to PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF to PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS to PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV to MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM to MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV to MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI to MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 to MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 to WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM to MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV to MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI to MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 to AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV to AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV to AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI to MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 to GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV to GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV to GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI to GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF to MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF to WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF to MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 to MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV to MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV to MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM to MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI to MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 to WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV to WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 to OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A to MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A to WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC to MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC to WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC to FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG to MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG to WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV to MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 to WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC to MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF to JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF to PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF to TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel to CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`, `.xls` | none | ## Notes {#notes} * Các cấu hình là endpoint API hạng nhất và cũng hợp lệ trong các yêu cầu xử lý hàng loạt nơi route gốc của chúng hỗ trợ xử lý hàng loạt. * Các cấu hình sử dụng chuyển đổi video có thể trả về `202 Accepted`; hãy kết nối tới endpoint SSE theo dõi tiến trình tác vụ trước khi tải kết quả. * Với các tùy chọn nâng cao mà cấu hình không phơi bày, hãy gọi trực tiếp công cụ chuyển đổi gốc và đặt định dạng đầu ra trong `settings`. --- --- url: https://docs.snapotter.com/zh-CN/tools/conversion-presets.md description: 由 SnapOtter 工具目录生成的专用转换预设端点。 --- # Conversion Presets {#conversion-presets} 除了基础转换器工具外,SnapOtter 还提供 83 个专用的转换预设端点。每个预设锁定输出格式并委托给其基础处理流程,因此其行为、校验和输出约定与下面列出的基础工具一致。 ## API Endpoint Pattern {#api-endpoint-pattern} `POST /api/v1/tools/
/` 发送 `multipart/form-data`,其中包含一个 `file` 部分和可选的 `settings` JSON 字符串。预设遵循基础工具的响应约定。快速预设通常返回 `200` 及一个 `downloadUrl`,但如果超出同步等待窗口,则可能返回 `202`。视频预设以及耗时较长的文件/文档预设返回 `202`,并从 `/api/v1/jobs//progress` 提供进度流。PDF 转图片预设返回各页的下载 URL 加一个 ZIP URL。 ## Image Presets {#image-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `jpg-to-png` | JPG 转 PNG | `/api/v1/tools/image/jpg-to-png` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-jpg` | PNG 转 JPG | `/api/v1/tools/image/png-to-jpg` | `convert` | `.png` | quality | | `jpg-to-webp` | JPG 转 WebP | `/api/v1/tools/image/jpg-to-webp` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-webp` | PNG 转 WebP | `/api/v1/tools/image/png-to-webp` | `convert` | `.png` | quality | | `webp-to-jpg` | WebP 转 JPG | `/api/v1/tools/image/webp-to-jpg` | `convert` | `.webp` | quality | | `webp-to-png` | WebP 转 PNG | `/api/v1/tools/image/webp-to-png` | `convert` | `.webp` | quality | | `jpg-to-avif` | JPG 转 AVIF | `/api/v1/tools/image/jpg-to-avif` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-avif` | PNG 转 AVIF | `/api/v1/tools/image/png-to-avif` | `convert` | `.png` | quality | | `webp-to-avif` | WebP 转 AVIF | `/api/v1/tools/image/webp-to-avif` | `convert` | `.webp` | quality | | `heic-to-jpg` | HEIC 转 JPG | `/api/v1/tools/image/heic-to-jpg` | `convert` | `.heic`、`.heif` | quality | | `heic-to-png` | HEIC 转 PNG | `/api/v1/tools/image/heic-to-png` | `convert` | `.heic`、`.heif` | quality | | `heic-to-avif` | HEIC 转 AVIF | `/api/v1/tools/image/heic-to-avif` | `convert` | `.heic`、`.heif` | quality | | `jpg-to-gif` | JPG 转 GIF | `/api/v1/tools/image/jpg-to-gif` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-gif` | PNG 转 GIF | `/api/v1/tools/image/png-to-gif` | `convert` | `.png` | quality | | `gif-to-jpg` | GIF 转 JPG | `/api/v1/tools/image/gif-to-jpg` | `convert` | `.gif` | quality | | `gif-to-png` | GIF 转 PNG | `/api/v1/tools/image/gif-to-png` | `convert` | `.gif` | quality | | `webp-to-gif` | WebP 转 GIF | `/api/v1/tools/image/webp-to-gif` | `convert` | `.webp` | quality | | `jpg-to-tiff` | JPG 转 TIFF | `/api/v1/tools/image/jpg-to-tiff` | `convert` | `.jpg`、`.jpeg` | quality | | `png-to-tiff` | PNG 转 TIFF | `/api/v1/tools/image/png-to-tiff` | `convert` | `.png` | quality | | `tiff-to-jpg` | TIFF 转 JPG | `/api/v1/tools/image/tiff-to-jpg` | `convert` | `.tiff`、`.tif` | quality | | `tiff-to-png` | TIFF 转 PNG | `/api/v1/tools/image/tiff-to-png` | `convert` | `.tiff`、`.tif` | quality | | `psd-to-jpg` | PSD 转 JPG | `/api/v1/tools/image/psd-to-jpg` | `convert` | `.psd` | quality | | `psd-to-png` | PSD 转 PNG | `/api/v1/tools/image/psd-to-png` | `convert` | `.psd` | quality | | `png-to-eps` | PNG 转 EPS | `/api/v1/tools/image/png-to-eps` | `convert` | `.png` | quality | | `jpg-to-eps` | JPG 转 EPS | `/api/v1/tools/image/jpg-to-eps` | `convert` | `.jpg`、`.jpeg` | quality | | `eps-to-png` | EPS 转 PNG | `/api/v1/tools/image/eps-to-png` | `convert` | `.eps` | quality | | `eps-to-jpg` | EPS 转 JPG | `/api/v1/tools/image/eps-to-jpg` | `convert` | `.eps` | quality | | `png-to-svg` | PNG 转 SVG | `/api/v1/tools/image/png-to-svg` | `vectorize` | `.png` | none | | `jpg-to-svg` | JPG 转 SVG | `/api/v1/tools/image/jpg-to-svg` | `vectorize` | `.jpg`、`.jpeg` | none | | `tiff-to-svg` | TIFF 转 SVG | `/api/v1/tools/image/tiff-to-svg` | `vectorize` | `.tiff`、`.tif` | none | | `psd-to-svg` | PSD 转 SVG | `/api/v1/tools/image/psd-to-svg` | `vectorize` | `.psd` | none | | `eps-to-svg` | EPS 转 SVG | `/api/v1/tools/image/eps-to-svg` | `vectorize` | `.eps` | none | | `svg-to-png` | SVG 转 PNG | `/api/v1/tools/image/svg-to-png` | `svg-to-raster` | `.svg`、`.svgz` | quality, width, height, dpi, backgroundColor | | `svg-to-jpg` | SVG 转 JPG | `/api/v1/tools/image/svg-to-jpg` | `svg-to-raster` | `.svg`、`.svgz` | quality, width, height, dpi, backgroundColor | | `jpg-to-pdf` | JPG 转 PDF | `/api/v1/tools/image/jpg-to-pdf` | `image-to-pdf` | `.jpg`、`.jpeg` | pageSize, orientation, margin, targetSize, collate | | `png-to-pdf` | PNG 转 PDF | `/api/v1/tools/image/png-to-pdf` | `image-to-pdf` | `.png` | pageSize, orientation, margin, targetSize, collate | | `heic-to-pdf` | HEIC 转 PDF | `/api/v1/tools/image/heic-to-pdf` | `image-to-pdf` | `.heic`、`.heif` | pageSize, orientation, margin, targetSize, collate | | `tiff-to-pdf` | TIFF 转 PDF | `/api/v1/tools/image/tiff-to-pdf` | `image-to-pdf` | `.tiff`、`.tif` | pageSize, orientation, margin, targetSize, collate | | `webp-to-pdf` | WebP 转 PDF | `/api/v1/tools/image/webp-to-pdf` | `image-to-pdf` | `.webp` | pageSize, orientation, margin, targetSize, collate | | `gif-to-pdf` | GIF 转 PDF | `/api/v1/tools/image/gif-to-pdf` | `image-to-pdf` | `.gif` | pageSize, orientation, margin, targetSize, collate | | `eps-to-pdf` | EPS 转 PDF | `/api/v1/tools/image/eps-to-pdf` | `image-to-pdf` | `.eps` | pageSize, orientation, margin, targetSize, collate | ## Video Presets {#video-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `mov-to-mp4` | MOV 转 MP4 | `/api/v1/tools/video/mov-to-mp4` | `convert-video` | `.mov` | quality | | `webm-to-mp4` | WEBM 转 MP4 | `/api/v1/tools/video/webm-to-mp4` | `convert-video` | `.webm` | quality | | `mkv-to-mp4` | MKV 转 MP4 | `/api/v1/tools/video/mkv-to-mp4` | `convert-video` | `.mkv` | quality | | `avi-to-mp4` | AVI 转 MP4 | `/api/v1/tools/video/avi-to-mp4` | `convert-video` | `.avi` | quality | | `mp4-to-mov` | MP4 转 MOV | `/api/v1/tools/video/mp4-to-mov` | `convert-video` | `.mp4` | quality | | `mp4-to-webm` | MP4 转 WEBM | `/api/v1/tools/video/mp4-to-webm` | `convert-video` | `.mp4` | quality | | `webm-to-mov` | WEBM 转 MOV | `/api/v1/tools/video/webm-to-mov` | `convert-video` | `.webm` | quality | | `mkv-to-mov` | MKV 转 MOV | `/api/v1/tools/video/mkv-to-mov` | `convert-video` | `.mkv` | quality | | `avi-to-mov` | AVI 转 MOV | `/api/v1/tools/video/avi-to-mov` | `convert-video` | `.avi` | quality | | `mp4-to-avi` | MP4 转 AVI | `/api/v1/tools/video/mp4-to-avi` | `convert-video` | `.mp4` | quality | | `mov-to-avi` | MOV 转 AVI | `/api/v1/tools/video/mov-to-avi` | `convert-video` | `.mov` | quality | | `mkv-to-avi` | MKV 转 AVI | `/api/v1/tools/video/mkv-to-avi` | `convert-video` | `.mkv` | quality | | `avi-to-mkv` | AVI 转 MKV | `/api/v1/tools/video/avi-to-mkv` | `convert-video` | `.avi` | quality | | `mp4-to-gif` | MP4 转 GIF | `/api/v1/tools/video/mp4-to-gif` | `video-to-gif` | `.mp4` | fps, width, startS, durationS | | `mov-to-gif` | MOV 转 GIF | `/api/v1/tools/video/mov-to-gif` | `video-to-gif` | `.mov` | fps, width, startS, durationS | | `mkv-to-gif` | MKV 转 GIF | `/api/v1/tools/video/mkv-to-gif` | `video-to-gif` | `.mkv` | fps, width, startS, durationS | | `avi-to-gif` | AVI 转 GIF | `/api/v1/tools/video/avi-to-gif` | `video-to-gif` | `.avi` | fps, width, startS, durationS | | `gif-to-mp4` | GIF 转 MP4 | `/api/v1/tools/video/gif-to-mp4` | `gif-to-video` | `.gif` | none | | `gif-to-webm` | GIF 转 WEBM | `/api/v1/tools/video/gif-to-webm` | `gif-to-video` | `.gif` | none | | `gif-to-mov` | GIF 转 MOV | `/api/v1/tools/video/gif-to-mov` | `gif-to-video` | `.gif` | none | | `mp4-to-mp3` | MP4 转 MP3 | `/api/v1/tools/video/mp4-to-mp3` | `extract-audio` | `.mp4` | none | | `mov-to-mp3` | MOV 转 MP3 | `/api/v1/tools/video/mov-to-mp3` | `extract-audio` | `.mov` | none | | `mkv-to-mp3` | MKV 转 MP3 | `/api/v1/tools/video/mkv-to-mp3` | `extract-audio` | `.mkv` | none | | `webm-to-mp3` | WEBM 转 MP3 | `/api/v1/tools/video/webm-to-mp3` | `extract-audio` | `.webm` | none | | `avi-to-mp3` | AVI 转 MP3 | `/api/v1/tools/video/avi-to-mp3` | `extract-audio` | `.avi` | none | | `mp4-to-wav` | MP4 转 WAV | `/api/v1/tools/video/mp4-to-wav` | `extract-audio` | `.mp4` | none | | `mov-to-wav` | MOV 转 WAV | `/api/v1/tools/video/mov-to-wav` | `extract-audio` | `.mov` | none | | `mp4-to-ogg` | MP4 转 OGG | `/api/v1/tools/video/mp4-to-ogg` | `extract-audio` | `.mp4` | none | ## Audio Presets {#audio-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `m4a-to-mp3` | M4A 转 MP3 | `/api/v1/tools/audio/m4a-to-mp3` | `convert-audio` | `.m4a` | none | | `m4a-to-wav` | M4A 转 WAV | `/api/v1/tools/audio/m4a-to-wav` | `convert-audio` | `.m4a` | none | | `aac-to-mp3` | AAC 转 MP3 | `/api/v1/tools/audio/aac-to-mp3` | `convert-audio` | `.aac` | none | | `aac-to-wav` | AAC 转 WAV | `/api/v1/tools/audio/aac-to-wav` | `convert-audio` | `.aac` | none | | `aac-to-flac` | AAC 转 FLAC | `/api/v1/tools/audio/aac-to-flac` | `convert-audio` | `.aac` | none | | `ogg-to-mp3` | OGG 转 MP3 | `/api/v1/tools/audio/ogg-to-mp3` | `convert-audio` | `.ogg` | none | | `ogg-to-wav` | OGG 转 WAV | `/api/v1/tools/audio/ogg-to-wav` | `convert-audio` | `.ogg` | none | | `wav-to-mp3` | WAV 转 MP3 | `/api/v1/tools/audio/wav-to-mp3` | `convert-audio` | `.wav` | none | | `mp3-to-wav` | MP3 转 WAV | `/api/v1/tools/audio/mp3-to-wav` | `convert-audio` | `.mp3` | none | | `flac-to-mp3` | FLAC 转 MP3 | `/api/v1/tools/audio/flac-to-mp3` | `convert-audio` | `.flac` | none | ## PDF Presets {#pdf-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `pdf-to-jpg` | PDF 转 JPG | `/api/v1/tools/pdf/pdf-to-jpg` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-png` | PDF 转 PNG | `/api/v1/tools/pdf/pdf-to-png` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | | `pdf-to-tiff` | PDF 转 TIFF | `/api/v1/tools/pdf/pdf-to-tiff` | `pdf-to-image` | `.pdf` | dpi, quality, colorMode, pages | ## Files Presets {#files-presets} | Preset ID | Converts | Route | Base tool | Accepted inputs | Optional settings | |-----------|----------|-------|-----------|-----------------|-------------------| | `excel-to-csv` | Excel 转 CSV | `/api/v1/tools/files/excel-to-csv` | `convert-spreadsheet` | `.xlsx`、`.xls` | none | ## Notes {#notes} * 预设是一等的 API 端点,在其基础路由支持批处理的场景下,也可用于批处理请求。 * 使用视频转换的预设可能返回 `202 Accepted`;在下载结果前,请连接到作业进度 SSE 端点。 * 对于预设未暴露的高级选项,可直接调用基础转换器工具,并在 `settings` 中设置输出格式。 --- --- url: https://docs.snapotter.com/pt-BR/tools/pdf/pdfa-convert.md description: >- Converta um PDF para o formato de arquivamento PDF/A-2 para preservação de longo prazo. --- # Conversor de PDF/A {#pdf-a-convert} Converta um PDF para o formato de arquivamento PDF/A-2, adequado para preservação de longo prazo e conformidade regulatória. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdfa-convert` Aceita dados de formulário multipart com um arquivo PDF. Nenhum campo `settings` é necessário. ## Parameters {#parameters} Esta ferramenta não tem parâmetros de configuração. Envie o arquivo PDF diretamente. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdfa-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2600000 } ``` ## Notes {#notes} * A saída está em conformidade com o padrão PDF/A-2. * O PDF/A incorpora todas as fontes e não permite referências externas, portanto o arquivo de saída pode ser maior que o original. * Criptografia e JavaScript são removidos durante a conversão, pois não são permitidos pelo padrão PDF/A. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/gif-webp.md description: Converta GIF animado para WebP e vice-versa, preservando todos os quadros. --- # Conversor GIF/WebP {#gif-webp-converter} Converta arquivos GIF animados para WebP e vice-versa, preservando todos os quadros e a temporização da animação. As animações WebP costumam ser 25-35% menores do que os GIFs equivalentes. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Aceita dados de formulário multipart com um arquivo GIF ou WebP e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | quality | integer | Não | `80` | Qualidade de saída para a codificação WebP (1-100) | | lossless | boolean | Não | `false` | Usar compressão WebP sem perdas | | resizePercent | integer | Não | `100` | Escalar a saída por percentual (10-100) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Observações {#notes} * Apenas arquivos `.gif` e `.webp` são aceitos. Outros formatos de imagem não são suportados por esta ferramenta. * A direção da conversão é automática: entrada GIF produz saída WebP, e entrada WebP produz saída GIF. * As opções `quality` e `lossless` se aplicam apenas ao codificar para WebP. Ao converter para GIF, a saída usa a paleta GIF padrão. * Use `resizePercent` para reduzir as dimensões (e o tamanho do arquivo) de animações grandes. --- --- url: https://docs.snapotter.com/es/tools/pdf/pdfa-convert.md description: >- Convierte un PDF al formato de archivado PDF/A-2 para su conservación a largo plazo. --- # Conversor PDF/A {#pdf-a-convert} Convierte un PDF al formato de archivado PDF/A-2, adecuado para la conservación a largo plazo y el cumplimiento normativo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdfa-convert` Acepta datos de formulario multipart con un archivo PDF. No se requiere un campo `settings`. ## Parameters {#parameters} Esta herramienta no tiene parámetros de configuración. Sube el archivo PDF directamente. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdfa-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2600000 } ``` ## Notes {#notes} * La salida cumple con el estándar PDF/A-2. * PDF/A incrusta todas las fuentes y prohíbe las referencias externas, por lo que el archivo de salida puede ser más grande que el original. * El cifrado y JavaScript se eliminan durante la conversión, ya que no están permitidos por el estándar PDF/A. --- --- url: https://docs.snapotter.com/hi/tools/audio/convert-audio.md description: MP3, WAV, OGG, FLAC, और M4A फ़ॉर्मैट के बीच audio रूपांतरित करें। --- # Convert Audio {#convert-audio} MP3, WAV, OGG, FLAC, और M4A सहित सामान्य फ़ॉर्मैट के बीच audio फ़ाइलें रूपांतरित करें, कॉन्फ़िगर करने योग्य आउटपुट bitrate और सैंपल रेट के साथ। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` एक audio फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | आउटपुट फ़ॉर्मैट: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | No | `192` | kbps में आउटपुट bitrate (32 से 320) | | sampleRate | integer | No | मूल रेट | Hz में आउटपुट सैंपल रेट: `8000`, `16000`, `22050`, `32000`, `44100`, `48000`, या `96000`। मूल रेट बनाए रखने के लिए छोड़ दें | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Notes {#notes} * समर्थित इनपुट फ़ॉर्मैट में MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF, और OPUS शामिल हैं। * Bitrate केवल lossy फ़ॉर्मैट (MP3, OGG, M4A) पर लागू होता है। WAV और FLAC जैसे lossless फ़ॉर्मैट इस सेटिंग को नज़रअंदाज़ करते हैं। * MP3 आउटपुट 48000 Hz तक के सैंपल रेट का समर्थन करता है। 96000 Hz विकल्प केवल WAV, OGG, FLAC, और M4A पर लागू होता है। * MP3 bitrate सैंपल रेट द्वारा सीमित होता है: 8000 Hz पर अधिकतम 64 kbps और 16000 या 22050 Hz पर 160 kbps। सीमा से ऊपर के अनुरोध चुपचाप कम किए जाने के बजाय अस्वीकार कर दिए जाते हैं। * आउटपुट फ़ाइल नाम मूल नाम को नए एक्सटेंशन के साथ रखता है। --- --- url: https://docs.snapotter.com/id/tools/audio/convert-audio.md description: Konversi audio antara format MP3, WAV, OGG, FLAC, dan M4A. --- # Convert Audio {#convert-audio} Konversi file audio antara format umum termasuk MP3, WAV, OGG, FLAC, dan M4A, dengan bitrate output dan laju sampel yang dapat dikonfigurasi. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Menerima data formulir multipart dengan file audio dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | format | string | Tidak | `"mp3"` | Format output: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Tidak | `192` | Bitrate output dalam kbps (32 hingga 320) | | sampleRate | integer | Tidak | laju sumber | Laju sampel output dalam Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000`, atau `96000`. Kosongkan untuk mempertahankan laju sumber | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Catatan {#notes} * Format input yang didukung meliputi MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF, dan OPUS. * Bitrate hanya berlaku untuk format lossy (MP3, OGG, M4A). Format lossless seperti WAV dan FLAC mengabaikan pengaturan ini. * Output MP3 mendukung laju sampel hingga 48000 Hz. Opsi 96000 Hz hanya berlaku untuk WAV, OGG, FLAC, dan M4A. * Bitrate MP3 dibatasi oleh laju sampel: maksimal 64 kbps pada 8000 Hz dan 160 kbps pada 16000 atau 22050 Hz. Permintaan di atas batas tersebut ditolak, bukan diturunkan secara diam-diam. * Nama file output mempertahankan nama asli dengan ekstensi baru. --- --- url: https://docs.snapotter.com/ko/tools/audio/convert-audio.md description: MP3, WAV, OGG, FLAC, M4A 형식 간에 오디오를 변환합니다. --- # Convert Audio {#convert-audio} MP3, WAV, OGG, FLAC, M4A를 포함한 일반적인 형식 간에 오디오 파일을 변환하며, 출력 비트레이트와 샘플 레이트를 구성할 수 있습니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` 오디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 파라미터 {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | 출력 형식: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | No | `192` | 출력 비트레이트(kbps 단위, 32 ~ 320) | | sampleRate | integer | No | 원본 레이트 | 출력 샘플 레이트(Hz 단위): `8000`, `16000`, `22050`, `32000`, `44100`, `48000` 또는 `96000`. 생략하면 원본 레이트 유지 | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## 참고 {#notes} * 지원되는 입력 형식에는 MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF, OPUS가 포함됩니다. * 비트레이트는 손실 형식(MP3, OGG, M4A)에만 적용됩니다. WAV 및 FLAC 같은 무손실 형식은 이 설정을 무시합니다. * MP3 출력은 최대 48000 Hz의 샘플 레이트를 지원합니다. 96000 Hz 옵션은 WAV, OGG, FLAC, M4A에만 적용됩니다. * MP3 비트레이트는 샘플 레이트에 따라 상한이 정해집니다. 8000 Hz에서는 최대 64 kbps, 16000 또는 22050 Hz에서는 최대 160 kbps입니다. 상한을 초과하는 요청은 조용히 낮춰지는 대신 거부됩니다. * 출력 파일 이름은 원래 이름을 유지하고 새 확장자를 사용합니다. --- --- url: https://docs.snapotter.com/nl/tools/audio/convert-audio.md description: Converteer audio tussen de formaten MP3, WAV, OGG, FLAC en M4A. --- # Convert Audio {#convert-audio} Converteer audiobestanden tussen gangbare formaten waaronder MP3, WAV, OGG, FLAC en M4A, met configureerbare uitvoerbitrate en samplefrequentie. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Accepteert multipart-formuliergegevens met een audiobestand en een JSON `settings`-veld. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Nee | `"mp3"` | Uitvoerformaat: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Nee | `192` | Uitvoerbitrate in kbps (32 tot 320) | | sampleRate | integer | Nee | bronfrequentie | Uitvoersamplefrequentie in Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` of `96000`. Laat weg om de samplefrequentie van de bron te behouden | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Opmerkingen {#notes} * Ondersteunde invoerformaten zijn onder meer MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF en OPUS. * Bitrate is alleen van toepassing op lossy-formaten (MP3, OGG, M4A). Lossless-formaten zoals WAV en FLAC negeren deze instelling. * MP3-uitvoer ondersteunt samplefrequenties tot 48000 Hz. De optie 96000 Hz is alleen van toepassing op WAV, OGG, FLAC en M4A. * De MP3-bitrate wordt begrensd door de samplefrequentie: maximaal 64 kbps bij 8000 Hz en 160 kbps bij 16000 of 22050 Hz. Verzoeken boven deze limiet worden geweigerd in plaats van stilzwijgend verlaagd. * De uitvoerbestandsnaam behoudt de oorspronkelijke naam met de nieuwe extensie. --- --- url: https://docs.snapotter.com/sv/tools/audio/convert-audio.md description: Konvertera ljud mellan formaten MP3, WAV, OGG, FLAC och M4A. --- # Convert Audio {#convert-audio} Konvertera ljudfiler mellan vanliga format inklusive MP3, WAV, OGG, FLAC och M4A, med konfigurerbar utdatabithastighet och samplingsfrekvens. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Accepterar multipart-formulärdata med en ljudfil och ett JSON `settings`-fält. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | format | string | Nej | `"mp3"` | Utdataformat: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Nej | `192` | Utdatabithastighet i kbps (32 till 320) | | sampleRate | integer | Nej | källans frekvens | Utdatasamplingsfrekvens i Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` eller `96000`. Utelämna för att behålla källans frekvens | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Anteckningar {#notes} * Inmatningsformat som stöds inkluderar MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF och OPUS. * Bithastighet gäller endast förlustkomprimerade format (MP3, OGG, M4A). Förlustfria format som WAV och FLAC ignorerar den här inställningen. * MP3-utdata stöder samplingsfrekvenser upp till 48000 Hz. Alternativet 96000 Hz gäller endast WAV, OGG, FLAC och M4A. * MP3-bithastigheten begränsas av samplingsfrekvensen: högst 64 kbps vid 8000 Hz och 160 kbps vid 16000 eller 22050 Hz. Förfrågningar över gränsen avvisas i stället för att tyst sänkas. * Utdatafilnamnet behåller det ursprungliga namnet med den nya filändelsen. --- --- url: https://docs.snapotter.com/th/tools/audio/convert-audio.md description: แปลงเสียงระหว่างรูปแบบ MP3, WAV, OGG, FLAC และ M4A --- # Convert Audio {#convert-audio} แปลงไฟล์เสียงระหว่างรูปแบบทั่วไปรวมถึง MP3, WAV, OGG, FLAC และ M4A พร้อมบิตเรตเอาต์พุตและอัตราสุ่มตัวอย่างที่กำหนดค่าได้ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` รับข้อมูลฟอร์มแบบ multipart พร้อมไฟล์เสียงและฟิลด์ JSON `settings` ## พารามิเตอร์ {#parameters} | พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย | |-----------|------|----------|---------|-------------| | format | string | ไม่ | `"mp3"` | รูปแบบเอาต์พุต: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | ไม่ | `192` | บิตเรตเอาต์พุตเป็น kbps (32 ถึง 320) | | sampleRate | integer | ไม่ | อัตราเดิม | อัตราสุ่มตัวอย่างเอาต์พุตเป็น Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` หรือ `96000` ละไว้เพื่อคงอัตราเดิม | ## ตัวอย่างคำขอ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## ตัวอย่างการตอบกลับ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## หมายเหตุ {#notes} * รูปแบบอินพุตที่รองรับรวมถึง MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF และ OPUS * บิตเรตใช้ได้กับรูปแบบแบบสูญเสีย (MP3, OGG, M4A) เท่านั้น รูปแบบแบบไม่สูญเสียเช่น WAV และ FLAC จะเพิกเฉยการตั้งค่านี้ * เอาต์พุต MP3 รองรับอัตราสุ่มตัวอย่างสูงสุด 48000 Hz ตัวเลือก 96000 Hz ใช้ได้กับ WAV, OGG, FLAC และ M4A เท่านั้น * บิตเรต MP3 ถูกจำกัดตามอัตราสุ่มตัวอย่าง: สูงสุด 64 kbps ที่ 8000 Hz และ 160 kbps ที่ 16000 หรือ 22050 Hz คำขอที่เกินขีดจำกัดจะถูกปฏิเสธแทนที่จะถูกปรับลดลงโดยไม่แจ้ง * ชื่อไฟล์เอาต์พุตคงชื่อเดิมไว้พร้อมนามสกุลใหม่ --- --- url: https://docs.snapotter.com/tr/tools/audio/convert-audio.md description: Sesi MP3, WAV, OGG, FLAC ve M4A formatları arasında dönüştürün. --- # Convert Audio {#convert-audio} Ses dosyalarını MP3, WAV, OGG, FLAC ve M4A dahil yaygın formatlar arasında, yapılandırılabilir çıktı bit hızı ve örnekleme hızıyla dönüştürün. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Bir ses dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | format | string | Hayır | `"mp3"` | Çıktı formatı: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Hayır | `192` | kbps cinsinden çıktı bit hızı (32 ile 320 arası) | | sampleRate | integer | Hayır | kaynak hızı | Hz cinsinden çıktı örnekleme hızı: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` veya `96000`. Kaynak hızını korumak için atlayın | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Notlar {#notes} * Desteklenen girdi formatları arasında MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF ve OPUS bulunur. * Bit hızı yalnızca kayıplı formatlar (MP3, OGG, M4A) için geçerlidir. WAV ve FLAC gibi kayıpsız formatlar bu ayarı yok sayar. * MP3 çıktısı 48000 Hz'e kadar örnekleme hızlarını destekler. 96000 Hz seçeneği yalnızca WAV, OGG, FLAC ve M4A için geçerlidir. * MP3 bit hızı örnekleme hızına göre sınırlıdır: 8000 Hz'de en fazla 64 kbps, 16000 veya 22050 Hz'de ise en fazla 160 kbps. Sınırın üzerindeki istekler sessizce düşürülmek yerine reddedilir. * Çıktı dosya adı, orijinal adı yeni uzantıyla korur. --- --- url: https://docs.snapotter.com/de/tools/files/convert-document.md description: Konvertiert zwischen Word-, OpenDocument-, RTF- und Klartextformaten. --- # Convert Document {#convert-document} Konvertiert Dokumente mithilfe von LibreOffice zwischen den Formaten Word (DOCX), OpenDocument (ODT), RTF und Klartext. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Akzeptiert Multipart-Formulardaten mit einer Word-/ODT-/RTF-/TXT-Datei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Ausgabeformat: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Gibt `202 Accepted` zurück. Verfolge den Fortschritt per SSE unter `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akzeptierte Eingabeformate: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Die Konvertierung wird von LibreOffice im Headless-Modus auf dem Server durchgeführt. * Komplexe Formatierungen (Makros, eingebettete Objekte) überstehen die Konvertierung zwischen Formaten möglicherweise nicht. * Das Ausgabeformat muss sich vom Eingabeformat unterscheiden. --- --- url: https://docs.snapotter.com/hi/tools/files/convert-document.md description: Word, OpenDocument, RTF, और plain text फ़ॉर्मेट के बीच कन्वर्ट करें। --- # Convert Document {#convert-document} LibreOffice का उपयोग करके दस्तावेज़ों को Word (DOCX), OpenDocument (ODT), RTF, और plain text फ़ॉर्मेट के बीच कन्वर्ट करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` एक Word/ODT/RTF/TXT फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | आउटपुट फ़ॉर्मेट: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} `202 Accepted` लौटाता है। `/api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति को ट्रैक करें। ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * स्वीकृत इनपुट फ़ॉर्मेट: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`। * कन्वर्ज़न सर्वर पर headless चल रहे LibreOffice द्वारा नियंत्रित किया जाता है। * जटिल फ़ॉर्मेटिंग (macros, embedded objects) फ़ॉर्मेट के बीच कन्वर्ज़न में बची न रह सकती है। * आउटपुट फ़ॉर्मेट इनपुट फ़ॉर्मेट से भिन्न होना चाहिए। --- --- url: https://docs.snapotter.com/id/tools/files/convert-document.md description: Konversi antar format Word, OpenDocument, RTF, dan teks biasa. --- # Convert Document {#convert-document} Konversi dokumen antar format Word (DOCX), OpenDocument (ODT), RTF, dan teks biasa menggunakan LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Menerima multipart form data berisi file Word/ODT/RTF/TXT dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Format output: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Mengembalikan `202 Accepted`. Lacak progres melalui SSE di `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Format input yang diterima: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Konversi ditangani oleh LibreOffice yang berjalan headless di server. * Pemformatan kompleks (makro, objek tersemat) mungkin tidak bertahan pada konversi antar format. * Format output harus berbeda dari format input. --- --- url: https://docs.snapotter.com/it/tools/files/convert-document.md description: Converte tra i formati Word, OpenDocument, RTF e testo semplice. --- # Convert Document {#convert-document} Converte i documenti tra i formati Word (DOCX), OpenDocument (ODT), RTF e testo semplice usando LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Accetta dati form multipart con un file Word/ODT/RTF/TXT e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Formato di output: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Formati di input accettati: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * La conversione è gestita da LibreOffice in esecuzione headless sul server. * La formattazione complessa (macro, oggetti incorporati) potrebbe non sopravvivere alla conversione tra i formati. * Il formato di output deve essere diverso dal formato di input. --- --- url: https://docs.snapotter.com/ja/tools/files/convert-document.md description: Word、OpenDocument、RTF、プレーンテキストの各形式間で変換します。 --- # Convert Document {#convert-document} LibreOffice を使用して、ドキュメントを Word(DOCX)、OpenDocument(ODT)、RTF、プレーンテキストの各形式間で変換します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Word/ODT/RTF/TXT ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | 出力形式: `docx`、`odt`、`rtf`、`txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} `202 Accepted` を返します。`/api/v1/jobs/{jobId}/progress` の SSE で進捗を追跡します。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 受け付ける入力形式: `.docx`、`.doc`、`.odt`、`.rtf`、`.txt`。 * 変換はサーバー上でヘッドレスで動作する LibreOffice によって処理されます。 * 複雑な書式(マクロ、埋め込みオブジェクト)は形式間の変換で保持されないことがあります。 * 出力形式は入力形式と異なる必要があります。 --- --- url: https://docs.snapotter.com/nl/tools/files/convert-document.md description: Converteer tussen Word-, OpenDocument-, RTF- en platte-tekstformaten. --- # Convert Document {#convert-document} Converteer documenten tussen Word (DOCX), OpenDocument (ODT), RTF en platte-tekstformaten met LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Accepteert multipart-formulierdata met een Word-/ODT-/RTF-/TXT-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Uitvoerformaat: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Retourneert `202 Accepted`. Volg de voortgang via SSE op `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Geaccepteerde invoerformaten: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * De conversie wordt uitgevoerd door LibreOffice dat headless op de server draait. * Complexe opmaak (macro's, ingesloten objecten) blijft mogelijk niet behouden bij conversie tussen formaten. * Het uitvoerformaat moet verschillen van het invoerformaat. --- --- url: https://docs.snapotter.com/pl/tools/files/convert-document.md description: Konwertuje między formatami Word, OpenDocument, RTF i zwykłego tekstu. --- # Convert Document {#convert-document} Konwertuje dokumenty między formatami Word (DOCX), OpenDocument (ODT), RTF i zwykłego tekstu przy użyciu LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Przyjmuje dane formularza multipart z plikiem Word/ODT/RTF/TXT oraz polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | format | string | Tak | - | Format wyjściowy: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Zwraca `202 Accepted`. Śledź postęp przez SSE pod `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akceptowane formaty wejściowe: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Konwersję obsługuje LibreOffice działający w trybie headless na serwerze. * Złożone formatowanie (makra, obiekty osadzone) może nie przetrwać konwersji między formatami. * Format wyjściowy musi różnić się od formatu wejściowego. --- --- url: https://docs.snapotter.com/sv/tools/files/convert-document.md description: Konvertera mellan formaten Word, OpenDocument, RTF och oformaterad text. --- # Convert Document {#convert-document} Konvertera dokument mellan formaten Word (DOCX), OpenDocument (ODT), RTF och oformaterad text med LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Tar emot multipart-formulärdata med en Word/ODT/RTF/TXT-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Utdataformat: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Returnerar `202 Accepted`. Följ förloppet via SSE på `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Godkända indataformat: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Konverteringen hanteras av LibreOffice som körs utan grafiskt gränssnitt på servern. * Komplex formatering (makron, inbäddade objekt) kanske inte överlever konvertering mellan format. * Utdataformatet måste skilja sig från indataformatet. --- --- url: https://docs.snapotter.com/th/tools/files/convert-document.md description: แปลงระหว่างรูปแบบ Word, OpenDocument, RTF และข้อความธรรมดา --- # Convert Document {#convert-document} แปลงเอกสารระหว่างรูปแบบ Word (DOCX), OpenDocument (ODT), RTF และข้อความธรรมดา โดยใช้ LibreOffice ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` รับข้อมูล multipart form ที่มีไฟล์ Word/ODT/RTF/TXT และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | รูปแบบผลลัพธ์: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} ส่งคืน `202 Accepted` ติดตามความคืบหน้าผ่าน SSE ที่ `/api/v1/jobs/{jobId}/progress` ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * รูปแบบอินพุตที่รับได้: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt` * การแปลงจัดการโดย LibreOffice ที่ทำงานแบบ headless บนเซิร์ฟเวอร์ * การจัดรูปแบบที่ซับซ้อน (มาโคร ออบเจกต์ที่ฝัง) อาจไม่คงอยู่ผ่านการแปลงระหว่างรูปแบบ * รูปแบบผลลัพธ์ต้องแตกต่างจากรูปแบบอินพุต --- --- url: https://docs.snapotter.com/tr/tools/files/convert-document.md description: Word, OpenDocument, RTF ve düz metin formatları arasında dönüştürün. --- # Convert Document {#convert-document} LibreOffice kullanarak belgeleri Word (DOCX), OpenDocument (ODT), RTF ve düz metin formatları arasında dönüştürün. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Bir Word/ODT/RTF/TXT dosyası ve JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Çıktı formatı: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} `202 Accepted` döndürür. İlerlemeyi `/api/v1/jobs/{jobId}/progress` adresinde SSE üzerinden izleyin. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Kabul edilen giriş formatları: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Dönüştürme, sunucuda başsız (headless) çalışan LibreOffice tarafından gerçekleştirilir. * Karmaşık biçimlendirme (makrolar, gömülü nesneler) formatlar arasında dönüştürmede korunmayabilir. * Çıktı formatı giriş formatından farklı olmalıdır. --- --- url: https://docs.snapotter.com/uk/tools/files/convert-document.md description: Конвертація між форматами Word, OpenDocument, RTF та простим текстом. --- # Convert Document {#convert-document} Конвертація документів між форматами Word (DOCX), OpenDocument (ODT), RTF та простим текстом за допомогою LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Приймає дані форми multipart з файлом Word/ODT/RTF/TXT та JSON-полем `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Формат виводу: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Повертає `202 Accepted`. Відстежуйте прогрес через SSE за адресою `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Прийнятні вхідні формати: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Конвертація обробляється LibreOffice, що працює в безголовому режимі на сервері. * Складне форматування (макроси, вбудовані об'єкти) може не зберегтися під час конвертації між форматами. * Формат виводу має відрізнятися від вхідного формату. --- --- url: https://docs.snapotter.com/vi/tools/files/convert-document.md description: Chuyển đổi giữa các định dạng Word, OpenDocument, RTF và văn bản thuần túy. --- # Convert Document {#convert-document} Chuyển đổi tài liệu giữa các định dạng Word (DOCX), OpenDocument (ODT), RTF và văn bản thuần túy bằng LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Nhận dữ liệu multipart form với một tệp Word/ODT/RTF/TXT và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Định dạng đầu ra: `docx`, `odt`, `rtf`, `txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} Trả về `202 Accepted`. Theo dõi tiến trình qua SSE tại `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Các định dạng đầu vào được chấp nhận: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * Việc chuyển đổi được xử lý bởi LibreOffice chạy ở chế độ headless trên máy chủ. * Định dạng phức tạp (macro, đối tượng nhúng) có thể không được giữ nguyên khi chuyển đổi giữa các định dạng. * Định dạng đầu ra phải khác với định dạng đầu vào. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/convert-document.md description: 在 Word、OpenDocument、RTF 和纯文本格式之间转换。 --- # Convert Document {#convert-document} 使用 LibreOffice 在 Word(DOCX)、OpenDocument(ODT)、RTF 和纯文本格式之间转换文档。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` 接受包含 Word/ODT/RTF/TXT 文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | 输出格式:`docx`、`odt`、`rtf`、`txt` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Example Response {#example-response} 返回 `202 Accepted`。通过 `/api/v1/jobs/{jobId}/progress` 处的 SSE 跟踪进度。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 接受的输入格式:`.docx`、`.doc`、`.odt`、`.rtf`、`.txt`。 * 转换由服务器上以无头模式运行的 LibreOffice 处理。 * 复杂格式(宏、嵌入对象)在格式之间转换时可能无法保留。 * 输出格式必须与输入格式不同。 --- --- url: https://docs.snapotter.com/de/tools/files/convert-presentation.md description: Konvertiert zwischen PowerPoint- und OpenDocument-Präsentationsformaten. --- # Convert Presentation {#convert-presentation} Konvertiert Präsentationen zwischen den Formaten PowerPoint (PPTX) und OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Akzeptiert Multipart-Formulardaten mit einer PowerPoint-/ODP-Datei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Ausgabeformat: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Gibt `202 Accepted` zurück. Verfolge den Fortschritt per SSE unter `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akzeptierte Eingabeformate: `.pptx`, `.ppt`, `.odp`. * Die Konvertierung wird von LibreOffice im Headless-Modus auf dem Server durchgeführt. * Animationen und Übergangseffekte bleiben zwischen Formaten möglicherweise nicht erhalten. * Das Ausgabeformat muss sich vom Eingabeformat unterscheiden. --- --- url: https://docs.snapotter.com/hi/tools/files/convert-presentation.md description: PowerPoint और OpenDocument प्रेजेंटेशन फ़ॉर्मेट के बीच कन्वर्ट करें। --- # Convert Presentation {#convert-presentation} प्रेजेंटेशन को PowerPoint (PPTX) और OpenDocument Presentation (ODP) फ़ॉर्मेट के बीच कन्वर्ट करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` एक PowerPoint/ODP फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | आउटपुट फ़ॉर्मेट: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} `202 Accepted` लौटाता है। `/api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति को ट्रैक करें। ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * स्वीकृत इनपुट फ़ॉर्मेट: `.pptx`, `.ppt`, `.odp`। * कन्वर्ज़न सर्वर पर headless चल रहे LibreOffice द्वारा नियंत्रित किया जाता है। * एनिमेशन और ट्रांज़िशन प्रभाव फ़ॉर्मेट के बीच संरक्षित न रह सकते हैं। * आउटपुट फ़ॉर्मेट इनपुट फ़ॉर्मेट से भिन्न होना चाहिए। --- --- url: https://docs.snapotter.com/id/tools/files/convert-presentation.md description: Konversi antar format presentasi PowerPoint dan OpenDocument. --- # Convert Presentation {#convert-presentation} Konversi presentasi antar format PowerPoint (PPTX) dan OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Menerima multipart form data berisi file PowerPoint/ODP dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Format output: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Mengembalikan `202 Accepted`. Lacak progres melalui SSE di `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Format input yang diterima: `.pptx`, `.ppt`, `.odp`. * Konversi ditangani oleh LibreOffice yang berjalan headless di server. * Efek animasi dan transisi mungkin tidak dipertahankan antar format. * Format output harus berbeda dari format input. --- --- url: https://docs.snapotter.com/it/tools/files/convert-presentation.md description: Converte tra i formati di presentazione PowerPoint e OpenDocument. --- # Convert Presentation {#convert-presentation} Converte le presentazioni tra i formati PowerPoint (PPTX) e OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Accetta dati form multipart con un file PowerPoint/ODP e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Formato di output: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Formati di input accettati: `.pptx`, `.ppt`, `.odp`. * La conversione è gestita da LibreOffice in esecuzione headless sul server. * Le animazioni e gli effetti di transizione potrebbero non essere preservati tra i formati. * Il formato di output deve essere diverso dal formato di input. --- --- url: https://docs.snapotter.com/ja/tools/files/convert-presentation.md description: PowerPoint と OpenDocument プレゼンテーション形式間で変換します。 --- # Convert Presentation {#convert-presentation} プレゼンテーションを PowerPoint(PPTX)と OpenDocument Presentation(ODP)形式間で変換します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` PowerPoint/ODP ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | 出力形式: `pptx`、`odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} `202 Accepted` を返します。`/api/v1/jobs/{jobId}/progress` の SSE で進捗を追跡します。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 受け付ける入力形式: `.pptx`、`.ppt`、`.odp`。 * 変換はサーバー上でヘッドレスで動作する LibreOffice によって処理されます。 * アニメーションや切り替え効果は形式間で保持されないことがあります。 * 出力形式は入力形式と異なる必要があります。 --- --- url: https://docs.snapotter.com/nl/tools/files/convert-presentation.md description: Converteer tussen PowerPoint- en OpenDocument-presentatieformaten. --- # Convert Presentation {#convert-presentation} Converteer presentaties tussen PowerPoint (PPTX) en OpenDocument Presentation (ODP) formaten. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Accepteert multipart-formulierdata met een PowerPoint-/ODP-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Uitvoerformaat: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Retourneert `202 Accepted`. Volg de voortgang via SSE op `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Geaccepteerde invoerformaten: `.pptx`, `.ppt`, `.odp`. * De conversie wordt uitgevoerd door LibreOffice dat headless op de server draait. * Animaties en overgangseffecten blijven mogelijk niet behouden bij conversie tussen formaten. * Het uitvoerformaat moet verschillen van het invoerformaat. --- --- url: https://docs.snapotter.com/pl/tools/files/convert-presentation.md description: Konwertuje między formatami prezentacji PowerPoint i OpenDocument. --- # Convert Presentation {#convert-presentation} Konwertuje prezentacje między formatami PowerPoint (PPTX) i OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Przyjmuje dane formularza multipart z plikiem PowerPoint/ODP oraz polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | format | string | Tak | - | Format wyjściowy: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Zwraca `202 Accepted`. Śledź postęp przez SSE pod `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akceptowane formaty wejściowe: `.pptx`, `.ppt`, `.odp`. * Konwersję obsługuje LibreOffice działający w trybie headless na serwerze. * Animacje i efekty przejść mogą nie zostać zachowane między formatami. * Format wyjściowy musi różnić się od formatu wejściowego. --- --- url: https://docs.snapotter.com/sv/tools/files/convert-presentation.md description: Konvertera mellan presentationsformaten PowerPoint och OpenDocument. --- # Convert Presentation {#convert-presentation} Konvertera presentationer mellan formaten PowerPoint (PPTX) och OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Tar emot multipart-formulärdata med en PowerPoint/ODP-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Utdataformat: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Returnerar `202 Accepted`. Följ förloppet via SSE på `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Godkända indataformat: `.pptx`, `.ppt`, `.odp`. * Konverteringen hanteras av LibreOffice som körs utan grafiskt gränssnitt på servern. * Animationer och övergångseffekter bevaras kanske inte mellan format. * Utdataformatet måste skilja sig från indataformatet. --- --- url: https://docs.snapotter.com/th/tools/files/convert-presentation.md description: แปลงระหว่างรูปแบบงานนำเสนอ PowerPoint และ OpenDocument --- # Convert Presentation {#convert-presentation} แปลงงานนำเสนอระหว่างรูปแบบ PowerPoint (PPTX) และ OpenDocument Presentation (ODP) ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` รับข้อมูล multipart form ที่มีไฟล์ PowerPoint/ODP และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | รูปแบบผลลัพธ์: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} ส่งคืน `202 Accepted` ติดตามความคืบหน้าผ่าน SSE ที่ `/api/v1/jobs/{jobId}/progress` ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * รูปแบบอินพุตที่รับได้: `.pptx`, `.ppt`, `.odp` * การแปลงจัดการโดย LibreOffice ที่ทำงานแบบ headless บนเซิร์ฟเวอร์ * แอนิเมชันและเอฟเฟกต์การเปลี่ยนสไลด์อาจไม่คงอยู่ข้ามรูปแบบ * รูปแบบผลลัพธ์ต้องแตกต่างจากรูปแบบอินพุต --- --- url: https://docs.snapotter.com/tr/tools/files/convert-presentation.md description: PowerPoint ve OpenDocument sunum formatları arasında dönüştürün. --- # Convert Presentation {#convert-presentation} Sunumları PowerPoint (PPTX) ve OpenDocument Presentation (ODP) formatları arasında dönüştürün. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Bir PowerPoint/ODP dosyası ve JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Çıktı formatı: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} `202 Accepted` döndürür. İlerlemeyi `/api/v1/jobs/{jobId}/progress` adresinde SSE üzerinden izleyin. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Kabul edilen giriş formatları: `.pptx`, `.ppt`, `.odp`. * Dönüştürme, sunucuda başsız (headless) çalışan LibreOffice tarafından gerçekleştirilir. * Animasyonlar ve geçiş efektleri formatlar arasında korunmayabilir. * Çıktı formatı giriş formatından farklı olmalıdır. --- --- url: https://docs.snapotter.com/uk/tools/files/convert-presentation.md description: Конвертація між форматами презентацій PowerPoint та OpenDocument. --- # Convert Presentation {#convert-presentation} Конвертація презентацій між форматами PowerPoint (PPTX) та OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Приймає дані форми multipart з файлом PowerPoint/ODP та JSON-полем `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Формат виводу: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Повертає `202 Accepted`. Відстежуйте прогрес через SSE за адресою `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Прийнятні вхідні формати: `.pptx`, `.ppt`, `.odp`. * Конвертація обробляється LibreOffice, що працює в безголовому режимі на сервері. * Анімації та ефекти переходів можуть не зберегтися між форматами. * Формат виводу має відрізнятися від вхідного формату. --- --- url: https://docs.snapotter.com/vi/tools/files/convert-presentation.md description: Chuyển đổi giữa các định dạng bản trình bày PowerPoint và OpenDocument. --- # Convert Presentation {#convert-presentation} Chuyển đổi bản trình bày giữa các định dạng PowerPoint (PPTX) và OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Nhận dữ liệu multipart form với một tệp PowerPoint/ODP và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Định dạng đầu ra: `pptx`, `odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} Trả về `202 Accepted`. Theo dõi tiến trình qua SSE tại `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Các định dạng đầu vào được chấp nhận: `.pptx`, `.ppt`, `.odp`. * Việc chuyển đổi được xử lý bởi LibreOffice chạy ở chế độ headless trên máy chủ. * Hiệu ứng hoạt ảnh và chuyển cảnh có thể không được giữ nguyên giữa các định dạng. * Định dạng đầu ra phải khác với định dạng đầu vào. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/convert-presentation.md description: 在 PowerPoint 和 OpenDocument 演示文稿格式之间转换。 --- # Convert Presentation {#convert-presentation} 在 PowerPoint(PPTX)和 OpenDocument 演示文稿(ODP)格式之间转换演示文稿。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` 接受包含 PowerPoint/ODP 文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | 输出格式:`pptx`、`odp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Example Response {#example-response} 返回 `202 Accepted`。通过 `/api/v1/jobs/{jobId}/progress` 处的 SSE 跟踪进度。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 接受的输入格式:`.pptx`、`.ppt`、`.odp`。 * 转换由服务器上以无头模式运行的 LibreOffice 处理。 * 动画和过渡效果在不同格式之间可能无法保留。 * 输出格式必须与输入格式不同。 --- --- url: https://docs.snapotter.com/de/tools/files/convert-spreadsheet.md description: Konvertiert zwischen Excel-, OpenDocument- und CSV-Formaten. --- # Convert Spreadsheet {#convert-spreadsheet} Konvertiert Tabellenkalkulationen zwischen den Formaten Excel (XLSX), OpenDocument Spreadsheet (ODS) und CSV. Bei Arbeitsmappen mit mehreren Blättern wird beim Konvertieren nach CSV das erste Blatt exportiert. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Akzeptiert Multipart-Formulardaten mit einer Excel-/ODS-/CSV-Datei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Ausgabeformat: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Gibt `202 Accepted` zurück. Verfolge den Fortschritt per SSE unter `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akzeptierte Eingabeformate: `.xlsx`, `.xls`, `.ods`, `.csv`. * Beim Konvertieren einer Arbeitsmappe mit mehreren Blättern nach CSV wird nur das erste Blatt exportiert. * Formeln werden ausgewertet und als statische Werte in die CSV-Ausgabe exportiert. * Das Ausgabeformat muss sich vom Eingabeformat unterscheiden. --- --- url: https://docs.snapotter.com/hi/tools/files/convert-spreadsheet.md description: Excel, OpenDocument, और CSV फ़ॉर्मेट के बीच कन्वर्ट करें। --- # Convert Spreadsheet {#convert-spreadsheet} स्प्रेडशीट को Excel (XLSX), OpenDocument Spreadsheet (ODS), और CSV फ़ॉर्मेट के बीच कन्वर्ट करें। CSV में कन्वर्ट करते समय multi-sheet वर्कबुक पहली शीट को निर्यात करती हैं। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` एक Excel/ODS/CSV फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | आउटपुट फ़ॉर्मेट: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} `202 Accepted` लौटाता है। `/api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति को ट्रैक करें। ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * स्वीकृत इनपुट फ़ॉर्मेट: `.xlsx`, `.xls`, `.ods`, `.csv`। * multi-sheet वर्कबुक को CSV में कन्वर्ट करते समय, केवल पहली शीट निर्यात की जाती है। * CSV आउटपुट में फ़ॉर्मूले मूल्यांकित किए जाते हैं और स्थिर मानों के रूप में निर्यात किए जाते हैं। * आउटपुट फ़ॉर्मेट इनपुट फ़ॉर्मेट से भिन्न होना चाहिए। --- --- url: https://docs.snapotter.com/id/tools/files/convert-spreadsheet.md description: Konversi antar format Excel, OpenDocument, dan CSV. --- # Convert Spreadsheet {#convert-spreadsheet} Konversi spreadsheet antar format Excel (XLSX), OpenDocument Spreadsheet (ODS), dan CSV. Workbook multi-sheet mengekspor sheet pertama saat dikonversi ke CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Menerima multipart form data berisi file Excel/ODS/CSV dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Format output: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Mengembalikan `202 Accepted`. Lacak progres melalui SSE di `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Format input yang diterima: `.xlsx`, `.xls`, `.ods`, `.csv`. * Saat mengonversi workbook multi-sheet ke CSV, hanya sheet pertama yang diekspor. * Formula dievaluasi dan diekspor sebagai nilai statis dalam output CSV. * Format output harus berbeda dari format input. --- --- url: https://docs.snapotter.com/it/tools/files/convert-spreadsheet.md description: Converte tra i formati Excel, OpenDocument e CSV. --- # Convert Spreadsheet {#convert-spreadsheet} Converte i fogli di calcolo tra i formati Excel (XLSX), OpenDocument Spreadsheet (ODS) e CSV. Le cartelle di lavoro multi-foglio esportano il primo foglio quando si converte in CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Accetta dati form multipart con un file Excel/ODS/CSV e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Formato di output: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Formati di input accettati: `.xlsx`, `.xls`, `.ods`, `.csv`. * Quando si converte una cartella di lavoro multi-foglio in CSV, viene esportato solo il primo foglio. * Le formule vengono valutate ed esportate come valori statici nell'output CSV. * Il formato di output deve essere diverso dal formato di input. --- --- url: https://docs.snapotter.com/ja/tools/files/convert-spreadsheet.md description: Excel、OpenDocument、CSV の各形式間で変換します。 --- # Convert Spreadsheet {#convert-spreadsheet} スプレッドシートを Excel(XLSX)、OpenDocument Spreadsheet(ODS)、CSV の各形式間で変換します。複数シートのブックは、CSV に変換する際に最初のシートをエクスポートします。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Excel/ODS/CSV ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | 出力形式: `xlsx`、`ods`、`csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} `202 Accepted` を返します。`/api/v1/jobs/{jobId}/progress` の SSE で進捗を追跡します。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 受け付ける入力形式: `.xlsx`、`.xls`、`.ods`、`.csv`。 * 複数シートのブックを CSV に変換する場合、最初のシートのみがエクスポートされます。 * 数式は評価され、CSV 出力では静的な値としてエクスポートされます。 * 出力形式は入力形式と異なる必要があります。 --- --- url: https://docs.snapotter.com/nl/tools/files/convert-spreadsheet.md description: Converteer tussen Excel-, OpenDocument- en CSV-formaten. --- # Convert Spreadsheet {#convert-spreadsheet} Converteer spreadsheets tussen Excel (XLSX), OpenDocument Spreadsheet (ODS) en CSV-formaten. Werkmappen met meerdere bladen exporteren het eerste blad bij conversie naar CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Accepteert multipart-formulierdata met een Excel-/ODS-/CSV-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Uitvoerformaat: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Retourneert `202 Accepted`. Volg de voortgang via SSE op `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Geaccepteerde invoerformaten: `.xlsx`, `.xls`, `.ods`, `.csv`. * Bij conversie van een werkmap met meerdere bladen naar CSV wordt alleen het eerste blad geëxporteerd. * Formules worden geëvalueerd en als statische waarden geëxporteerd in de CSV-uitvoer. * Het uitvoerformaat moet verschillen van het invoerformaat. --- --- url: https://docs.snapotter.com/pl/tools/files/convert-spreadsheet.md description: Konwertuje między formatami Excel, OpenDocument i CSV. --- # Convert Spreadsheet {#convert-spreadsheet} Konwertuje arkusze kalkulacyjne między formatami Excel (XLSX), OpenDocument Spreadsheet (ODS) i CSV. Skoroszyty wieloarkuszowe eksportują pierwszy arkusz podczas konwersji do CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Przyjmuje dane formularza multipart z plikiem Excel/ODS/CSV oraz polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | format | string | Tak | - | Format wyjściowy: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Zwraca `202 Accepted`. Śledź postęp przez SSE pod `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akceptowane formaty wejściowe: `.xlsx`, `.xls`, `.ods`, `.csv`. * Podczas konwersji skoroszytu wieloarkuszowego do CSV eksportowany jest tylko pierwszy arkusz. * Formuły są obliczane i eksportowane jako wartości statyczne w wyniku CSV. * Format wyjściowy musi różnić się od formatu wejściowego. --- --- url: https://docs.snapotter.com/sv/tools/files/convert-spreadsheet.md description: Konvertera mellan formaten Excel, OpenDocument och CSV. --- # Convert Spreadsheet {#convert-spreadsheet} Konvertera kalkylblad mellan formaten Excel (XLSX), OpenDocument Spreadsheet (ODS) och CSV. Arbetsböcker med flera blad exporterar det första bladet vid konvertering till CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Tar emot multipart-formulärdata med en Excel/ODS/CSV-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Utdataformat: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Returnerar `202 Accepted`. Följ förloppet via SSE på `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Godkända indataformat: `.xlsx`, `.xls`, `.ods`, `.csv`. * Vid konvertering av en arbetsbok med flera blad till CSV exporteras endast det första bladet. * Formler beräknas och exporteras som statiska värden i CSV-utdata. * Utdataformatet måste skilja sig från indataformatet. --- --- url: https://docs.snapotter.com/th/tools/files/convert-spreadsheet.md description: แปลงระหว่างรูปแบบ Excel, OpenDocument และ CSV --- # Convert Spreadsheet {#convert-spreadsheet} แปลงสเปรดชีตระหว่างรูปแบบ Excel (XLSX), OpenDocument Spreadsheet (ODS) และ CSV เวิร์กบุ๊กหลายชีตจะส่งออกชีตแรกเมื่อแปลงเป็น CSV ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` รับข้อมูล multipart form ที่มีไฟล์ Excel/ODS/CSV และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | รูปแบบผลลัพธ์: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} ส่งคืน `202 Accepted` ติดตามความคืบหน้าผ่าน SSE ที่ `/api/v1/jobs/{jobId}/progress` ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * รูปแบบอินพุตที่รับได้: `.xlsx`, `.xls`, `.ods`, `.csv` * เมื่อแปลงเวิร์กบุ๊กหลายชีตเป็น CSV จะส่งออกเฉพาะชีตแรกเท่านั้น * สูตรจะถูกประเมินผลและส่งออกเป็นค่าคงที่ในผลลัพธ์ CSV * รูปแบบผลลัพธ์ต้องแตกต่างจากรูปแบบอินพุต --- --- url: https://docs.snapotter.com/tr/tools/files/convert-spreadsheet.md description: Excel, OpenDocument ve CSV formatları arasında dönüştürün. --- # Convert Spreadsheet {#convert-spreadsheet} Hesap tablolarını Excel (XLSX), OpenDocument Spreadsheet (ODS) ve CSV formatları arasında dönüştürün. Çok sayfalı çalışma kitapları CSV'ye dönüştürülürken ilk sayfayı dışa aktarır. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Bir Excel/ODS/CSV dosyası ve JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Çıktı formatı: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} `202 Accepted` döndürür. İlerlemeyi `/api/v1/jobs/{jobId}/progress` adresinde SSE üzerinden izleyin. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Kabul edilen giriş formatları: `.xlsx`, `.xls`, `.ods`, `.csv`. * Çok sayfalı bir çalışma kitabını CSV'ye dönüştürürken yalnızca ilk sayfa dışa aktarılır. * Formüller değerlendirilir ve CSV çıktısında statik değerler olarak dışa aktarılır. * Çıktı formatı giriş formatından farklı olmalıdır. --- --- url: https://docs.snapotter.com/uk/tools/files/convert-spreadsheet.md description: Конвертація між форматами Excel, OpenDocument та CSV. --- # Convert Spreadsheet {#convert-spreadsheet} Конвертація електронних таблиць між форматами Excel (XLSX), OpenDocument Spreadsheet (ODS) та CSV. Багатоаркушеві книги експортують перший аркуш під час конвертації в CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Приймає дані форми multipart з файлом Excel/ODS/CSV та JSON-полем `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Формат виводу: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Повертає `202 Accepted`. Відстежуйте прогрес через SSE за адресою `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Прийнятні вхідні формати: `.xlsx`, `.xls`, `.ods`, `.csv`. * Під час конвертації багатоаркушевої книги в CSV експортується лише перший аркуш. * Формули обчислюються та експортуються як статичні значення у виводі CSV. * Формат виводу має відрізнятися від вхідного формату. --- --- url: https://docs.snapotter.com/vi/tools/files/convert-spreadsheet.md description: Chuyển đổi giữa các định dạng Excel, OpenDocument và CSV. --- # Convert Spreadsheet {#convert-spreadsheet} Chuyển đổi bảng tính giữa các định dạng Excel (XLSX), OpenDocument Spreadsheet (ODS) và CSV. Sổ làm việc nhiều trang sẽ xuất trang đầu tiên khi chuyển sang CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Nhận dữ liệu multipart form với một tệp Excel/ODS/CSV và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Định dạng đầu ra: `xlsx`, `ods`, `csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} Trả về `202 Accepted`. Theo dõi tiến trình qua SSE tại `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Các định dạng đầu vào được chấp nhận: `.xlsx`, `.xls`, `.ods`, `.csv`. * Khi chuyển một sổ làm việc nhiều trang sang CSV, chỉ trang đầu tiên được xuất. * Công thức được tính toán và xuất dưới dạng giá trị tĩnh trong đầu ra CSV. * Định dạng đầu ra phải khác với định dạng đầu vào. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/convert-spreadsheet.md description: 在 Excel、OpenDocument 和 CSV 格式之间转换。 --- # Convert Spreadsheet {#convert-spreadsheet} 在 Excel(XLSX)、OpenDocument 电子表格(ODS)和 CSV 格式之间转换电子表格。多工作表工作簿在转换为 CSV 时会导出第一个工作表。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` 接受包含 Excel/ODS/CSV 文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | 输出格式:`xlsx`、`ods`、`csv` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Example Response {#example-response} 返回 `202 Accepted`。通过 `/api/v1/jobs/{jobId}/progress` 处的 SSE 跟踪进度。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 接受的输入格式:`.xlsx`、`.xls`、`.ods`、`.csv`。 * 将多工作表工作簿转换为 CSV 时,只导出第一个工作表。 * 公式会被求值,并在 CSV 输出中导出为静态值。 * 输出格式必须与输入格式不同。 --- --- url: https://docs.snapotter.com/hi/tools/files/to-epub.md description: Word, Markdown, HTML, या सादा टेक्स्ट फ़ाइलों को EPUB में बदलें। --- # Convert to EPUB {#convert-to-epub} Word दस्तावेज़, Markdown, HTML, या सादा टेक्स्ट फ़ाइलों को EPUB ई-बुक प्रारूप में बदलें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` एक Word/Markdown/HTML/TXT फ़ाइल के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} इस टूल में कोई कॉन्फ़िगर करने योग्य पैरामीटर नहीं है। एक दस्तावेज़ अपलोड करें और इसे EPUB में बदल दिया जाएगा। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} `202 Accepted` लौटाता है। `/api/v1/jobs/{jobId}/progress` पर SSE के ज़रिए प्रगति ट्रैक करें। ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * स्वीकृत इनपुट प्रारूप: `.docx`, `.md`, `.html`, `.txt`। * EPUB आउटपुट EPUB 3 विनिर्देश का पालन करता है। * स्रोत दस्तावेज़ के शीर्षकों का उपयोग सामग्री तालिका बनाने के लिए किया जाता है। * रूपांतरण सर्वर पर Pandoc द्वारा संभाला जाता है। --- --- url: https://docs.snapotter.com/ja/tools/files/to-epub.md description: Word、Markdown、HTML、またはプレーンテキストファイルを EPUB に変換します。 --- # Convert to EPUB {#convert-to-epub} Word ドキュメント、Markdown、HTML、またはプレーンテキストファイルを EPUB 電子書籍形式に変換します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` Word/Markdown/HTML/TXT ファイルを含むマルチパートフォームデータを受け付けます。 ## Parameters {#parameters} このツールに設定可能なパラメータはありません。ドキュメントをアップロードすると EPUB に変換されます。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} `202 Accepted` を返します。進捗は `/api/v1/jobs/{jobId}/progress` の SSE で追跡できます。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 受け付ける入力形式: `.docx`、`.md`、`.html`、`.txt`。 * EPUB 出力は EPUB 3 仕様に準拠します。 * ソースドキュメント内の見出しが目次の生成に使用されます。 * 変換はサーバー上の Pandoc によって処理されます。 --- --- url: https://docs.snapotter.com/ko/tools/files/to-epub.md description: Word, Markdown, HTML 또는 일반 텍스트 파일을 EPUB로 변환합니다. --- # Convert to EPUB {#convert-to-epub} Word 문서, Markdown, HTML 또는 일반 텍스트 파일을 EPUB 전자책 형식으로 변환합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/files/to-epub` Word/Markdown/HTML/TXT 파일이 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} 이 도구에는 구성 가능한 매개변수가 없습니다. 문서를 업로드하면 EPUB로 변환됩니다. ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## 응답 예시 {#example-response} `202 Accepted`을(를) 반환합니다. `/api/v1/jobs/{jobId}/progress`에서 SSE를 통해 진행 상황을 추적할 수 있습니다. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## 참고 사항 {#notes} * 허용되는 입력 형식: `.docx`, `.md`, `.html`, `.txt`. * EPUB 출력은 EPUB 3 사양을 따릅니다. * 소스 문서의 제목은 목차를 생성하는 데 사용됩니다. * 변환은 서버의 Pandoc이 처리합니다. --- --- url: https://docs.snapotter.com/th/tools/files/to-epub.md description: แปลงไฟล์ Word, Markdown, HTML หรือข้อความล้วนเป็น EPUB --- # Convert to EPUB {#convert-to-epub} แปลงเอกสาร Word, Markdown, HTML หรือไฟล์ข้อความล้วนเป็นรูปแบบหนังสืออิเล็กทรอนิกส์ EPUB ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` รับข้อมูลแบบ multipart form data พร้อมไฟล์ Word/Markdown/HTML/TXT ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์ที่กำหนดค่าได้ อัปโหลดเอกสารแล้วจะถูกแปลงเป็น EPUB ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} ส่งคืน `202 Accepted` ติดตามความคืบหน้าผ่าน SSE ที่ `/api/v1/jobs/{jobId}/progress` ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * รูปแบบไฟล์อินพุตที่รองรับ: `.docx`, `.md`, `.html`, `.txt` * เอาต์พุต EPUB เป็นไปตามข้อกำหนด EPUB 3 * หัวข้อในเอกสารต้นฉบับจะถูกใช้สร้างสารบัญ * การแปลงจัดการโดย Pandoc บนเซิร์ฟเวอร์ --- --- url: https://docs.snapotter.com/vi/tools/files/to-epub.md description: Chuyển đổi tệp Word, Markdown, HTML hoặc văn bản thuần sang EPUB. --- # Convert to EPUB {#convert-to-epub} Chuyển đổi tài liệu Word, Markdown, HTML hoặc tệp văn bản thuần sang định dạng sách điện tử EPUB. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` Chấp nhận dữ liệu biểu mẫu multipart với một tệp Word/Markdown/HTML/TXT. ## Parameters {#parameters} Công cụ này không có tham số nào có thể cấu hình. Tải lên một tài liệu và nó sẽ được chuyển đổi thành EPUB. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} Trả về `202 Accepted`. Theo dõi tiến trình qua SSE tại `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Các định dạng đầu vào được chấp nhận: `.docx`, `.md`, `.html`, `.txt`. * Đầu ra EPUB tuân theo đặc tả EPUB 3. * Các tiêu đề trong tài liệu nguồn được dùng để tạo mục lục. * Việc chuyển đổi được xử lý bởi Pandoc trên máy chủ. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/to-epub.md description: 将 Word、Markdown、HTML 或纯文本文件转换为 EPUB。 --- # Convert to EPUB {#convert-to-epub} 将 Word 文档、Markdown、HTML 或纯文本文件转换为 EPUB 电子书格式。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` 接受包含 Word/Markdown/HTML/TXT 文件的 multipart 表单数据。 ## Parameters {#parameters} 此工具没有可配置的参数。上传一个文档即可将其转换为 EPUB。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} 返回 `202 Accepted`。通过 `/api/v1/jobs/{jobId}/progress` 处的 SSE 跟踪进度。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 接受的输入格式:`.docx`、`.md`、`.html`、`.txt`。 * EPUB 输出遵循 EPUB 3 规范。 * 源文档中的标题用于生成目录。 * 转换由服务器上的 Pandoc 处理。 --- --- url: https://docs.snapotter.com/zh-TW/tools/files/to-epub.md description: 將 Word、Markdown、HTML 或純文字檔案轉換為 EPUB。 --- # Convert to EPUB {#convert-to-epub} 將 Word 文件、Markdown、HTML 或純文字檔案轉換為 EPUB 電子書格式。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` 接受包含 Word/Markdown/HTML/TXT 檔案的 multipart form data。 ## Parameters {#parameters} 此工具沒有可設定的參數。上傳一個文件,它就會被轉換為 EPUB。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} 回傳 `202 Accepted`。可透過 SSE 在 `/api/v1/jobs/{jobId}/progress` 追蹤進度。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 接受的輸入格式:`.docx`、`.md`、`.html`、`.txt`。 * EPUB 輸出遵循 EPUB 3 規範。 * 來源文件中的標題會用來產生目錄。 * 轉換由伺服器上的 Pandoc 處理。 --- --- url: https://docs.snapotter.com/ar/tools/video/convert-video.md description: تحويل مقاطع الفيديو بين MP4 وMOV وWebM وAVI وMKV. --- # Convert Video {#convert-video} تحويل مقاطع الفيديو بين صيغ MP4 وMOV وWebM وAVI وMKV مع إعدادات جودة مسبقة قابلة للتهيئة. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو وحقل JSON `settings`. هذه نقطة نهاية غير متزامنة - تُرجع `202 Accepted` فوراً ويُبَثّ التقدم عبر SSE على `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | صيغة الإخراج: `mp4` أو `mov` أو `webm` أو `avi` أو `mkv` | | quality | string | No | `"balanced"` | إعداد الجودة المسبق: `high` أو `balanced` أو `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * يُنتج إعداد الجودة المسبق `high` أفضل دقة صورة لكن بملفات أكبر. يضغط الإعداد المسبق `small` بقوة للحصول على أصغر حجم ملف. * يستخدم إخراج WebM ترميز VP9. يستخدم MP4 وMOV ترميز H.264. تتوفر AVI وMKV لسير العمل القديم أو الأرشفة. * تحديثات التقدم متاحة عبر SSE على `GET /api/v1/jobs/{jobId}/progress` حتى تكتمل المهمة. --- --- url: https://docs.snapotter.com/de/tools/video/convert-video.md description: Videos zwischen MP4, MOV, WebM, AVI und MKV konvertieren. --- # Convert Video {#convert-video} Videos zwischen den Formaten MP4, MOV, WebM, AVI und MKV mit konfigurierbaren Qualitätsvoreinstellungen konvertieren. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Nimmt Multipart-Formulardaten mit einer Videodatei und einem JSON-Feld `settings` entgegen. Dies ist ein asynchroner Endpunkt: Er gibt sofort `202 Accepted` zurück, und der Fortschritt wird per SSE unter `GET /api/v1/jobs/{jobId}/progress` gestreamt. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Ausgabeformat: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Qualitätsvoreinstellung: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Die Qualitätsvoreinstellung `high` erzeugt die beste visuelle Wiedergabetreue, aber größere Dateien. Die Voreinstellung `small` komprimiert aggressiv für minimale Dateigröße. * WebM-Ausgabe verwendet VP9-Kodierung. MP4 und MOV verwenden H.264. AVI und MKV sind für Legacy- oder Archivierungs-Workflows verfügbar. * Fortschrittsaktualisierungen sind per SSE unter `GET /api/v1/jobs/{jobId}/progress` verfügbar, bis der Job abgeschlossen ist. --- --- url: https://docs.snapotter.com/es/tools/video/convert-video.md description: Convierte vídeos entre MP4, MOV, WebM, AVI y MKV. --- # Convert Video {#convert-video} Convierte vídeos entre los formatos MP4, MOV, WebM, AVI y MKV con preajustes de calidad configurables. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Acepta datos de formulario multipart con un archivo de vídeo y un campo JSON `settings`. Este es un endpoint asíncrono: devuelve `202 Accepted` de inmediato y el progreso se transmite vía SSE en `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Formato de salida: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Preajuste de calidad: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * El preajuste de calidad `high` produce la mejor fidelidad visual, pero archivos más grandes. El preajuste `small` comprime de forma agresiva para lograr el tamaño de archivo mínimo. * La salida WebM usa codificación VP9. MP4 y MOV usan H.264. AVI y MKV están disponibles para flujos de trabajo heredados o de archivado. * Las actualizaciones de progreso están disponibles vía SSE en `GET /api/v1/jobs/{jobId}/progress` hasta que el trabajo se completa. --- --- url: https://docs.snapotter.com/fr/tools/video/convert-video.md description: Convertit des vidéos entre MP4, MOV, WebM, AVI et MKV. --- # Convert Video {#convert-video} Convertit des vidéos entre les formats MP4, MOV, WebM, AVI et MKV avec des préréglages de qualité configurables. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Accepte des données de formulaire multipart avec un fichier vidéo et un champ JSON `settings`. Il s'agit d'un point de terminaison asynchrone : il renvoie immédiatement `202 Accepted` et la progression est diffusée via SSE sur `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Format de sortie : `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Préréglage de qualité : `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Le préréglage de qualité `high` produit la meilleure fidélité visuelle mais des fichiers plus volumineux. Le préréglage `small` compresse agressivement pour une taille de fichier minimale. * La sortie WebM utilise l'encodage VP9. MP4 et MOV utilisent H.264. AVI et MKV sont disponibles pour les workflows hérités ou d'archivage. * Les mises à jour de progression sont disponibles via SSE sur `GET /api/v1/jobs/{jobId}/progress` jusqu'à la fin de la tâche. --- --- url: https://docs.snapotter.com/hi/tools/video/convert-video.md description: MP4, MOV, WebM, AVI, और MKV के बीच वीडियो कन्वर्ट करें। --- # Convert Video {#convert-video} समायोज्य गुणवत्ता प्रीसेट के साथ MP4, MOV, WebM, AVI, और MKV फ़ॉर्मैट के बीच वीडियो कन्वर्ट करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। यह एक async endpoint है - यह तुरंत `202 Accepted` लौटाता है और प्रगति `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से स्ट्रीम की जाती है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | आउटपुट फ़ॉर्मैट: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | गुणवत्ता प्रीसेट: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `high` गुणवत्ता प्रीसेट सबसे अच्छी दृश्य निष्ठा देता है लेकिन बड़ी फ़ाइलें बनाता है। `small` प्रीसेट न्यूनतम फ़ाइल आकार के लिए आक्रामक रूप से संपीड़ित करता है। * WebM आउटपुट VP9 encoding का उपयोग करता है। MP4 और MOV H.264 का उपयोग करते हैं। AVI और MKV लीगेसी या आर्काइवल वर्कफ़्लो के लिए उपलब्ध हैं। * जॉब पूरा होने तक `GET /api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति अपडेट उपलब्ध रहते हैं। --- --- url: https://docs.snapotter.com/id/tools/video/convert-video.md description: Mengonversi video antara MP4, MOV, WebM, AVI, dan MKV. --- # Convert Video {#convert-video} Mengonversi video antara format MP4, MOV, WebM, AVI, dan MKV dengan preset kualitas yang dapat dikonfigurasi. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Menerima multipart form data dengan file video dan field JSON `settings`. Ini adalah endpoint asinkron - ia langsung mengembalikan `202 Accepted` dan progres dialirkan melalui SSE di `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Format keluaran: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Preset kualitas: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Preset kualitas `high` menghasilkan ketepatan visual terbaik tetapi file lebih besar. Preset `small` mengompresi secara agresif untuk ukuran file minimum. * Keluaran WebM menggunakan enkoding VP9. MP4 dan MOV menggunakan H.264. AVI dan MKV tersedia untuk alur kerja lama atau pengarsipan. * Pembaruan progres tersedia melalui SSE di `GET /api/v1/jobs/{jobId}/progress` hingga job selesai. --- --- url: https://docs.snapotter.com/it/tools/video/convert-video.md description: Converti i video tra MP4, MOV, WebM, AVI e MKV. --- # Convert Video {#convert-video} Converti i video tra i formati MP4, MOV, WebM, AVI e MKV con preset di qualità configurabili. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Accetta dati form multipart con un file video e un campo JSON `settings`. Questo è un endpoint asincrono: restituisce `202 Accepted` immediatamente e l'avanzamento viene trasmesso tramite SSE su `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Formato di output: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Preset di qualità: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Il preset di qualità `high` produce la migliore fedeltà visiva ma file più grandi. Il preset `small` comprime in modo aggressivo per ottenere la dimensione minima del file. * L'output WebM usa la codifica VP9. MP4 e MOV usano H.264. AVI e MKV sono disponibili per flussi di lavoro legacy o di archiviazione. * Gli aggiornamenti sull'avanzamento sono disponibili tramite SSE su `GET /api/v1/jobs/{jobId}/progress` finché il job non è completato. --- --- url: https://docs.snapotter.com/ja/tools/video/convert-video.md description: 動画を MP4、MOV、WebM、AVI、MKV 間で変換します。 --- # Convert Video {#convert-video} 設定可能な品質プリセットで、動画を MP4、MOV、WebM、AVI、MKV フォーマット間で変換します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。これは非同期エンドポイントで、即座に `202 Accepted` を返し、進捗は `GET /api/v1/jobs/{jobId}/progress` の SSE でストリーミングされます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 出力フォーマット: `mp4`、`mov`、`webm`、`avi`、`mkv` | | quality | string | No | `"balanced"` | 品質プリセット: `high`、`balanced`、`small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `high` 品質プリセットは最良の視覚的忠実度を生み出しますが、ファイルは大きくなります。`small` プリセットは最小のファイルサイズを目指して積極的に圧縮します。 * WebM 出力は VP9 エンコードを使用します。MP4 と MOV は H.264 を使用します。AVI と MKV はレガシーまたはアーカイブ用途向けに利用できます。 * ジョブが完了するまで、進捗の更新は `GET /api/v1/jobs/{jobId}/progress` の SSE で確認できます。 --- --- url: https://docs.snapotter.com/ko/tools/video/convert-video.md description: MP4, MOV, WebM, AVI, MKV 사이에서 비디오를 변환합니다. --- # Convert Video {#convert-video} 구성 가능한 품질 프리셋과 함께 MP4, MOV, WebM, AVI, MKV 형식 사이에서 비디오를 변환합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` 비디오 파일과 JSON `settings` 필드가 담긴 multipart form data를 받습니다. 이 엔드포인트는 비동기입니다. 즉시 `202 Accepted`를 반환하고 진행 상황은 `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 스트리밍됩니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 출력 형식: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | 품질 프리셋: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `high` 품질 프리셋은 최상의 시각적 충실도를 제공하지만 파일이 더 큽니다. `small` 프리셋은 최소 파일 크기를 위해 적극적으로 압축합니다. * WebM 출력은 VP9 인코딩을 사용합니다. MP4와 MOV는 H.264를 사용합니다. AVI와 MKV는 레거시 또는 아카이브 워크플로용으로 제공됩니다. * 작업이 완료될 때까지 진행 상황 업데이트는 `GET /api/v1/jobs/{jobId}/progress`에서 SSE를 통해 제공됩니다. --- --- url: https://docs.snapotter.com/nl/tools/video/convert-video.md description: Video's converteren tussen MP4, MOV, WebM, AVI en MKV. --- # Convert Video {#convert-video} Converteer video's tussen de formaten MP4, MOV, WebM, AVI en MKV met instelbare kwaliteitspresets. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Accepteert multipart form data met een videobestand en een JSON-veld `settings`. Dit is een async endpoint: het retourneert direct `202 Accepted` en de voortgang wordt via SSE gestreamd op `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Nee | `"mp4"` | Uitvoerformaat: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | Nee | `"balanced"` | Kwaliteitspreset: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * De kwaliteitspreset `high` levert de beste visuele getrouwheid op, maar grotere bestanden. De preset `small` comprimeert agressief voor een minimale bestandsgrootte. * WebM-uitvoer gebruikt VP9-encoding. MP4 en MOV gebruiken H.264. AVI en MKV zijn beschikbaar voor legacy- of archiveringsworkflows. * Voortgangsupdates zijn beschikbaar via SSE op `GET /api/v1/jobs/{jobId}/progress` totdat de taak is voltooid. --- --- url: https://docs.snapotter.com/pl/tools/video/convert-video.md description: Konwersja wideo między MP4, MOV, WebM, AVI i MKV. --- # Convert Video {#convert-video} Konwertuje wideo między formatami MP4, MOV, WebM, AVI i MKV z konfigurowalnymi ustawieniami wstępnymi jakości. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Przyjmuje dane formularza multipart z plikiem wideo i polem JSON `settings`. To jest endpoint asynchroniczny - zwraca `202 Accepted` natychmiast, a postęp jest przesyłany strumieniowo przez SSE pod `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | format | string | Nie | `"mp4"` | Format wyjściowy: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | Nie | `"balanced"` | Ustawienie wstępne jakości: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Ustawienie wstępne jakości `high` zapewnia najlepszą wierność wizualną, ale większe pliki. Ustawienie wstępne `small` agresywnie kompresuje, aby uzyskać minimalny rozmiar pliku. * Wyjście WebM używa kodowania VP9. MP4 i MOV używają H.264. AVI i MKV są dostępne dla starszych lub archiwalnych przepływów pracy. * Aktualizacje postępu są dostępne przez SSE pod `GET /api/v1/jobs/{jobId}/progress` aż do zakończenia zadania. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/convert-video.md description: Converte vídeos entre MP4, MOV, WebM, AVI e MKV. --- # Convert Video {#convert-video} Converte vídeos entre os formatos MP4, MOV, WebM, AVI e MKV com presets de qualidade configuráveis. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. Este é um endpoint assíncrono - ele retorna `202 Accepted` imediatamente e o progresso é transmitido via SSE em `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Não | `"mp4"` | Formato de saída: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | Não | `"balanced"` | Preset de qualidade: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * O preset de qualidade `high` produz a melhor fidelidade visual, mas arquivos maiores. O preset `small` comprime de forma agressiva para o menor tamanho de arquivo. * A saída WebM usa codificação VP9. MP4 e MOV usam H.264. AVI e MKV estão disponíveis para fluxos de trabalho legados ou de arquivamento. * As atualizações de progresso ficam disponíveis via SSE em `GET /api/v1/jobs/{jobId}/progress` até que o job seja concluído. --- --- url: https://docs.snapotter.com/ru/tools/video/convert-video.md description: Конвертация видео между форматами MP4, MOV, WebM, AVI и MKV. --- # Convert Video {#convert-video} Конвертация видео между форматами MP4, MOV, WebM, AVI и MKV с настраиваемыми пресетами качества. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Принимает multipart form data с файлом видео и полем JSON `settings`. Это асинхронная конечная точка: она сразу возвращает `202 Accepted`, а прогресс передаётся через SSE по адресу `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Выходной формат: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Пресет качества: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Пресет качества `high` обеспечивает лучшую визуальную точность, но файлы получаются больше. Пресет `small` агрессивно сжимает для минимального размера файла. * Вывод в WebM использует кодирование VP9. MP4 и MOV используют H.264. AVI и MKV доступны для устаревших или архивных рабочих процессов. * Обновления прогресса доступны через SSE по адресу `GET /api/v1/jobs/{jobId}/progress` до завершения задания. --- --- url: https://docs.snapotter.com/th/tools/video/convert-video.md description: แปลงวิดีโอระหว่าง MP4, MOV, WebM, AVI และ MKV --- # Convert Video {#convert-video} แปลงวิดีโอระหว่างรูปแบบ MP4, MOV, WebM, AVI และ MKV พร้อมพรีเซ็ตคุณภาพที่กำหนดค่าได้ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` นี่คือ endpoint แบบ async โดยจะคืนค่า `202 Accepted` ทันที และความคืบหน้าจะถูกสตรีมผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | รูปแบบเอาต์พุต: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | พรีเซ็ตคุณภาพ: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * พรีเซ็ตคุณภาพ `high` ให้ความคมชัดของภาพดีที่สุดแต่ไฟล์ใหญ่กว่า ส่วนพรีเซ็ต `small` บีบอัดอย่างมากเพื่อขนาดไฟล์ที่เล็กที่สุด * เอาต์พุต WebM ใช้การเข้ารหัส VP9 ส่วน MP4 และ MOV ใช้ H.264 ส่วน AVI และ MKV มีให้ใช้สำหรับเวิร์กโฟลว์แบบเก่าหรือการเก็บถาวร * การอัปเดตความคืบหน้าดูได้ผ่าน SSE ที่ `GET /api/v1/jobs/{jobId}/progress` จนกว่างานจะเสร็จสมบูรณ์ --- --- url: https://docs.snapotter.com/tr/tools/video/convert-video.md description: Videoları MP4, MOV, WebM, AVI ve MKV arasında dönüştürün. --- # Convert Video {#convert-video} Videoları yapılandırılabilir kalite ön ayarlarıyla MP4, MOV, WebM, AVI ve MKV formatları arasında dönüştürün. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Bir video dosyası ve bir JSON `settings` alanı içeren multipart form data kabul eder. Bu asenkron bir uç noktadır; hemen `202 Accepted` döndürür ve ilerleme `GET /api/v1/jobs/{jobId}/progress` adresinde SSE ile aktarılır. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Çıktı formatı: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Kalite ön ayarı: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `high` kalite ön ayarı en iyi görsel doğruluğu üretir ancak daha büyük dosyalar oluşturur. `small` ön ayarı ise en küçük dosya boyutu için agresif şekilde sıkıştırır. * WebM çıktısı VP9 kodlaması kullanır. MP4 ve MOV, H.264 kullanır. AVI ve MKV, eski veya arşivleme iş akışları için mevcuttur. * İş tamamlanana kadar ilerleme güncellemeleri `GET /api/v1/jobs/{jobId}/progress` adresinde SSE ile sunulur. --- --- url: https://docs.snapotter.com/uk/tools/video/convert-video.md description: Конвертує відео між MP4, MOV, WebM, AVI та MKV. --- # Convert Video {#convert-video} Конвертує відео між форматами MP4, MOV, WebM, AVI та MKV із налаштовуваними пресетами якості. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Приймає дані форми multipart із відеофайлом і полем JSON `settings`. Це асинхронний ендпоінт: він одразу повертає `202 Accepted`, а прогрес передається через SSE за адресою `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Вихідний формат: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Пресет якості: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Пресет якості `high` дає найкращу візуальну точність, але більші файли. Пресет `small` агресивно стискає для мінімального розміру файлу. * Вихід у WebM використовує кодування VP9. MP4 і MOV використовують H.264. AVI та MKV доступні для застарілих або архівних робочих процесів. * Оновлення прогресу доступні через SSE за адресою `GET /api/v1/jobs/{jobId}/progress` до завершення завдання. --- --- url: https://docs.snapotter.com/vi/tools/video/convert-video.md description: Chuyển đổi video giữa MP4, MOV, WebM, AVI và MKV. --- # Convert Video {#convert-video} Chuyển đổi video giữa các định dạng MP4, MOV, WebM, AVI và MKV với các preset chất lượng có thể cấu hình. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` Nhận multipart form data gồm một file video và một trường JSON `settings`. Đây là endpoint bất đồng bộ - nó trả về `202 Accepted` ngay lập tức và tiến độ được truyền qua SSE tại `GET /api/v1/jobs/{jobId}/progress`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Định dạng đầu ra: `mp4`, `mov`, `webm`, `avi`, `mkv` | | quality | string | No | `"balanced"` | Preset chất lượng: `high`, `balanced`, `small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Preset chất lượng `high` tạo ra độ trung thực hình ảnh tốt nhất nhưng file lớn hơn. Preset `small` nén mạnh để có kích thước file nhỏ nhất. * Đầu ra WebM dùng mã hóa VP9. MP4 và MOV dùng H.264. AVI và MKV có sẵn cho các quy trình cũ hoặc lưu trữ. * Cập nhật tiến độ có sẵn qua SSE tại `GET /api/v1/jobs/{jobId}/progress` cho đến khi tác vụ hoàn tất. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/convert-video.md description: 在 MP4、MOV、WebM、AVI 和 MKV 之间转换视频。 --- # Convert Video {#convert-video} 在 MP4、MOV、WebM、AVI 和 MKV 格式之间转换视频,并可配置质量预设。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` 接受包含视频文件和 JSON `settings` 字段的 multipart 表单数据。这是一个异步端点:它会立即返回 `202 Accepted`,进度通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 处流式传输。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 输出格式:`mp4`、`mov`、`webm`、`avi`、`mkv` | | quality | string | No | `"balanced"` | 质量预设:`high`、`balanced`、`small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `high` 质量预设可获得最佳视觉保真度,但文件较大。`small` 预设会激进压缩以获得最小文件大小。 * WebM 输出使用 VP9 编码。MP4 和 MOV 使用 H.264。AVI 和 MKV 可用于传统或归档工作流。 * 在任务完成前,可通过 SSE 在 `GET /api/v1/jobs/{jobId}/progress` 处获取进度更新。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/convert-video.md description: 在 MP4、MOV、WebM、AVI 和 MKV 之間轉換影片。 --- # Convert Video {#convert-video} 在 MP4、MOV、WebM、AVI 和 MKV 格式之間轉換影片,並可設定品質預設。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/convert-video` 接受包含一個影片檔案和一個 JSON `settings` 欄位的 multipart form data。這是一個非同步端點,它會立即回傳 `202 Accepted`,進度則透過 SSE 於 `GET /api/v1/jobs/{jobId}/progress` 串流傳送。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 輸出格式:`mp4`、`mov`、`webm`、`avi`、`mkv` | | quality | string | No | `"balanced"` | 品質預設:`high`、`balanced`、`small` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/convert-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "webm", "quality": "balanced"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * `high` 品質預設會產生最佳的視覺保真度,但檔案較大。`small` 預設則會積極壓縮以取得最小的檔案大小。 * WebM 輸出使用 VP9 編碼。MP4 和 MOV 使用 H.264。AVI 和 MKV 可用於舊有或封存工作流程。 * 在工作完成之前,可透過 SSE 於 `GET /api/v1/jobs/{jobId}/progress` 取得進度更新。 --- --- url: https://docs.snapotter.com/pt-BR/tools/files/convert-presentation.md description: Converta entre os formatos de apresentação PowerPoint e OpenDocument. --- # Converter Apresentação {#convert-presentation} Converta apresentações entre os formatos PowerPoint (PPTX) e OpenDocument Presentation (ODP). ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Aceita dados de formulário multipart com um arquivo PowerPoint/ODP e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Sim | - | Formato de saída: `pptx`, `odp` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Exemplo de Resposta {#example-response} Retorna `202 Accepted`. Acompanhe o progresso via SSE em `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceitos: `.pptx`, `.ppt`, `.odp`. * A conversão é realizada pelo LibreOffice executando em modo headless no servidor. * Animações e efeitos de transição podem não ser preservados entre os formatos. * O formato de saída deve ser diferente do formato de entrada. --- --- url: https://docs.snapotter.com/pt-BR/tools/audio/convert-audio.md description: Converta áudio entre os formatos MP3, WAV, OGG, FLAC e M4A. --- # Converter Áudio {#convert-audio} Converta arquivos de áudio entre formatos comuns, incluindo MP3, WAV, OGG, FLAC e M4A, com bitrate de saída e taxa de amostragem configuráveis. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Aceita dados de formulário multipart com um arquivo de áudio e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Não | `"mp3"` | Formato de saída: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Não | `192` | Bitrate de saída em kbps (32 a 320) | | sampleRate | integer | Não | taxa original | Taxa de amostragem de saída em Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` ou `96000`. Omita para manter a taxa original | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Notas {#notes} * Os formatos de entrada suportados incluem MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF e OPUS. * O bitrate só se aplica a formatos com perda (MP3, OGG, M4A). Formatos sem perda como WAV e FLAC ignoram essa configuração. * A saída em MP3 suporta taxas de amostragem de até 48000 Hz. A opção de 96000 Hz só se aplica a WAV, OGG, FLAC e M4A. * O bitrate do MP3 é limitado pela taxa de amostragem: no máximo 64 kbps a 8000 Hz e 160 kbps a 16000 ou 22050 Hz. Requisições acima do limite são rejeitadas em vez de serem reduzidas silenciosamente. * O nome do arquivo de saída mantém o nome original com a nova extensão. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/epub-convert.md description: Converta um EPUB para PDF, DOCX, HTML ou Markdown. --- # Converter de EPUB {#convert-epub} Converta um e-book EPUB para PDF, Word (DOCX), HTML ou Markdown. Recursos remotos dentro do livro não são buscados. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Aceita dados de formulário multipart com um arquivo EPUB e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Sim | - | Formato de saída: `pdf`, `docx`, `html`, `md` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Exemplo de Resposta {#example-response} Retorna `202 Accepted`. Acompanhe o progresso via SSE em `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formato de entrada aceito: `.epub`. * Recursos remotos incorporados no EPUB (imagens e fontes externas) não são buscados por segurança. * A fidelidade das imagens na saída convertida pode variar dependendo da estrutura do EPUB. * A conversão é realizada pelo Pandoc no servidor. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/convert-document.md description: Converta entre os formatos Word, OpenDocument, RTF e texto simples. --- # Converter Documento {#convert-document} Converta documentos entre os formatos Word (DOCX), OpenDocument (ODT), RTF e texto simples usando o LibreOffice. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/convert-document` Aceita dados de formulário multipart com um arquivo Word/ODT/RTF/TXT e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Sim | - | Formato de saída: `docx`, `odt`, `rtf`, `txt` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Exemplo de Resposta {#example-response} Retorna `202 Accepted`. Acompanhe o progresso via SSE em `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceitos: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * A conversão é realizada pelo LibreOffice executando em modo headless no servidor. * Formatações complexas (macros, objetos incorporados) podem não sobreviver à conversão entre formatos. * O formato de saída deve ser diferente do formato de entrada. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/convert.md description: >- Converta imagens entre formatos, incluindo formatos modernos como AVIF, JXL e HEIC. --- # Converter Imagem {#convert} Converta imagens entre formatos. Suporta formatos web comuns, bem como formatos especializados como HEIC, JXL, BMP, ICO, JP2, QOI e PSD. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/convert` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Sim | - | Formato alvo: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | Não | - | Qualidade de saída (1-100). Aplica-se a formatos com perdas como jpg, webp, avif, heic. | ## Formatos de Saída Suportados {#supported-output-formats} | Formato | Tipo | Notas | |--------|------|-------| | jpg | Com perdas | JPEG, melhor compatibilidade | | png | Sem perdas | Suporta transparência | | webp | Ambos | Formato web moderno, boa compressão | | avif | Com perdas | Formato de nova geração, excelente compressão | | tiff | Ambos | Fluxos de trabalho de impressão/publicação | | gif | Sem perdas | Limitado a 256 cores | | heic / heif | Com perdas | Formato do ecossistema Apple | | jxl | Ambos | JPEG XL, formato de nova geração | | bmp | Sem perdas | Bitmap não comprimido | | ico | Sem perdas | Formato de ícone do Windows | | jp2 | Com perdas | JPEG 2000 | | qoi | Sem perdas | Formato Quite OK Image | | psd | Em camadas | Adobe Photoshop (requer ImageMagick) | | ppm | Sem perdas | Portable Pixmap (PPM/PGM/PBM) | | eps | Vetor | Encapsulated PostScript | | tga | Sem perdas | Formato de imagem Targa | ## Exemplo de Requisição {#example-request} Converter para WebP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` Converter para PNG (sem perdas): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Notas {#notes} * A extensão do nome do arquivo de saída é atualizada automaticamente para corresponder ao formato alvo. * Entradas SVG são rasterizadas a 300 DPI antes da conversão. * A conversão para PSD requer que o ImageMagick esteja instalado no servidor. * BMP, EPS, ICO, JP2, JXL, PPM, QOI e TGA usam codificadores de CLI especializados e contornam o processamento do Sharp. * A codificação HEIC/HEIF usa a biblioteca codificadora HEIC do sistema. * Os formatos de entrada são amplos: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, etc.), PSD, SVG, BMP e mais. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/to-epub.md description: Converta arquivos Word, Markdown, HTML ou texto simples em EPUB. --- # Converter para EPUB {#convert-to-epub} Converta documentos do Word, Markdown, HTML ou arquivos de texto simples no formato de e-book EPUB. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` Aceita dados de formulário multipart com um arquivo Word/Markdown/HTML/TXT. ## Parâmetros {#parameters} Esta ferramenta não tem parâmetros configuráveis. Envie um documento e ele será convertido em EPUB. ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Exemplo de Resposta {#example-response} Retorna `202 Accepted`. Acompanhe o progresso via SSE em `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Observações {#notes} * Formatos de entrada aceitos: `.docx`, `.md`, `.html`, `.txt`. * A saída EPUB segue a especificação EPUB 3. * Os títulos no documento de origem são usados para gerar o sumário. * A conversão é feita pelo Pandoc no servidor. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/convert-spreadsheet.md description: Converta entre os formatos Excel, OpenDocument e CSV. --- # Converter Planilha {#convert-spreadsheet} Converta planilhas entre os formatos Excel (XLSX), OpenDocument Spreadsheet (ODS) e CSV. Pastas de trabalho com várias planilhas exportam a primeira planilha ao converter para CSV. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Aceita dados de formulário multipart com um arquivo Excel/ODS/CSV e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Sim | - | Formato de saída: `xlsx`, `ods`, `csv` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Exemplo de Resposta {#example-response} Retorna `202 Accepted`. Acompanhe o progresso via SSE em `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceitos: `.xlsx`, `.xls`, `.ods`, `.csv`. * Ao converter uma pasta de trabalho com várias planilhas para CSV, apenas a primeira planilha é exportada. * Fórmulas são avaliadas e exportadas como valores estáticos na saída CSV. * O formato de saída deve ser diferente do formato de entrada. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/yaml-json.md description: Converta entre YAML e JSON, nos dois sentidos. --- # Converter YAML / JSON {#yaml-json} Converta entre os formatos YAML e JSON nos dois sentidos. Envie um arquivo YAML para obter JSON, ou envie um arquivo JSON para obter YAML. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/yaml-json` Aceita dados de formulário multipart com um arquivo YAML ou JSON. Não é necessário nenhum campo de configurações. ## Parâmetros {#parameters} Esta ferramenta não tem parâmetros configuráveis. O sentido da conversão é determinado pela extensão do arquivo de entrada. ## Exemplo de Requisição {#example-request} YAML para JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.yaml" ``` JSON para YAML: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.json" ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.json", "originalSize": 620, "processedSize": 780 } ``` ## Observações {#notes} * O sentido da conversão é detectado automaticamente pela extensão do arquivo de entrada: `.yaml` ou `.yml` produz `.json`, e `.json` produz `.yaml`. * Ambas as extensões `.yaml` e `.yml` são aceitas. * Apenas o primeiro documento de um arquivo YAML com múltiplos documentos é convertido; documentos adicionais separados por `---` são ignorados. --- --- url: https://docs.snapotter.com/nl/tools/files/to-epub.md description: Converteer Word-, Markdown-, HTML- of platte-tekstbestanden naar EPUB. --- # Converteren naar EPUB {#convert-to-epub} Converteer Word-documenten, Markdown, HTML of platte-tekstbestanden naar het EPUB-e-boekformaat. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` Accepteert multipart form data met een Word/Markdown/HTML/TXT-bestand. ## Parameters {#parameters} Deze tool heeft geen instelbare parameters. Upload een document en het wordt naar EPUB geconverteerd. ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Voorbeeldantwoord {#example-response} Retourneert `202 Accepted`. Volg de voortgang via SSE op `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Opmerkingen {#notes} * Geaccepteerde invoerformaten: `.docx`, `.md`, `.html`, `.txt`. * De EPUB-uitvoer volgt de EPUB 3-specificatie. * Koppen in het bronddocument worden gebruikt om de inhoudsopgave te genereren. * De conversie wordt uitgevoerd door Pandoc op de server. --- --- url: https://docs.snapotter.com/nl/tools/files/epub-convert.md description: Converteer een EPUB naar PDF, DOCX, HTML of Markdown. --- # Converteren vanuit EPUB {#convert-epub} Converteer een EPUB-e-book naar PDF, Word (DOCX), HTML of Markdown. Externe bronnen binnen het boek worden niet opgehaald. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Accepteert multipart-formulierdata met een EPUB-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Ja | - | Uitvoerformaat: `pdf`, `docx`, `html`, `md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} Retourneert `202 Accepted`. Volg de voortgang via SSE op `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Geaccepteerd invoerformaat: `.epub`. * Externe bronnen die in de EPUB zijn ingesloten (externe afbeeldingen, lettertypen) worden om veiligheidsredenen niet opgehaald. * De afbeeldingskwaliteit in de geconverteerde uitvoer kan variëren afhankelijk van de EPUB-structuur. * De conversie wordt uitgevoerd door Pandoc op de server. --- --- url: https://docs.snapotter.com/it/tools/audio/convert-audio.md description: Converti l'audio tra i formati MP3, WAV, OGG, FLAC e M4A. --- # Converti audio {#convert-audio} Converti i file audio tra i formati comuni tra cui MP3, WAV, OGG, FLAC e M4A, con bitrate di output e frequenza di campionamento configurabili. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Accetta dati di form multipart con un file audio e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Formato di output: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | No | `192` | Bitrate di output in kbps (da 32 a 320) | | sampleRate | integer | No | frequenza originale | Frequenza di campionamento di output in Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` o `96000`. Ometti per mantenere la frequenza originale | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Note {#notes} * I formati di input supportati includono MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF e OPUS. * Il bitrate si applica solo ai formati con perdita (MP3, OGG, M4A). I formati senza perdita come WAV e FLAC ignorano questa impostazione. * L'output MP3 supporta frequenze di campionamento fino a 48000 Hz. L'opzione 96000 Hz si applica solo a WAV, OGG, FLAC e M4A. * Il bitrate MP3 è limitato dalla frequenza di campionamento: al massimo 64 kbps a 8000 Hz e 160 kbps a 16000 o 22050 Hz. Le richieste superiori al limite vengono rifiutate invece di essere ridotte silenziosamente. * Il nome del file di output mantiene il nome originale con la nuova estensione. --- --- url: https://docs.snapotter.com/it/tools/files/epub-convert.md description: Converte un EPUB in PDF, DOCX, HTML o Markdown. --- # Converti da EPUB {#convert-epub} Converte un e-book EPUB in PDF, Word (DOCX), HTML o Markdown. Le risorse remote all'interno del libro non vengono recuperate. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Accetta dati form multipart con un file EPUB e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Formato di output: `pdf`, `docx`, `html`, `md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Formato di input accettato: `.epub`. * Le risorse remote incorporate nell'EPUB (immagini e font esterni) non vengono recuperate per motivi di sicurezza. * La fedeltà delle immagini nell'output convertito può variare a seconda della struttura dell'EPUB. * La conversione è gestita da Pandoc sul server. --- --- url: https://docs.snapotter.com/it/tools/image/convert.md description: Converti immagini tra formati, inclusi formati moderni come AVIF, JXL e HEIC. --- # Converti Immagine {#convert} Converti immagini tra formati. Supporta i formati web comuni oltre a formati specializzati come HEIC, JXL, BMP, ICO, JP2, QOI e PSD. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/convert` Accetta dati di form multipart con un file immagine e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | format | string | Sì | - | Formato di destinazione: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | No | - | Qualità di output (1-100). Si applica ai formati con perdita come jpg, webp, avif, heic. | ## Formati di output supportati {#supported-output-formats} | Formato | Tipo | Note | |--------|------|-------| | jpg | Con perdita | JPEG, migliore compatibilità | | png | Senza perdita | Supporta la trasparenza | | webp | Entrambi | Formato web moderno, buona compressione | | avif | Con perdita | Formato di nuova generazione, compressione eccellente | | tiff | Entrambi | Flussi di lavoro per stampa/editoria | | gif | Senza perdita | Limitato a 256 colori | | heic / heif | Con perdita | Formato dell'ecosistema Apple | | jxl | Entrambi | JPEG XL, formato di nuova generazione | | bmp | Senza perdita | Bitmap non compressa | | ico | Senza perdita | Formato icona di Windows | | jp2 | Con perdita | JPEG 2000 | | qoi | Senza perdita | Formato Quite OK Image | | psd | A livelli | Adobe Photoshop (richiede ImageMagick) | | ppm | Senza perdita | Portable Pixmap (PPM/PGM/PBM) | | eps | Vettoriale | Encapsulated PostScript | | tga | Senza perdita | Formato immagine Targa | ## Esempio di richiesta {#example-request} Converti in WebP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` Converti in PNG (senza perdita): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Note {#notes} * L'estensione del nome del file di output viene aggiornata automaticamente per corrispondere al formato di destinazione. * Gli input SVG vengono rasterizzati a 300 DPI prima della conversione. * La conversione PSD richiede che ImageMagick sia installato sul server. * BMP, EPS, ICO, JP2, JXL, PPM, QOI e TGA usano encoder CLI specializzati e bypassano l'elaborazione di Sharp. * La codifica HEIC/HEIF usa la libreria di codifica HEIC di sistema. * I formati di input sono ampi: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, ecc.), PSD, SVG, BMP e altri. --- --- url: https://docs.snapotter.com/it/tools/files/to-epub.md description: Converte file Word, Markdown, HTML o testo semplice in EPUB. --- # Converti in EPUB {#convert-to-epub} Converte documenti Word, Markdown, HTML o file di testo semplice nel formato e-book EPUB. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/files/to-epub` Accetta dati di form multipart con un file Word/Markdown/HTML/TXT. ## Parametri {#parameters} Questo strumento non ha parametri configurabili. Carica un documento e verrà convertito in EPUB. ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Esempio di risposta {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Note {#notes} * Formati di input accettati: `.docx`, `.md`, `.html`, `.txt`. * L'output EPUB segue la specifica EPUB 3. * Le intestazioni del documento di origine vengono usate per generare l'indice. * La conversione è gestita da Pandoc sul server. --- --- url: https://docs.snapotter.com/it/tools/files/yaml-json.md description: Converte tra YAML e JSON, in entrambe le direzioni. --- # Converti YAML / JSON {#yaml-json} Converte tra i formati YAML e JSON in entrambe le direzioni. Carica un file YAML per ottenere JSON, oppure carica un file JSON per ottenere YAML. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/files/yaml-json` Accetta dati di form multipart con un file YAML o JSON. Non è richiesto alcun campo di impostazioni. ## Parametri {#parameters} Questo strumento non ha parametri configurabili. La direzione della conversione è determinata dall'estensione del file di input. ## Esempio di richiesta {#example-request} Da YAML a JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.yaml" ``` Da JSON a YAML: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.json" ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.json", "originalSize": 620, "processedSize": 780 } ``` ## Note {#notes} * La direzione della conversione viene rilevata automaticamente dall'estensione del file di input: `.yaml` o `.yml` produce `.json`, e `.json` produce `.yaml`. * Sono accettate entrambe le estensioni `.yaml` e `.yml`. * Viene convertito solo il primo documento in un file YAML multi-documento; i documenti aggiuntivi separati da `---` vengono ignorati. --- --- url: https://docs.snapotter.com/es/tools/image/gif-webp.md description: Convierte GIF animados a WebP y viceversa, conservando todos los fotogramas. --- # Convertidor GIF/WebP {#gif-webp-converter} Convierte archivos GIF animados a WebP y viceversa, conservando todos los fotogramas y la sincronización de la animación. Las animaciones WebP suelen ser entre un 25 % y un 35 % más pequeñas que los GIF equivalentes. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Acepta datos de formulario multipart con un archivo GIF o WebP y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | quality | integer | No | `80` | Calidad de salida para la codificación WebP (1-100) | | lossless | boolean | No | `false` | Usar compresión WebP sin pérdidas | | resizePercent | integer | No | `100` | Escalar la salida por porcentaje (10-100) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Notas {#notes} * Solo se aceptan archivos `.gif` y `.webp`. Esta herramienta no admite otros formatos de imagen. * La dirección de la conversión es automática: la entrada GIF produce una salida WebP, y la entrada WebP produce una salida GIF. * Las opciones `quality` y `lossless` solo se aplican al codificar a WebP. Al convertir a GIF, la salida usa la paleta GIF estándar. * Usa `resizePercent` para reducir las dimensiones (y el tamaño del archivo) de las animaciones grandes. --- --- url: https://docs.snapotter.com/es/tools/files/to-epub.md description: Convierte archivos de Word, Markdown, HTML o texto plano a EPUB. --- # Convertir a EPUB {#convert-to-epub} Convierte documentos de Word, Markdown, HTML o archivos de texto plano al formato de libro electrónico EPUB. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/to-epub` Acepta datos de formulario multipart con un archivo Word/Markdown/HTML/TXT. ## Parameters {#parameters} Esta herramienta no tiene parámetros configurables. Sube un documento y se convertirá a EPUB. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Example Response {#example-response} Devuelve `202 Accepted`. Sigue el progreso mediante SSE en `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Formatos de entrada aceptados: `.docx`, `.md`, `.html`, `.txt`. * La salida EPUB sigue la especificación EPUB 3. * Los encabezados del documento de origen se usan para generar la tabla de contenidos. * La conversión la realiza Pandoc en el servidor. --- --- url: https://docs.snapotter.com/es/tools/audio/convert-audio.md description: Convierte audio entre los formatos MP3, WAV, OGG, FLAC y M4A. --- # Convertir audio {#convert-audio} Convierte archivos de audio entre formatos comunes como MP3, WAV, OGG, FLAC y M4A, con tasa de bits y frecuencia de muestreo de salida configurables. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Formato de salida: `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | No | `192` | Tasa de bits de salida en kbps (32 a 320) | | sampleRate | integer | No | frecuencia de origen | Frecuencia de muestreo de salida en Hz: `8000`, `16000`, `22050`, `32000`, `44100`, `48000` o `96000`. Omítelo para conservar la frecuencia de origen | ## Solicitud de ejemplo {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Respuesta de ejemplo {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Notas {#notes} * Los formatos de entrada admitidos incluyen MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF y OPUS. * La tasa de bits solo se aplica a los formatos con pérdida (MP3, OGG, M4A). Los formatos sin pérdida como WAV y FLAC ignoran esta configuración. * La salida MP3 admite frecuencias de muestreo de hasta 48000 Hz. La opción de 96000 Hz solo se aplica a WAV, OGG, FLAC y M4A. * La tasa de bits de MP3 está limitada por la frecuencia de muestreo: como máximo 64 kbps a 8000 Hz y 160 kbps a 16000 o 22050 Hz. Las solicitudes por encima del límite se rechazan en lugar de reducirse silenciosamente. * El nombre del archivo de salida conserva el nombre original con la nueva extensión. --- --- url: https://docs.snapotter.com/fr/tools/files/epub-convert.md description: Convertit un EPUB en PDF, DOCX, HTML ou Markdown. --- # Convertir depuis EPUB {#convert-epub} Convertit un livre électronique EPUB en PDF, Word (DOCX), HTML ou Markdown. Les ressources distantes contenues dans le livre ne sont pas récupérées. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Accepte des données de formulaire multipart avec un fichier EPUB et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | format | string | Oui | - | Format de sortie : `pdf`, `docx`, `html`, `md` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Exemple de réponse {#example-response} Renvoie `202 Accepted`. Suivez la progression via SSE à `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Remarques {#notes} * Format d'entrée accepté : `.epub`. * Les ressources distantes intégrées dans l'EPUB (images externes, polices) ne sont pas récupérées pour des raisons de sécurité. * La fidélité des images dans la sortie convertie peut varier selon la structure de l'EPUB. * La conversion est effectuée par Pandoc sur le serveur. --- --- url: https://docs.snapotter.com/es/tools/files/epub-convert.md description: Convierte un EPUB a PDF, DOCX, HTML o Markdown. --- # Convertir desde EPUB {#convert-epub} Convierte un libro electrónico EPUB a PDF, Word (DOCX), HTML o Markdown. Los recursos remotos dentro del libro no se descargan. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Acepta datos de formulario multipart con un archivo EPUB y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | format | string | Sí | - | Formato de salida: `pdf`, `docx`, `html`, `md` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Ejemplo de respuesta {#example-response} Devuelve `202 Accepted`. Sigue el progreso mediante SSE en `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formato de entrada aceptado: `.epub`. * Los recursos remotos incrustados en el EPUB (imágenes y fuentes externas) no se descargan por seguridad. * La fidelidad de las imágenes en la salida convertida puede variar según la estructura del EPUB. * La conversión la gestiona Pandoc en el servidor. --- --- url: https://docs.snapotter.com/es/tools/files/convert-document.md description: Convierte entre formatos Word, OpenDocument, RTF y texto plano. --- # Convertir documento {#convert-document} Convierte documentos entre los formatos Word (DOCX), OpenDocument (ODT), RTF y texto plano usando LibreOffice. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-document` Acepta datos de formulario multipart con un archivo Word/ODT/RTF/TXT y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | format | string | Sí | - | Formato de salida: `docx`, `odt`, `rtf`, `txt` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Ejemplo de respuesta {#example-response} Devuelve `202 Accepted`. Sigue el progreso mediante SSE en `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceptados: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * La conversión la gestiona LibreOffice ejecutándose sin interfaz gráfica en el servidor. * El formato complejo (macros, objetos incrustados) puede no conservarse en la conversión entre formatos. * El formato de salida debe ser distinto del formato de entrada. --- --- url: https://docs.snapotter.com/fr/tools/files/to-epub.md description: Convertit des fichiers Word, Markdown, HTML ou texte brut en EPUB. --- # Convertir en EPUB {#convert-to-epub} Convertit des documents Word, du Markdown, du HTML ou des fichiers texte brut au format de livre numérique EPUB. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/to-epub` Accepte des données de formulaire multipart contenant un fichier Word/Markdown/HTML/TXT. ## Paramètres {#parameters} Cet outil n'a aucun paramètre configurable. Téléversez un document et il sera converti en EPUB. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Exemple de réponse {#example-response} Renvoie `202 Accepted`. Suivez la progression via SSE sur `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Remarques {#notes} * Formats d'entrée acceptés : `.docx`, `.md`, `.html`, `.txt`. * La sortie EPUB respecte la spécification EPUB 3. * Les titres du document source servent à générer la table des matières. * La conversion est prise en charge par Pandoc sur le serveur. --- --- url: https://docs.snapotter.com/es/tools/files/convert-spreadsheet.md description: Convierte entre los formatos Excel, OpenDocument y CSV. --- # Convertir hoja de cálculo {#convert-spreadsheet} Convierte hojas de cálculo entre los formatos Excel (XLSX), OpenDocument Spreadsheet (ODS) y CSV. Los libros con varias hojas exportan la primera hoja al convertir a CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Acepta datos de formulario multipart con un archivo Excel/ODS/CSV y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | format | string | Sí | - | Formato de salida: `xlsx`, `ods`, `csv` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Ejemplo de respuesta {#example-response} Devuelve `202 Accepted`. Sigue el progreso mediante SSE en `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceptados: `.xlsx`, `.xls`, `.ods`, `.csv`. * Al convertir un libro con varias hojas a CSV, solo se exporta la primera hoja. * Las fórmulas se evalúan y se exportan como valores estáticos en la salida CSV. * El formato de salida debe ser distinto del formato de entrada. --- --- url: https://docs.snapotter.com/es/tools/image/convert.md description: >- Convierte imágenes entre formatos, incluidos formatos modernos como AVIF, JXL y HEIC. --- # Convertir imagen {#convert} Convierte imágenes entre formatos. Admite formatos web comunes así como formatos especializados como HEIC, JXL, BMP, ICO, JP2, QOI y PSD. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/convert` Acepta datos de formulario multipart con un archivo de imagen y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | format | string | Sí | - | Formato objetivo: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | No | - | Calidad de salida (1-100). Se aplica a formatos con pérdida como jpg, webp, avif, heic. | ## Formatos de salida admitidos {#supported-output-formats} | Formato | Tipo | Notas | |--------|------|-------| | jpg | Con pérdida | JPEG, la mejor compatibilidad | | png | Sin pérdida | Admite transparencia | | webp | Ambos | Formato web moderno, buena compresión | | avif | Con pérdida | Formato de nueva generación, excelente compresión | | tiff | Ambos | Flujos de trabajo de impresión/publicación | | gif | Sin pérdida | Limitado a 256 colores | | heic / heif | Con pérdida | Formato del ecosistema Apple | | jxl | Ambos | JPEG XL, formato de nueva generación | | bmp | Sin pérdida | Mapa de bits sin comprimir | | ico | Sin pérdida | Formato de icono de Windows | | jp2 | Con pérdida | JPEG 2000 | | qoi | Sin pérdida | Formato Quite OK Image | | psd | Por capas | Adobe Photoshop (requiere ImageMagick) | | ppm | Sin pérdida | Portable Pixmap (PPM/PGM/PBM) | | eps | Vectorial | Encapsulated PostScript | | tga | Sin pérdida | Formato de imagen Targa | ## Ejemplo de solicitud {#example-request} Convertir a WebP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` Convertir a PNG (sin pérdida): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Notas {#notes} * La extensión del nombre del archivo de salida se actualiza automáticamente para coincidir con el formato objetivo. * Las entradas SVG se rasterizan a 300 DPI antes de la conversión. * La conversión a PSD requiere que ImageMagick esté instalado en el servidor. * BMP, EPS, ICO, JP2, JXL, PPM, QOI y TGA usan codificadores CLI especializados y omiten el procesamiento de Sharp. * La codificación HEIC/HEIF usa la biblioteca del codificador HEIC del sistema. * Los formatos de entrada son amplios: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, etc.), PSD, SVG, BMP y más. --- --- url: https://docs.snapotter.com/fr/tools/audio/convert-audio.md description: Convertir l'audio entre les formats MP3, WAV, OGG, FLAC et M4A. --- # Convertir l'audio {#convert-audio} Convertir des fichiers audio entre les formats courants, dont MP3, WAV, OGG, FLAC et M4A, avec un débit de sortie et une fréquence d'échantillonnage configurables. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/audio/convert-audio` Accepte des données de formulaire multipart avec un fichier audio et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | format | string | Non | `"mp3"` | Format de sortie : `mp3`, `wav`, `ogg`, `flac`, `m4a` | | bitrateKbps | integer | Non | `192` | Débit de sortie en kbps (32 à 320) | | sampleRate | integer | Non | fréquence d'origine | Fréquence d'échantillonnage de sortie en Hz : `8000`, `16000`, `22050`, `32000`, `44100`, `48000` ou `96000`. Omettre pour conserver la fréquence d'origine | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/convert-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"format": "mp3", "bitrateKbps": 192, "sampleRate": 44100}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Les formats d'entrée pris en charge incluent MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF et OPUS. * Le débit ne s'applique qu'aux formats avec perte (MP3, OGG, M4A). Les formats sans perte comme WAV et FLAC ignorent ce paramètre. * La sortie MP3 prend en charge les fréquences d'échantillonnage jusqu'à 48000 Hz. L'option 96000 Hz ne s'applique qu'aux formats WAV, OGG, FLAC et M4A. * Le débit MP3 est plafonné par la fréquence d'échantillonnage : au maximum 64 kbps à 8000 Hz et 160 kbps à 16000 ou 22050 Hz. Les requêtes dépassant ce plafond sont rejetées au lieu d'être abaissées silencieusement. * Le nom du fichier de sortie conserve le nom d'origine avec la nouvelle extension. --- --- url: https://docs.snapotter.com/es/tools/files/convert-presentation.md description: Convierte entre los formatos de presentación de PowerPoint y OpenDocument. --- # Convertir presentación {#convert-presentation} Convierte presentaciones entre los formatos PowerPoint (PPTX) y OpenDocument Presentation (ODP). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Acepta datos de formulario multipart con un archivo PowerPoint/ODP y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | format | string | Sí | - | Formato de salida: `pptx`, `odp` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Ejemplo de respuesta {#example-response} Devuelve `202 Accepted`. Sigue el progreso mediante SSE en `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceptados: `.pptx`, `.ppt`, `.odp`. * La conversión la gestiona LibreOffice ejecutándose sin interfaz gráfica en el servidor. * Es posible que las animaciones y los efectos de transición no se conserven entre formatos. * El formato de salida debe ser distinto del formato de entrada. --- --- url: https://docs.snapotter.com/fr/tools/files/convert-document.md description: Convertit entre les formats Word, OpenDocument, RTF et texte brut. --- # Convertir un document {#convert-document} Convertit des documents entre les formats Word (DOCX), OpenDocument (ODT), RTF et texte brut à l'aide de LibreOffice. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/convert-document` Accepte des données de formulaire multipart avec un fichier Word/ODT/RTF/TXT et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | format | string | Oui | - | Format de sortie : `docx`, `odt`, `rtf`, `txt` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-document \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" \ -F 'settings={"format": "odt"}' ``` ## Exemple de réponse {#example-response} Renvoie `202 Accepted`. Suivez la progression via SSE à `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Remarques {#notes} * Formats d'entrée acceptés : `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * La conversion est effectuée par LibreOffice exécuté en mode headless sur le serveur. * La mise en forme complexe (macros, objets intégrés) peut ne pas survivre à la conversion entre formats. * Le format de sortie doit être différent du format d'entrée. --- --- url: https://docs.snapotter.com/fr/tools/files/convert-spreadsheet.md description: Convertit entre les formats Excel, OpenDocument et CSV. --- # Convertir une feuille de calcul {#convert-spreadsheet} Convertit des feuilles de calcul entre les formats Excel (XLSX), OpenDocument Spreadsheet (ODS) et CSV. Les classeurs à plusieurs feuilles exportent la première feuille lors de la conversion en CSV. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/convert-spreadsheet` Accepte des données de formulaire multipart avec un fichier Excel/ODS/CSV et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | format | string | Oui | - | Format de sortie : `xlsx`, `ods`, `csv` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-spreadsheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.xlsx" \ -F 'settings={"format": "csv"}' ``` ## Exemple de réponse {#example-response} Renvoie `202 Accepted`. Suivez la progression via SSE à `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Remarques {#notes} * Formats d'entrée acceptés : `.xlsx`, `.xls`, `.ods`, `.csv`. * Lors de la conversion d'un classeur à plusieurs feuilles en CSV, seule la première feuille est exportée. * Les formules sont évaluées et exportées sous forme de valeurs statiques dans la sortie CSV. * Le format de sortie doit être différent du format d'entrée. --- --- url: https://docs.snapotter.com/fr/tools/image/convert.md description: >- Convertissez les images entre formats, y compris les formats modernes comme AVIF, JXL et HEIC. --- # Convertir une image {#convert} Convertissez les images entre formats. Prend en charge les formats web courants ainsi que les formats spécialisés comme HEIC, JXL, BMP, ICO, JP2, QOI et PSD. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/convert` Accepte des données de formulaire multipart avec un fichier image et un champ JSON `settings`. ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | format | string | Oui | - | Format cible : `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | Non | - | Qualité de sortie (1-100). S'applique aux formats avec perte comme jpg, webp, avif, heic. | ## Supported Output Formats {#supported-output-formats} | Format | Type | Remarques | |--------|------|-------| | jpg | Avec perte | JPEG, meilleure compatibilité | | png | Sans perte | Prend en charge la transparence | | webp | Les deux | Format web moderne, bonne compression | | avif | Avec perte | Format nouvelle génération, excellente compression | | tiff | Les deux | Flux de travail impression/édition | | gif | Sans perte | Limité à 256 couleurs | | heic / heif | Avec perte | Format de l'écosystème Apple | | jxl | Les deux | JPEG XL, format nouvelle génération | | bmp | Sans perte | Bitmap non compressé | | ico | Sans perte | Format d'icône Windows | | jp2 | Avec perte | JPEG 2000 | | qoi | Sans perte | Format Quite OK Image | | psd | En calques | Adobe Photoshop (nécessite ImageMagick) | | ppm | Sans perte | Portable Pixmap (PPM/PGM/PBM) | | eps | Vectoriel | Encapsulated PostScript | | tga | Sans perte | Format d'image Targa | ## Example Request {#example-request} Convertir en WebP : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` Convertir en PNG (sans perte) : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Notes {#notes} * L'extension du nom de fichier de sortie est automatiquement mise à jour pour correspondre au format cible. * Les entrées SVG sont rastérisées à 300 DPI avant la conversion. * La conversion PSD nécessite l'installation d'ImageMagick sur le serveur. * BMP, EPS, ICO, JP2, JXL, PPM, QOI et TGA utilisent des encodeurs CLI spécialisés et contournent le traitement Sharp. * L'encodage HEIC/HEIF utilise la bibliothèque d'encodage HEIC du système. * Les formats d'entrée sont larges : JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, etc.), PSD, SVG, BMP et plus encore. --- --- url: https://docs.snapotter.com/fr/tools/files/convert-presentation.md description: Convertit entre les formats de présentation PowerPoint et OpenDocument. --- # Convertir une présentation {#convert-presentation} Convertit des présentations entre les formats PowerPoint (PPTX) et OpenDocument Presentation (ODP). ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/convert-presentation` Accepte des données de formulaire multipart avec un fichier PowerPoint/ODP et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | format | string | Oui | - | Format de sortie : `pptx`, `odp` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/convert-presentation \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" \ -F 'settings={"format": "odp"}' ``` ## Exemple de réponse {#example-response} Renvoie `202 Accepted`. Suivez la progression via SSE à `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Remarques {#notes} * Formats d'entrée acceptés : `.pptx`, `.ppt`, `.odp`. * La conversion est effectuée par LibreOffice exécuté en mode headless sur le serveur. * Les animations et les effets de transition peuvent ne pas être conservés d'un format à l'autre. * Le format de sortie doit être différent du format d'entrée. --- --- url: https://docs.snapotter.com/es/tools/files/yaml-json.md description: Convierte entre YAML y JSON en ambos sentidos. --- # Convertir YAML / JSON {#yaml-json} Convierte entre los formatos YAML y JSON en ambos sentidos. Sube un archivo YAML para obtener JSON, o sube un archivo JSON para obtener YAML. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/yaml-json` Acepta datos de formulario multipart con un archivo YAML o JSON. No se requiere ningún campo de configuración. ## Parameters {#parameters} Esta herramienta no tiene parámetros configurables. El sentido de la conversión se determina por la extensión del archivo de entrada. ## Example Request {#example-request} YAML a JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.yaml" ``` JSON a YAML: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.json" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.json", "originalSize": 620, "processedSize": 780 } ``` ## Notes {#notes} * El sentido de la conversión se detecta automáticamente a partir de la extensión del archivo de entrada: `.yaml` o `.yml` produce `.json`, y `.json` produce `.yaml`. * Se aceptan tanto las extensiones `.yaml` como `.yml`. * Solo se convierte el primer documento de un archivo YAML con varios documentos; los documentos adicionales separados por `---` se ignoran. --- --- url: https://docs.snapotter.com/fr/tools/files/yaml-json.md description: Convertit entre YAML et JSON, dans les deux sens. --- # Convertir YAML / JSON {#yaml-json} Convertit entre les formats YAML et JSON dans les deux sens. Téléversez un fichier YAML pour obtenir du JSON, ou téléversez un fichier JSON pour obtenir du YAML. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/yaml-json` Accepte des données de formulaire multipart contenant un fichier YAML ou JSON. Aucun champ de paramètres n'est requis. ## Paramètres {#parameters} Cet outil n'a aucun paramètre configurable. Le sens de la conversion est déterminé par l'extension du fichier d'entrée. ## Exemple de requête {#example-request} YAML vers JSON : ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.yaml" ``` JSON vers YAML : ```bash curl -X POST http://localhost:1349/api/v1/tools/files/yaml-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@config.json" ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.json", "originalSize": 620, "processedSize": 780 } ``` ## Remarques {#notes} * Le sens de la conversion est détecté automatiquement à partir de l'extension du fichier d'entrée : `.yaml` ou `.yml` produit `.json`, et `.json` produit `.yaml`. * Les extensions `.yaml` et `.yml` sont toutes deux acceptées. * Seul le premier document d'un fichier YAML multi-documents est converti ; les documents supplémentaires séparés par `---` sont ignorés. --- --- url: https://docs.snapotter.com/fr/tools/image/gif-webp.md description: >- Convertissez un GIF animé en WebP et inversement, en préservant toutes les images. --- # Convertisseur GIF/WebP {#gif-webp-converter} Convertissez des fichiers GIF animés en WebP et inversement, en préservant toutes les images et le timing de l'animation. Les animations WebP sont généralement 25 à 35 % plus petites que les GIF équivalents. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Accepte des données de formulaire multipart avec un fichier GIF ou WebP et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | quality | integer | Non | `80` | Qualité de sortie pour l'encodage WebP (1-100) | | lossless | boolean | Non | `false` | Utiliser la compression WebP sans perte | | resizePercent | integer | Non | `100` | Mettre la sortie à l'échelle par pourcentage (10-100) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Notes {#notes} * Seuls les fichiers `.gif` et `.webp` sont acceptés. Les autres formats d'image ne sont pas pris en charge par cet outil. * Le sens de la conversion est automatique : une entrée GIF produit une sortie WebP, et une entrée WebP produit une sortie GIF. * Les options `quality` et `lossless` ne s'appliquent que lors de l'encodage en WebP. Lors de la conversion en GIF, la sortie utilise la palette GIF standard. * Utilisez `resizePercent` pour réduire les dimensions (et la taille de fichier) des grandes animations. --- --- url: https://docs.snapotter.com/fr/tools/pdf/pdfa-convert.md description: >- Convertir un PDF au format d'archivage PDF/A-2 pour une conservation à long terme. --- # Convertisseur PDF/A {#pdf-a-convert} Convertissez un PDF au format d'archivage PDF/A-2, adapté à la conservation à long terme et à la conformité réglementaire. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/pdfa-convert` Accepte des données de formulaire multipart avec un fichier PDF. Aucun champ `settings` n'est requis. ## Paramètres {#parameters} Cet outil n'a aucun paramètre de réglage. Téléversez directement le fichier PDF. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdfa-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2600000 } ``` ## Remarques {#notes} * La sortie est conforme à la norme PDF/A-2. * Le format PDF/A intègre toutes les polices et interdit les références externes, de sorte que le fichier de sortie peut être plus volumineux que l'original. * Le chiffrement et le JavaScript sont supprimés lors de la conversion, car ils ne sont pas autorisés par la norme PDF/A. --- --- url: https://docs.snapotter.com/it/tools/image/gif-webp.md description: Converti GIF animate in WebP e viceversa, preservando tutti i fotogrammi. --- # Convertitore GIF/WebP {#gif-webp-converter} Converti file GIF animati in WebP e viceversa, preservando tutti i fotogrammi e la temporizzazione dell'animazione. Le animazioni WebP sono in genere più piccole del 25-35% rispetto alle GIF equivalenti. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Accetta dati di form multipart con un file GIF o WebP e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | quality | integer | No | `80` | Qualità dell'output per la codifica WebP (1-100) | | lossless | boolean | No | `false` | Usa la compressione WebP senza perdita | | resizePercent | integer | No | `100` | Scala l'output per percentuale (10-100) | ## Richiesta di Esempio {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Risposta di Esempio {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Note {#notes} * Sono accettati solo file `.gif` e `.webp`. Altri formati immagine non sono supportati da questo strumento. * La direzione della conversione è automatica: l'input GIF produce output WebP, e l'input WebP produce output GIF. * Le opzioni `quality` e `lossless` si applicano solo durante la codifica in WebP. Durante la conversione in GIF, l'output usa la palette GIF standard. * Usa `resizePercent` per ridurre le dimensioni (e la dimensione del file) di animazioni di grandi dimensioni. --- --- url: https://docs.snapotter.com/it/tools/pdf/pdfa-convert.md description: >- Converti un PDF nel formato di archiviazione PDF/A-2 per la conservazione a lungo termine. --- # Convertitore PDF/A {#pdf-a-convert} Converti un PDF nel formato di archiviazione PDF/A-2, adatto alla conservazione a lungo termine e alla conformità normativa. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/pdfa-convert` Accetta dati di form multipart con un file PDF. Non è richiesto alcun campo `settings`. ## Parameters {#parameters} Questo strumento non ha parametri di configurazione. Carica direttamente il file PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/pdfa-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2600000 } ``` ## Notes {#notes} * L'output è conforme allo standard PDF/A-2. * PDF/A incorpora tutti i caratteri e non consente riferimenti esterni, quindi il file di output potrebbe essere più grande dell'originale. * La crittografia e JavaScript vengono rimossi durante la conversione, poiché non sono consentiti dallo standard PDF/A. --- --- url: https://docs.snapotter.com/fr/tools/image/transparency-fixer.md description: >- Corrige les faux PNG transparents grâce au détourage par IA (BiRefNet) pour produire une véritable transparence alpha, avec un nettoyage des contours par défrangeage. --- # Correcteur de transparence PNG {#png-transparency-fixer} Corrige les faux PNG transparents en un clic. Utilise le détourage par IA (modèle BiRefNet HR Matting) pour produire une véritable transparence alpha, avec un post-traitement de défrangeage pour nettoyer les contours. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/transparency-fixer` **Traitement :** asynchrone (renvoie 202, interroger `/api/v1/jobs/{jobId}/progress` pour le statut via SSE) **Bundle de modèle :** `background-removal` (4-5 Go) ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | file | file | Oui | - | Fichier image (multipart) | | defringe | number | Non | `30` | Intensité du défrangeage (0-100). Supprime les pixels de frange semi-transparents autour des contours | | outputFormat | string | Non | `"png"` | Format de sortie : `png` ou `webp` | | removeWatermark | boolean | Non | `false` | Applique un prétraitement de suppression de filigrane (filtre médian) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":40,"outputFormat":"png"}' ``` ## Réponse {#response} ### Réponse initiale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progression (SSE sur `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Processing transparency...","percent":50} ``` ### Résultat final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/fake-transparent_fixed.png", "originalSize": 180000, "processedSize": 150000, "filename": "fake-transparent.png" } } ``` ## Remarques {#notes} * Nécessite l'installation du bundle de modèle `background-removal` (4-5 Go). * Utilise `birefnet-hr-matting` comme modèle principal pour un détourage alpha de haute qualité. Revient à `birefnet-general` si le modèle HR manque de mémoire. * L'option `defringe` supprime les pixels de frange semi-transparents que le détourage par IA laisse parfois autour des cheveux, de la fourrure et des contours fins. Elle fonctionne en floutant le canal alpha et en mettant à zéro les pixels de faible confiance. * L'option `removeWatermark` applique une étape de prétraitement par filtre médian. Il s'agit d'une réduction de filigrane basique, et non d'un outil dédié à la suppression de filigrane. * Ne produit que du PNG ou du WebP sans perte (tous deux prennent en charge la transparence alpha). * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR via un décodage automatique. --- --- url: https://docs.snapotter.com/es/tools/image/transparency-fixer.md description: >- Corrige PNG con falsa transparencia mediante matting por IA (BiRefNet) para producir un alfa real, además de limpieza de bordes con defringe. --- # Corrector de transparencia PNG {#png-transparency-fixer} Corrige PNG con falsa transparencia con un solo clic. Usa matting por IA (modelo BiRefNet HR Matting) para producir una transparencia alfa real, con postprocesamiento de defringe para limpiar los bordes. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/transparency-fixer` **Procesamiento:** Asíncrono (devuelve 202, sondea `/api/v1/jobs/{jobId}/progress` para conocer el estado mediante SSE) **Paquete de modelos:** `background-removal` (4-5 GB) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | defringe | number | No | `30` | Intensidad de defringe (0-100). Elimina los píxeles de franja semitransparente alrededor de los bordes | | outputFormat | string | No | `"png"` | Formato de salida: `png` o `webp` | | removeWatermark | boolean | No | `false` | Aplica un preprocesamiento de eliminación de marca de agua (filtro de mediana) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":40,"outputFormat":"png"}' ``` ## Respuesta {#response} ### Respuesta inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progreso (SSE en `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Processing transparency...","percent":50} ``` ### Resultado final (mediante SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/fake-transparent_fixed.png", "originalSize": 180000, "processedSize": 150000, "filename": "fake-transparent.png" } } ``` ## Notas {#notes} * Requiere que el paquete de modelos `background-removal` esté instalado (4-5 GB). * Usa `birefnet-hr-matting` como modelo principal para un matting alfa de alta calidad. Recurre a `birefnet-general` si el modelo HR se queda sin memoria. * La opción `defringe` elimina los píxeles de franja semitransparente que el matting por IA a veces deja alrededor del cabello, el pelaje y los bordes finos. Funciona desenfocando el canal alfa y poniendo a cero los píxeles de baja confianza. * La opción `removeWatermark` aplica un paso de preprocesamiento con filtro de mediana. Es una reducción básica de marcas de agua, no una herramienta dedicada a la eliminación de marcas de agua. * Solo produce PNG o WebP sin pérdida (ambos admiten transparencia alfa). * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/transparency-fixer.md description: >- Corrige PNGs com transparência falsa usando matting por IA (BiRefNet) para produzir alfa verdadeiro, além de limpeza de bordas com defringe. --- # Corretor de Transparência de PNG {#png-transparency-fixer} Corrige PNGs com transparência falsa em um clique. Usa matting por IA (modelo BiRefNet HR Matting) para produzir transparência alfa verdadeira, com pós-processamento de defringe para limpar as bordas. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/transparency-fixer` **Processamento:** Assíncrono (retorna 202, consulte `/api/v1/jobs/{jobId}/progress` para obter o status via SSE) **Pacote de modelo:** `background-removal` (4-5 GB) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | defringe | number | Não | `30` | Intensidade de defringe (0-100). Remove pixels de franja semitransparentes ao redor das bordas | | outputFormat | string | Não | `"png"` | Formato de saída: `png` ou `webp` | | removeWatermark | boolean | Não | `false` | Aplica pré-processamento de remoção de marca d'água (filtro de mediana) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":40,"outputFormat":"png"}' ``` ## Resposta {#response} ### Resposta Inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progresso (SSE em `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Processing transparency...","percent":50} ``` ### Resultado Final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/fake-transparent_fixed.png", "originalSize": 180000, "processedSize": 150000, "filename": "fake-transparent.png" } } ``` ## Notas {#notes} * Requer que o pacote de modelo `background-removal` esteja instalado (4-5 GB). * Usa `birefnet-hr-matting` como modelo principal para matting alfa de alta qualidade. Recai para `birefnet-general` se o modelo HR ficar sem memória. * A opção `defringe` remove pixels de franja semitransparentes que o matting por IA às vezes deixa ao redor de cabelos, pelos e bordas finas. Ela funciona desfocando o canal alfa e zerando pixels de baixa confiança. * A opção `removeWatermark` aplica uma etapa de pré-processamento com filtro de mediana. É uma redução básica de marca d'água, não uma ferramenta dedicada de remoção de marca d'água. * Produz apenas PNG ou WebP sem perdas (ambos suportam transparência alfa). * Suporta os formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR via decodificação automática. --- --- url: https://docs.snapotter.com/it/tools/image/transparency-fixer.md description: >- Corregge i PNG con falsa trasparenza usando il matting con IA (BiRefNet) per produrre un vero canale alfa, con pulizia dei bordi tramite defringe. --- # Correzione trasparenza PNG {#png-transparency-fixer} Corregge i PNG con falsa trasparenza in un clic. Usa il matting con IA (modello BiRefNet HR Matting) per produrre una vera trasparenza alfa, con post-elaborazione defringe per ripulire i bordi. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/transparency-fixer` **Elaborazione:** Asincrona (restituisce 202, interroga `/api/v1/jobs/{jobId}/progress` per lo stato tramite SSE) **Bundle del modello:** `background-removal` (4-5 GB) ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | file | file | Sì | - | File immagine (multipart) | | defringe | number | No | `30` | Intensità del defringe (0-100). Rimuove i pixel di frangia semitrasparenti attorno ai bordi | | outputFormat | string | No | `"png"` | Formato di output: `png` o `webp` | | removeWatermark | boolean | No | `false` | Applica la pre-elaborazione di rimozione della filigrana (filtro mediano) | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":40,"outputFormat":"png"}' ``` ## Risposta {#response} ### Risposta iniziale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Avanzamento (SSE su `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Processing transparency...","percent":50} ``` ### Risultato finale (tramite SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/fake-transparent_fixed.png", "originalSize": 180000, "processedSize": 150000, "filename": "fake-transparent.png" } } ``` ## Note {#notes} * Richiede l'installazione del bundle del modello `background-removal` (4-5 GB). * Usa `birefnet-hr-matting` come modello principale per un matting alfa di alta qualità. Ripiega su `birefnet-general` se il modello HR esaurisce la memoria. * L'opzione `defringe` rimuove i pixel di frangia semitrasparenti che il matting con IA a volte lascia attorno a capelli, pelo e bordi fini. Funziona sfocando il canale alfa e azzerando i pixel a bassa confidenza. * L'opzione `removeWatermark` applica una fase di pre-elaborazione con filtro mediano. È una riduzione di base della filigrana, non uno strumento dedicato alla rimozione della filigrana. * Produce in output solo PNG o WebP lossless (entrambi supportano la trasparenza alfa). * Supporta i formati di input HEIC/HEIF, RAW, TGA, PSD, EXR e HDR tramite decodifica automatica. --- --- url: https://docs.snapotter.com/it/guide/telemetry.md description: >- Quali dati di utilizzo anonimi raccoglie SnapOtter, quando vengono inviati e come disattivare le analisi di prodotto a livello di istanza. --- # Cosa raccoglie SnapOtter {#what-snapotter-collects} Le analisi di prodotto anonime sono attive per impostazione predefinita e vengono impostate per l'intera istanza da un amministratore. Disattivale in Impostazioni > Sistema > Privacy. ## Eventi che inviamo (quando abilitati) {#events-we-send-when-enabled} * tool\_used: id dello strumento, stato, durata, categoria, se è uno strumento AI, un codice di errore in caso di fallimento. * pipeline\_executed: numero di passaggi, id degli strumenti, flag batch, numero di file, durata, stato. * ai\_bundle\_action: id del bundle, azione, durata. * Utilizzo del frontend: quali pagine degli strumenti vengono aperte, file aggiunti (solo conteggi), strumento avviato, download, salvataggi, ricerca (solo numero di risultati), elaborazione batch. * Report sui crash: tipo di errore e uno stack sorgente con solo i nomi base dei file. ## Cosa non raccogliamo mai {#what-we-never-collect} * Nomi o percorsi dei file * Contenuti dei file * Testo dell'output OCR * Metadati delle immagini (EXIF) * Testo estratto dai documenti * Il tuo indirizzo IP o la tua identità di account ## Come disattivarle {#turning-it-off} Admin: Impostazioni > Sistema > Privacy, disattiva "Analisi di prodotto anonime". Si interrompe immediatamente, a livello di istanza. Per compilare un'immagine che non può mai emettere dati, imposta il build arg `SNAPOTTER_ANALYTICS=off`. --- --- url: https://docs.snapotter.com/es/tools/files/chart-maker.md description: Crea gráficos de barras, líneas o circulares a partir de datos CSV o JSON. --- # Creador de gráficos {#chart-maker} Crea gráficos de barras, líneas o circulares a partir de datos CSV o JSON. Devuelve una imagen PNG del gráfico renderizado. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Acepta datos de formulario multipart con un archivo CSV o JSON y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | kind | string | No | `"bar"` | Tipo de gráfico: `bar`, `line`, `pie` | | title | string | No | - | Título del gráfico (máximo 120 caracteres) | | width | integer | No | `960` | Ancho del gráfico en píxeles (320-2048) | | height | integer | No | `540` | Alto del gráfico en píxeles (240-1536) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notas {#notes} * La entrada debe ser un archivo `.csv` o `.json`. Los archivos CSV deben tener una fila de encabezado con los nombres de las columnas. * La primera columna se usa como etiqueta de categoría; la segunda columna debe ser numérica y proporciona los valores de datos. Solo se usan dos columnas. * La entrada JSON debe ser un arreglo de objetos `{label, value}`, o un objeto simple cuyas claves se conviertan en etiquetas y cuyos valores se conviertan en puntos de datos. * Máximo 100 puntos de datos. Todos los valores deben ser cero o mayores. * La salida siempre es una imagen PNG, independientemente del formato de entrada. --- --- url: https://docs.snapotter.com/es/tools/audio/ringtone-maker.md description: Crea un clip de tono de llamada a partir de cualquier archivo de audio. --- # Creador de tonos de llamada {#ringtone-maker} Crea un clip de tono de llamada (.m4r) a partir de cualquier archivo de audio seleccionando una hora de inicio y una duración. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/audio/ringtone-maker` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | startS | number | No | `0` | Hora de inicio en segundos (mínimo 0) | | durationS | number | No | `30` | Duración del clip en segundos (1 a 30) | ## Solicitud de ejemplo {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/ringtone-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"startS": 15, "durationS": 20}' ``` ## Respuesta de ejemplo {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.m4r", "originalSize": 4500000, "processedSize": 620000 } ``` ## Notas {#notes} * La salida siempre está en formato M4R, compatible con los tonos de llamada del iPhone. * La duración máxima del tono de llamada es de 30 segundos (límite de Apple). * Se puede usar cualquier formato de audio como entrada. --- --- url: https://docs.snapotter.com/es/tools/files/create-zip.md description: Agrupa varios archivos en un único archivo ZIP. --- # Crear ZIP {#create-zip} Agrupa varios archivos de cualquier tipo en un único archivo ZIP. Los nombres de archivo duplicados se deduplican automáticamente. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Acepta datos de formulario multipart con dos o más archivos. No se requiere un campo de ajustes. ## Parámetros {#parameters} Esta herramienta no tiene parámetros configurables. Sube de 2 a 50 archivos de cualquier tipo para agruparlos. ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notas {#notes} * Requiere entre 2 y 50 archivos de entrada. * Se acepta cualquier tipo de archivo; no hay restricciones sobre el formato de entrada. * Si varios archivos comparten el mismo nombre, se deduplican automáticamente con sufijos numéricos. * El archivo de salida usa la compresión ZIP estándar (deflate). --- --- url: https://docs.snapotter.com/de/tools/files/create-zip.md description: Bündelt mehrere Dateien in einem einzigen ZIP-Archiv. --- # Create ZIP {#create-zip} Bündelt mehrere Dateien beliebigen Typs in einem einzigen ZIP-Archiv. Doppelte Dateinamen werden automatisch dedupliziert. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Akzeptiert Multipart-Formulardaten mit zwei oder mehr Dateien. Es ist kein Einstellungsfeld erforderlich. ## Parameters {#parameters} Dieses Tool hat keine konfigurierbaren Parameter. Lade 2-50 Dateien beliebigen Typs zum Bündeln hoch. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Erfordert zwischen 2 und 50 Eingabedateien. * Jeder Dateityp wird akzeptiert; es gibt keine Einschränkungen beim Eingabeformat. * Wenn mehrere Dateien denselben Namen haben, werden sie automatisch mit numerischen Suffixen dedupliziert. * Das Ausgabearchiv verwendet die Standard-ZIP-Komprimierung (Deflate). --- --- url: https://docs.snapotter.com/hi/tools/files/create-zip.md description: कई फ़ाइलों को एक ही ZIP संग्रह में बंडल करें। --- # Create ZIP {#create-zip} किसी भी प्रकार की कई फ़ाइलों को एक ही ZIP संग्रह में बंडल करें। डुप्लिकेट फ़ाइल नाम स्वचालित रूप से डी-डुप्लिकेट किए जाते हैं। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` दो या अधिक फ़ाइलों के साथ multipart form data स्वीकार करता है। किसी settings फ़ील्ड की आवश्यकता नहीं है। ## Parameters {#parameters} इस टूल में कोई कॉन्फ़िगर करने योग्य पैरामीटर नहीं है। बंडल करने के लिए किसी भी प्रकार की 2-50 फ़ाइलें अपलोड करें। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * 2 से 50 के बीच इनपुट फ़ाइलों की आवश्यकता है। * किसी भी प्रकार की फ़ाइल स्वीकार की जाती है; इनपुट फ़ॉर्मेट पर कोई प्रतिबंध नहीं है। * यदि कई फ़ाइलें एक ही नाम साझा करती हैं, तो उन्हें संख्यात्मक प्रत्ययों के साथ स्वचालित रूप से डी-डुप्लिकेट किया जाता है। * आउटपुट संग्रह मानक ZIP संपीड़न (deflate) का उपयोग करता है। --- --- url: https://docs.snapotter.com/id/tools/files/create-zip.md description: Gabungkan beberapa file menjadi satu arsip ZIP. --- # Create ZIP {#create-zip} Gabungkan beberapa file dari jenis apa pun menjadi satu arsip ZIP. Nama file duplikat secara otomatis dideduplikasi. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Menerima multipart form data berisi dua file atau lebih. Tidak diperlukan field settings. ## Parameters {#parameters} Tool ini tidak memiliki parameter yang dapat dikonfigurasi. Unggah 2-50 file dari jenis apa pun untuk digabungkan. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Memerlukan antara 2 hingga 50 file input. * Jenis file apa pun diterima; tidak ada batasan pada format input. * Jika beberapa file memiliki nama yang sama, file tersebut secara otomatis dideduplikasi dengan sufiks numerik. * Arsip output menggunakan kompresi ZIP standar (deflate). --- --- url: https://docs.snapotter.com/it/tools/files/create-zip.md description: Raggruppa più file in un unico archivio ZIP. --- # Create ZIP {#create-zip} Raggruppa più file di qualsiasi tipo in un unico archivio ZIP. I nomi di file duplicati vengono deduplicati automaticamente. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Accetta dati form multipart con due o più file. Non è richiesto alcun campo settings. ## Parameters {#parameters} Questo strumento non ha parametri configurabili. Carica da 2 a 50 file di qualsiasi tipo da raggruppare. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Richiede tra 2 e 50 file di input. * È accettato qualsiasi tipo di file; non ci sono restrizioni sul formato di input. * Se più file condividono lo stesso nome, vengono deduplicati automaticamente con suffissi numerici. * L'archivio di output usa la compressione ZIP standard (deflate). --- --- url: https://docs.snapotter.com/ja/tools/files/create-zip.md description: 複数のファイルを 1 つの ZIP アーカイブにまとめます。 --- # Create ZIP {#create-zip} 任意の種類の複数ファイルを 1 つの ZIP アーカイブにまとめます。重複するファイル名は自動的に重複が解消されます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` 2 つ以上のファイルを含む multipart フォームデータを受け付けます。settings フィールドは不要です。 ## Parameters {#parameters} このツールには設定可能なパラメータはありません。まとめる任意の種類のファイルを 2〜50 個アップロードします。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * 2〜50 個の入力ファイルが必要です。 * 任意のファイル形式を受け付けます。入力形式に制限はありません。 * 複数のファイルが同じ名前を共有する場合、数値のサフィックスを付けて自動的に重複が解消されます。 * 出力アーカイブは標準の ZIP 圧縮(deflate)を使用します。 --- --- url: https://docs.snapotter.com/nl/tools/files/create-zip.md description: Bundel meerdere bestanden tot één ZIP-archief. --- # Create ZIP {#create-zip} Bundel meerdere bestanden van elk type tot één ZIP-archief. Dubbele bestandsnamen worden automatisch ontdubbeld. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Accepteert multipart-formulierdata met twee of meer bestanden. Er is geen instellingenveld vereist. ## Parameters {#parameters} Deze tool heeft geen instelbare parameters. Upload 2-50 bestanden van elk type om te bundelen. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Vereist tussen 2 en 50 invoerbestanden. * Elk bestandstype wordt geaccepteerd; er zijn geen beperkingen op het invoerformaat. * Als meerdere bestanden dezelfde naam delen, worden ze automatisch ontdubbeld met numerieke achtervoegsels. * Het uitvoerarchief gebruikt standaard ZIP-compressie (deflate). --- --- url: https://docs.snapotter.com/pl/tools/files/create-zip.md description: Pakuje wiele plików w jedno archiwum ZIP. --- # Create ZIP {#create-zip} Pakuje wiele plików dowolnego typu w jedno archiwum ZIP. Zduplikowane nazwy plików są automatycznie deduplikowane. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Przyjmuje dane formularza multipart z dwoma lub więcej plikami. Pole ustawień nie jest wymagane. ## Parameters {#parameters} To narzędzie nie ma konfigurowalnych parametrów. Prześlij od 2 do 50 plików dowolnego typu do spakowania. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Wymaga od 2 do 50 plików wejściowych. * Akceptowany jest dowolny typ pliku; nie ma ograniczeń co do formatu wejściowego. * Jeśli kilka plików ma tę samą nazwę, są one automatycznie deduplikowane przez dodanie sufiksów liczbowych. * Archiwum wyjściowe korzysta ze standardowej kompresji ZIP (deflate). --- --- url: https://docs.snapotter.com/sv/tools/files/create-zip.md description: Bunta ihop flera filer till ett enda ZIP-arkiv. --- # Create ZIP {#create-zip} Bunta ihop flera filer av valfri typ till ett enda ZIP-arkiv. Dubbletter av filnamn dedupliceras automatiskt. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Tar emot multipart-formulärdata med två eller flera filer. Inget inställningsfält krävs. ## Parameters {#parameters} Detta verktyg har inga konfigurerbara parametrar. Ladda upp 2-50 filer av valfri typ att bunta ihop. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Kräver mellan 2 och 50 indatafiler. * Alla filtyper godtas; det finns inga begränsningar för indataformat. * Om flera filer delar samma namn dedupliceras de automatiskt med numeriska suffix. * Utdataarkivet använder ZIP-standardkomprimering (deflate). --- --- url: https://docs.snapotter.com/th/tools/files/create-zip.md description: รวมไฟล์หลายไฟล์เป็นไฟล์เก็บถาวร ZIP เดียว --- # Create ZIP {#create-zip} รวมไฟล์หลายไฟล์ทุกประเภทเป็นไฟล์เก็บถาวร ZIP เดียว ชื่อไฟล์ที่ซ้ำกันจะถูกกำจัดความซ้ำโดยอัตโนมัติ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` รับข้อมูล multipart form ที่มีไฟล์ตั้งแต่สองไฟล์ขึ้นไป ไม่จำเป็นต้องมีฟิลด์การตั้งค่า ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์ที่กำหนดค่าได้ อัปโหลดไฟล์ 2-50 ไฟล์ทุกประเภทเพื่อรวมเข้าด้วยกัน ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * ต้องการไฟล์อินพุตระหว่าง 2 ถึง 50 ไฟล์ * รับไฟล์ทุกประเภท ไม่มีข้อจำกัดในรูปแบบอินพุต * หากไฟล์หลายไฟล์ใช้ชื่อเดียวกัน ระบบจะกำจัดความซ้ำโดยอัตโนมัติด้วยส่วนต่อท้ายที่เป็นตัวเลข * ไฟล์เก็บถาวรผลลัพธ์ใช้การบีบอัด ZIP มาตรฐาน (deflate) --- --- url: https://docs.snapotter.com/tr/tools/files/create-zip.md description: Birden fazla dosyayı tek bir ZIP arşivinde birleştirin. --- # Create ZIP {#create-zip} Herhangi bir türdeki birden fazla dosyayı tek bir ZIP arşivinde birleştirin. Yinelenen dosya adları otomatik olarak tekilleştirilir. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` İki veya daha fazla dosya içeren multipart form verisi kabul eder. Bir ayarlar alanı gerekmez. ## Parameters {#parameters} Bu aracın yapılandırılabilir parametresi yoktur. Birleştirmek için herhangi bir türde 2-50 dosya yükleyin. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * 2 ile 50 arasında giriş dosyası gerektirir. * Herhangi bir dosya türü kabul edilir; giriş formatında herhangi bir kısıtlama yoktur. * Birden fazla dosya aynı adı paylaşıyorsa, sayısal soneklerle otomatik olarak tekilleştirilir. * Çıktı arşivi standart ZIP sıkıştırması (deflate) kullanır. --- --- url: https://docs.snapotter.com/uk/tools/files/create-zip.md description: Об'єднання кількох файлів в один архів ZIP. --- # Create ZIP {#create-zip} Об'єднання кількох файлів будь-якого типу в один архів ZIP. Дублікати імен файлів автоматично усуваються. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Приймає дані форми multipart із двома або більше файлами. Поле налаштувань не потрібне. ## Parameters {#parameters} Цей інструмент не має налаштовуваних параметрів. Завантажте від 2 до 50 файлів будь-якого типу для об'єднання. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Потребує від 2 до 50 вхідних файлів. * Приймається будь-який тип файлу; немає обмежень щодо вхідного формату. * Якщо кілька файлів мають однакове ім'я, вони автоматично усуваються дублюванням із числовими суфіксами. * Вихідний архів використовує стандартне стиснення ZIP (deflate). --- --- url: https://docs.snapotter.com/vi/tools/files/create-zip.md description: Gộp nhiều tệp thành một tệp lưu trữ ZIP duy nhất. --- # Create ZIP {#create-zip} Gộp nhiều tệp thuộc bất kỳ loại nào thành một tệp lưu trữ ZIP duy nhất. Tên tệp trùng lặp được tự động khử trùng. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` Nhận dữ liệu multipart form với hai tệp trở lên. Không cần trường settings. ## Parameters {#parameters} Công cụ này không có tham số cấu hình. Tải lên 2-50 tệp thuộc bất kỳ loại nào để gộp. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * Yêu cầu từ 2 đến 50 tệp đầu vào. * Chấp nhận mọi loại tệp; không có giới hạn về định dạng đầu vào. * Nếu nhiều tệp có cùng tên, chúng sẽ được tự động khử trùng bằng hậu tố số. * Tệp lưu trữ đầu ra sử dụng nén ZIP tiêu chuẩn (deflate). --- --- url: https://docs.snapotter.com/zh-CN/tools/files/create-zip.md description: 将多个文件打包成单个 ZIP 压缩包。 --- # Create ZIP {#create-zip} 将任意类型的多个文件打包成单个 ZIP 压缩包。重复的文件名会被自动去重。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/create-zip` 接受包含两个或更多文件的 multipart 表单数据。不需要 settings 字段。 ## Parameters {#parameters} 此工具没有可配置的参数。上传 2 到 50 个任意类型的文件进行打包。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notes {#notes} * 需要 2 到 50 个输入文件。 * 接受任意文件类型;对输入格式没有限制。 * 如果多个文件同名,会自动用数字后缀去重。 * 输出压缩包使用标准 ZIP 压缩(deflate)。 --- --- url: https://docs.snapotter.com/fr/tools/files/chart-maker.md description: >- Crée des graphiques en barres, en courbes ou en camembert à partir de données CSV ou JSON. --- # Créateur de graphiques {#chart-maker} Crée des graphiques en barres, en courbes ou en camembert à partir de données CSV ou JSON. Renvoie une image PNG du graphique rendu. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Accepte des données de formulaire multipart avec un fichier CSV ou JSON et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | kind | string | Non | `"bar"` | Type de graphique : `bar`, `line`, `pie` | | title | string | Non | - | Titre du graphique (120 caractères max.) | | width | integer | Non | `960` | Largeur du graphique en pixels (320-2048) | | height | integer | Non | `540` | Hauteur du graphique en pixels (240-1536) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Remarques {#notes} * L'entrée doit être un fichier `.csv` ou `.json`. Les fichiers CSV doivent comporter une ligne d'en-tête avec les noms des colonnes. * La première colonne sert d'étiquette de catégorie ; la deuxième colonne doit être numérique et fournit les valeurs des données. Seules deux colonnes sont utilisées. * L'entrée JSON doit être un tableau d'objets `{label, value}`, ou un objet simple dont les clés deviennent des étiquettes et les valeurs des points de données. * Maximum de 100 points de données. Toutes les valeurs doivent être supérieures ou égales à zéro. * La sortie est toujours une image PNG, quel que soit le format d'entrée. --- --- url: https://docs.snapotter.com/fr/tools/audio/ringtone-maker.md description: Créer un extrait de sonnerie à partir de n'importe quel fichier audio. --- # Créateur de sonneries {#ringtone-maker} Créer un extrait de sonnerie (.m4r) à partir de n'importe quel fichier audio en sélectionnant un temps de départ et une durée. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/audio/ringtone-maker` Accepte des données de formulaire multipart avec un fichier audio et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | startS | number | Non | `0` | Temps de départ en secondes (minimum 0) | | durationS | number | Non | `30` | Durée de l'extrait en secondes (1 à 30) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/ringtone-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"startS": 15, "durationS": 20}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.m4r", "originalSize": 4500000, "processedSize": 620000 } ``` ## Notes {#notes} * La sortie est toujours au format M4R, compatible avec les sonneries iPhone. * La durée maximale d'une sonnerie est de 30 secondes (limite Apple). * N'importe quel format audio peut servir d'entrée. --- --- url: https://docs.snapotter.com/it/tools/audio/ringtone-maker.md description: Crea una suoneria da qualsiasi file audio. --- # Creatore di suonerie {#ringtone-maker} Crea una suoneria (.m4r) da qualsiasi file audio selezionando un tempo di inizio e una durata. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/ringtone-maker` Accetta dati di form multipart con un file audio e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | startS | number | No | `0` | Tempo di inizio in secondi (minimo 0) | | durationS | number | No | `30` | Durata della clip in secondi (da 1 a 30) | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/ringtone-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"startS": 15, "durationS": 20}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.m4r", "originalSize": 4500000, "processedSize": 620000 } ``` ## Note {#notes} * L'output è sempre in formato M4R, compatibile con le suonerie iPhone. * La durata massima della suoneria è di 30 secondi (limite Apple). * È possibile usare qualsiasi formato audio come input. --- --- url: https://docs.snapotter.com/fr/tools/files/create-zip.md description: Regroupe plusieurs fichiers dans une seule archive ZIP. --- # Créer un ZIP {#create-zip} Regroupe plusieurs fichiers de tout type dans une seule archive ZIP. Les noms de fichiers en double sont automatiquement dédupliqués. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/create-zip` Accepte des données de formulaire multipart avec deux fichiers ou plus. Aucun champ de réglages n'est requis. ## Paramètres {#parameters} Cet outil n'a aucun paramètre configurable. Chargez entre 2 et 50 fichiers de tout type à regrouper. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Remarques {#notes} * Nécessite entre 2 et 50 fichiers d'entrée. * Tout type de fichier est accepté ; il n'y a aucune restriction sur le format d'entrée. * Si plusieurs fichiers portent le même nom, ils sont automatiquement dédupliqués avec des suffixes numériques. * L'archive de sortie utilise la compression ZIP standard (deflate). --- --- url: https://docs.snapotter.com/pt-BR/tools/files/chart-maker.md description: Crie gráficos de barras, de linhas ou de pizza a partir de dados CSV ou JSON. --- # Criador de Gráficos {#chart-maker} Crie gráficos de barras, de linhas ou de pizza a partir de dados CSV ou JSON. Retorna uma imagem PNG do gráfico renderizado. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/chart-maker` Aceita dados de formulário multipart com um arquivo CSV ou JSON e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | kind | string | Não | `"bar"` | Tipo de gráfico: `bar`, `line`, `pie` | | title | string | Não | - | Título do gráfico (máximo 120 caracteres) | | width | integer | Não | `960` | Largura do gráfico em pixels (320-2048) | | height | integer | Não | `540` | Altura do gráfico em pixels (240-1536) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/chart-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@sales.csv" \ -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales_chart.png", "originalSize": 1024, "processedSize": 48500 } ``` ## Notas {#notes} * A entrada deve ser um arquivo `.csv` ou `.json`. Arquivos CSV devem ter uma linha de cabeçalho com os nomes das colunas. * A primeira coluna é usada como rótulo de categoria; a segunda coluna deve ser numérica e fornece os valores dos dados. Apenas duas colunas são usadas. * A entrada JSON deve ser um array de objetos `{label, value}`, ou um objeto simples cujas chaves se tornam rótulos e cujos valores se tornam pontos de dados. * Máximo de 100 pontos de dados. Todos os valores devem ser zero ou maiores. * A saída é sempre uma imagem PNG, independentemente do formato de entrada. --- --- url: https://docs.snapotter.com/pt-BR/tools/audio/ringtone-maker.md description: Crie um trecho de toque de celular a partir de qualquer arquivo de áudio. --- # Criador de Toque {#ringtone-maker} Crie um trecho de toque de celular (.m4r) a partir de qualquer arquivo de áudio, selecionando um tempo inicial e uma duração. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/audio/ringtone-maker` Aceita dados de formulário multipart com um arquivo de áudio e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | startS | number | Não | `0` | Tempo inicial em segundos (mínimo 0) | | durationS | number | Não | `30` | Duração do trecho em segundos (1 a 30) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/ringtone-maker \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"startS": 15, "durationS": 20}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.m4r", "originalSize": 4500000, "processedSize": 620000 } ``` ## Notas {#notes} * A saída é sempre no formato M4R, compatível com toques do iPhone. * A duração máxima do toque é de 30 segundos (limite da Apple). * Qualquer formato de áudio pode ser usado como entrada. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/create-zip.md description: Agrupe vários arquivos em um único arquivo ZIP. --- # Criar ZIP {#create-zip} Agrupe vários arquivos de qualquer tipo em um único arquivo ZIP. Nomes de arquivo duplicados são automaticamente diferenciados. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/create-zip` Aceita dados de formulário multipart com dois ou mais arquivos. Nenhum campo de configurações é necessário. ## Parâmetros {#parameters} Esta ferramenta não tem parâmetros configuráveis. Envie de 2 a 50 arquivos de qualquer tipo para agrupar. ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/create-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.pdf" \ -F "file=@data.csv" \ -F "file=@photo.jpg" ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", "originalSize": 3500000, "processedSize": 2800000 } ``` ## Notas {#notes} * Requer entre 2 e 50 arquivos de entrada. * Qualquer tipo de arquivo é aceito; não há restrições quanto ao formato de entrada. * Se vários arquivos compartilharem o mesmo nome, eles são automaticamente diferenciados com sufixos numéricos. * O arquivo de saída usa compressão ZIP padrão (deflate). --- --- url: https://docs.snapotter.com/ar/tools/pdf/crop-pdf.md description: اقتصاص جميع صفحات ملف PDF بهامش موحّد. --- # Crop PDF {#crop-pdf} اقتصّ جميع صفحات ملف PDF بتطبيق هامش موحّد، مع تشذيب المحتوى من كل حافة بالتساوي. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` يقبل بيانات نموذج multipart تحتوي على ملف PDF وحقل `settings` بصيغة JSON. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | هامش الاقتصاص الموحّد بالنقاط (من 0 إلى 2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * قيمة الهامش بنقاط PDF (نقطة واحدة = 1/72 بوصة). * يُطبَّق الهامش نفسه على الحواف الأربع لكل صفحة. * يزيل الهامش `0` جميع هوامش الاقتصاص الموجودة، مُظهِراً مربّع الوسائط الكامل. --- --- url: https://docs.snapotter.com/hi/tools/pdf/crop-pdf.md description: एक समान मार्जिन के साथ PDF के सभी पृष्ठों को क्रॉप करें। --- # Crop PDF {#crop-pdf} एक समान मार्जिन लागू करके PDF के सभी पृष्ठों को क्रॉप करें, प्रत्येक किनारे से सामग्री को समान रूप से ट्रिम करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` एक PDF फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | पॉइंट में एक समान क्रॉप मार्जिन (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * मार्जिन मान PDF पॉइंट में होता है (1 पॉइंट = 1/72 इंच)। * वही मार्जिन प्रत्येक पृष्ठ के चारों किनारों पर लागू किया जाता है। * `0` का मार्जिन सभी मौजूदा क्रॉप मार्जिन हटा देता है, जिससे पूरा मीडिया बॉक्स दिखता है। --- --- url: https://docs.snapotter.com/id/tools/pdf/crop-pdf.md description: Pangkas semua halaman PDF dengan margin yang seragam. --- # Crop PDF {#crop-pdf} Pangkas semua halaman PDF dengan menerapkan margin yang seragam, memotong konten dari setiap tepi secara merata. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Menerima data form multipart berisi file PDF dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | Margin pemangkasan seragam dalam poin (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * Nilai margin dinyatakan dalam poin PDF (1 poin = 1/72 inci). * Margin yang sama diterapkan ke keempat tepi setiap halaman. * Margin sebesar `0` menghapus semua margin pemangkasan yang ada, menampilkan seluruh media box. --- --- url: https://docs.snapotter.com/ja/tools/pdf/crop-pdf.md description: PDF の全ページを均一なマージンで切り抜きます。 --- # Crop PDF {#crop-pdf} 均一なマージンを適用して PDF の全ページを切り抜き、各辺から均等にコンテンツをトリミングします。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` PDF ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | 均一な切り抜きマージン(ポイント単位、0〜2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * マージン値は PDF ポイント単位です(1 ポイント = 1/72 インチ)。 * 同じマージンがすべてのページの 4 辺すべてに適用されます。 * マージンが `0` の場合、既存の切り抜きマージンをすべて削除し、メディアボックス全体を表示します。 --- --- url: https://docs.snapotter.com/ko/tools/pdf/crop-pdf.md description: 균일한 여백으로 PDF의 모든 페이지를 자릅니다. --- # Crop PDF {#crop-pdf} 균일한 여백을 적용하여 각 가장자리에서 콘텐츠를 동일하게 잘라내는 방식으로 PDF의 모든 페이지를 자릅니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` PDF 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | 균일한 자르기 여백(포인트 단위, 0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * 여백 값은 PDF 포인트 단위입니다(1포인트 = 1/72인치). * 동일한 여백이 모든 페이지의 네 가장자리 전부에 적용됩니다. * `0` 여백은 기존의 모든 자르기 여백을 제거하여 전체 media box를 표시합니다. --- --- url: https://docs.snapotter.com/nl/tools/pdf/crop-pdf.md description: Snijd alle pagina's van een PDF bij met een uniforme marge. --- # Crop PDF {#crop-pdf} Snijd alle pagina's van een PDF bij door een uniforme marge toe te passen, waarbij van elke rand evenveel inhoud wordt weggenomen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Accepteert multipart-formuliergegevens met een PDF-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | margin | number | Nee | `20` | Uniforme bijsnijmarge in punten (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * De margewaarde is in PDF-punten (1 punt = 1/72 inch). * Dezelfde marge wordt toegepast op alle vier de randen van elke pagina. * Een marge van `0` verwijdert alle bestaande bijsnijmarges en toont de volledige media box. --- --- url: https://docs.snapotter.com/pl/tools/pdf/crop-pdf.md description: Przytnij wszystkie strony pliku PDF jednolitym marginesem. --- # Crop PDF {#crop-pdf} Przytnij wszystkie strony pliku PDF, stosując jednolity margines i usuwając treść z każdej krawędzi w równym stopniu. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Przyjmuje dane formularza multipart z plikiem PDF oraz polem JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | Jednolity margines przycięcia w punktach (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * Wartość marginesu podawana jest w punktach PDF (1 punkt = 1/72 cala). * Ten sam margines jest stosowany do wszystkich czterech krawędzi każdej strony. * Margines `0` usuwa wszystkie istniejące marginesy przycięcia, pokazując pełną ramkę mediów (media box). --- --- url: https://docs.snapotter.com/pt-BR/tools/pdf/crop-pdf.md description: Recorte todas as páginas de um PDF com uma margem uniforme. --- # Crop PDF {#crop-pdf} Recorte todas as páginas de um PDF aplicando uma margem uniforme, cortando o conteúdo de cada borda igualmente. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Aceita dados de formulário multipart com um arquivo PDF e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | margin | number | Não | `20` | Margem de recorte uniforme em pontos (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * O valor da margem é em pontos PDF (1 ponto = 1/72 polegada). * A mesma margem é aplicada às quatro bordas de cada página. * Uma margem de `0` remove todas as margens de recorte existentes, exibindo a media box completa. --- --- url: https://docs.snapotter.com/ru/tools/pdf/crop-pdf.md description: Обрезка всех страниц PDF с равномерным полем. --- # Crop PDF {#crop-pdf} Обрежьте все страницы PDF, применив равномерное поле и отсекая содержимое от каждого края одинаково. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Принимает данные multipart form с PDF-файлом и JSON-полем `settings`. ## Parameters {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | margin | number | Нет | `20` | Равномерное поле обрезки в пунктах (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * Значение поля задаётся в пунктах PDF (1 пункт = 1/72 дюйма). * Одно и то же поле применяется ко всем четырём краям каждой страницы. * Поле, равное `0`, убирает все существующие поля обрезки, показывая полный media box. --- --- url: https://docs.snapotter.com/sv/tools/pdf/crop-pdf.md description: Beskär alla sidor i en PDF med en enhetlig marginal. --- # Crop PDF {#crop-pdf} Beskär alla sidor i en PDF genom att tillämpa en enhetlig marginal och trimma innehåll lika mycket från varje kant. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Tar emot multipart-formulärdata med en PDF-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | margin | number | Nej | `20` | Enhetlig beskärningsmarginal i punkter (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * Marginalvärdet anges i PDF-punkter (1 punkt = 1/72 tum). * Samma marginal tillämpas på alla fyra kanterna på varje sida. * En marginal på `0` tar bort alla befintliga beskärningsmarginaler och visar hela mediarutan. --- --- url: https://docs.snapotter.com/th/tools/pdf/crop-pdf.md description: ครอปทุกหน้าของ PDF ด้วยระยะขอบที่เท่ากัน --- # Crop PDF {#crop-pdf} ครอปทุกหน้าของ PDF โดยใช้ระยะขอบที่เท่ากัน ตัดเนื้อหาออกจากแต่ละขอบเท่า ๆ กัน ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` รับข้อมูลแบบ multipart form data พร้อมไฟล์ PDF และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | ระยะขอบครอปที่เท่ากันเป็นพอยต์ (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * ค่าระยะขอบมีหน่วยเป็นพอยต์ของ PDF (1 พอยต์ = 1/72 นิ้ว) * ระยะขอบเดียวกันจะถูกใช้กับทั้งสี่ขอบของทุกหน้า * ระยะขอบเท่ากับ `0` จะลบระยะขอบครอปเดิมทั้งหมด แสดงกล่องสื่อ (media box) เต็มขนาด --- --- url: https://docs.snapotter.com/uk/tools/pdf/crop-pdf.md description: Обрізання всіх сторінок PDF з рівномірним полем. --- # Crop PDF {#crop-pdf} Обрізайте всі сторінки PDF, застосовуючи рівномірне поле, яке однаково обтинає вміст з кожного краю. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Приймає багаточастинні (multipart) дані форми з файлом PDF та полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | Рівномірне поле обрізки в пунктах (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * Значення поля вказується в пунктах PDF (1 пункт = 1/72 дюйма). * Однакове поле застосовується до всіх чотирьох країв кожної сторінки. * Поле `0` видаляє всі наявні поля обрізки, показуючи повний медіабокс. --- --- url: https://docs.snapotter.com/vi/tools/pdf/crop-pdf.md description: Cắt xén tất cả các trang của một PDF với lề đồng nhất. --- # Crop PDF {#crop-pdf} Cắt xén tất cả các trang của một PDF bằng cách áp dụng một lề đồng nhất, cắt bỏ nội dung ở mỗi cạnh bằng nhau. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` Chấp nhận dữ liệu biểu mẫu multipart với một tệp PDF và một trường JSON `settings`. ## Parameters {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | margin | number | Không | `20` | Lề cắt xén đồng nhất tính bằng điểm (0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * Giá trị lề được tính bằng điểm PDF (1 điểm = 1/72 inch). * Cùng một lề được áp dụng cho cả bốn cạnh của mọi trang. * Lề `0` loại bỏ tất cả các lề cắt xén hiện có, hiển thị toàn bộ media box. --- --- url: https://docs.snapotter.com/zh-CN/tools/pdf/crop-pdf.md description: 以统一的边距裁剪 PDF 的所有页面。 --- # Crop PDF {#crop-pdf} 通过应用统一边距裁剪 PDF 的所有页面,从每条边等量地裁去内容。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/crop-pdf` 接受包含一个 PDF 文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | margin | number | No | `20` | 以点为单位的统一裁剪边距(0-2000) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/crop-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"margin": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2440000 } ``` ## Notes {#notes} * 边距值以 PDF 点为单位(1 点 = 1/72 英寸)。 * 相同的边距会应用到每一页的全部四条边。 * 边距为 `0` 会移除所有现有的裁剪边距,显示完整的媒体框。 --- --- url: https://docs.snapotter.com/ar/tools/video/crop-video.md description: اقتصاص منطقة من الفيديو. --- # Crop Video {#crop-video} اقتصاص منطقة مستطيلة من الفيديو بتحديد حجم المنطقة وموضعها. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو وحقل JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | عرض منطقة الاقتصاص بالبكسل (بحد أدنى 16) | | height | integer | Yes | - | ارتفاع منطقة الاقتصاص بالبكسل (بحد أدنى 16) | | x | integer | No | `0` | الإزاحة الأفقية من الزاوية العلوية اليسرى | | y | integer | No | `0` | الإزاحة الرأسية من الزاوية العلوية اليسرى | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * يجب أن تتسع منطقة الاقتصاص ضمن أبعاد الفيديو. إذا تجاوز `x + width` أو `y + height` حجم المصدر، يُرجع الطلب خطأ 400. * الحد الأدنى لحجم الاقتصاص هو 16x16 بكسل. * تُقرَّب الأبعاد إلى أرقام زوجية كما تتطلب معظم برامج ترميز الفيديو. --- --- url: https://docs.snapotter.com/de/tools/video/crop-video.md description: Einen Bereich aus einem Video ausschneiden. --- # Crop Video {#crop-video} Einen rechteckigen Bereich aus einem Video ausschneiden, indem Größe und Position des Bereichs angegeben werden. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Nimmt Multipart-Formulardaten mit einer Videodatei und einem JSON-Feld `settings` entgegen. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Breite des Zuschneidebereichs in Pixeln (Minimum 16) | | height | integer | Yes | - | Höhe des Zuschneidebereichs in Pixeln (Minimum 16) | | x | integer | No | `0` | Horizontaler Versatz von der oberen linken Ecke | | y | integer | No | `0` | Vertikaler Versatz von der oberen linken Ecke | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Der Zuschneidebereich muss innerhalb der Videoabmessungen liegen. Wenn `x + width` oder `y + height` die Quellgröße überschreitet, gibt die Anfrage einen 400-Fehler zurück. * Die minimale Zuschneidegröße beträgt 16x16 Pixel. * Abmessungen werden auf gerade Zahlen gerundet, wie es die meisten Videocodecs erfordern. --- --- url: https://docs.snapotter.com/es/tools/video/crop-video.md description: Recorta una región de un vídeo. --- # Crop Video {#crop-video} Recorta una región rectangular de un vídeo especificando el tamaño y la posición de la región. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Acepta datos de formulario multipart con un archivo de vídeo y un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Ancho de la región de recorte en píxeles (mínimo 16) | | height | integer | Yes | - | Alto de la región de recorte en píxeles (mínimo 16) | | x | integer | No | `0` | Desplazamiento horizontal desde la esquina superior izquierda | | y | integer | No | `0` | Desplazamiento vertical desde la esquina superior izquierda | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * La región de recorte debe caber dentro de las dimensiones del vídeo. Si `x + width` o `y + height` supera el tamaño de origen, la petición devuelve un error 400. * El tamaño mínimo de recorte es de 16x16 píxeles. * Las dimensiones se redondean a números pares, tal como exigen la mayoría de los códecs de vídeo. --- --- url: https://docs.snapotter.com/fr/tools/video/crop-video.md description: Recadre une région d'une vidéo. --- # Crop Video {#crop-video} Recadre une région rectangulaire d'une vidéo en spécifiant la taille et la position de la région. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Accepte des données de formulaire multipart avec un fichier vidéo et un champ JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Largeur de la région de recadrage en pixels (minimum 16) | | height | integer | Yes | - | Hauteur de la région de recadrage en pixels (minimum 16) | | x | integer | No | `0` | Décalage horizontal par rapport au coin supérieur gauche | | y | integer | No | `0` | Décalage vertical par rapport au coin supérieur gauche | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * La région de recadrage doit tenir dans les dimensions de la vidéo. Si `x + width` ou `y + height` dépasse la taille source, la requête renvoie une erreur 400. * La taille de recadrage minimale est de 16x16 pixels. * Les dimensions sont arrondies à des nombres pairs, comme l'exigent la plupart des codecs vidéo. --- --- url: https://docs.snapotter.com/hi/tools/video/crop-video.md description: किसी वीडियो में से एक क्षेत्र क्रॉप करें। --- # Crop Video {#crop-video} क्षेत्र का आकार और स्थिति निर्दिष्ट करके किसी वीडियो में से एक आयताकार क्षेत्र क्रॉप करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | पिक्सेल में क्रॉप क्षेत्र की चौड़ाई (न्यूनतम 16) | | height | integer | Yes | - | पिक्सेल में क्रॉप क्षेत्र की ऊँचाई (न्यूनतम 16) | | x | integer | No | `0` | ऊपरी-बाएँ कोने से क्षैतिज ऑफ़सेट | | y | integer | No | `0` | ऊपरी-बाएँ कोने से ऊर्ध्वाधर ऑफ़सेट | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * क्रॉप क्षेत्र वीडियो आयामों के भीतर फिट होना चाहिए। यदि `x + width` या `y + height` स्रोत आकार से अधिक हो, तो अनुरोध 400 त्रुटि लौटाता है। * न्यूनतम क्रॉप आकार 16x16 पिक्सेल है। * अधिकांश वीडियो कोडेक की आवश्यकता के अनुसार आयामों को सम संख्याओं में गोल किया जाता है। --- --- url: https://docs.snapotter.com/id/tools/video/crop-video.md description: Memotong sebuah region dari video. --- # Crop Video {#crop-video} Memotong sebuah region persegi panjang dari video dengan menentukan ukuran dan posisi region tersebut. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Menerima multipart form data dengan file video dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Lebar region potong dalam piksel (minimum 16) | | height | integer | Yes | - | Tinggi region potong dalam piksel (minimum 16) | | x | integer | No | `0` | Offset horizontal dari sudut kiri atas | | y | integer | No | `0` | Offset vertikal dari sudut kiri atas | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Region potong harus muat di dalam dimensi video. Jika `x + width` atau `y + height` melebihi ukuran sumber, permintaan akan mengembalikan galat 400. * Ukuran potong minimum adalah 16x16 piksel. * Dimensi dibulatkan ke angka genap sebagaimana disyaratkan oleh sebagian besar codec video. --- --- url: https://docs.snapotter.com/it/tools/video/crop-video.md description: Ritaglia una regione da un video. --- # Crop Video {#crop-video} Ritaglia una regione rettangolare da un video specificando la dimensione e la posizione della regione. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Accetta dati form multipart con un file video e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Larghezza della regione di ritaglio in pixel (minimo 16) | | height | integer | Yes | - | Altezza della regione di ritaglio in pixel (minimo 16) | | x | integer | No | `0` | Offset orizzontale dall'angolo in alto a sinistra | | y | integer | No | `0` | Offset verticale dall'angolo in alto a sinistra | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * La regione di ritaglio deve rientrare nelle dimensioni del video. Se `x + width` o `y + height` supera la dimensione della sorgente, la richiesta restituisce un errore 400. * La dimensione minima di ritaglio è 16x16 pixel. * Le dimensioni vengono arrotondate a numeri pari come richiesto dalla maggior parte dei codec video. --- --- url: https://docs.snapotter.com/ja/tools/video/crop-video.md description: 動画から特定の領域を切り出します。 --- # Crop Video {#crop-video} 領域のサイズと位置を指定して、動画から矩形領域を切り出します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | 切り出す領域の幅(ピクセル単位、最小16) | | height | integer | Yes | - | 切り出す領域の高さ(ピクセル単位、最小16) | | x | integer | No | `0` | 左上隅からの水平方向のオフセット | | y | integer | No | `0` | 左上隅からの垂直方向のオフセット | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * 切り出す領域は動画の寸法内に収まる必要があります。`x + width` または `y + height` がソースサイズを超えると、リクエストは 400 エラーを返します。 * 切り出しの最小サイズは 16x16 ピクセルです。 * 寸法は、ほとんどの動画コーデックが要求するとおり偶数に丸められます。 --- --- url: https://docs.snapotter.com/ko/tools/video/crop-video.md description: 비디오에서 특정 영역을 잘라냅니다. --- # Crop Video {#crop-video} 영역의 크기와 위치를 지정하여 비디오에서 직사각형 영역을 잘라냅니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` 비디오 파일과 JSON `settings` 필드가 담긴 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | 크롭 영역 너비(픽셀, 최소 16) | | height | integer | Yes | - | 크롭 영역 높이(픽셀, 최소 16) | | x | integer | No | `0` | 왼쪽 위 모서리로부터의 수평 오프셋 | | y | integer | No | `0` | 왼쪽 위 모서리로부터의 수직 오프셋 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * 크롭 영역은 비디오 크기 안에 맞아야 합니다. `x + width` 또는 `y + height`가 원본 크기를 초과하면 요청은 400 오류를 반환합니다. * 최소 크롭 크기는 16x16 픽셀입니다. * 대부분의 비디오 코덱이 요구하는 대로 크기는 짝수로 반올림됩니다. --- --- url: https://docs.snapotter.com/nl/tools/video/crop-video.md description: Een gebied uit een video bijsnijden. --- # Crop Video {#crop-video} Snijd een rechthoekig gebied uit een video bij door de grootte en positie van het gebied op te geven. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Accepteert multipart form data met een videobestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | width | integer | Ja | - | Breedte van het bijsnijdgebied in pixels (minimaal 16) | | height | integer | Ja | - | Hoogte van het bijsnijdgebied in pixels (minimaal 16) | | x | integer | Nee | `0` | Horizontale verschuiving vanaf de linkerbovenhoek | | y | integer | Nee | `0` | Verticale verschuiving vanaf de linkerbovenhoek | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Het bijsnijdgebied moet binnen de videoafmetingen passen. Als `x + width` of `y + height` de brongrootte overschrijdt, geeft het verzoek een 400-fout terug. * De minimale bijsnijdgrootte is 16x16 pixels. * Afmetingen worden afgerond op even getallen, zoals de meeste videocodecs vereisen. --- --- url: https://docs.snapotter.com/pl/tools/video/crop-video.md description: Wykadrowanie obszaru z wideo. --- # Crop Video {#crop-video} Kadruje prostokątny obszar z wideo, określając rozmiar i położenie tego obszaru. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Przyjmuje dane formularza multipart z plikiem wideo i polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | width | integer | Tak | - | Szerokość obszaru kadrowania w pikselach (minimum 16) | | height | integer | Tak | - | Wysokość obszaru kadrowania w pikselach (minimum 16) | | x | integer | Nie | `0` | Przesunięcie poziome od lewego górnego rogu | | y | integer | Nie | `0` | Przesunięcie pionowe od lewego górnego rogu | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Obszar kadrowania musi mieścić się w wymiarach wideo. Jeśli `x + width` lub `y + height` przekracza rozmiar źródła, żądanie zwraca błąd 400. * Minimalny rozmiar kadrowania to 16x16 pikseli. * Wymiary są zaokrąglane do liczb parzystych, zgodnie z wymaganiami większości kodeków wideo. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/crop-video.md description: Recorta uma região de um vídeo. --- # Crop Video {#crop-video} Recorta uma região retangular de um vídeo especificando o tamanho e a posição da região. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | width | integer | Sim | - | Largura da região de recorte em pixels (mínimo 16) | | height | integer | Sim | - | Altura da região de recorte em pixels (mínimo 16) | | x | integer | Não | `0` | Deslocamento horizontal a partir do canto superior esquerdo | | y | integer | Não | `0` | Deslocamento vertical a partir do canto superior esquerdo | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * A região de recorte deve caber dentro das dimensões do vídeo. Se `x + width` ou `y + height` exceder o tamanho da origem, a requisição retorna um erro 400. * O tamanho mínimo de recorte é 16x16 pixels. * As dimensões são arredondadas para números pares, conforme exigido pela maioria dos codecs de vídeo. --- --- url: https://docs.snapotter.com/ru/tools/video/crop-video.md description: Обрезка области из видео. --- # Crop Video {#crop-video} Обрезка прямоугольной области из видео путём указания размера и положения области. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Принимает multipart form data с файлом видео и полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Ширина области обрезки в пикселях (минимум 16) | | height | integer | Yes | - | Высота области обрезки в пикселях (минимум 16) | | x | integer | No | `0` | Горизонтальное смещение от левого верхнего угла | | y | integer | No | `0` | Вертикальное смещение от левого верхнего угла | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Область обрезки должна помещаться в пределах размеров видео. Если `x + width` или `y + height` превышает размер исходника, запрос возвращает ошибку 400. * Минимальный размер обрезки - 16x16 пикселей. * Размеры округляются до чётных чисел, как того требует большинство видеокодеков. --- --- url: https://docs.snapotter.com/th/tools/video/crop-video.md description: ครอบตัดพื้นที่ออกจากวิดีโอ --- # Crop Video {#crop-video} ครอบตัดพื้นที่รูปสี่เหลี่ยมออกจากวิดีโอโดยระบุขนาดและตำแหน่งของพื้นที่นั้น ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | ความกว้างของพื้นที่ครอบตัดเป็นพิกเซล (ต่ำสุด 16) | | height | integer | Yes | - | ความสูงของพื้นที่ครอบตัดเป็นพิกเซล (ต่ำสุด 16) | | x | integer | No | `0` | ระยะเลื่อนแนวนอนจากมุมบนซ้าย | | y | integer | No | `0` | ระยะเลื่อนแนวตั้งจากมุมบนซ้าย | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * พื้นที่ครอบตัดต้องอยู่ภายในขนาดของวิดีโอ หาก `x + width` หรือ `y + height` เกินขนาดต้นฉบับ คำขอจะคืนค่าข้อผิดพลาด 400 * ขนาดครอบตัดต่ำสุดคือ 16x16 พิกเซล * ขนาดจะถูกปัดเป็นเลขคู่ตามที่โคเดกวิดีโอส่วนใหญ่กำหนด --- --- url: https://docs.snapotter.com/tr/tools/video/crop-video.md description: Bir videodan bir bölge kırpın. --- # Crop Video {#crop-video} Bölgenin boyutunu ve konumunu belirterek bir videodan dikdörtgen bir bölge kırpın. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Bir video dosyası ve bir JSON `settings` alanı içeren multipart form data kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Piksel cinsinden kırpma bölgesi genişliği (en az 16) | | height | integer | Yes | - | Piksel cinsinden kırpma bölgesi yüksekliği (en az 16) | | x | integer | No | `0` | Sol üst köşeden yatay ofset | | y | integer | No | `0` | Sol üst köşeden dikey ofset | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Kırpma bölgesi video boyutlarına sığmalıdır. `x + width` veya `y + height` kaynak boyutunu aşarsa, istek 400 hatası döndürür. * Minimum kırpma boyutu 16x16 pikseldir. * Boyutlar, çoğu video codec'inin gerektirdiği gibi çift sayılara yuvarlanır. --- --- url: https://docs.snapotter.com/uk/tools/video/crop-video.md description: Обрізає ділянку з відео. --- # Crop Video {#crop-video} Обрізає прямокутну ділянку з відео, задаючи розмір і положення ділянки. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Приймає дані форми multipart із відеофайлом і полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Ширина ділянки обрізання в пікселях (мінімум 16) | | height | integer | Yes | - | Висота ділянки обрізання в пікселях (мінімум 16) | | x | integer | No | `0` | Горизонтальне зміщення від верхнього лівого кута | | y | integer | No | `0` | Вертикальне зміщення від верхнього лівого кута | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Ділянка обрізання має вміщатися в розміри відео. Якщо `x + width` або `y + height` перевищує розмір джерела, запит повертає помилку 400. * Мінімальний розмір обрізання - 16x16 пікселів. * Розміри округлюються до парних чисел, як цього вимагає більшість відеокодеків. --- --- url: https://docs.snapotter.com/vi/tools/video/crop-video.md description: Cắt một vùng ra khỏi video. --- # Crop Video {#crop-video} Cắt một vùng hình chữ nhật ra khỏi video bằng cách chỉ định kích thước và vị trí của vùng đó. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` Nhận multipart form data gồm một file video và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | Chiều rộng vùng cắt tính bằng pixel (tối thiểu 16) | | height | integer | Yes | - | Chiều cao vùng cắt tính bằng pixel (tối thiểu 16) | | x | integer | No | `0` | Độ lệch ngang từ góc trên bên trái | | y | integer | No | `0` | Độ lệch dọc từ góc trên bên trái | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * Vùng cắt phải nằm gọn trong kích thước video. Nếu `x + width` hoặc `y + height` vượt quá kích thước nguồn, yêu cầu trả về lỗi 400. * Kích thước cắt tối thiểu là 16x16 pixel. * Kích thước được làm tròn thành số chẵn theo yêu cầu của hầu hết các codec video. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/crop-video.md description: 从视频中裁剪出一个区域。 --- # Crop Video {#crop-video} 通过指定区域的尺寸和位置,从视频中裁剪出一个矩形区域。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` 接受包含视频文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | 裁剪区域宽度,单位为像素(最小 16) | | height | integer | Yes | - | 裁剪区域高度,单位为像素(最小 16) | | x | integer | No | `0` | 相对于左上角的水平偏移 | | y | integer | No | `0` | 相对于左上角的垂直偏移 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * 裁剪区域必须位于视频尺寸范围内。如果 `x + width` 或 `y + height` 超出源尺寸,请求将返回 400 错误。 * 最小裁剪尺寸为 16x16 像素。 * 根据大多数视频编解码器的要求,尺寸会被舍入为偶数。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/crop-video.md description: 從影片中裁切出一個區域。 --- # Crop Video {#crop-video} 透過指定區域的大小和位置,從影片中裁切出一個矩形區域。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/crop-video` 接受包含一個影片檔案和一個 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | Yes | - | 裁切區域寬度(以像素為單位,最小 16) | | height | integer | Yes | - | 裁切區域高度(以像素為單位,最小 16) | | x | integer | No | `0` | 從左上角起算的水平偏移量 | | y | integer | No | `0` | 從左上角起算的垂直偏移量 | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/crop-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 5200000 } ``` ## Notes {#notes} * 裁切區域必須位於影片尺寸範圍內。若 `x + width` 或 `y + height` 超出來源大小,請求會回傳 400 錯誤。 * 最小裁切尺寸為 16x16 像素。 * 尺寸會四捨五入為偶數,因為大多數影片編解碼器都有此要求。 --- --- url: https://docs.snapotter.com/es/tools/files/csv-excel.md description: Convierte entre CSV y Excel (XLSX), en ambas direcciones. --- # CSV a Excel {#csv-to-excel} Convierte entre los formatos CSV y Excel (XLSX) en ambas direcciones. Sube un archivo CSV o TSV para obtener XLSX, o sube un archivo XLSX para obtener CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Acepta datos de formulario multipart con un archivo CSV, TSV o XLSX y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | Número de hoja de cálculo que se exporta al convertir desde XLSX (mín. 1) | ## Ejemplo de solicitud {#example-request} CSV a Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel a CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notas {#notes} * La dirección de conversión se detecta automáticamente a partir de la extensión del archivo de entrada: `.csv` o `.tsv` produce `.xlsx`, y `.xlsx` produce `.csv`. * El parámetro `sheet` solo se aplica al convertir desde XLSX. Selecciona qué hoja de cálculo se exporta. * Los archivos TSV (valores separados por tabuladores) se admiten junto con CSV. --- --- url: https://docs.snapotter.com/es/tools/files/csv-json.md description: Convierte entre CSV y JSON, en ambas direcciones. --- # CSV a JSON {#csv-to-json} Convierte entre los formatos CSV y JSON en ambas direcciones. Sube un archivo CSV o TSV para obtener un arreglo JSON de objetos, o sube un arreglo JSON para obtener un archivo CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Acepta datos de formulario multipart con un archivo CSV, TSV o JSON y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | Formatea la salida JSON con sangría | ## Ejemplo de solicitud {#example-request} CSV a JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON a CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notas {#notes} * La dirección de conversión se detecta automáticamente a partir de la extensión del archivo de entrada: `.csv` o `.tsv` produce `.json`, y `.json` produce `.csv`. * El parámetro `pretty` solo afecta a la salida JSON. Cuando se establece en `false`, la salida es una cadena JSON compacta de una sola línea. * La entrada JSON debe ser un arreglo de objetos con claves coherentes. Cada objeto se convierte en una fila y cada clave se convierte en un encabezado de columna. * Los archivos TSV (valores separados por tabuladores) se admiten junto con CSV. --- --- url: https://docs.snapotter.com/de/tools/files/split-csv.md description: Eine CSV nach Zeilenanzahl in kleinere Dateien aufteilen. --- # CSV aufteilen {#split-csv} Teilt eine große CSV- oder TSV-Datei nach Zeilenanzahl in kleinere Dateien auf. Gibt ein ZIP-Archiv mit den Teilen zurück. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/files/split-csv` Nimmt Multipart-Formulardaten mit einer CSV-Datei und einem JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | rowsPerFile | integer | Nein | `1000` | Anzahl der Datenzeilen pro Ausgabedatei (1-1.000.000) | | keepHeader | boolean | Nein | `true` | Die Kopfzeile in jeder Ausgabedatei wiederholen | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Hinweise {#notes} * Die Ausgabe ist immer ein ZIP-Archiv mit den aufgeteilten CSV-Teilen, die fortlaufend benannt sind (z. B. `part-1.csv`, `part-2.csv`). * Wenn `keepHeader` auf `true` steht, enthält jeder Teil die ursprüngliche Kopfzeile, sodass jede Datei eigenständig verwendet werden kann. * Sowohl CSV- als auch TSV-Dateien werden als Eingabe akzeptiert. * Die Zeilenanzahl bezieht sich nur auf Datenzeilen; die Kopfzeile wird nicht mitgezählt. --- --- url: https://docs.snapotter.com/tr/tools/files/split-csv.md description: Bir CSV'yi satır sayısına göre daha küçük dosyalara bölün. --- # CSV Böl {#split-csv} Büyük bir CSV veya TSV dosyasını satır sayısına göre daha küçük dosyalara bölün. Parçaları içeren bir ZIP arşivi döndürür. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/files/split-csv` Bir CSV dosyası ve bir JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | rowsPerFile | tam sayı | Hayır | `1000` | Çıktı dosyası başına veri satırı sayısı (1-1.000.000) | | keepHeader | boole | Hayır | `true` | Başlık satırını her çıktı dosyasında tekrarla | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Notlar {#notes} * Çıktı her zaman, sıralı olarak adlandırılmış bölünmüş CSV parçalarını içeren bir ZIP arşividir (ör. `part-1.csv`, `part-2.csv`). * `keepHeader` `true` olduğunda, her parça özgün başlık satırını içerir; böylece her dosya bağımsız olarak kullanılabilir. * Hem CSV hem de TSV dosyaları giriş olarak kabul edilir. * Satır sayısı yalnızca veri satırlarını ifade eder; başlık satırı sayılmaz. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/csv-excel.md description: Converta entre CSV e Excel (XLSX), em ambas as direções. --- # CSV para Excel {#csv-to-excel} Converta entre os formatos CSV e Excel (XLSX) em ambas as direções. Envie um arquivo CSV ou TSV para obter XLSX, ou envie um arquivo XLSX para obter CSV. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Aceita dados de formulário multipart com um arquivo CSV, TSV ou XLSX e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | sheet | integer | Não | `1` | Número da planilha a exportar ao converter de XLSX (mín. 1) | ## Exemplo de Requisição {#example-request} CSV para Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel para CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notas {#notes} * A direção da conversão é detectada automaticamente pela extensão do arquivo de entrada: `.csv` ou `.tsv` produz `.xlsx`, e `.xlsx` produz `.csv`. * O parâmetro `sheet` só se aplica ao converter de XLSX. Ele seleciona qual planilha exportar. * Arquivos TSV (valores separados por tabulação) são suportados junto com CSV. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/csv-json.md description: Converta entre CSV e JSON, em ambas as direções. --- # CSV para JSON {#csv-to-json} Converta entre os formatos CSV e JSON em ambas as direções. Envie um arquivo CSV ou TSV para obter um array JSON de objetos, ou envie um array JSON para obter um arquivo CSV. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/csv-json` Aceita dados de formulário multipart com um arquivo CSV, TSV ou JSON e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | pretty | boolean | Não | `true` | Formatar a saída JSON de forma legível, com indentação | ## Exemplo de Requisição {#example-request} CSV para JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON para CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notas {#notes} * A direção da conversão é detectada automaticamente pela extensão do arquivo de entrada: `.csv` ou `.tsv` produz `.json`, e `.json` produz `.csv`. * O parâmetro `pretty` afeta apenas a saída JSON. Quando definido como `false`, a saída é uma string JSON compacta de linha única. * A entrada JSON deve ser um array de objetos com chaves consistentes. Cada objeto se torna uma linha, e cada chave se torna um cabeçalho de coluna. * Arquivos TSV (valores separados por tabulação) são suportados junto com CSV. --- --- url: https://docs.snapotter.com/nl/tools/files/split-csv.md description: Splits een CSV op in kleinere bestanden op basis van het aantal rijen. --- # CSV splitsen {#split-csv} Splits een groot CSV- of TSV-bestand op in kleinere bestanden op basis van het aantal rijen. Retourneert een ZIP-archief met de onderdelen. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/files/split-csv` Accepteert multipart form data met een CSV-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | rowsPerFile | integer | Nee | `1000` | Aantal datarijen per uitvoerbestand (1-1.000.000) | | keepHeader | boolean | Nee | `true` | Herhaal de koprij in elk uitvoerbestand | ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Opmerkingen {#notes} * De uitvoer is altijd een ZIP-archief met de gesplitste CSV-onderdelen, opeenvolgend benoemd (bijv. `part-1.csv`, `part-2.csv`). * Wanneer `keepHeader` `true` is, bevat elk onderdeel de originele koprij, zodat elk bestand zelfstandig kan worden gebruikt. * Zowel CSV- als TSV-bestanden worden als invoer geaccepteerd. * Het rijaantal verwijst alleen naar datarijen; de koprij wordt niet meegeteld. --- --- url: https://docs.snapotter.com/de/tools/files/csv-excel.md description: Konvertiert zwischen CSV und Excel (XLSX), in beide Richtungen. --- # CSV to Excel {#csv-to-excel} Konvertiert zwischen den Formaten CSV und Excel (XLSX) in beide Richtungen. Lade eine CSV- oder TSV-Datei hoch, um XLSX zu erhalten, oder lade eine XLSX-Datei hoch, um CSV zu erhalten. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Akzeptiert Multipart-Formulardaten mit einer CSV-, TSV- oder XLSX-Datei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | sheet | integer | Nein | `1` | Nummer des zu exportierenden Arbeitsblatts beim Konvertieren aus XLSX (min. 1) | ## Example Request {#example-request} CSV zu Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel zu CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Die Konvertierungsrichtung wird automatisch aus der Dateierweiterung der Eingabe erkannt: `.csv` oder `.tsv` erzeugt `.xlsx`, und `.xlsx` erzeugt `.csv`. * Der Parameter `sheet` gilt nur beim Konvertieren aus XLSX. Er wählt aus, welches Arbeitsblatt exportiert wird. * TSV-Dateien (durch Tabulatoren getrennte Werte) werden neben CSV unterstützt. --- --- url: https://docs.snapotter.com/hi/tools/files/csv-excel.md description: CSV और Excel (XLSX) के बीच, दोनों दिशाओं में कन्वर्ट करें। --- # CSV to Excel {#csv-to-excel} CSV और Excel (XLSX) फ़ॉर्मेट के बीच दोनों दिशाओं में कन्वर्ट करें। XLSX पाने के लिए एक CSV या TSV फ़ाइल अपलोड करें, या CSV पाने के लिए एक XLSX फ़ाइल अपलोड करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` एक CSV, TSV, या XLSX फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | XLSX से कन्वर्ट करते समय निर्यात करने के लिए वर्कशीट संख्या (न्यूनतम 1) | ## Example Request {#example-request} CSV to Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * कन्वर्ज़न दिशा इनपुट फ़ाइल एक्सटेंशन से स्वतः पहचानी जाती है: `.csv` या `.tsv` `.xlsx` उत्पन्न करता है, और `.xlsx` `.csv` उत्पन्न करता है। * `sheet` पैरामीटर केवल XLSX से कन्वर्ट करते समय लागू होता है। यह चुनता है कि किस वर्कशीट को निर्यात करना है। * TSV (tab-separated values) फ़ाइलें CSV के साथ समर्थित हैं। --- --- url: https://docs.snapotter.com/id/tools/files/csv-excel.md description: Konversi antar CSV dan Excel (XLSX), kedua arah. --- # CSV to Excel {#csv-to-excel} Konversi antar format CSV dan Excel (XLSX) dalam kedua arah. Unggah file CSV atau TSV untuk mendapatkan XLSX, atau unggah file XLSX untuk mendapatkan CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Menerima multipart form data berisi file CSV, TSV, atau XLSX dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | Nomor worksheet yang diekspor saat mengonversi dari XLSX (min 1) | ## Example Request {#example-request} CSV ke Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel ke CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Arah konversi terdeteksi otomatis dari ekstensi file input: `.csv` atau `.tsv` menghasilkan `.xlsx`, dan `.xlsx` menghasilkan `.csv`. * Parameter `sheet` hanya berlaku saat mengonversi dari XLSX. Parameter ini memilih worksheet mana yang diekspor. * File TSV (nilai yang dipisahkan tab) didukung selain CSV. --- --- url: https://docs.snapotter.com/it/tools/files/csv-excel.md description: Converte tra CSV ed Excel (XLSX), in entrambe le direzioni. --- # CSV to Excel {#csv-to-excel} Converte tra i formati CSV ed Excel (XLSX) in entrambe le direzioni. Carica un file CSV o TSV per ottenere XLSX, oppure carica un file XLSX per ottenere CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Accetta dati form multipart con un file CSV, TSV o XLSX e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | Numero del foglio di lavoro da esportare quando si converte da XLSX (min 1) | ## Example Request {#example-request} CSV to Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * La direzione della conversione viene rilevata automaticamente dall'estensione del file di input: `.csv` o `.tsv` produce `.xlsx`, e `.xlsx` produce `.csv`. * Il parametro `sheet` si applica solo quando si converte da XLSX. Seleziona quale foglio di lavoro esportare. * I file TSV (valori separati da tabulazioni) sono supportati insieme a CSV. --- --- url: https://docs.snapotter.com/ja/tools/files/csv-excel.md description: CSV と Excel(XLSX)を双方向に変換します。 --- # CSV to Excel {#csv-to-excel} CSV と Excel(XLSX)形式を双方向に変換します。CSV または TSV ファイルをアップロードすると XLSX が得られ、XLSX ファイルをアップロードすると CSV が得られます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` CSV、TSV、または XLSX ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | XLSX から変換する際にエクスポートするワークシート番号(最小 1) | ## Example Request {#example-request} CSV から Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel から CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * 変換方向は入力ファイルの拡張子から自動検出されます。`.csv` または `.tsv` は `.xlsx` を生成し、`.xlsx` は `.csv` を生成します。 * `sheet` パラメータは XLSX から変換する場合にのみ適用されます。どのワークシートをエクスポートするかを選択します。 * TSV(タブ区切り値)ファイルは CSV とともにサポートされます。 --- --- url: https://docs.snapotter.com/ko/tools/files/csv-excel.md description: CSV와 Excel(XLSX) 간 양방향 변환. --- # CSV to Excel {#csv-to-excel} CSV와 Excel(XLSX) 형식 간에 양방향으로 변환합니다. CSV 또는 TSV 파일을 업로드하여 XLSX를 얻거나, XLSX 파일을 업로드하여 CSV를 얻으세요. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/files/csv-excel` CSV, TSV, 또는 XLSX 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | sheet | integer | 아니요 | `1` | XLSX에서 변환할 때 내보낼 워크시트 번호(최소 1) | ## 요청 예시 {#example-request} CSV to Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## 참고 사항 {#notes} * 변환 방향은 입력 파일 확장자로 자동 감지됩니다: `.csv` 또는 `.tsv`는 `.xlsx`을 생성하고, `.xlsx`는 `.csv`을 생성합니다. * `sheet` 매개변수는 XLSX에서 변환할 때만 적용됩니다. 내보낼 워크시트를 선택합니다. * TSV(탭 구분 값) 파일은 CSV와 함께 지원됩니다. --- --- url: https://docs.snapotter.com/nl/tools/files/csv-excel.md description: Converteer tussen CSV en Excel (XLSX), in beide richtingen. --- # CSV to Excel {#csv-to-excel} Converteer tussen CSV en Excel (XLSX) formaten in beide richtingen. Upload een CSV- of TSV-bestand om XLSX te krijgen, of upload een XLSX-bestand om CSV te krijgen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Accepteert multipart-formulierdata met een CSV-, TSV- of XLSX-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | sheet | integer | Nee | `1` | Nummer van het werkblad om te exporteren bij conversie vanuit XLSX (min. 1) | ## Example Request {#example-request} CSV naar Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel naar CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * De conversierichting wordt automatisch bepaald op basis van de bestandsextensie van de invoer: `.csv` of `.tsv` levert `.xlsx`, en `.xlsx` levert `.csv`. * De parameter `sheet` is alleen van toepassing bij conversie vanuit XLSX. Hij selecteert welk werkblad wordt geëxporteerd. * TSV-bestanden (tab-gescheiden waarden) worden naast CSV ondersteund. --- --- url: https://docs.snapotter.com/pl/tools/files/csv-excel.md description: Konwertuje między CSV a Excel (XLSX) w obu kierunkach. --- # CSV to Excel {#csv-to-excel} Konwertuje między formatami CSV a Excel (XLSX) w obu kierunkach. Prześlij plik CSV lub TSV, aby otrzymać XLSX, albo prześlij plik XLSX, aby otrzymać CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Przyjmuje dane formularza multipart z plikiem CSV, TSV lub XLSX oraz polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | sheet | integer | Nie | `1` | Numer arkusza do wyeksportowania podczas konwersji z XLSX (min. 1) | ## Example Request {#example-request} CSV na Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel na CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Kierunek konwersji jest automatycznie wykrywany na podstawie rozszerzenia pliku wejściowego: `.csv` lub `.tsv` tworzy `.xlsx`, a `.xlsx` tworzy `.csv`. * Parametr `sheet` ma zastosowanie tylko podczas konwersji z XLSX. Wybiera arkusz do wyeksportowania. * Pliki TSV (wartości rozdzielane tabulatorami) są obsługiwane obok CSV. --- --- url: https://docs.snapotter.com/sv/tools/files/csv-excel.md description: Konvertera mellan CSV och Excel (XLSX), i båda riktningarna. --- # CSV to Excel {#csv-to-excel} Konvertera mellan formaten CSV och Excel (XLSX) i båda riktningarna. Ladda upp en CSV- eller TSV-fil för att få XLSX, eller ladda upp en XLSX-fil för att få CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Tar emot multipart-formulärdata med en CSV-, TSV- eller XLSX-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | Arbetsbladsnummer att exportera vid konvertering från XLSX (minst 1) | ## Example Request {#example-request} CSV till Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel till CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Konverteringsriktningen identifieras automatiskt från indatafilens filändelse: `.csv` eller `.tsv` ger `.xlsx`, och `.xlsx` ger `.csv`. * Parametern `sheet` gäller endast vid konvertering från XLSX. Den väljer vilket arbetsblad som ska exporteras. * TSV-filer (tabbseparerade värden) stöds vid sidan av CSV. --- --- url: https://docs.snapotter.com/th/tools/files/csv-excel.md description: แปลงระหว่าง CSV และ Excel (XLSX) ทั้งสองทิศทาง --- # CSV to Excel {#csv-to-excel} แปลงระหว่างรูปแบบ CSV และ Excel (XLSX) ทั้งสองทิศทาง อัปโหลดไฟล์ CSV หรือ TSV เพื่อรับ XLSX หรืออัปโหลดไฟล์ XLSX เพื่อรับ CSV ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` รับข้อมูล multipart form ที่มีไฟล์ CSV, TSV หรือ XLSX และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | หมายเลขเวิร์กชีตที่จะส่งออกเมื่อแปลงจาก XLSX (ต่ำสุด 1) | ## Example Request {#example-request} CSV to Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * ทิศทางการแปลงถูกตรวจจับโดยอัตโนมัติจากนามสกุลไฟล์อินพุต: `.csv` หรือ `.tsv` ให้ผลเป็น `.xlsx` และ `.xlsx` ให้ผลเป็น `.csv` * พารามิเตอร์ `sheet` ใช้เฉพาะเมื่อแปลงจาก XLSX เท่านั้น โดยเลือกว่าจะส่งออกเวิร์กชีตใด * ไฟล์ TSV (ค่าที่คั่นด้วยแท็บ) ได้รับการรองรับควบคู่กับ CSV --- --- url: https://docs.snapotter.com/tr/tools/files/csv-excel.md description: CSV ve Excel (XLSX) arasında her iki yönde dönüştürün. --- # CSV to Excel {#csv-to-excel} CSV ve Excel (XLSX) formatları arasında her iki yönde dönüştürün. XLSX almak için bir CSV veya TSV dosyası yükleyin veya CSV almak için bir XLSX dosyası yükleyin. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Bir CSV, TSV veya XLSX dosyası ve JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | XLSX'ten dönüştürürken dışa aktarılacak çalışma sayfası numarası (min 1) | ## Example Request {#example-request} CSV'den Excel'e: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel'den CSV'ye: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Dönüştürme yönü giriş dosyası uzantısından otomatik olarak algılanır: `.csv` veya `.tsv` `.xlsx` üretir ve `.xlsx` `.csv` üretir. * `sheet` parametresi yalnızca XLSX'ten dönüştürürken geçerlidir. Hangi çalışma sayfasının dışa aktarılacağını seçer. * TSV (sekme ile ayrılmış değerler) dosyaları CSV ile birlikte desteklenir. --- --- url: https://docs.snapotter.com/uk/tools/files/csv-excel.md description: Конвертація між CSV та Excel (XLSX) в обох напрямках. --- # CSV to Excel {#csv-to-excel} Конвертація між форматами CSV та Excel (XLSX) в обох напрямках. Завантажте файл CSV чи TSV, щоб отримати XLSX, або завантажте файл XLSX, щоб отримати CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Приймає дані форми multipart з файлом CSV, TSV чи XLSX та JSON-полем `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | Номер аркуша для експорту під час конвертації з XLSX (мінімум 1) | ## Example Request {#example-request} CSV у Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel у CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Напрямок конвертації визначається автоматично з розширення вхідного файлу: `.csv` або `.tsv` дає `.xlsx`, а `.xlsx` дає `.csv`. * Параметр `sheet` застосовується лише під час конвертації з XLSX. Він вибирає, який аркуш експортувати. * Файли TSV (значення, розділені табуляцією) підтримуються поряд із CSV. --- --- url: https://docs.snapotter.com/vi/tools/files/csv-excel.md description: Chuyển đổi giữa CSV và Excel (XLSX), cả hai chiều. --- # CSV to Excel {#csv-to-excel} Chuyển đổi giữa các định dạng CSV và Excel (XLSX) theo cả hai chiều. Tải lên tệp CSV hoặc TSV để nhận XLSX, hoặc tải lên tệp XLSX để nhận CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Nhận dữ liệu multipart form với một tệp CSV, TSV hoặc XLSX và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | Số thứ tự trang tính cần xuất khi chuyển từ XLSX (tối thiểu 1) | ## Example Request {#example-request} CSV sang Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel sang CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * Chiều chuyển đổi được tự động phát hiện từ phần mở rộng tệp đầu vào: `.csv` hoặc `.tsv` tạo ra `.xlsx`, còn `.xlsx` tạo ra `.csv`. * Tham số `sheet` chỉ áp dụng khi chuyển từ XLSX. Nó chọn trang tính nào để xuất. * Các tệp TSV (giá trị phân tách bằng tab) được hỗ trợ song song với CSV. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/csv-excel.md description: 在 CSV 与 Excel(XLSX)之间双向转换。 --- # CSV to Excel {#csv-to-excel} 在 CSV 与 Excel(XLSX)格式之间双向转换。上传 CSV 或 TSV 文件可得到 XLSX,或上传 XLSX 文件可得到 CSV。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` 接受包含 CSV、TSV 或 XLSX 文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | 从 XLSX 转换时要导出的工作表编号(最小为 1) | ## Example Request {#example-request} CSV 转 Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel 转 CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * 转换方向根据输入文件扩展名自动检测:`.csv` 或 `.tsv` 生成 `.xlsx`,而 `.xlsx` 生成 `.csv`。 * `sheet` 参数仅在从 XLSX 转换时适用。它用于选择要导出的工作表。 * 除 CSV 外,还支持 TSV(制表符分隔值)文件。 --- --- url: https://docs.snapotter.com/de/tools/files/csv-json.md description: Konvertiert zwischen CSV und JSON, in beide Richtungen. --- # CSV to JSON {#csv-to-json} Konvertiert zwischen den Formaten CSV und JSON in beide Richtungen. Lade eine CSV- oder TSV-Datei hoch, um ein JSON-Array von Objekten zu erhalten, oder lade ein JSON-Array hoch, um eine CSV-Datei zu erhalten. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Akzeptiert Multipart-Formulardaten mit einer CSV-, TSV- oder JSON-Datei und einem JSON-Feld `settings`. ## Parameters {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | pretty | boolean | Nein | `true` | JSON-Ausgabe mit Einrückung formatiert ausgeben | ## Example Request {#example-request} CSV zu JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON zu CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Die Konvertierungsrichtung wird automatisch aus der Dateierweiterung der Eingabe erkannt: `.csv` oder `.tsv` erzeugt `.json`, und `.json` erzeugt `.csv`. * Der Parameter `pretty` wirkt sich nur auf die JSON-Ausgabe aus. Wenn er auf `false` gesetzt ist, ist die Ausgabe ein kompakter, einzeiliger JSON-String. * Die JSON-Eingabe muss ein Array von Objekten mit konsistenten Schlüsseln sein. Jedes Objekt wird zu einer Zeile, und jeder Schlüssel wird zu einer Spaltenüberschrift. * TSV-Dateien (durch Tabulatoren getrennte Werte) werden neben CSV unterstützt. --- --- url: https://docs.snapotter.com/hi/tools/files/csv-json.md description: CSV और JSON के बीच, दोनों दिशाओं में कन्वर्ट करें। --- # CSV to JSON {#csv-to-json} CSV और JSON फ़ॉर्मेट के बीच दोनों दिशाओं में कन्वर्ट करें। ऑब्जेक्ट्स का एक JSON ऐरे पाने के लिए एक CSV या TSV फ़ाइल अपलोड करें, या CSV फ़ाइल पाने के लिए एक JSON ऐरे अपलोड करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` एक CSV, TSV, या JSON फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | इंडेंटेशन के साथ JSON आउटपुट को Pretty-print करें | ## Example Request {#example-request} CSV to JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * कन्वर्ज़न दिशा इनपुट फ़ाइल एक्सटेंशन से स्वतः पहचानी जाती है: `.csv` या `.tsv` `.json` उत्पन्न करता है, और `.json` `.csv` उत्पन्न करता है। * `pretty` पैरामीटर केवल JSON आउटपुट को प्रभावित करता है। जब `false` पर सेट किया जाता है, तो आउटपुट एक कॉम्पैक्ट सिंगल-लाइन JSON स्ट्रिंग होता है। * JSON इनपुट सुसंगत कुंजियों वाले ऑब्जेक्ट्स का एक ऐरे होना चाहिए। प्रत्येक ऑब्जेक्ट एक पंक्ति बन जाता है, और प्रत्येक कुंजी एक कॉलम हेडर बन जाती है। * TSV (tab-separated values) फ़ाइलें CSV के साथ समर्थित हैं। --- --- url: https://docs.snapotter.com/id/tools/files/csv-json.md description: Konversi antar CSV dan JSON, kedua arah. --- # CSV to JSON {#csv-to-json} Konversi antar format CSV dan JSON dalam kedua arah. Unggah file CSV atau TSV untuk mendapatkan array objek JSON, atau unggah array JSON untuk mendapatkan file CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Menerima multipart form data berisi file CSV, TSV, atau JSON dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | Cetak-rapi output JSON dengan indentasi | ## Example Request {#example-request} CSV ke JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON ke CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Arah konversi terdeteksi otomatis dari ekstensi file input: `.csv` atau `.tsv` menghasilkan `.json`, dan `.json` menghasilkan `.csv`. * Parameter `pretty` hanya memengaruhi output JSON. Ketika diatur ke `false`, output berupa string JSON satu baris yang kompak. * Input JSON harus berupa array objek dengan key yang konsisten. Setiap objek menjadi baris, dan setiap key menjadi header kolom. * File TSV (nilai yang dipisahkan tab) didukung selain CSV. --- --- url: https://docs.snapotter.com/it/tools/files/csv-json.md description: Converte tra CSV e JSON, in entrambe le direzioni. --- # CSV to JSON {#csv-to-json} Converte tra i formati CSV e JSON in entrambe le direzioni. Carica un file CSV o TSV per ottenere un array JSON di oggetti, oppure carica un array JSON per ottenere un file CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Accetta dati form multipart con un file CSV, TSV o JSON e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | Formatta l'output JSON con indentazione | ## Example Request {#example-request} CSV to JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * La direzione della conversione viene rilevata automaticamente dall'estensione del file di input: `.csv` o `.tsv` produce `.json`, e `.json` produce `.csv`. * Il parametro `pretty` influisce solo sull'output JSON. Quando impostato su `false`, l'output è una stringa JSON compatta su una sola riga. * L'input JSON deve essere un array di oggetti con chiavi coerenti. Ogni oggetto diventa una riga e ogni chiave diventa un'intestazione di colonna. * I file TSV (valori separati da tabulazioni) sono supportati insieme a CSV. --- --- url: https://docs.snapotter.com/ja/tools/files/csv-json.md description: CSV と JSON を双方向に変換します。 --- # CSV to JSON {#csv-to-json} CSV と JSON 形式を双方向に変換します。CSV または TSV ファイルをアップロードするとオブジェクトの JSON 配列が得られ、JSON 配列をアップロードすると CSV ファイルが得られます。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` CSV、TSV、または JSON ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | JSON 出力をインデント付きで整形して表示します | ## Example Request {#example-request} CSV から JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON から CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * 変換方向は入力ファイルの拡張子から自動検出されます。`.csv` または `.tsv` は `.json` を生成し、`.json` は `.csv` を生成します。 * `pretty` パラメータは JSON 出力にのみ影響します。`false` に設定すると、出力はコンパクトな 1 行の JSON 文字列になります。 * JSON 入力は、一貫したキーを持つオブジェクトの配列である必要があります。各オブジェクトが 1 行になり、各キーが列ヘッダーになります。 * TSV(タブ区切り値)ファイルは CSV とともにサポートされます。 --- --- url: https://docs.snapotter.com/ko/tools/files/csv-json.md description: CSV와 JSON 간 양방향 변환. --- # CSV to JSON {#csv-to-json} CSV와 JSON 형식 간에 양방향으로 변환합니다. CSV 또는 TSV 파일을 업로드하여 객체의 JSON 배열을 얻거나, JSON 배열을 업로드하여 CSV 파일을 얻으세요. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/files/csv-json` CSV, TSV, 또는 JSON 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | pretty | boolean | 아니요 | `true` | 들여쓰기와 함께 JSON 출력을 보기 좋게 출력 | ## 요청 예시 {#example-request} CSV to JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## 참고 사항 {#notes} * 변환 방향은 입력 파일 확장자로 자동 감지됩니다: `.csv` 또는 `.tsv`는 `.json`을 생성하고, `.json`는 `.csv`을 생성합니다. * `pretty` 매개변수는 JSON 출력에만 영향을 줍니다. `false`로 설정하면 출력이 한 줄로 된 간결한 JSON 문자열이 됩니다. * JSON 입력은 일관된 키를 가진 객체의 배열이어야 합니다. 각 객체가 하나의 행이 되고, 각 키가 하나의 열 헤더가 됩니다. * TSV(탭 구분 값) 파일은 CSV와 함께 지원됩니다. --- --- url: https://docs.snapotter.com/nl/tools/files/csv-json.md description: Converteer tussen CSV en JSON, in beide richtingen. --- # CSV to JSON {#csv-to-json} Converteer tussen CSV- en JSON-formaten in beide richtingen. Upload een CSV- of TSV-bestand om een JSON-array van objecten te krijgen, of upload een JSON-array om een CSV-bestand te krijgen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Accepteert multipart-formulierdata met een CSV-, TSV- of JSON-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | pretty | boolean | Nee | `true` | JSON-uitvoer opmaken met inspringing | ## Example Request {#example-request} CSV naar JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON naar CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * De conversierichting wordt automatisch bepaald op basis van de bestandsextensie van de invoer: `.csv` of `.tsv` levert `.json`, en `.json` levert `.csv`. * De parameter `pretty` heeft alleen invloed op de JSON-uitvoer. Wanneer ingesteld op `false`, is de uitvoer een compacte JSON-string op één regel. * JSON-invoer moet een array van objecten zijn met consistente sleutels. Elk object wordt een rij, en elke sleutel wordt een kolomkop. * TSV-bestanden (tab-gescheiden waarden) worden naast CSV ondersteund. --- --- url: https://docs.snapotter.com/pl/tools/files/csv-json.md description: Konwertuje między CSV a JSON w obu kierunkach. --- # CSV to JSON {#csv-to-json} Konwertuje między formatami CSV a JSON w obu kierunkach. Prześlij plik CSV lub TSV, aby otrzymać tablicę obiektów JSON, albo prześlij tablicę JSON, aby otrzymać plik CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Przyjmuje dane formularza multipart z plikiem CSV, TSV lub JSON oraz polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślny | Opis | |-----------|------|----------|---------|-------------| | pretty | boolean | Nie | `true` | Formatuje wynik JSON z wcięciami dla czytelności | ## Example Request {#example-request} CSV na JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON na CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Kierunek konwersji jest automatycznie wykrywany na podstawie rozszerzenia pliku wejściowego: `.csv` lub `.tsv` tworzy `.json`, a `.json` tworzy `.csv`. * Parametr `pretty` wpływa tylko na wynik JSON. Ustawiony na `false` powoduje, że wynikiem jest zwarty jednowierszowy ciąg JSON. * Wejście JSON musi być tablicą obiektów o spójnych kluczach. Każdy obiekt staje się wierszem, a każdy klucz nagłówkiem kolumny. * Pliki TSV (wartości rozdzielane tabulatorami) są obsługiwane obok CSV. --- --- url: https://docs.snapotter.com/sv/tools/files/csv-json.md description: Konvertera mellan CSV och JSON, i båda riktningarna. --- # CSV to JSON {#csv-to-json} Konvertera mellan formaten CSV och JSON i båda riktningarna. Ladda upp en CSV- eller TSV-fil för att få en JSON-array av objekt, eller ladda upp en JSON-array för att få en CSV-fil. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Tar emot multipart-formulärdata med en CSV-, TSV- eller JSON-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | Formatera JSON-utdata snyggt med indrag | ## Example Request {#example-request} CSV till JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON till CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Konverteringsriktningen identifieras automatiskt från indatafilens filändelse: `.csv` eller `.tsv` ger `.json`, och `.json` ger `.csv`. * Parametern `pretty` påverkar endast JSON-utdata. När den är satt till `false` blir utdata en kompakt JSON-sträng på en enda rad. * JSON-indata måste vara en array av objekt med konsekventa nycklar. Varje objekt blir en rad, och varje nyckel blir en kolumnrubrik. * TSV-filer (tabbseparerade värden) stöds vid sidan av CSV. --- --- url: https://docs.snapotter.com/th/tools/files/csv-json.md description: แปลงระหว่าง CSV และ JSON ทั้งสองทิศทาง --- # CSV to JSON {#csv-to-json} แปลงระหว่างรูปแบบ CSV และ JSON ทั้งสองทิศทาง อัปโหลดไฟล์ CSV หรือ TSV เพื่อรับอาร์เรย์ JSON ของออบเจกต์ หรืออัปโหลดอาร์เรย์ JSON เพื่อรับไฟล์ CSV ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` รับข้อมูล multipart form ที่มีไฟล์ CSV, TSV หรือ JSON และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | จัดรูปแบบผลลัพธ์ JSON ให้อ่านง่ายพร้อมการเยื้อง | ## Example Request {#example-request} CSV to JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON to CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * ทิศทางการแปลงถูกตรวจจับโดยอัตโนมัติจากนามสกุลไฟล์อินพุต: `.csv` หรือ `.tsv` ให้ผลเป็น `.json` และ `.json` ให้ผลเป็น `.csv` * พารามิเตอร์ `pretty` ส่งผลต่อผลลัพธ์ JSON เท่านั้น เมื่อตั้งค่าเป็น `false` ผลลัพธ์จะเป็นสตริง JSON บรรทัดเดียวแบบกะทัดรัด * อินพุต JSON ต้องเป็นอาร์เรย์ของออบเจกต์ที่มีคีย์ที่สอดคล้องกัน แต่ละออบเจกต์กลายเป็นหนึ่งแถว และแต่ละคีย์กลายเป็นส่วนหัวคอลัมน์ * ไฟล์ TSV (ค่าที่คั่นด้วยแท็บ) ได้รับการรองรับควบคู่กับ CSV --- --- url: https://docs.snapotter.com/tr/tools/files/csv-json.md description: CSV ve JSON arasında her iki yönde dönüştürün. --- # CSV to JSON {#csv-to-json} CSV ve JSON formatları arasında her iki yönde dönüştürün. Bir nesne dizisi olan JSON almak için bir CSV veya TSV dosyası yükleyin veya bir CSV dosyası almak için bir JSON dizisi yükleyin. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Bir CSV, TSV veya JSON dosyası ve JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | JSON çıktısını girintileme ile düzenli yazdır | ## Example Request {#example-request} CSV'den JSON'a: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON'dan CSV'ye: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Dönüştürme yönü giriş dosyası uzantısından otomatik olarak algılanır: `.csv` veya `.tsv` `.json` üretir ve `.json` `.csv` üretir. * `pretty` parametresi yalnızca JSON çıktısını etkiler. `false` olarak ayarlandığında, çıktı kompakt tek satırlık bir JSON dizesidir. * JSON girişi tutarlı anahtarlara sahip nesnelerden oluşan bir dizi olmalıdır. Her nesne bir satıra dönüşür ve her anahtar bir sütun başlığına dönüşür. * TSV (sekme ile ayrılmış değerler) dosyaları CSV ile birlikte desteklenir. --- --- url: https://docs.snapotter.com/uk/tools/files/csv-json.md description: Конвертація між CSV та JSON в обох напрямках. --- # CSV to JSON {#csv-to-json} Конвертація між форматами CSV та JSON в обох напрямках. Завантажте файл CSV чи TSV, щоб отримати масив об'єктів JSON, або завантажте масив JSON, щоб отримати файл CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Приймає дані форми multipart з файлом CSV, TSV чи JSON та JSON-полем `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | Форматований вивід JSON з відступами | ## Example Request {#example-request} CSV у JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON у CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Напрямок конвертації визначається автоматично з розширення вхідного файлу: `.csv` або `.tsv` дає `.json`, а `.json` дає `.csv`. * Параметр `pretty` впливає лише на вивід JSON. Коли встановлено `false`, вивід є компактним однорядковим рядком JSON. * Вхідні дані JSON мають бути масивом об'єктів із узгодженими ключами. Кожен об'єкт стає рядком, а кожен ключ стає заголовком стовпця. * Файли TSV (значення, розділені табуляцією) підтримуються поряд із CSV. --- --- url: https://docs.snapotter.com/vi/tools/files/csv-json.md description: Chuyển đổi giữa CSV và JSON, cả hai chiều. --- # CSV to JSON {#csv-to-json} Chuyển đổi giữa các định dạng CSV và JSON theo cả hai chiều. Tải lên tệp CSV hoặc TSV để nhận một mảng JSON các đối tượng, hoặc tải lên một mảng JSON để nhận tệp CSV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` Nhận dữ liệu multipart form với một tệp CSV, TSV hoặc JSON và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | In đẹp đầu ra JSON với thụt lề | ## Example Request {#example-request} CSV sang JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON sang CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * Chiều chuyển đổi được tự động phát hiện từ phần mở rộng tệp đầu vào: `.csv` hoặc `.tsv` tạo ra `.json`, còn `.json` tạo ra `.csv`. * Tham số `pretty` chỉ ảnh hưởng đến đầu ra JSON. Khi đặt thành `false`, đầu ra là một chuỗi JSON gọn trên một dòng. * Đầu vào JSON phải là một mảng các đối tượng có các khóa nhất quán. Mỗi đối tượng trở thành một hàng, và mỗi khóa trở thành một tiêu đề cột. * Các tệp TSV (giá trị phân tách bằng tab) được hỗ trợ song song với CSV. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/csv-json.md description: 在 CSV 与 JSON 之间双向转换。 --- # CSV to JSON {#csv-to-json} 在 CSV 与 JSON 格式之间双向转换。上传 CSV 或 TSV 文件可得到 JSON 对象数组,或上传 JSON 数组可得到 CSV 文件。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` 接受包含 CSV、TSV 或 JSON 文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | 以带缩进的方式美化输出 JSON | ## Example Request {#example-request} CSV 转 JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON 转 CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * 转换方向根据输入文件扩展名自动检测:`.csv` 或 `.tsv` 生成 `.json`,而 `.json` 生成 `.csv`。 * `pretty` 参数只影响 JSON 输出。设为 `false` 时,输出为紧凑的单行 JSON 字符串。 * JSON 输入必须是键一致的对象数组。每个对象成为一行,每个键成为一个列标题。 * 除 CSV 外,还支持 TSV(制表符分隔值)文件。 --- --- url: https://docs.snapotter.com/fr/tools/files/csv-excel.md description: Convertit entre CSV et Excel (XLSX), dans les deux sens. --- # CSV vers Excel {#csv-to-excel} Convertit entre les formats CSV et Excel (XLSX) dans les deux sens. Chargez un fichier CSV ou TSV pour obtenir un XLSX, ou chargez un fichier XLSX pour obtenir un CSV. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Accepte des données de formulaire multipart avec un fichier CSV, TSV ou XLSX et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | sheet | integer | Non | `1` | Numéro de la feuille de calcul à exporter lors de la conversion depuis XLSX (min. 1) | ## Exemple de requête {#example-request} CSV vers Excel : ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel vers CSV : ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Remarques {#notes} * Le sens de conversion est détecté automatiquement à partir de l'extension du fichier d'entrée : `.csv` ou `.tsv` produit `.xlsx`, et `.xlsx` produit `.csv`. * Le paramètre `sheet` ne s'applique que lors de la conversion depuis XLSX. Il sélectionne la feuille de calcul à exporter. * Les fichiers TSV (valeurs séparées par des tabulations) sont pris en charge au même titre que le CSV. --- --- url: https://docs.snapotter.com/fr/tools/files/csv-json.md description: Convertit entre CSV et JSON, dans les deux sens. --- # CSV vers JSON {#csv-to-json} Convertit entre les formats CSV et JSON dans les deux sens. Chargez un fichier CSV ou TSV pour obtenir un tableau JSON d'objets, ou chargez un tableau JSON pour obtenir un fichier CSV. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/csv-json` Accepte des données de formulaire multipart avec un fichier CSV, TSV ou JSON et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | Non | `true` | Met en forme la sortie JSON avec indentation | ## Exemple de requête {#example-request} CSV vers JSON : ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON vers CSV : ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Remarques {#notes} * Le sens de conversion est détecté automatiquement à partir de l'extension du fichier d'entrée : `.csv` ou `.tsv` produit `.json`, et `.json` produit `.csv`. * Le paramètre `pretty` n'affecte que la sortie JSON. Lorsqu'il est défini sur `false`, la sortie est une chaîne JSON compacte sur une seule ligne. * L'entrée JSON doit être un tableau d'objets avec des clés cohérentes. Chaque objet devient une ligne, et chaque clé devient un en-tête de colonne. * Les fichiers TSV (valeurs séparées par des tabulations) sont pris en charge au même titre que le CSV. --- --- url: https://docs.snapotter.com/ru/tools/files/csv-excel.md description: Конвертация между CSV и Excel (XLSX) в обоих направлениях. --- # CSV в Excel {#csv-to-excel} Конвертация между форматами CSV и Excel (XLSX) в обоих направлениях. Загрузите файл CSV или TSV, чтобы получить XLSX, или загрузите файл XLSX, чтобы получить CSV. ## Эндпоинт API {#api-endpoint} `POST /api/v1/tools/files/csv-excel` Принимает multipart form data с файлом CSV, TSV или XLSX и JSON-полем `settings`. ## Параметры {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | sheet | integer | Нет | `1` | Номер листа для экспорта при конвертации из XLSX (минимум 1) | ## Пример запроса {#example-request} CSV в Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel в CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Пример ответа {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Примечания {#notes} * Направление конвертации автоматически определяется по расширению входного файла: `.csv` или `.tsv` производит `.xlsx`, а `.xlsx` производит `.csv`. * Параметр `sheet` применяется только при конвертации из XLSX. Он выбирает, какой лист экспортировать. * Файлы TSV (значения, разделённые табуляцией) поддерживаются наряду с CSV. --- --- url: https://docs.snapotter.com/ru/tools/files/csv-json.md description: Конвертация между CSV и JSON в обоих направлениях. --- # CSV в JSON {#csv-to-json} Конвертация между форматами CSV и JSON в обоих направлениях. Загрузите файл CSV или TSV, чтобы получить массив объектов JSON, или загрузите массив JSON, чтобы получить файл CSV. ## Эндпоинт API {#api-endpoint} `POST /api/v1/tools/files/csv-json` Принимает multipart form data с файлом CSV, TSV или JSON и JSON-полем `settings`. ## Параметры {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | pretty | boolean | Нет | `true` | Форматированный вывод JSON с отступами | ## Пример запроса {#example-request} CSV в JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON в CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Пример ответа {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Примечания {#notes} * Направление конвертации автоматически определяется по расширению входного файла: `.csv` или `.tsv` производит `.json`, а `.json` производит `.csv`. * Параметр `pretty` влияет только на вывод JSON. При значении `false` выводом является компактная однострочная строка JSON. * Входные данные JSON должны быть массивом объектов с согласованными ключами. Каждый объект становится строкой, а каждый ключ становится заголовком столбца. * Файлы TSV (значения, разделённые табуляцией) поддерживаются наряду с CSV. --- --- url: https://docs.snapotter.com/ar/tools/files/csv-excel.md description: التحويل بين CSV وExcel (XLSX)، في الاتجاهين. --- # CSV إلى Excel {#csv-to-excel} حوِّل بين تنسيقي CSV وExcel (XLSX) في الاتجاهين. ارفع ملف CSV أو TSV للحصول على XLSX، أو ارفع ملف XLSX للحصول على CSV. ## نقطة نهاية API {#api-endpoint} `POST /api/v1/tools/files/csv-excel` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف CSV أو TSV أو XLSX وحقل JSON بصيغة `settings`. ## المعاملات {#parameters} | المعامل | النوع | مطلوب | الافتراضي | الوصف | |-----------|------|----------|---------|-------------| | sheet | integer | لا | `1` | رقم ورقة العمل المراد تصديرها عند التحويل من XLSX (الحد الأدنى 1) | ## مثال على الطلب {#example-request} CSV إلى Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel إلى CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## مثال على الاستجابة {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## ملاحظات {#notes} * يُكتشف اتجاه التحويل تلقائيًا من امتداد ملف الدخل: `.csv` أو `.tsv` يُنتج `.xlsx`، و`.xlsx` يُنتج `.csv`. * ينطبق المعامل `sheet` فقط عند التحويل من XLSX. وهو يحدّد ورقة العمل المراد تصديرها. * تُدعَم ملفات TSV (قيم مفصولة بعلامات جدولة) إلى جانب CSV. --- --- url: https://docs.snapotter.com/ar/tools/files/csv-json.md description: التحويل بين CSV وJSON، في الاتجاهين. --- # CSV إلى JSON {#csv-to-json} حوِّل بين تنسيقي CSV وJSON في الاتجاهين. ارفع ملف CSV أو TSV للحصول على مصفوفة JSON من الكائنات، أو ارفع مصفوفة JSON للحصول على ملف CSV. ## نقطة نهاية API {#api-endpoint} `POST /api/v1/tools/files/csv-json` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف CSV أو TSV أو JSON وحقل JSON بصيغة `settings`. ## المعاملات {#parameters} | المعامل | النوع | مطلوب | الافتراضي | الوصف | |-----------|------|----------|---------|-------------| | pretty | boolean | لا | `true` | طباعة خرج JSON بتنسيق أنيق مع مسافات بادئة | ## مثال على الطلب {#example-request} CSV إلى JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON إلى CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## مثال على الاستجابة {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## ملاحظات {#notes} * يُكتشف اتجاه التحويل تلقائيًا من امتداد ملف الدخل: `.csv` أو `.tsv` يُنتج `.json`، و`.json` يُنتج `.csv`. * يؤثّر المعامل `pretty` في خرج JSON فقط. عند ضبطه على `false`، يكون الخرج سلسلة JSON مضغوطة في سطر واحد. * يجب أن يكون دخل JSON مصفوفة من الكائنات ذات مفاتيح متسقة. يصبح كل كائن صفًّا، ويصبح كل مفتاح ترويسة عمود. * تُدعَم ملفات TSV (قيم مفصولة بعلامات جدولة) إلى جانب CSV. --- --- url: https://docs.snapotter.com/zh-TW/tools/files/csv-excel.md description: 在 CSV 與 Excel(XLSX)之間雙向轉換。 --- # CSV 轉 Excel {#csv-to-excel} 在 CSV 與 Excel(XLSX)格式之間雙向轉換。上傳 CSV 或 TSV 檔案以取得 XLSX,或上傳 XLSX 檔案以取得 CSV。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-excel` 接受包含一個 CSV、TSV 或 XLSX 檔案以及一個 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sheet | integer | No | `1` | 從 XLSX 轉換時要匯出的工作表編號(最小值 1) | ## Example Request {#example-request} CSV 轉 Excel: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@data.csv" \ -F 'settings={"sheet": 1}' ``` Excel 轉 CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-excel \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.xlsx" \ -F 'settings={"sheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", "originalSize": 2048, "processedSize": 5120 } ``` ## Notes {#notes} * 轉換方向會依輸入檔案的副檔名自動偵測:`.csv` 或 `.tsv` 會產生 `.xlsx`,而 `.xlsx` 會產生 `.csv`。 * `sheet` 參數只在從 XLSX 轉換時適用。它會選擇要匯出哪個工作表。 * 除了 CSV 之外,也支援 TSV(以定位字元分隔的值)檔案。 --- --- url: https://docs.snapotter.com/zh-TW/tools/files/csv-json.md description: 在 CSV 與 JSON 之間雙向轉換。 --- # CSV 轉 JSON {#csv-to-json} 在 CSV 與 JSON 格式之間雙向轉換。上傳 CSV 或 TSV 檔案以取得一個物件的 JSON 陣列,或上傳一個 JSON 陣列以取得 CSV 檔案。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/csv-json` 接受包含一個 CSV、TSV 或 JSON 檔案以及一個 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | pretty | boolean | No | `true` | 以縮排美化輸出 JSON | ## Example Request {#example-request} CSV 轉 JSON: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.csv" \ -F 'settings={"pretty": true}' ``` JSON 轉 CSV: ```bash curl -X POST http://localhost:1349/api/v1/tools/files/csv-json \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@users.json" \ -F 'settings={}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", "originalSize": 1500, "processedSize": 2200 } ``` ## Notes {#notes} * 轉換方向會依輸入檔案的副檔名自動偵測:`.csv` 或 `.tsv` 會產生 `.json`,而 `.json` 會產生 `.csv`。 * `pretty` 參數只會影響 JSON 輸出。設為 `false` 時,輸出為緊湊的單行 JSON 字串。 * JSON 輸入必須是一個具有一致鍵的物件陣列。每個物件會成為一列,每個鍵會成為一個欄位標題。 * 除了 CSV 之外,也支援 TSV(以定位字元分隔的值)檔案。 --- --- url: https://docs.snapotter.com/tr/tools/files/merge-csvs.md description: >- Eşleşen sütunlara sahip birden fazla CSV veya TSV dosyasını tek bir dosyada birleştirin. --- # CSV'leri Birleştir {#merge-csvs} Eşleşen sütunlara sahip birden fazla CSV veya TSV dosyasını tek bir birleştirilmiş dosyada bir araya getirin. Tüm giriş dosyaları aynı sütun başlıklarına sahip olmalıdır. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/files/merge-csvs` İki veya daha fazla CSV dosyası içeren multipart form verisi kabul eder. Ayarlar alanı gerekli değildir. ## Parametreler {#parameters} Bu aracın yapılandırılabilir parametresi yoktur. Eşleşen sütun başlıklarına sahip 2-20 CSV veya TSV dosyası yükleyin. ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/merge-csvs \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@january.csv" \ -F "file=@february.csv" \ -F "file=@march.csv" ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", "originalSize": 30000, "processedSize": 28500 } ``` ## Notlar {#notes} * 2 ile 20 arasında giriş dosyası gerektirir. * Tüm dosyalar aynı sütun başlıklarını paylaşmalıdır. Sütunlar eşleşmezse birleştirme başarısız olur. * Başlık satırı çıktıya bir kez dahil edilir; tüm dosyalardaki veri satırları yükleme sırasına göre art arda eklenir. * Hem CSV hem de TSV dosyaları kabul edilir, ancak tek bir istekteki tüm dosyalar aynı ayırıcıyı kullanmalıdır. --- --- url: https://docs.snapotter.com/nl/tools/files/merge-csvs.md description: >- Combineer meerdere CSV- of TSV-bestanden met overeenkomende kolommen tot één bestand. --- # CSV's samenvoegen {#merge-csvs} Combineer meerdere CSV- of TSV-bestanden met overeenkomende kolommen tot één samengevoegd bestand. Alle invoerbestanden moeten dezelfde kolomkoppen hebben. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/files/merge-csvs` Accepteert multipart form data met twee of meer CSV-bestanden. Er is geen settings-veld vereist. ## Parameters {#parameters} Deze tool heeft geen instelbare parameters. Upload 2-20 CSV- of TSV-bestanden met overeenkomende kolomkoppen. ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/merge-csvs \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@january.csv" \ -F "file=@february.csv" \ -F "file=@march.csv" ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", "originalSize": 30000, "processedSize": 28500 } ``` ## Opmerkingen {#notes} * Vereist tussen 2 en 20 invoerbestanden. * Alle bestanden moeten dezelfde kolomkoppen delen. Het samenvoegen mislukt als de kolommen niet overeenkomen. * De koprij wordt eenmaal in de uitvoer opgenomen; datarijen uit alle bestanden worden samengevoegd in uploadvolgorde. * Zowel CSV- als TSV-bestanden worden geaccepteerd, maar alle bestanden in één aanvraag moeten hetzelfde scheidingsteken gebruiken. --- --- url: https://docs.snapotter.com/de/tools/files/merge-csvs.md description: >- Mehrere CSV- oder TSV-Dateien mit übereinstimmenden Spalten zu einer einzigen zusammenführen. --- # CSVs zusammenführen {#merge-csvs} Fügt mehrere CSV- oder TSV-Dateien mit übereinstimmenden Spalten zu einer einzigen zusammengeführten Datei zusammen. Alle Eingabedateien müssen dieselben Spaltenüberschriften haben. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/files/merge-csvs` Nimmt Multipart-Formulardaten mit zwei oder mehr CSV-Dateien entgegen. Es ist kein settings-Feld erforderlich. ## Parameter {#parameters} Dieses Werkzeug hat keine konfigurierbaren Parameter. Laden Sie 2 bis 20 CSV- oder TSV-Dateien mit übereinstimmenden Spaltenüberschriften hoch. ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/merge-csvs \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@january.csv" \ -F "file=@february.csv" \ -F "file=@march.csv" ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", "originalSize": 30000, "processedSize": 28500 } ``` ## Hinweise {#notes} * Erfordert zwischen 2 und 20 Eingabedateien. * Alle Dateien müssen dieselben Spaltenüberschriften haben. Die Zusammenführung schlägt fehl, wenn die Spalten nicht übereinstimmen. * Die Kopfzeile wird in der Ausgabe einmal aufgenommen; die Datenzeilen aller Dateien werden in der Reihenfolge des Uploads aneinandergehängt. * Sowohl CSV- als auch TSV-Dateien werden akzeptiert, doch alle Dateien einer einzelnen Anfrage sollten dasselbe Trennzeichen verwenden. --- --- url: https://docs.snapotter.com/vi/guide/scim.md description: >- Thiết lập cung cấp tài khoản SCIM 2.0 để đồng bộ người dùng và nhóm từ nhà cung cấp danh tính của bạn sang SnapOtter. Bao gồm Okta, Azure AD / Entra ID, và các tích hợp tùy chỉnh. --- # Cung cấp tài khoản SCIM {#scim-provisioning} SnapOtter triển khai SCIM 2.0 (System for Cross-domain Identity Management) để tự động cung cấp người dùng và nhóm. Nhà cung cấp danh tính của bạn có thể tạo, cập nhật, vô hiệu hóa và kích hoạt lại tài khoản người dùng cũng như đồng bộ tư cách thành viên nhóm một cách tự động. ::: tip Tính năng dành cho doanh nghiệp Cung cấp tài khoản SCIM yêu cầu giấy phép **enterprise** với tính năng `scim`. Tính năng này không có sẵn trong gói team. Nếu không có tính năng này, tất cả các endpoint SCIM (ngoại trừ discovery) trả về 403. ::: ## Điều kiện tiên quyết {#prerequisites} * Một phiên bản SnapOtter đang chạy, có thể truy cập tại một URL công khai * Một khóa giấy phép enterprise với tính năng `scim` * Tài khoản SnapOtter `admin` tích hợp với đầy đủ quyền có hiệu lực. Vai trò tùy chỉnh được ủy quyền hoặc khóa API quản trị viên thiếu bất kỳ quyền quản trị viên nào đều không thể tạo hoặc thu hồi mã thông báo SCIM chung. * Quyền truy cập admin vào cài đặt cung cấp tài khoản của nhà cung cấp danh tính của bạn ## Bắt đầu nhanh {#quick-start} 1. Tạo một token bearer SCIM: ```bash curl -X POST https://photos.example.com/api/v1/enterprise/scim/token \ -H "Cookie: snapotter-session=YOUR_SESSION" \ -H "Content-Type: application/json" ``` Phản hồi chứa token. Hãy lưu lại ngay lập tức; nó không thể được truy xuất lại. ```json { "token": "so_scim_v2_a1b2c3d4e5f6...", "message": "Save this token - it cannot be retrieved again" } ``` 2. Trong nhà cung cấp danh tính của bạn, cấu hình cung cấp tài khoản SCIM với: * **Base URL**: `https://photos.example.com/api/v1/scim/v2` * **Authentication**: Bearer token (dán token từ bước 1) ## Xác thực {#authentication} Các endpoint SCIM sử dụng một token Bearer chuyên dụng, tách biệt với phiên người dùng và khóa API. ### Tạo một token {#generating-a-token} `POST /api/v1/enterprise/scim/token` tạo mã thông báo SCIM mới. Vì mã thông báo có thể cung cấp và thay đổi người dùng trên toàn bộ phiên bản nên điểm cuối này yêu cầu vai trò `admin` tích hợp sẵn với bộ quyền quản trị viên hiệu quả hoàn chỉnh. Giữ `users:manage` trong vai trò tùy chỉnh là không đủ. Token được trả về ở dạng văn bản thuần túy đúng một lần. SnapOtter chỉ lưu trữ một hash scrypt. Nếu bạn mất token, hãy thu hồi nó và tạo một token mới. Chỉ có một token SCIM hoạt động tại một thời điểm. Việc tạo một token mới sẽ thay thế token trước đó. ::: warning Phát hành lại mã thông báo sau khi nâng cấp Mã thông báo SCIM cũ chưa được phiên bản sẽ bị từ chối. Sau khi nâng cấp lên bản phát hành phát hành mã thông báo `so_scim_v2_...`, hãy tạo mã thông báo mới và cập nhật nhà cung cấp danh tính của bạn trước khi tiếp tục cấp phép. ::: ### Thu hồi một token {#revoking-a-token} `DELETE /api/v1/enterprise/scim/token` thu hồi mã thông báo SCIM hiện tại. Nó có yêu cầu quản trị tích hợp đầy đủ giống như việc tạo mã thông báo. ### Giới hạn tốc độ {#rate-limiting} Các endpoint SCIM bị giới hạn tốc độ ở mức 1000 yêu cầu mỗi phút cho mỗi token. Vượt quá giới hạn này sẽ trả về HTTP 429. ## Tài nguyên được hỗ trợ {#supported-resources} | Tài nguyên SCIM | Khái niệm SnapOtter | Tạo | Đọc | Cập nhật | Xóa | |---|---|---|---|---|---| | User | Tài khoản người dùng | Có | Có | Có | Xóa mềm | | Group | Team | Có | Có | Có | Có | ::: warning Các Group SCIM ánh xạ tới **teams** của SnapOtter, không phải vai trò. SCIM không thể đặt vai trò của người dùng. Tất cả người dùng được tạo qua SCIM đều được gán vai trò `user`. Để thay đổi vai trò của người dùng, hãy sử dụng giao diện admin của SnapOtter. ::: ## Các thao tác với người dùng {#user-operations} ### Tạo người dùng {#create-user} `POST /api/v1/scim/v2/Users` Tạo một tài khoản người dùng mới với `authProvider` đặt thành `scim` và vai trò `user`. Người dùng được gán vào team Default. Nếu `active` là `false`, vai trò được đặt thành `disabled` thay vào đó. Thuộc tính bắt buộc: `userName`. Tùy chọn: `externalId`, `emails`, `active` (mặc định `true`). ### Liệt kê và lọc người dùng {#list-and-filter-users} `GET /api/v1/scim/v2/Users` Trả về một danh sách người dùng được phân trang. Hỗ trợ các tham số truy vấn `startIndex` và `count` (tối đa 200 kết quả mỗi trang). Việc lọc chỉ hỗ trợ `eq` (bằng), trên các thuộc tính sau: * `userName eq "jane"` * `externalId eq "ext-12345"` Các toán tử lọc và thuộc tính khác trả về HTTP 400. ### Lấy người dùng {#get-user} `GET /api/v1/scim/v2/Users/:id` Trả về một người dùng duy nhất theo ID người dùng SnapOtter của họ. ### Thay thế người dùng {#replace-user} `PUT /api/v1/scim/v2/Users/:id` Thay thế các thuộc tính của người dùng. Hỗ trợ `userName`, `externalId`, `emails`, và `active`. Việc thay đổi tên người dùng được kiểm tra xung đột (409 nếu tên người dùng mới đã bị người dùng khác chiếm dụng). ### Vá người dùng {#patch-user} `PATCH /api/v1/scim/v2/Users/:id` Cập nhật một phần bằng SCIM PatchOp. Các thao tác được hỗ trợ: | Thao tác | Đường dẫn | |---|---| | `replace` | `active`, `userName`, `externalId`, `emails`, `emails[type eq "work"].value`, `name.formatted`, `displayName` | | `add` | Giống như `replace` | | `remove` | `externalId`, `emails` | Các đường dẫn `name.formatted` và `displayName` được chấp nhận để tương thích nhưng không có tác động lâu dài (SnapOtter không lưu trữ một tên hiển thị riêng biệt). Các thao tác `replace` không có giá trị (khi giá trị là một object không có `path`) cũng được hỗ trợ, với các khóa `userName`, `externalId`, `emails`, và `active`. ### Vô hiệu hóa người dùng (xóa mềm) {#deactivate-user-soft-delete} `DELETE /api/v1/scim/v2/Users/:id` SnapOtter không xóa cứng người dùng qua SCIM. Thay vào đó, DELETE thực hiện một quá trình vô hiệu hóa mềm: 1. Vai trò của người dùng được đổi từ giá trị hiện tại (ví dụ `editor`) thành `disabled:editor`, giữ nguyên vai trò gốc. 2. Mật khẩu của người dùng được xóa. 3. Tất cả các phiên đang hoạt động bị thu hồi. 4. Tất cả các khóa API bị thu hồi. Người dùng không còn có thể đăng nhập hoặc sử dụng bất kỳ khóa API nào. Dữ liệu của họ (tệp, lịch sử) được giữ lại. ### Kích hoạt lại người dùng {#reactivate-user} Để kích hoạt lại một người dùng đã bị vô hiệu hóa trước đó, hãy gửi một yêu cầu `PUT` hoặc `PATCH` với `active: true`. SnapOtter khôi phục vai trò gốc từ trước khi bị vô hiệu hóa (ví dụ `disabled:editor` trở lại thành `editor`). Nếu không thể xác định vai trò gốc, nó quay về `user`. ::: details Ví dụ: vô hiệu hóa và kích hoạt lại qua PATCH ```json // Deactivate { "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": false } ] } // Reactivate { "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": true } ] } ``` ::: ## Các thao tác với nhóm {#group-operations} Các Group SCIM ánh xạ tới các team của SnapOtter. Tạo một nhóm sẽ tạo một team. Tư cách thành viên nhóm kiểm soát người dùng thuộc về team nào. ### Tạo nhóm {#create-group} `POST /api/v1/scim/v2/Groups` Bắt buộc: `displayName`. Tùy chọn: `members` (mảng gồm `{ value: userId }`). ### Liệt kê và lọc nhóm {#list-and-filter-groups} `GET /api/v1/scim/v2/Groups` Việc lọc chỉ hỗ trợ `displayName eq "..."`. Được phân trang với `startIndex` và `count` (tối đa 200 kết quả mỗi trang). ### Lấy nhóm {#get-group} `GET /api/v1/scim/v2/Groups/:id` ### Thay thế nhóm {#replace-group} `PUT /api/v1/scim/v2/Groups/:id` Thay thế tên nhóm và toàn bộ danh sách thành viên. Các thành viên hiện có không nằm trong danh sách mới sẽ được chuyển sang team Default. ### Vá nhóm {#patch-group} `PATCH /api/v1/scim/v2/Groups/:id` Hỗ trợ các thao tác sau: | Thao tác | Đường dẫn | Tác động | |---|---|---| | `add` | `members` | Thêm người dùng vào team | | `remove` | `members[value eq "userId"]` | Chuyển người dùng sang team Default | | `replace` | `displayName` | Đổi tên team | | `replace` | `members` | Thay thế toàn bộ thành viên (các thành viên bị loại bỏ chuyển sang team Default) | ### Xóa nhóm {#delete-group} `DELETE /api/v1/scim/v2/Groups/:id` Xóa team. Tất cả thành viên của team bị xóa được chuyển sang team Default. Người dùng không bị vô hiệu hóa hoặc xóa. ## Thiết lập IdP {#idp-setup} ### Okta {#okta} 1. Trong bảng điều khiển admin của Okta, mở ứng dụng SnapOtter của bạn (hoặc tạo một ứng dụng mới). 2. Đi tới tab **Provisioning** và nhấp **Configure API Integration**. 3. Chọn **Enable API Integration** và nhập: * **Base URL**: `https://photos.example.com/api/v1/scim/v2` * **API Token**: Token bearer SCIM được tạo ở trên 4. Nhấp **Test API Credentials**, sau đó **Save**. 5. Trong mục **Provisioning > To App**, bật: * **Create Users** * **Update User Attributes** * **Deactivate Users** 6. Trong mục **Push Groups**, cấu hình những nhóm Okta nào sẽ đồng bộ thành các team SnapOtter. ### Azure AD / Entra ID {#azure-ad-entra-id} 1. Trong cổng Azure, đi tới ứng dụng doanh nghiệp SnapOtter của bạn. 2. Đi tới **Provisioning** và đặt **Provisioning Mode** thành **Automatic**. 3. Trong mục **Admin Credentials**, nhập: * **Tenant URL**: `https://photos.example.com/api/v1/scim/v2` * **Secret Token**: Token bearer SCIM được tạo ở trên 4. Nhấp **Test Connection**, sau đó **Save**. 5. Trong mục **Mappings**, cấu hình ánh xạ thuộc tính người dùng và nhóm. Các giá trị mặc định thường hoạt động, nhưng hãy xác minh rằng `userName` ánh xạ tới `userPrincipalName` hoặc `mail` theo mong muốn. 6. Đặt **Provisioning Status** thành **On** và lưu. Azure cung cấp người dùng và nhóm theo một chu kỳ đồng bộ cố định (thường là mỗi 40 phút). ## Các endpoint discovery {#discovery-endpoints} Ba endpoint này có sẵn mà không cần xác thực và mô tả các khả năng của máy chủ SCIM: | Endpoint | Mô tả | |---|---| | `GET /api/v1/scim/v2/ServiceProviderConfig` | Khả năng của máy chủ và các tính năng được hỗ trợ | | `GET /api/v1/scim/v2/Schemas` | Định nghĩa schema cho User và Group | | `GET /api/v1/scim/v2/ResourceTypes` | Các loại tài nguyên có sẵn (User, Group) | `ServiceProviderConfig` công bố các khả năng sau: | Tính năng | Được hỗ trợ | |---|---| | Patch | Có | | Bulk | Không | | Filter | Có (tối đa 200 kết quả, chỉ toán tử `eq`) | | Change password | Không | | Sort | Không | | ETag | Không | ## Hạn chế {#limitations} * **Lọc**: Chỉ hỗ trợ toán tử `eq`. Các bộ lọc phức tạp, toán tử `and`/`or`, `co` (chứa), và `sw` (bắt đầu bằng) không được triển khai. * **Thao tác hàng loạt**: Không được hỗ trợ. * **Sort và ETag**: Không được hỗ trợ. * **Vai trò**: SCIM không thể gán vai trò SnapOtter. Tất cả người dùng được cung cấp đều nhận vai trò `user`. * **MAX\_USERS**: Giới hạn của biến môi trường `MAX_USERS` không được thực thi khi tạo người dùng SCIM. Nếu bạn cần giới hạn số lượng người dùng, hãy quản lý việc gán trong IdP của bạn. * **Một token**: Chỉ một token SCIM có thể hoạt động tại một thời điểm. Nếu nhiều IdP cần quyền truy cập SCIM, chúng phải dùng chung token. * **Nhóm là team**: Các Group SCIM tương ứng với team, không phải vai trò hay nhóm quyền. ## Khắc phục sự cố {#troubleshooting} ### 403 "SCIM provisioning requires an enterprise license with the scim feature" {#\_403-scim-provisioning-requires-an-enterprise-license-with-the-scim-feature} Giấy phép của bạn không bao gồm tính năng `scim`, hoặc không có giấy phép nào được cấu hình. SCIM yêu cầu một giấy phép gói enterprise. Hãy xác minh `SNAPOTTER_LICENSE_KEY` đã được đặt và giấy phép bao gồm tính năng `scim`. ### 401 "Bearer token required" {#\_401-bearer-token-required} Yêu cầu SCIM không bao gồm header `Authorization: Bearer `. Hãy kiểm tra cấu hình cung cấp tài khoản của IdP của bạn. ### 401 "Invalid token" {#\_401-invalid-token} Mã thông báo không đúng định dạng, sử dụng định dạng không phiên bản đã ngừng hoạt động hoặc không khớp với hàm băm được lưu trữ. Tạo mã thông báo `so_scim_v2_...` hiện tại và cập nhật mã thông báo trong cài đặt cung cấp IdP của bạn. ### 401 "SCIM not configured" {#\_401-scim-not-configured} Chưa có token SCIM nào được tạo. Hãy sử dụng endpoint `POST /api/v1/enterprise/scim/token` để tạo một token. ### 409 "User already exists" / "userName already taken" {#\_409-user-already-exists-username-already-taken} Một người dùng có cùng tên người dùng đã tồn tại. Điều này có thể xảy ra khi một IdP thử lại một thao tác tạo bị thất bại. Hãy kiểm tra tên người dùng trùng lặp trong bảng điều khiển admin của SnapOtter. ### 429 "SCIM rate limit exceeded" {#\_429-scim-rate-limit-exceeded} IdP đang gửi hơn 1000 yêu cầu mỗi phút. Điều này thường xảy ra trong lần đồng bộ ban đầu quy mô lớn. Hầu hết các IdP tự động thử lại sau khi cửa sổ giới hạn tốc độ được đặt lại. Nếu sự cố vẫn tiếp diễn, hãy kiểm tra khoảng thời gian đồng bộ cung cấp tài khoản của IdP của bạn. ### Người dùng bị hủy cung cấp nhưng không bị xóa khỏi giao diện {#users-deprovisioned-but-not-removed-from-the-ui} SCIM DELETE là một quá trình vô hiệu hóa mềm. Người dùng bị vô hiệu hóa vẫn xuất hiện trong danh sách người dùng của admin với trạng thái đã tắt. Đây là thiết kế có chủ đích để dữ liệu của họ được bảo toàn. Vai trò của họ hiển thị là `disabled:`. --- --- url: https://docs.snapotter.com/pl/tools/image/barcode-read.md description: >- Skanuj obrazy w poszukiwaniu kodów QR, kodów kreskowych i kodów 2D z opatrzonym adnotacjami wynikiem. --- # Czytnik kodów kreskowych {#barcode-reader} Skanuj przesłane obrazy w poszukiwaniu wszystkich typów kodów kreskowych i kodów QR. Zwraca odkodowany tekst, typ kodu kreskowego i dane o położeniu dla każdego wykrytego kodu. Generuje również obraz z adnotacjami z kolorowymi ramkami wokół wykrytych kodów. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/barcode-read` Przyjmuje dane formularza multipart z plikiem obrazu oraz opcjonalnym polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | tryHarder | boolean | Nie | `true` | Włącz agresywny tryb skanowania dla trudniejszych do odczytania kodów kreskowych (wolniejszy, ale dokładniejszy) | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-read \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@receipt.jpg" \ -F 'settings={"tryHarder": true}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "filename": "receipt.jpg", "barcodes": [ { "type": "QRCode", "text": "https://example.com/product/123", "position": { "topLeft": { "x": 100, "y": 50 }, "topRight": { "x": 250, "y": 50 }, "bottomLeft": { "x": 100, "y": 200 }, "bottomRight": { "x": 250, "y": 200 } } }, { "type": "EAN-13", "text": "5901234123457", "position": { "topLeft": { "x": 50, "y": 400 }, "topRight": { "x": 300, "y": 400 }, "bottomLeft": { "x": 50, "y": 450 }, "bottomRight": { "x": 300, "y": 450 } } } ], "annotatedUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/annotated-receipt.png" } ``` ## Pola odpowiedzi {#response-fields} | Pole | Typ | Opis | |-------|------|-------------| | filename | string | Oryginalna nazwa pliku | | barcodes | array | Tablica wykrytych obiektów kodów kreskowych | | annotatedUrl | string lub null | Adres URL do pobrania obrazu z adnotacjami (null, jeśli nie znaleziono kodów kreskowych) | | previewUrl | string lub null | Taki sam jak annotatedUrl (dla zgodności z podglądem frontendu) | ### Obiekt kodu kreskowego {#barcode-object} | Pole | Typ | Opis | |-------|------|-------------| | type | string | Format kodu kreskowego (QRCode, EAN-13, Code128, DataMatrix, PDF417 itd.) | | text | string | Odkodowana treść kodu kreskowego | | position | object | Ramka ograniczająca ze współrzędnymi topLeft, topRight, bottomLeft, bottomRight | ## Obsługiwane typy kodów kreskowych {#supported-barcode-types} Kody kreskowe 1D: Code128, Code39, Code93, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E Kody 2D: QRCode, DataMatrix, PDF417, Aztec, MaxiCode ## Uwagi {#notes} * Używa biblioteki zxing-wasm do wykrywania kodów kreskowych. * Obraz z adnotacjami nakłada kolorowe ramki wielokątne i numerowane etykiety na każdy wykryty kod kreskowy. * W jednym obrazie można wykryć do 255 kodów kreskowych. * Jeśli nie znaleziono żadnych kodów kreskowych, `barcodes` jest pustą tablicą, a `annotatedUrl` ma wartość null. * Tryb `tryHarder` przeprowadza dokładniejsze skanowanie kosztem czasu przetwarzania. Wyłącz go, aby szybciej przetwarzać czyste, dobrze wyrównane kody kreskowe. * Wynik z adnotacjami jest zawsze w formacie PNG. * Dane wejściowe HEIC, RAW, PSD i SVG są automatycznie dekodowane przed skanowaniem. * Orientacja EXIF jest automatycznie stosowana przed przetworzeniem. --- --- url: https://docs.snapotter.com/it/tools/files/markdown-to-pdf.md description: Converte un file Markdown in un PDF con stile applicato. --- # Da Markdown a PDF {#markdown-to-pdf} Converte un file Markdown in un documento PDF con stile applicato. Le risorse remote sono disabilitate per motivi di privacy. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/files/markdown-to-pdf` Accetta dati di form multipart con un file Markdown. ## Parametri {#parameters} Questo strumento non ha parametri configurabili. Carica un file Markdown e verrà convertito in PDF. ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/markdown-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.md" ``` ## Esempio di risposta {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Note {#notes} * Formati di input accettati: `.md`, `.markdown`. * Le risorse remote (immagini, fogli di stile referenziati tramite URL) non vengono scaricate per motivi di privacy e sicurezza. * Il Markdown viene prima renderizzato in HTML, poi convertito in PDF tramite WeasyPrint. * Blocchi di codice, tabelle e altri elementi Markdown vengono formattati nell'output PDF. --- --- url: https://docs.snapotter.com/it/tools/files/powerpoint-to-pdf.md description: Converte le presentazioni in PDF. --- # Da PowerPoint a PDF {#powerpoint-to-pdf} Converte presentazioni PowerPoint o OpenDocument in PDF, con una diapositiva per pagina. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/files/powerpoint-to-pdf` Accetta dati di form multipart con un file PowerPoint/ODP. ## Parametri {#parameters} Questo strumento non ha parametri configurabili. Carica una presentazione e verrà convertita in PDF. ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/powerpoint-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@slides.pptx" ``` ## Esempio di risposta {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Note {#notes} * Formati di input accettati: `.pptx`, `.ppt`, `.odp`. * Ogni diapositiva diventa una pagina nel PDF. * La conversione è gestita da LibreOffice in esecuzione headless sul server. * Animazioni e transizioni non sono incluse nell'output PDF. --- --- url: https://docs.snapotter.com/it/tools/files/word-to-pdf.md description: Converte documenti Word in PDF. --- # Da Word a PDF {#word-to-pdf} Converte documenti Word, testo OpenDocument, RTF o file di testo semplice in PDF. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/files/word-to-pdf` Accetta dati di form multipart con un file Word/ODT/RTF/TXT. ## Parametri {#parameters} Questo strumento non ha parametri configurabili. Carica un documento e verrà convertito in PDF. ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/word-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@report.docx" ``` ## Esempio di risposta {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Note {#notes} * Formati di input accettati: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. * La conversione è gestita da LibreOffice in esecuzione headless sul server. * I font incorporati nel documento vengono usati quando disponibili; altrimenti vengono sostituiti con i font di sistema. * Intestazioni, piè di pagina, tabelle e immagini sono mantenuti nell'output PDF. --- --- url: https://docs.snapotter.com/it/tools/files/xml-to-csv.md description: Estrae elementi ripetuti da un XML in una tabella CSV. --- # Da XML a CSV {#xml-to-csv} Estrae elementi ripetuti da un file XML in una tabella CSV piatta. Lo strumento trova automaticamente il primo array di oggetti nell'albero XML e mappa ogni elemento a una riga. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/files/xml-to-csv` Accetta dati di form multipart con un file XML. Non è richiesto alcun campo di impostazioni. ## Parametri {#parameters} Questo strumento non ha parametri configurabili. L'elemento ripetuto viene rilevato automaticamente dalla struttura XML. ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/xml-to-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@catalog.xml" ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/catalog.csv", "originalSize": 4500, "processedSize": 1800 } ``` ## Note {#notes} * Sono accettati come input solo file `.xml`. * Lo strumento analizza l'albero XML alla ricerca del primo insieme ripetuto di elementi fratelli e li usa come righe. * Ogni nome univoco di elemento figlio o attributo diventa un'intestazione di colonna CSV. * Questa è una conversione a senso unico. Per la conversione bidirezionale JSON/XML, usa lo strumento [Da JSON a XML](/it/tools/files/json-xml). --- --- url: https://docs.snapotter.com/tr/guide/deployment.md description: >- SnapOtter'ı Docker ile üretime dağıtın. Donanım gereksinimleri, GPU kurulumu ve Nginx, Traefik ve Cloudflare için ters proxy yapılandırmaları. --- # Dağıtım {#deployment} SnapOtter, 3 konteynerli bir Docker Compose yığını olarak dağıtılır: SnapOtter uygulama imajı, PostgreSQL 17 ve Redis 8. Uygulama imajı **linux/amd64** (AI hızlandırması için NVIDIA CUDA ile) ve **linux/arm64** (CPU) mimarilerini destekler, bu nedenle Intel/AMD sunucularda, Apple Silicon Mac'lerde ve Raspberry Pi 4/5 gibi ARM cihazlarda yerel olarak çalışır. VA-API, Quick Sync veya OpenCL üzerinden Intel/AMD iGPU hızlandırması şu anda AI çıkarımı için desteklenmemektedir. GPU kurulumu, Docker Compose örnekleri ve sürüm sabitleme için [Docker İmajı](./docker-tags) sayfasına bakın. ::: info Korece OCR uyumluluğu Hızlı OCR `auto`, `en`, `de`, `es`, `fr`, `zh` ve `ja` dillerini destekler, ancak Koreceyi (`ko`) desteklemez. Korece için doğru OCR paketi ve `balanced` ya da `best` gerekir. Paket resmi Linux amd64 ve arm64 kapsayıcılarında, OCR’nin CPU’da kaldığı NVIDIA ana bilgisayarları dahil çalışır. Desteklenmeyen sistemler açık bir uyumluluk hatası alır ve sessizce `fast` seçeneğine dönülmez. Korece ile `fast` veya eski `tesseract` diğer adı kuyruk öncesinde `FEATURE_INCOMPATIBLE` ve `fast-korean-unsupported` ile reddedilir. ::: ## Hızlı Başlangıç (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` Uygulama daha sonra `http://localhost:1349` adresinde kullanılabilir olur. > **Docker Hub hız sınırları mı?** Bunun yerine GitHub Container Registry'den çekmek için `snapotter/snapotter:latest` ifadesini `ghcr.io/snapotter-hq/snapotter:latest` ile değiştirin. Her iki kayıt defteri de her sürümde aynı imajı alır. ## Hızlı Başlangıç (NVIDIA CUDA) {#quick-start-nvidia-cuda} Desteklenen AI araçlarında NVIDIA CUDA hızlandırma için (arka planı kaldırma, yükseltme, yüz geliştirme): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Yerel olmayan dağıtımlar için bunu değiştirin POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### GPU hızlandırmayı doğrulayın {#verify-gpu-acceleration} Günlüklerde CUDA algılamasını kontrol edin: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` `--gpus all` ve NVIDIA Container Toolkit doğru ayarlanmış olmasına rağmen AI araçları CPU'da çalışıyorsa, etkilenen paketi (örneğin Arka Plan Kaldırma) **Ayarlar → AI Özellikleri**'nden yeniden yükleyin. Yükleyici, ONNX Runtime'ın GPU yapısını geri yükler; başka bir paket (transkripsiyon gibi) tarafından çekilen yalnızca CPU içeren bir yapı, aksi takdirde paylaşılan AI ortamında gölge oluşturabilir. Kullanıcı arayüzünden yeniden yükleme eski bir görüntüdeki GPU'yu geri yüklemezse, [sorun #490](https://github.com/snapotter-hq/SnapOtter/issues/490)'daki manuel onarıma bakın. ## Donanım Gereksinimleri {#hardware-requirements} Bu sayılar, NVIDIA RTX 4070'li modern bir amd64 iş istasyonundan Raspberry Pi'ye kadar çeşitli sistemlerde yapılan kıyaslamalardan gelmektedir; her birinde tüm araç kataloğu çalıştırılmış ve gerçek alt sınırı bulmak için Docker kaynak limitleri taranmıştır. Bu seviyelerin alt ucunda mı çalışıyorsunuz (bir Pi, eski bir dizüstü, 2 GB'lık bir VPS)? [Düşük Kaynaklı Kurulumlar](/tr/guide/low-resource) bu sayıları, ayarlanmış sınırlar içeren somut bir adım adım kılavuza dönüştürür. ### Hızlı Referans {#quick-reference} | Seviye | Kullanım Senaryosu | CPU | RAM | GPU | Depolama | |------|----------|-----|-----|-----|---------| | Minimum | Görsel, dosya ve hafif PDF araçları; tek kullanıcı; küçük gruplar | 2 çekirdek | 2 GB | Yok | ~7 GB | | Önerilen | Video, PDF ve CPU üzerinde AI dahil beş modalitenin tamamı; gruplar; birkaç kullanıcı | 4 çekirdek | 4 GB | Yok | ~25 GB | | Tam | GPU AI dahil her şey hızlı; büyük gruplar; çok kullanıcı | 6-8 çekirdek | 8 GB | NVIDIA 8 GB+ VRAM (12 GB rahat) | ~35 GB | **Mimari: yalnızca 64-bit** (`linux/amd64` veya `linux/arm64`). SnapOtter, Intel/AMD sunucularda, Apple Silicon Mac'lerde ve **Raspberry Pi 4 ve 5** (4-8 GB) dahil 64-bit ARM kartlarında yerel olarak çalışır. 32-bit ARM (`armv7`/`armhf`) üzerinde **çalışmaz** (bunun için imaj oluşturulmamıştır) ve bellek alt sınırının altında kalan Pi Zero gibi 512 MB sınıfı kartlarda da çalışmaz (aşağıya bakın). ### Minimum (görsel, dosya ve hafif PDF araçları; AI yok) {#minimum-image-files-and-light-pdf-tools-no-ai} | Kaynak | Gereksinim | |---|---| | CPU | 2 çekirdek | | RAM | 2 GB | | Disk | ~5,5 GB (imaj) + veri birimi | | GPU | Gerekli değil | 222 AI olmayan katalog aracının tamamı - görsel (yeniden boyutlandırma, kırpma, dönüştürme, sıkıştırma, ayarlama, filigran), video (kırpma, sessize alma, remux), ses (dönüştürme, normalleştirme, kırpma), PDF (birleştirme, bölme, sıkıştırma, döndürme, koruma), dosya dönüştürmeleri ve özel dönüştürme ön ayarları - mütevazı donanımlarda çalışır. Çoğu işlem büyük bir dosyada bile bir saniyenin çok altında tamamlanır: 2,7 MB'lık bir görsel ~0,05 sn içinde yeniden boyutlandırılır ve ~2 sn içinde WebP'ye yeniden kodlanır. Bellek alt sınırı gerçektir; Docker kaynak limiti taramasından: **512 MB yığını başlatamaz** (tek bir görsel yeniden boyutlandırması bile sonlandırılır), **1 GB** tek dosya işlemlerini idare eder ancak çok dosyalı bir grup belleği tüketir ve **2 GB / 2 çekirdek**, grupları rahatça idare eden en küçük yapılandırmadır. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **Tek CPU yoğun istisna video yeniden kodlamadır.** Akış kopyalama işlemleri (kırpma, sessize alma, konteyner remux) anlıktır, ancak farklı bir codec'e kod dönüştürme CPU'ya bağlıdır. VP9'a (WebM) yeniden kodlanan 1080p / 45 saniyelik bir klip, hızlı modern bir CPU'da kabaca **~40 sn**, Apple Silicon'da ~45 sn, eski bir mobil 4 çekirdekli işlemcide ~80 sn ve eski bir 4 çekirdekli sunucuda **~130 sn** sürer. İş yükünüz video ağırlıklıysa, CPU çekirdeklerine ve saat hızına öncelik verin veya konteynerin `cpus:` limitini yükseltin; birlikte gelen compose, uygulamayı varsayılan olarak 4 çekirdekle sınırlar (GPU compose'da 8). ### Önerilen (CPU üzerinde AI araçları) {#recommended-ai-tools-on-cpu} | Kaynak | Gereksinim | |---|---| | CPU | 4 çekirdek | | RAM | 4 GB | | Disk | 3 GB (görüntü) + yaklaşık 20 GB (tüm isteğe bağlı AI paketleri) + çalışma alanı | | GPU | Gerekli değil (CPU yedeği) | **Daha büyük AI paketlerini yüklemek ve çalıştırmak, öneriyi 4 GB RAM'ye iten şeydir.** Hiçbir isteğe bağlı paket yüklenmediğinde uygulama 360 MB civarında boşta kalır. Eski Python araçları bir sidecar'yi paylaşırken, doğru OCR, aktif değişmez nesle sabitlenmiş özel, uzun ömürlü bir dispatcher kullanır. Etkinleştirmeden önce yükleyici aday üzerinde bir smoke test çalıştırır. Daha sonra atomik olarak yeni dispatcher'ye geçer ve garbage collection'den önce önceki dispatcher'yi boşaltır. Her resmi doğru OCR yapıtı, en kötü durum release suite'yi 4 GiB cgroup içinde geçmelidir; 4 GB ana bilgisayar önerisi ise Node.js uygulaması, Postgres, Redis, kuyruklar ve eşzamanlı çalışma için boşluk bırakır. Çoğu AI aracı CPU'da gayet kullanılabilir; birkaçı gerçekten bir GPU ister. Modern bir 4 çekirdekli CPU üzerinde ölçülmüştür: | AI Aracı | CPU Süresi | CPU'da Kullanılabilir mi? | |---|---|---| | Yüz algılama (yüz bulanıklaştırma, akıllı kırpma, kırmızı göz), gürültü giderme | 1 sn'nin altında | Evet | | OCR, transkripsiyon, altyazılar | 1-3 sn | Evet | | Renklendirme, yüz iyileştirme | ~10 sn | Evet | | Arka plan kaldırma / değiştirme / bulanıklaştırma | ~29 sn | Evet (beklersiniz) | | AI ölçek büyütme (RealESRGAN) | küçükte ~33 sn; büyük görsellerde dakikalar | Sınırda - GPU şiddetle önerilir | | Fotoğraf restorasyonu (tam ardışık düzen) | birkaç dakika | Hayır - GPU veya hızlı çok çekirdekli bir CPU gerektirir | SnapOtter bu model indirmelerini kasıtlı olarak Docker imajına gömmez. AI paketleri yalnızca bir yönetici ilgili aracı etkinleştirdiğinde çekilir, kalıcı `/data/ai` biriminde saklanır ve aynı model yığınına bağımlı her araç tarafından paylaşılır. Bu, son konteyner imajını küçük tutarken, tam bir AI kurulumunun aşağıdaki daha büyük depolama sayılarına ulaşmasına da izin verir. Bazı araçlar birden fazla paylaşılan pakete bağımlıdır. Örneğin, Pasaport Fotoğrafı hem `background-removal` hem de `face-detection` gerektirir; `background-removal` zaten kuruluysa, Pasaport Fotoğrafı'nı etkinleştirmek yalnızca eksik `face-detection` paketini indirir. Aynı yeniden kullanım tüm AI araçlarında geçerlidir. İsteğe bağlı AI paketi depolama tahminleri: | Paket | Disk Boyutu | |---|---| | Arka plan kaldırma | 4-5 GB | | Ölçek büyütme + Yüz iyileştirme + Gürültü giderme | 5-6 GB | | Yüz algılama | 200-300 MB | | Nesne silici + Renklendirme | 1-2 GB | | Doğru OCR (`balanced`/`best`) | ~208-234 MiB indir / ~409-488 MiB kuruldu | | Fotoğraf restorasyonu | 4-5 GB | | Transkripsiyon | ~600MB | | **Tüm paketler** | **~20 GB yüklü** | Hızlı OCR, Tesseract aracılığıyla görüntüye yerleşiktir, yaklaşık 25 MiB ekler ve isteğe bağlı OCR paketini veya 4 GiB bellek gereksinimini gerektirmez. Doğru paket, resmi Linux amd64 ve arm64 kaplarında mevcuttur ve CPU üzerinde ONNX Runtime'yi çalıştırır. NVIDIA ana bilgisayarları aynı CPU OCR çalışma zamanını kullanır, bu nedenle OCR, CUDA sürümüne veya GPU mimarisine bağlı değildir. Doğru çalışma zamanı en az 4 GiB etkili bellek gerektirir: yapılandırılmış kapsayıcı cgroup sınırı, aksi takdirde ana bilgisayar belleği. SnapOtter, paketi indirmeden önce minimum imzalı uyumluluk altındaki sistemleri reddeder. libc ve Python ABI garanti edilemeyen bare-metal/önceden oluşturulmuş arşivlerde de doğru paket kurulumu reddedilir. Aynı `DATA_DIR` dizinini paylaşan replikalar aynı CPU mimarisini kullanmalıdır; çok replikalı dağıtımları düğüm benzeşimiyle uyumlu düğümlere sabitleyin. Karma amd64/arm64 replikaları için ayrı veri depolama birimleri ve bağımsız SnapOtter dağıtımları gerekir. Doğru çalışma zamanı, bir aktif nesli tutar ve etkinleştirmeden sonra indirme önbelleğini temizler. Bu sürüm için, ilk kurulumda arşiv artı hazırlama için geçici olarak yaklaşık 620-720 MiB gerekir ve eski nesil aktif kalırken yükseltme 1,2 GiB civarında zirve yapabilir. Yükleyici, indirmeden veya çıkarmadan önce imzalı dizinden ve mevcut nesillerden tam gereksinimi hesaplar ve veri hacmi çok küçükse erken başarısız olur. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Tam (NVIDIA CUDA üzerinde AI araçları) {#full-ai-tools-on-nvidia-cuda} | Kaynak | Gereksinim | |---|---| | CPU | 6-8 çekirdek (video hazırlığı + eşzamanlılık, GPU AI ile bile CPU üzerinde çalışır) | | RAM | 8 GB | | GPU | 8+ GB VRAM'li NVIDIA (12 GB önerilir) | | Disk | toplam ~35 GB | Bir NVIDIA GPU (CUDA), ağır AI modellerini önemli ölçüde hızlandırır. Modern bir CPU'ya karşı RTX 4070 üzerinde ölçülmüştür: | AI Aracı | GPU ile Hızlanma | Notlar | |---|---|---| | AI ölçek büyütme (RealESRGAN 2×) | **~47×** | En büyük kazanç - ~33 sn'ye karşı bir saniyenin altında (büyük görsellerde dakikalar) | | Yüz iyileştirme (CodeFormer) | **~12×** | ~11 sn'ye karşı ~0,9 sn | | Transkripsiyon (Whisper) | ~4,5× | | | Arka plan kaldırma / değiştirme / bulanıklaştırma | ~4× | CPU'da ~29 sn'ye karşı GPU'da ~7 sn | | Renklendirme | ~1,8× | | | OCR, yüz algılama, kırmızı göz, gürültü giderme | ~1× | CPU'da zaten hızlı - bir GPU yardımcı olmaz | | Fotoğraf restorasyonu | yok | GPU'da bile CPU'ya bağlı (%0 GPU kullanımı); burada hızlı bir CPU bir GPU'dan daha önemlidir | GPU'ya değecek araçlar **ölçek büyütme, yüz iyileştirme, transkripsiyon ve arka plan kaldırma**dır. Yüz algılama, OCR ve kırmızı göz CPU'ya bağlıdır ve zaten hızlıdır, bu nedenle bir GPU hiçbir şey katmaz. Pik VRAM kullanımı, yüz iyileştirmeli ölçek büyütme sırasında 7,5 GB'a ulaşır. 6 GB'lık bir NVIDIA GPU çoğu AI aracında ayrı ayrı çalışır ancak ölçek büyütmede başarısız olur. 8-12 GB VRAM her şeyi idare eder. VA-API, Quick Sync veya OpenCL üzerinden Intel/AMD iGPU hızlandırması şu anda AI çıkarımı için desteklenmemektedir. `/dev/dri` öğesini konteynere eşlemek AI GPU hızlandırmasını etkinleştirmez; NVIDIA CUDA mevcut olmadıkça SnapOtter AI araçlarını CPU üzerinde çalıştırır. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Eşzamanlı Kullanıcılar {#concurrent-users} Varsayılan 4 çekirdekle sınırlı uygulama konteynerine karşı paralel görsel yeniden boyutlandırma istekleri: | Eşzamanlı İstekler | Ort. Yanıt Süresi | Hatalar | |---|---|---| | 1 | 0,4sn | 0 | | 5 | 1,2sn | 0 | | 10 | 2,1sn | 0 | Yanıt süresi, iş parçacığı havuzu doyduğunda hatasız olarak alt-doğrusal bir şekilde bozulur. Uygulama konteynerinin `cpus:` limitini yükseltmek (veya daha fazla çekirdeğe sahip bir ana bilgisayar kullanmak) tavanı yükseltir. Ağır işlerin (video kod dönüştürme, CPU AI) tüm süreleri boyunca bir iş parçacığını tuttuğunu unutmayın, bu nedenle CPU'yu yalnızca istek sayısına göre değil, beklenen eşzamanlı ağır iş sayınıza göre boyutlandırın. ### Desteklenen Görsel Formatları {#supported-image-formats} SnapOtter, 20+ kamera markasından RAW dosyaları, profesyonel formatlar (PSD, EPS, OpenEXR, HDR), modern codec'ler (JPEG XL, AVIF, HEIC, QOI) ve bilimsel/oyun formatları (FITS, DDS) dahil olmak üzere **55+ giriş formatı** ve **14 çıkış formatı** destekler. Desteklenen her format, kullanılan kod çözücü ve mevcut kalite kontrolleri hakkında ayrıntılar için [tam format listesine](/tr/guide/supported-formats) bakın. ### Bilinen Sınırlamalar {#known-limitations} * **İçeriğe duyarlı yeniden boyutlandırma**, caire ikili dosyasındaki bir sınırlama nedeniyle büyük görsellerde (>5 MP) çöker. Daha küçük görsellerle sorunsuz çalışır. * **HEIF kod çözme** 13-23 saniye sürer. HEIC (Apple'ın çeşidi) 0,3-0,9 saniye ile çok daha hızlıdır. * **Ölçek büyütme**, küçük görseller dışındaki her şey için CPU'da zaman aşımına uğrar. Pratik kullanım için GPU gereklidir. * **CodeFormer** yüz iyileştirme, GFPGAN'dan önemli ölçüde daha yavaştır (GPU'da 53sn'ye karşı 2sn). Çoğu kullanım senaryosu için GFPGAN önerilir. ## Birimler {#volumes} | Bağlama / Birim | Amaç | Gerekli mi? | |---|---|---| | `/data` (uygulama) | AI modelleri, Python venv, kullanıcı dosyaları | **Evet** - onsuz dosya kaybı | | `/tmp/workspace` (uygulama) | Geçici işleme dosyaları (otomatik temizlenir) | Önerilir | | `SnapOtter-pgdata` (postgres) | PostgreSQL veri dizini (kullanıcılar, ayarlar, ardışık düzenler, işler) | **Evet** - onsuz veri kaybı | | `SnapOtter-redisdata` (redis) | Dayanıklı iş kuyrukları için Redis salt-ekleme dosyası | Önerilir | ### Bağlama noktaları vs. adlandırılmış birimler {#bind-mounts-vs-named-volumes} **Adlandırılmış birimler** (önerilir) - Docker izinleri otomatik olarak yönetir: ```yaml volumes: - SnapOtter-data:/data ``` **Bağlama noktaları** - İzinleri siz yönetirsiniz. Ana bilgisayar kullanıcınızla eşleşecek şekilde `PUID`/`PGID` ayarlayın: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Depolama izinleri {#storage-permissions} SnapOtter çalışma zamanında iki konuma yazar: `/data` (kullanıcı dosyaları, günlükler, AI modelleri ve Python venv) ve `/tmp/workspace` (geçici işleme çalışma alanı). Her ikisi de konteynerin çalıştığı kullanıcı tarafından yazılabilir olmalıdır. Herhangi biri değilse, konteyner **başlangıçta hızlıca başarısız olur** ve dizini, çalışan UID/GID'yi ve nasıl düzeltileceğini belirten bir mesaj verir; "sağlıklı" olarak önyükleme yapıp ardından ilk yüklemede şifreli bir hatayla başarısız olmak yerine. İzinlerin nasıl işlendiği, konteynerin nasıl başlatıldığına bağlıdır: **Varsayılan (root olarak başlar, `snapotter` kullanıcısına düşer)** - giriş noktası root olarak başlar, bağlanan birimlerin sahipliğini düzeltir, ardından `gosu` aracılığıyla ayrıcalıksız `snapotter` kullanıcısına düşer. Adlandırılmış birimler yapılandırma gerektirmeden çalışır. Bağlama noktaları için, yazdığı dosyaların size ait olması için `PUID`/`PGID` ayarını ana bilgisayar kullanıcınıza ayarlayın (yukarıda). **Kubernetes / OpenShift (`runAsUser` aracılığıyla root olmayan)** - doğrudan root olmayan bir kullanıcı olarak başlatıldığında, konteyner birimleri kendisi chown yapamaz, bu nedenle orkestratör onları yazılabilir yapmalıdır. `fsGroup` ayarlayın: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` İmajın yazılabilir dizinleri GID 0 tarafından grup sahipliğinde ve grup tarafından yazılabilir, bu nedenle **rastgele bir UID** artı root ek grubu (OpenShift varsayılanı) ile çalışan bir pod, `chown` olmadan yazabilir. **TrueNAS Scale (ve diğer "yabancı UID" kurulumları)** - TrueNAS, uygulamaları root olmayan bir kullanıcı olarak (genellikle `568:568`) çalıştırır ve farklı bir kullanıcıya ait ana bilgisayar veri kümelerini bağlar, bu nedenle ne giriş noktası ne de `fsGroup` onları kendi başına yazılabilir yapar. Birini seçin: * **Uygulamayı root olarak çalıştırın** (önerilir) - uygulamanın kullanıcısını ayarlamadan bırakın veya `0` olarak ayarlayın ve varsayılan giriş noktasının izinleri düzeltmesine ve `snapotter` kullanıcısına düşmesine izin verin. * **UID `999` olarak çalıştırın** - uygulamanın kullanıcısını/grubunu `999:999` (SnapOtter'ın yerleşik `snapotter` kullanıcısı) olarak ayarlayın, böylece imajın sahipliğiyle eşleşir. * **`chown`** ana bilgisayar veri kümesini konteynerin çalıştığı UID'ye, TrueNAS kabuğundan: ```bash # Başlangıç hatasındaki UID'yi kullanın (veya konteyner içinde `id` çalıştırın) chown -R 568:568 /mnt// ``` Başlangıç hatası kullanılacak tam UID'yi belirtir, bu nedenle en hızlı yol uygulamayı bir kez başlatmak, mesajı okumak, ardından buna göre `chown` (veya kullanıcıyı ayarlamak) yapmaktır. ## Ortam Değişkenleri {#environment-variables} | Değişken | Varsayılan | Açıklama | |---|---|---| | `AUTH_ENABLED` | `true` | Oturum açma gereksinimini etkinleştir/devre dışı bırak | | `DEFAULT_USERNAME` | `admin` | Başlangıç yönetici kullanıcı adı | | `DEFAULT_PASSWORD` | `admin` | Başlangıç yönetici parolası (ilk oturum açmada zorunlu değişiklik) | | `MAX_UPLOAD_SIZE_MB` | `0` (sınırsız) | Dosya başına MB cinsinden yükleme limiti. İmaj `0` ile gelir; kaynaktan yapılan bir derleme 100 ile başlar | | `MAX_BATCH_SIZE` | `0` (sınırsız) | Grup isteği başına maksimum dosya. İmaj `0` ile gelir; kaynaktan yapılan bir derleme 100 ile başlar | | `RATE_LIMIT_PER_MIN` | `1000` | IP başına dakikada API isteği (devre dışı bırakmak için 0 ayarlayın) | | `MAX_USERS` | `0` (sınırsız) | Maksimum kullanıcı hesabı | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Hangi uçların istemci IP'sini `X-Forwarded-For` üzerinden belirleyebileceği. Varsayılan olarak yalnızca özel ağlar | | `PUID` | `999` | Bu UID olarak çalıştır (bağlama noktası izinleri için) | | `PGID` | `999` | Bu GID olarak çalıştır (bağlama noktası izinleri için) | | `LOG_LEVEL` | `info` | Günlük ayrıntı düzeyi: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (otomatik) | Maksimum paralel AI işleme işi | | `SESSION_DURATION_HOURS` | `168` | Oturum açma oturumu ömrü (7 gün) | | `CORS_ORIGIN` | (boş) | Virgülle ayrılmış izin verilen kaynaklar veya aynı kaynak için boş | ### Giden proxy ve özel CA {#outbound-proxy-and-private-ca} Resmi kapsayıcı, Node'un ortam proxy desteğini etkinleştirir. SnapOtter'nin OCR çalışma zamanı deposuna veya diğer HTTPS hizmetlerine kurumsal bir proxy aracılığıyla ulaşması gerekiyorsa, `HTTPS_PROXY`'yi (ve gerektiğinde `HTTP_PROXY`) ayarlayın. `NO_PROXY`'yi, Postgres, Redis ve dahili nesne depolama gibi doğrudan ulaşılması gereken ana bilgisayarların virgülle ayrılmış bir listesine ayarlayın. Proxy veya dahili hizmet özel bir sertifika yetkilisi tarafından imzalanmışsa CA sertifikasını salt okunur olarak bağlayın ve `NODE_EXTRA_CA_CERTS`'yi ona yönlendirin. Düğüm işlemi başladığında dosyanın mevcut olması gerekir: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Proxy kimlik bilgilerini Compose dosyasının dışında tutun (örneğin, korumalı bir `.env` dosyasında veya gizli dosyada). TLS doğrulamasını devre dışı bırakmayın: İmzalı OCR dizini yayın meta verilerinin kimliğini doğrularken, normal TLS doğrulaması hâlâ taşımayı ve diğer tüm giden istekleri korur. ## Sağlık Kontrolü {#health-check} Konteyner yerleşik bir sağlık kontrolü içerir: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Ters Proxy {#reverse-proxy} `TRUST_PROXY` varsayılan olarak `loopback,linklocal,uniquelocal` değerindedir; bu yüzden SnapOtter `X-Forwarded-For` başlığına yalnızca özel ağdaki bir uçtan geldiğinde inanır. Aynı makinedeki, bir Docker ağındaki ya da LAN'ınızdaki bir ters proxy kutudan çıktığı haliyle güvenilir sayılır; böylece hız sınırlaması, oturum açmadaki kaba kuvvet sınırlayıcısı, denetim günlüğü ve enterprise sürümün IP izin listesi hiçbir yapılandırma olmadan gerçek istemci IP'sini görür. `TRUST_PROXY=true` değerini yalnızca öndeki proxy SnapOtter'a **herkese açık** bir adresten ulaşıyorsa ayarlayın; örneğin başka bir ağdaki bir bulut yük dengeleyicisi. Doğrudan açığa çıkmış bir örnekte bu değer `request.ip` alanını saldırganın denetimine bırakır, çünkü başlığı sürekli değiştiren biri her istekte taze bir hız sınırı sayacı elde eder. İstemci IP'lerini ölçmeye girişmeden önce bilinmesi gereken iki şey var. macOS ve Windows üzerindeki Docker Desktop, yayımlanan bir bağlantı noktasını her kaynak adresini `192.168.65.1` sanal makine ağ geçidine yeniden yazan bir kullanıcı alanı proxy'si üzerinden sunar; orada `TRUST_PROXY` değerlerinin hiçbiri gerçek istemciyi geri getirmez, internete açılan her şeyi Linux üzerinde dağıtın. Ayrıca her platformda, yayımlanan bir bağlantı noktasına `localhost` üzerinden erişmek sizin istemciniz yerine köprü ağ geçidi olarak görülür; dolayısıyla localhost testi gerçek bir istemcinin nasıl ilişkilendirildiği hakkında hiçbir şey söylemez. `TRUST_PROXY` değerlerinin tam tablosu ve Docker Desktop uyarısı [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy) içinde yer alır. Aşağıdaki her proxy için iki şey önemlidir: büyük istek gövdelerine (yüklemeler) izin verin ve yanıtları ara belleğe almayın. Yanıt arabelleğe alan bir proxy, SSE ilerlemesini keser ve daha görünür bir şekilde büyük bir dosya indirme işlemini "başlatır ancak hiçbir zaman bitirmez" çünkü proxy, aktarmadan önce tüm dosyayı tutar. SnapOtter, indirmelerde `X-Accel-Buffering: no`'yi gönderir, böylece ara belleğe alma başka bir yerde bırakılsa bile nginx bunları akışa alır, ancak nginx dışındaki proxy'lerin yanıt arabelleğe almanın açıkça devre dışı bırakılması gerekir (aşağıdaki her yapılandırmada gösterilmiştir). İndirme işlemi yarıda durursa, kontrol edilecek ilk şey öndeki ara belleğe alma proxy'sidir. ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Ara belleğe alma yerine akış yanıtları: SSE ilerlemesi (toplu, yapay zeka, özellik yüklemeleri) ve büyük dosya indirmeleri için gereklidir. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Yeni bir Proxy Host ekleyin 2. Domain Name'i alan adınıza ayarlayın 3. Scheme'i `http`, Forward Hostname'i `SnapOtter` (veya konteyner IP'niz), Forward Port'u `1349` olarak ayarlayın 4. WebSocket desteğini etkinleştirin 5. Advanced altında şunları ekleyin: `client_max_body_size 500M;` ve `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1`, SSE ilerleme olayları (toplu işleme, yapay zeka araçları, özellik yüklemeleri) ve büyük dosya indirmelerinin durmak yerine akışa alınması için gerekli olan yanıt arabelleğe almayı devre dışı bırakır. Uzatılmış zaman aşımları, Caddy'nin bağlantıyı erken kapatmasına gerek kalmadan büyük dosya yüklemelerinin tamamlanmasına olanak tanır. ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Not: Cloudflare'in ücretsiz planlarda 100 MB yükleme limiti vardır. Eşleştirmek için `MAX_UPLOAD_SIZE_MB=100` ayarlayın. ## CI/CD {#ci-cd} GitHub deposunda üç iş akışı vardır: * **ci.yml** - Her push ve PR'de otomatik olarak çalışır. Lint, tip kontrolü, testler, derleme yapar ve Docker imajını doğrular (push yapmadan). * **release.yml** - `workflow_dispatch` aracılığıyla manuel olarak tetiklenir. Bir sürüm etiketi ve GitHub sürümü oluşturmak için semantic-release çalıştırır, ardından çok mimarili bir Docker imajı (amd64 + arm64) derler ve Docker Hub'a (`snapotter/snapotter`) ve GitHub Container Registry'ye (`ghcr.io/snapotter-hq/snapotter`) push yapar. * **deploy-docs.yml** - Bu dokümantasyon sitesini derler ve `main` üzerine push yapıldığında Cloudflare Pages'e dağıtır. Bir sürüm oluşturmak için GitHub arayüzünde **Actions > Release > Run workflow** bölümüne gidin veya şunu çalıştırın: ```bash gh workflow run release.yml ``` Semantic-release, sürümü commit geçmişinden belirler. `latest` Docker etiketi her zaman en son sürüme işaret eder. ## Analitik {#analytics} SnapOtter, hataları yakalamaya ve özellikleri iyileştirmeye yardımcı olmak için anonim ürün analitiği (araç kullanım kalıpları, hata raporları) içerir. Varsayılan olarak açıktır. Dosyalarınız, dosya adlarınız ve kişisel verileriniz asla bunun bir parçası değildir. SnapOtter, analitik devre dışıyken normal şekilde çalışır. ### Analitiği devre dışı bırakma {#disabling-analytics} Çalışma zamanı vazgeçme, tek tıklamalık bir yönetici geçişidir. Settings > System > Privacy bölümünü açın ve Anonymous Product Analytics'i kapatın. Yeniden derleme gerekmeden tüm örnek için hemen durur. Asla analitik yayamayan bir imaj için, depoyu klonlayarak ve yeniden derleyerek derleme zamanı kesin kapatmayı ayarlayın: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` Veya derleme argümanını mevcut `docker-compose.yml` dosyanıza ekleyin: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/tr/tools/image/circle-crop.md description: Bir görseli, köşeleri saydam olacak şekilde ortalanmış bir daireye kırpın. --- # Daire Kırpma {#circle-crop} Bir görseli, köşeleri saydam olacak şekilde ortalanmış bir daireye kırpın. Ayarlanabilir yakınlaştırma, konum kayması, kenarlık ve çıktı boyutunu destekler. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/circle-crop` Bir görsel dosyası ve bir JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | zoom | sayı | Hayır | `1` | Yakınlaştırma faktörü (1-5); daha yüksek değerler daha sıkı kırpar | | offsetX | sayı | Hayır | `0.5` | Yatay merkez konumu (0-1) | | offsetY | sayı | Hayır | `0.5` | Dikey merkez konumu (0-1) | | borderWidth | tam sayı | Hayır | `0` | Piksel cinsinden kenarlık genişliği (0-200) | | borderColor | dize | Hayır | `"#ffffff"` | Onaltılık kenarlık rengi | | background | dize | Hayır | `"transparent"` | Köşe doldurma: `"transparent"` veya bir onaltılık renk | | outputSize | tam sayı | Hayır | - | Piksel cinsinden nihai kare boyutu (16-4096) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/circle-crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 185000 } ``` ## Notlar {#notes} * Saydam köşeleri korumak için çıktı her zaman PNG'dir (`background` düz bir renge ayarlanmadıkça). * Daire, görselin kısa kenarına yazılır. Daha sıkı kırpmak için `zoom`, görünür alanı kaydırmak için `offsetX`/`offsetY` kullanın. * `outputSize` sağlandığında, sonuç kırpmanın ardından bu kare boyutuna yeniden boyutlandırılır. * HEIC, RAW, PSD ve SVG girişleri işlenmeden önce otomatik olarak çözülür. --- --- url: https://docs.snapotter.com/vi/tools/audio/reverse-audio.md description: Đảo ngược một tệp âm thanh để nó phát ngược. --- # Đảo ngược âm thanh {#reverse-audio} Đảo ngược một tệp âm thanh để nó phát ngược. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/reverse-audio` Chấp nhận dữ liệu form multipart với một tệp âm thanh và một trường JSON `settings`. ## Tham số {#parameters} Công cụ này không có tham số cấu hình. Toàn bộ tệp âm thanh được đảo ngược. ## Yêu cầu ví dụ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/reverse-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" ``` ## Phản hồi ví dụ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Ghi chú {#notes} * Toàn bộ bản âm thanh được đảo ngược từ cuối về đầu. * Đầu ra thường giữ container đầu vào. Đầu vào AAC được ghi thành M4A, và các đầu vào chỉ giải mã không được hỗ trợ sẽ chuyển về MP3. --- --- url: https://docs.snapotter.com/sv/guide/database.md description: >- PostgreSQL-databasschema, tabeller, migrationer och säkerhetskopieringsprocedurer för SnapOtter. --- # Databas {#database} SnapOtter använder PostgreSQL 17 med [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) för datapersistens. Schemat definieras i `apps/api/src/db/schema.ts`. Anslutningen konfigureras via miljövariabeln `DATABASE_URL` (standard `postgres://snapotter:snapotter@postgres:5432/snapotter`). I Docker Compose lagrar Postgres-containern sina data i den namngivna volymen `SnapOtter-pgdata`. ## Tabeller {#tables} ### users {#users} Lagrar användarkonton. Skapas automatiskt vid första körningen från `DEFAULT_USERNAME` och `DEFAULT_PASSWORD`. | Kolumn | Typ | Anmärkningar | |---|---|---| | `id` | uuid | Primärnyckel | | `username` | varchar | Unik, obligatorisk | | `passwordHash` | varchar | scrypt-hash | | `role` | varchar | `admin`, `editor` eller `user` | | `mustChangePassword` | boolean | Flagga för framtvingad lösenordsåterställning | | `createdAt` | timestamp | Skapandetidpunkt | | `updatedAt` | timestamp | Senaste uppdateringstidpunkt | ### sessions {#sessions} Aktiva inloggningssessioner. Varje rad knyter en sessionstoken till en användare. | Kolumn | Typ | Anmärkningar | |---|---|---| | `id` | varchar | Primärnyckel (sessionstoken) | | `userId` | uuid | Främmande nyckel till `users.id` | | `expiresAt` | timestamp | Utgångstidpunkt | | `createdAt` | timestamp | Skapandetidpunkt | ### teams {#teams} Grupper för att organisera användare. Administratörer kan tilldela användare till team. | Kolumn | Typ | Beskrivning | |--------|------|-------------| | `id` | uuid | Primärnyckel | | `name` | varchar (unik, max 50 tecken) | Teamnamn | | `createdAt` | timestamp | Skapandetidpunkt | ### api\_keys {#api-keys} API-nycklar för programmatisk åtkomst. Den råa nyckeln visas en gång vid skapandet; endast hashen lagras. | Kolumn | Typ | Anmärkningar | |---|---|---| | `id` | uuid | Primärnyckel | | `userId` | uuid | Främmande nyckel till `users.id` | | `keyHash` | varchar | scrypt-hash av nyckeln | | `name` | varchar | Användarangiven etikett | | `createdAt` | timestamp | Skapandetidpunkt | | `lastUsedAt` | timestamp | Uppdateras vid varje autentiserad begäran | Nycklar prefixas med `si_` följt av 96 hex-tecken (48 slumpmässiga byte). ### pipelines {#pipelines} Sparade verktygskedjor som användare skapar i användargränssnittet. | Kolumn | Typ | Anmärkningar | |---|---|---| | `id` | uuid | Primärnyckel | | `name` | varchar | Pipeline-namn | | `description` | varchar | Valfri beskrivning | | `steps` | jsonb | Array av `{ toolId, settings }`-objekt | | `createdAt` | timestamp | Skapandetidpunkt | ### user\_files {#user-files} Beständigt filbibliotek. En sparad ändring infogas som standard som en oberoende rotrad ("spara som ny": `version` 1, `parentId` null, så originalet ligger kvar i listan), eller som en förälderlänkad version när du skriver över originalet (`parentId` satt, `version` uppräknad, vilket ersätter det). Kolumnen `toolChain` registrerar vilka verktyg som tillämpades. | Kolumn | Typ | Beskrivning | |--------|------|-------------| | `id` | uuid | Primärnyckel | | `userId` | uuid | FK till users (CASCADE DELETE) | | `originalName` | varchar | Ursprungligt uppladdningsfilnamn | | `storedName` | varchar | Filnamn på disk | | `mimeType` | varchar | MIME-typ | | `size` | integer | Filstorlek i byte | | `width` | integer | Bildbredd i px | | `height` | integer | Bildhöjd i px | | `version` | integer | Versionsnummer (1 = original) | | `parentId` | uuid eller null | FK till user\_files (förälderversion) | | `toolChain` | jsonb | Verktygs-ID:n tillämpade i ordning för att producera den här versionen | | `createdAt` | timestamp | Skapandetidpunkt | ### jobs {#jobs} Spårar bearbetningsjobb för framstegsrapportering och rensning. | Kolumn | Typ | Anmärkningar | |---|---|---| | `id` | uuid | Primärnyckel | | `type` | varchar | Identifierare för verktyg eller pipeline | | `status` | varchar | `queued`, `processing`, `completed` eller `failed` | | `progress` | real | 0.0-1.0 andel | | `inputFiles` | jsonb | Array av sökvägar till indatafiler | | `outputPath` | varchar | Sökväg till resultatfilen | | `settings` | jsonb | Använda verktygsinställningar | | `error` | varchar | Felmeddelande om det misslyckades | | `createdAt` | timestamp | Skapandetidpunkt | | `completedAt` | timestamp | Slutförandetidpunkt | ### settings {#settings} Nyckel-värde-lager för serveromfattande inställningar som administratörer kan ändra från användargränssnittet. | Kolumn | Typ | Anmärkningar | |---|---|---| | `key` | varchar | Primärnyckel | | `value` | varchar | Inställningsvärde | | `updatedAt` | timestamp | Senaste uppdateringstidpunkt | ### roles {#roles} Anpassade roller med granulära behörigheter. | Kolumn | Typ | Anmärkningar | |---|---|---| | `id` | uuid | Primärnyckel | | `name` | varchar | Unikt rollnamn | | `description` | varchar | Valfri beskrivning | | `permissions` | jsonb | Array av behörighetssträngar | | `createdAt` | timestamp | Skapandetidpunkt | ### audit\_log {#audit-log} Logg över säkerhetsrelevanta åtgärder. | Kolumn | Typ | Anmärkningar | |---|---|---| | `id` | uuid | Primärnyckel | | `userId` | uuid | FK till users | | `action` | varchar | Åtgärdstyp | | `details` | jsonb | Åtgärdsspecifika data | | `createdAt` | timestamp | Åtgärdstidpunkt | ### user\_preferences {#user-preferences} Gränssnittstillstånd per användare, nycklat på inställningens namn. Lagrar startsidans fästa verktyg, som skrivs via `PUT /api/v1/preferences`. | Kolumn | Typ | Anmärkningar | |---|---|---| | `userId` | text | FK till users, kaskaderande borttagning. Primärnyckel tillsammans med `key` | | `key` | text | Inställningens namn. Primärnyckel tillsammans med `userId` | | `value` | jsonb | Inställningens innehåll | | `updatedAt` | timestamp | Senaste skrivning | ## Migrationer {#migrations} Drizzle sköter schemamigrationer. Migrationsfiler ligger i `apps/api/drizzle/`. Under utveckling: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` I produktion tillämpas väntande migrationer automatiskt vid uppstart. ## Säkerhetskopiera och återställa {#backup-and-restore} Relationsdatabasen finns i Postgres-behållarens `SnapOtter-pgdata`-volym, inte appens `/data`-volym. **Logisk säkerhetskopiering med validering (rekommenderas)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Denna databasdump innehåller inte sparade biblioteksobjekt i `/data/files` eller hållbart BullMQ-tillstånd i Redis. Säkerhetskopiera och återställ dem med den samordnade proceduren i [Säkerhet och härdning](/sv/guide/security#backup-and-recovery). **Önblicksbild av kall volym** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Kopiera inte en live PostgreSQL-datakatalog med `tar`. Komponera prefix volymnamn efter projekt, så lös de monterade volym-ID:n från `docker inspect` eller din lagringsplattform istället för att anta den bokstavliga etiketten `SnapOtter-pgdata`. ### Migrera från 1.x (SQLite) {#migrating-from-1-x-sqlite} Uppgradering från SnapOtter 1.x har sin egen guide: se [Uppgradera från 1.x till 2.0](./upgrading). Kort sagt, återanvänd din befintliga `/data`-volym så upptäcker och importerar 2.0 automatiskt `/data/snapotter.db` vid första uppstarten (eller ställ in `SQLITE_MIGRATE_PATH` för att peka på den explicit). Säkerhetskopiera hela `/data`-volymen först, inte bara `snapotter.db`: 1.x använder SQLite WAL-läge, så en stoppad container lämnar ofta det mesta av sina data i `snapotter.db-wal` bredvid en nästan tom `snapotter.db`. --- --- url: https://docs.snapotter.com/id/guide/database.md description: >- Skema database PostgreSQL, tabel, migrasi, dan prosedur pencadangan untuk SnapOtter. --- # Database {#database} SnapOtter menggunakan PostgreSQL 17 dengan [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) untuk persistensi data. Skema didefinisikan di `apps/api/src/db/schema.ts`. Koneksi dikonfigurasi melalui variabel lingkungan `DATABASE_URL` (default `postgres://snapotter:snapotter@postgres:5432/snapotter`). Di Docker Compose, kontainer Postgres menyimpan datanya di volume bernama `SnapOtter-pgdata`. ## Tabel {#tables} ### users {#users} Menyimpan akun pengguna. Dibuat otomatis pada saat pertama kali dijalankan dari `DEFAULT_USERNAME` dan `DEFAULT_PASSWORD`. | Kolom | Tipe | Catatan | |---|---|---| | `id` | uuid | Primary key | | `username` | varchar | Unik, wajib | | `passwordHash` | varchar | hash scrypt | | `role` | varchar | `admin`, `editor`, atau `user` | | `mustChangePassword` | boolean | Flag reset kata sandi paksa | | `createdAt` | timestamp | Waktu pembuatan | | `updatedAt` | timestamp | Waktu pembaruan terakhir | ### sessions {#sessions} Sesi login aktif. Setiap baris mengaitkan token sesi ke seorang pengguna. | Kolom | Tipe | Catatan | |---|---|---| | `id` | varchar | Primary key (token sesi) | | `userId` | uuid | Foreign key ke `users.id` | | `expiresAt` | timestamp | Waktu kedaluwarsa | | `createdAt` | timestamp | Waktu pembuatan | ### teams {#teams} Grup untuk mengorganisasi pengguna. Admin dapat menetapkan pengguna ke tim. | Kolom | Tipe | Deskripsi | |--------|------|-------------| | `id` | uuid | Primary key | | `name` | varchar (unik, maks 50 karakter) | Nama tim | | `createdAt` | timestamp | Waktu pembuatan | ### api\_keys {#api-keys} API key untuk akses secara programatik. Kunci mentah ditampilkan sekali saat pembuatan; hanya hash yang disimpan. | Kolom | Tipe | Catatan | |---|---|---| | `id` | uuid | Primary key | | `userId` | uuid | Foreign key ke `users.id` | | `keyHash` | varchar | hash scrypt dari kunci | | `name` | varchar | Label yang diberikan pengguna | | `createdAt` | timestamp | Waktu pembuatan | | `lastUsedAt` | timestamp | Diperbarui pada setiap permintaan terautentikasi | Kunci diberi awalan `si_` diikuti oleh 96 karakter heksadesimal (48 byte acak). ### pipelines {#pipelines} Rangkaian tool tersimpan yang dibuat pengguna di UI. | Kolom | Tipe | Catatan | |---|---|---| | `id` | uuid | Primary key | | `name` | varchar | Nama pipeline | | `description` | varchar | Deskripsi opsional | | `steps` | jsonb | Array objek `{ toolId, settings }` | | `createdAt` | timestamp | Waktu pembuatan | ### user\_files {#user-files} Pustaka file persisten. Secara default, sebuah editan yang disimpan dimasukkan sebagai baris akar independen ("simpan sebagai baru": `version` 1, `parentId` null, sehingga file asli tetap terdaftar), atau sebagai versi yang tertaut ke induk ketika Anda menimpa file asli (`parentId` diisi, `version` dinaikkan, menggantikannya). Kolom `toolChain` mencatat tool yang diterapkan. | Kolom | Tipe | Deskripsi | |--------|------|-------------| | `id` | uuid | Primary key | | `userId` | uuid | FK ke users (CASCADE DELETE) | | `originalName` | varchar | Nama file unggahan asli | | `storedName` | varchar | Nama file pada disk | | `mimeType` | varchar | Tipe MIME | | `size` | integer | Ukuran file dalam byte | | `width` | integer | Lebar gambar dalam px | | `height` | integer | Tinggi gambar dalam px | | `version` | integer | Nomor versi (1 = asli) | | `parentId` | uuid atau null | FK ke user\_files (versi induk) | | `toolChain` | jsonb | ID tool yang diterapkan secara berurutan untuk menghasilkan versi ini | | `createdAt` | timestamp | Waktu pembuatan | ### jobs {#jobs} Melacak job pemrosesan untuk pelaporan progres dan pembersihan. | Kolom | Tipe | Catatan | |---|---|---| | `id` | uuid | Primary key | | `type` | varchar | Identifikasi tool atau pipeline | | `status` | varchar | `queued`, `processing`, `completed`, atau `failed` | | `progress` | real | Fraksi 0.0-1.0 | | `inputFiles` | jsonb | Array path file input | | `outputPath` | varchar | Path ke file hasil | | `settings` | jsonb | Pengaturan tool yang digunakan | | `error` | varchar | Pesan kesalahan jika gagal | | `createdAt` | timestamp | Waktu pembuatan | | `completedAt` | timestamp | Waktu penyelesaian | ### settings {#settings} Penyimpanan key-value untuk pengaturan seluruh server yang dapat diubah admin dari UI. | Kolom | Tipe | Catatan | |---|---|---| | `key` | varchar | Primary key | | `value` | varchar | Nilai pengaturan | | `updatedAt` | timestamp | Waktu pembaruan terakhir | ### roles {#roles} Peran kustom dengan izin granular. | Kolom | Tipe | Catatan | |---|---|---| | `id` | uuid | Primary key | | `name` | varchar | Nama peran unik | | `description` | varchar | Deskripsi opsional | | `permissions` | jsonb | Array string izin | | `createdAt` | timestamp | Waktu pembuatan | ### audit\_log {#audit-log} Log aksi yang relevan dengan keamanan. | Kolom | Tipe | Catatan | |---|---|---| | `id` | uuid | Primary key | | `userId` | uuid | FK ke users | | `action` | varchar | Tipe aksi | | `details` | jsonb | Data khusus aksi | | `createdAt` | timestamp | Waktu aksi | ### user\_preferences {#user-preferences} Status UI per pengguna, dikunci berdasarkan nama preferensi. Menyimpan alat yang disematkan di halaman beranda, yang ditulis melalui `PUT /api/v1/preferences`. | Kolom | Tipe | Catatan | |---|---|---| | `userId` | text | FK ke users, menghapus secara berantai. Primary key bersama `key` | | `key` | text | Nama preferensi. Primary key bersama `userId` | | `value` | jsonb | Muatan preferensi | | `updatedAt` | timestamp | Penulisan terakhir | ## Migrasi {#migrations} Drizzle menangani migrasi skema. File migrasi berada di `apps/api/drizzle/`. Selama pengembangan: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Di produksi, migrasi yang tertunda diterapkan secara otomatis saat startup. ## Cadangkan dan pulihkan {#backup-and-restore} Basis data relasional berada di volume `SnapOtter-pgdata` container Postgres, bukan volume `/data` aplikasi. **Cadangan logis dengan validasi (disarankan)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Dump database ini tidak berisi objek perpustakaan yang disimpan di `/data/files` atau status BullMQ yang tahan lama di Redis. Cadangkan dan pulihkan dengan prosedur terkoordinasi di [Keamanan & Pengerasan](/id/guide/security#backup-and-recovery). **Snapshot volume dingin** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Jangan menyalin direktori data PostgreSQL langsung dengan `tar`. Tulis nama volume awalan berdasarkan proyek, jadi selesaikan ID volume yang terpasang dari `docker inspect` atau platform penyimpanan Anda daripada menggunakan label literal `SnapOtter-pgdata`. ### Migrasi dari 1.x (SQLite) {#migrating-from-1-x-sqlite} Memutakhirkan dari SnapOtter 1.x memiliki panduannya sendiri: lihat [Memutakhirkan dari 1.x ke 2.0](./upgrading). Singkatnya, gunakan kembali volume `/data` Anda yang ada dan 2.0 otomatis mendeteksi serta mengimpor `/data/snapotter.db` pada boot pertama (atau atur `SQLITE_MIGRATE_PATH` untuk menunjuk ke sana secara eksplisit). Cadangkan seluruh volume `/data` terlebih dahulu, bukan hanya `snapotter.db`: 1.x menggunakan mode SQLite WAL, sehingga kontainer yang dihentikan sering meninggalkan sebagian besar datanya di `snapotter.db-wal` di samping `snapotter.db` yang hampir kosong. --- --- url: https://docs.snapotter.com/it/guide/database.md description: >- Schema del database PostgreSQL, tabelle, migrazioni e procedure di backup per SnapOtter. --- # Database {#database} SnapOtter usa PostgreSQL 17 con [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) per la persistenza dei dati. Lo schema è definito in `apps/api/src/db/schema.ts`. La connessione è configurata tramite la variabile d'ambiente `DATABASE_URL` (predefinita `postgres://snapotter:snapotter@postgres:5432/snapotter`). In Docker Compose, il container Postgres memorizza i suoi dati nel volume denominato `SnapOtter-pgdata`. ## Tabelle {#tables} ### users {#users} Memorizza gli account utente. Creata automaticamente al primo avvio da `DEFAULT_USERNAME` e `DEFAULT_PASSWORD`. | Colonna | Tipo | Note | |---|---|---| | `id` | uuid | Chiave primaria | | `username` | varchar | Univoco, obbligatorio | | `passwordHash` | varchar | Hash scrypt | | `role` | varchar | `admin`, `editor` o `user` | | `mustChangePassword` | boolean | Flag di reimpostazione forzata della password | | `createdAt` | timestamp | Data di creazione | | `updatedAt` | timestamp | Data dell'ultimo aggiornamento | ### sessions {#sessions} Sessioni di login attive. Ogni riga associa un token di sessione a un utente. | Colonna | Tipo | Note | |---|---|---| | `id` | varchar | Chiave primaria (token di sessione) | | `userId` | uuid | Chiave esterna verso `users.id` | | `expiresAt` | timestamp | Data di scadenza | | `createdAt` | timestamp | Data di creazione | ### teams {#teams} Gruppi per organizzare gli utenti. Gli amministratori possono assegnare gli utenti ai team. | Colonna | Tipo | Descrizione | |--------|------|-------------| | `id` | uuid | Chiave primaria | | `name` | varchar (univoco, max 50 caratteri) | Nome del team | | `createdAt` | timestamp | Data di creazione | ### api\_keys {#api-keys} Chiavi API per l'accesso programmatico. La chiave grezza viene mostrata una sola volta alla creazione; viene memorizzato solo l'hash. | Colonna | Tipo | Note | |---|---|---| | `id` | uuid | Chiave primaria | | `userId` | uuid | Chiave esterna verso `users.id` | | `keyHash` | varchar | Hash scrypt della chiave | | `name` | varchar | Etichetta fornita dall'utente | | `createdAt` | timestamp | Data di creazione | | `lastUsedAt` | timestamp | Aggiornata a ogni richiesta autenticata | Le chiavi hanno il prefisso `si_` seguito da 96 caratteri esadecimali (48 byte casuali). ### pipelines {#pipelines} Catene di strumenti salvate che gli utenti creano nell'interfaccia. | Colonna | Tipo | Note | |---|---|---| | `id` | uuid | Chiave primaria | | `name` | varchar | Nome della pipeline | | `description` | varchar | Descrizione facoltativa | | `steps` | jsonb | Array di oggetti `{ toolId, settings }` | | `createdAt` | timestamp | Data di creazione | ### user\_files {#user-files} Libreria di file persistente. Per impostazione predefinita, una modifica salvata viene inserita come riga radice indipendente ("salva come nuovo": `version` 1, `parentId` null, così l'originale resta elencato), oppure come versione collegata al genitore quando sovrascrivi l'originale (`parentId` impostato, `version` incrementata, sostituendolo). La colonna `toolChain` registra gli strumenti applicati. | Colonna | Tipo | Descrizione | |--------|------|-------------| | `id` | uuid | Chiave primaria | | `userId` | uuid | FK verso users (CASCADE DELETE) | | `originalName` | varchar | Nome del file di caricamento originale | | `storedName` | varchar | Nome del file su disco | | `mimeType` | varchar | Tipo MIME | | `size` | integer | Dimensione del file in byte | | `width` | integer | Larghezza dell'immagine in px | | `height` | integer | Altezza dell'immagine in px | | `version` | integer | Numero di versione (1 = originale) | | `parentId` | uuid o null | FK verso user\_files (versione genitore) | | `toolChain` | jsonb | ID degli strumenti applicati in ordine per produrre questa versione | | `createdAt` | timestamp | Data di creazione | ### jobs {#jobs} Traccia i job di elaborazione per la segnalazione dell'avanzamento e la pulizia. | Colonna | Tipo | Note | |---|---|---| | `id` | uuid | Chiave primaria | | `type` | varchar | Identificatore dello strumento o della pipeline | | `status` | varchar | `queued`, `processing`, `completed` o `failed` | | `progress` | real | Frazione 0.0-1.0 | | `inputFiles` | jsonb | Array dei percorsi dei file di input | | `outputPath` | varchar | Percorso del file risultato | | `settings` | jsonb | Impostazioni dello strumento utilizzate | | `error` | varchar | Messaggio di errore in caso di fallimento | | `createdAt` | timestamp | Data di creazione | | `completedAt` | timestamp | Data di completamento | ### settings {#settings} Archivio chiave-valore per le impostazioni a livello di server che gli amministratori possono modificare dall'interfaccia. | Colonna | Tipo | Note | |---|---|---| | `key` | varchar | Chiave primaria | | `value` | varchar | Valore dell'impostazione | | `updatedAt` | timestamp | Data dell'ultimo aggiornamento | ### roles {#roles} Ruoli personalizzati con permessi granulari. | Colonna | Tipo | Note | |---|---|---| | `id` | uuid | Chiave primaria | | `name` | varchar | Nome univoco del ruolo | | `description` | varchar | Descrizione facoltativa | | `permissions` | jsonb | Array di stringhe di permesso | | `createdAt` | timestamp | Data di creazione | ### audit\_log {#audit-log} Registro delle azioni rilevanti per la sicurezza. | Colonna | Tipo | Note | |---|---|---| | `id` | uuid | Chiave primaria | | `userId` | uuid | FK verso users | | `action` | varchar | Tipo di azione | | `details` | jsonb | Dati specifici dell'azione | | `createdAt` | timestamp | Data dell'azione | ### user\_preferences {#user-preferences} Stato dell'interfaccia per singolo utente, indicizzato per nome della preferenza. Conserva gli strumenti fissati della pagina iniziale, scritti tramite `PUT /api/v1/preferences`. | Colonna | Tipo | Note | |---|---|---| | `userId` | text | FK verso users, con eliminazione a cascata. Chiave primaria insieme a `key` | | `key` | text | Nome della preferenza. Chiave primaria insieme a `userId` | | `value` | jsonb | Contenuto della preferenza | | `updatedAt` | timestamp | Ultima scrittura | ## Migrazioni {#migrations} Drizzle gestisce le migrazioni dello schema. I file di migrazione risiedono in `apps/api/drizzle/`. Durante lo sviluppo: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` In produzione, le migrazioni in sospeso vengono applicate automaticamente all'avvio. ## Backup e ripristino {#backup-and-restore} Il database relazionale si trova nel volume `SnapOtter-pgdata` del contenitore Postgres, non nel volume `/data` dell'app. **Backup logico con convalida (consigliato)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Questo dump del database non contiene oggetti di libreria salvati in `/data/files` o lo stato BullMQ durevole in Redis. Effettuare il backup e il ripristino di quelli con la procedura coordinata in [Sicurezza e rafforzamento](/it/guide/security#backup-and-recovery). **Istantanea del volume freddo** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Non copiare una directory di dati PostgreSQL live con `tar`. Componi i prefissi dei nomi dei volumi in base al progetto, quindi risolvi gli ID dei volumi montati da `docker inspect` o dalla tua piattaforma di archiviazione anziché assumere l'etichetta letterale `SnapOtter-pgdata`. ### Migrazione dalla 1.x (SQLite) {#migrating-from-1-x-sqlite} L'aggiornamento da SnapOtter 1.x ha una guida dedicata: vedi [Aggiornamento dalla 1.x alla 2.0](./upgrading). In breve, riutilizza il tuo volume `/data` esistente e la 2.0 rileva e importa automaticamente `/data/snapotter.db` al primo avvio (oppure imposta `SQLITE_MIGRATE_PATH` per puntarvi esplicitamente). Esegui prima il backup dell'intero volume `/data`, non solo di `snapotter.db`: la 1.x usa la modalità WAL di SQLite, quindi un container arrestato lascia spesso la maggior parte dei suoi dati in `snapotter.db-wal` accanto a un `snapotter.db` quasi vuoto. --- --- url: https://docs.snapotter.com/nl/guide/database.md description: >- PostgreSQL-databaseschema, tabellen, migraties en back-upprocedures voor SnapOtter. --- # Database {#database} SnapOtter gebruikt PostgreSQL 17 met [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) voor gegevensopslag. Het schema is gedefinieerd in `apps/api/src/db/schema.ts`. De verbinding wordt geconfigureerd via de omgevingsvariabele `DATABASE_URL` (standaard `postgres://snapotter:snapotter@postgres:5432/snapotter`). In Docker Compose slaat de Postgres-container zijn gegevens op in het benoemde volume `SnapOtter-pgdata`. ## Tabellen {#tables} ### users {#users} Slaat gebruikersaccounts op. Wordt bij de eerste run automatisch aangemaakt op basis van `DEFAULT_USERNAME` en `DEFAULT_PASSWORD`. | Kolom | Type | Opmerkingen | |---|---|---| | `id` | uuid | Primaire sleutel | | `username` | varchar | Uniek, vereist | | `passwordHash` | varchar | scrypt-hash | | `role` | varchar | `admin`, `editor` of `user` | | `mustChangePassword` | boolean | Vlag voor geforceerde wachtwoordreset | | `createdAt` | timestamp | Aanmaaktijd | | `updatedAt` | timestamp | Tijd van laatste update | ### sessions {#sessions} Actieve aanmeldsessies. Elke rij koppelt een sessietoken aan een gebruiker. | Kolom | Type | Opmerkingen | |---|---|---| | `id` | varchar | Primaire sleutel (sessietoken) | | `userId` | uuid | Vreemde sleutel naar `users.id` | | `expiresAt` | timestamp | Vervaltijd | | `createdAt` | timestamp | Aanmaaktijd | ### teams {#teams} Groepen om gebruikers te organiseren. Beheerders kunnen gebruikers aan teams toewijzen. | Kolom | Type | Beschrijving | |--------|------|-------------| | `id` | uuid | Primaire sleutel | | `name` | varchar (uniek, max. 50 tekens) | Teamnaam | | `createdAt` | timestamp | Aanmaaktijd | ### api\_keys {#api-keys} API-sleutels voor programmatische toegang. De onbewerkte sleutel wordt eenmalig getoond bij aanmaken; alleen de hash wordt opgeslagen. | Kolom | Type | Opmerkingen | |---|---|---| | `id` | uuid | Primaire sleutel | | `userId` | uuid | Vreemde sleutel naar `users.id` | | `keyHash` | varchar | scrypt-hash van de sleutel | | `name` | varchar | Door de gebruiker opgegeven label | | `createdAt` | timestamp | Aanmaaktijd | | `lastUsedAt` | timestamp | Bijgewerkt bij elk geauthenticeerd verzoek | Sleutels beginnen met het voorvoegsel `si_` gevolgd door 96 hexadecimale tekens (48 willekeurige bytes). ### pipelines {#pipelines} Opgeslagen toolketens die gebruikers in de UI aanmaken. | Kolom | Type | Opmerkingen | |---|---|---| | `id` | uuid | Primaire sleutel | | `name` | varchar | Pipelinenaam | | `description` | varchar | Optionele beschrijving | | `steps` | jsonb | Array van `{ toolId, settings }`-objecten | | `createdAt` | timestamp | Aanmaaktijd | ### user\_files {#user-files} Persistente bestandsbibliotheek. Een opgeslagen bewerking wordt standaard als een onafhankelijke root-rij ingevoegd ("opslaan als nieuw": `version` 1, `parentId` null, zodat het origineel in de lijst blijft staan), of als een aan de bovenliggende rij gekoppelde versie wanneer je het origineel overschrijft (`parentId` ingesteld, `version` opgehoogd, waarmee het wordt vervangen). De kolom `toolChain` registreert welke tools zijn toegepast. | Kolom | Type | Beschrijving | |--------|------|-------------| | `id` | uuid | Primaire sleutel | | `userId` | uuid | FK naar users (CASCADE DELETE) | | `originalName` | varchar | Oorspronkelijke bestandsnaam bij upload | | `storedName` | varchar | Bestandsnaam op schijf | | `mimeType` | varchar | MIME-type | | `size` | integer | Bestandsgrootte in bytes | | `width` | integer | Breedte van de afbeelding in px | | `height` | integer | Hoogte van de afbeelding in px | | `version` | integer | Versienummer (1 = origineel) | | `parentId` | uuid of null | FK naar user\_files (bovenliggende versie) | | `toolChain` | jsonb | Tool-ID's die op volgorde zijn toegepast om deze versie te maken | | `createdAt` | timestamp | Aanmaaktijd | ### jobs {#jobs} Volgt verwerkingsjobs voor voortgangsrapportage en opschoning. | Kolom | Type | Opmerkingen | |---|---|---| | `id` | uuid | Primaire sleutel | | `type` | varchar | Tool- of pipeline-identifier | | `status` | varchar | `queued`, `processing`, `completed` of `failed` | | `progress` | real | Fractie van 0.0-1.0 | | `inputFiles` | jsonb | Array van invoerbestandspaden | | `outputPath` | varchar | Pad naar het resultaatbestand | | `settings` | jsonb | Gebruikte toolinstellingen | | `error` | varchar | Foutmelding bij mislukken | | `createdAt` | timestamp | Aanmaaktijd | | `completedAt` | timestamp | Voltooiingstijd | ### settings {#settings} Sleutel-waardeopslag voor serverbrede instellingen die beheerders vanuit de UI kunnen wijzigen. | Kolom | Type | Opmerkingen | |---|---|---| | `key` | varchar | Primaire sleutel | | `value` | varchar | Instellingswaarde | | `updatedAt` | timestamp | Tijd van laatste update | ### roles {#roles} Aangepaste rollen met granulaire rechten. | Kolom | Type | Opmerkingen | |---|---|---| | `id` | uuid | Primaire sleutel | | `name` | varchar | Unieke rolnaam | | `description` | varchar | Optionele beschrijving | | `permissions` | jsonb | Array van rechtenstrings | | `createdAt` | timestamp | Aanmaaktijd | ### audit\_log {#audit-log} Logboek van beveiligingsrelevante acties. | Kolom | Type | Opmerkingen | |---|---|---| | `id` | uuid | Primaire sleutel | | `userId` | uuid | FK naar users | | `action` | varchar | Actietype | | `details` | jsonb | Actiespecifieke gegevens | | `createdAt` | timestamp | Tijd van de actie | ### user\_preferences {#user-preferences} UI-status per gebruiker, gesleuteld op voorkeursnaam. Bewaart de vastgezette tools van de startpagina, die via `PUT /api/v1/preferences` worden geschreven. | Kolom | Type | Opmerkingen | |---|---|---| | `userId` | text | FK naar users, cascaderend verwijderen. Samen met `key` de primaire sleutel | | `key` | text | Naam van de voorkeur. Samen met `userId` de primaire sleutel | | `value` | jsonb | Inhoud van de voorkeur | | `updatedAt` | timestamp | Laatste schrijfactie | ## Migraties {#migrations} Drizzle verzorgt schemamigraties. Migratiebestanden staan in `apps/api/drizzle/`. Tijdens ontwikkeling: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` In productie worden openstaande migraties automatisch toegepast bij het opstarten. ## Back-up en herstel {#backup-and-restore} De relationele database bevindt zich in het `SnapOtter-pgdata`-volume van de Postgres-container, niet in het `/data`-volume van de app. **Logische back-up met validatie (aanbevolen)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Deze databasedump bevat geen opgeslagen bibliotheekobjecten in `/data/files` of de duurzame BullMQ-status in Redis. Maak een back-up en herstel deze met de gecoördineerde procedure in [Beveiliging en verharding](/nl/guide/security#backup-and-recovery). **Koude volumemomentopname** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Kopieer geen live PostgreSQL-gegevensmap met `tar`. Stel volumenamen voor voorvoegsels samen per project, dus los de gekoppelde volume-ID's van `docker inspect` of uw opslagplatform op in plaats van het letterlijke label `SnapOtter-pgdata` aan te nemen. ### Migreren vanaf 1.x (SQLite) {#migrating-from-1-x-sqlite} Upgraden vanaf SnapOtter 1.x heeft een eigen gids: zie [Upgraden van 1.x naar 2.0](./upgrading). Kort gezegd: hergebruik je bestaande `/data`-volume, en 2.0 detecteert en importeert `/data/snapotter.db` automatisch bij de eerste keer opstarten (of stel `SQLITE_MIGRATE_PATH` in om er expliciet naar te verwijzen). Maak eerst een back-up van het volledige `/data`-volume, niet alleen van `snapotter.db`: 1.x gebruikt de SQLite WAL-modus, dus een gestopte container laat vaak het grootste deel van zijn gegevens in `snapotter.db-wal` staan naast een bijna leeg `snapotter.db`. --- --- url: https://docs.snapotter.com/de/guide/database.md description: >- PostgreSQL-Datenbankschema, Tabellen, Migrationen und Backup-Verfahren für SnapOtter. --- # Datenbank {#database} SnapOtter verwendet PostgreSQL 17 mit [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) für die Datenpersistenz. Das Schema ist in `apps/api/src/db/schema.ts` definiert. Die Verbindung wird über die Umgebungsvariable `DATABASE_URL` konfiguriert (Standard `postgres://snapotter:snapotter@postgres:5432/snapotter`). In Docker Compose speichert der Postgres-Container seine Daten im benannten Volume `SnapOtter-pgdata`. ## Tabellen {#tables} ### users {#users} Speichert Benutzerkonten. Wird beim ersten Start automatisch aus `DEFAULT_USERNAME` und `DEFAULT_PASSWORD` erstellt. | Spalte | Typ | Hinweise | |---|---|---| | `id` | uuid | Primärschlüssel | | `username` | varchar | Eindeutig, erforderlich | | `passwordHash` | varchar | scrypt-Hash | | `role` | varchar | `admin`, `editor` oder `user` | | `mustChangePassword` | boolean | Flag für erzwungenes Zurücksetzen des Passworts | | `createdAt` | timestamp | Erstellungszeitpunkt | | `updatedAt` | timestamp | Zeitpunkt der letzten Aktualisierung | ### sessions {#sessions} Aktive Anmelde-Sitzungen. Jede Zeile verknüpft ein Sitzungstoken mit einem Benutzer. | Spalte | Typ | Hinweise | |---|---|---| | `id` | varchar | Primärschlüssel (Sitzungstoken) | | `userId` | uuid | Fremdschlüssel auf `users.id` | | `expiresAt` | timestamp | Ablaufzeitpunkt | | `createdAt` | timestamp | Erstellungszeitpunkt | ### teams {#teams} Gruppen zum Organisieren von Benutzern. Admins können Benutzer Teams zuweisen. | Spalte | Typ | Beschreibung | |--------|------|-------------| | `id` | uuid | Primärschlüssel | | `name` | varchar (eindeutig, max. 50 Zeichen) | Teamname | | `createdAt` | timestamp | Erstellungszeitpunkt | ### api\_keys {#api-keys} API-Schlüssel für den programmatischen Zugriff. Der rohe Schlüssel wird nur einmal bei der Erstellung angezeigt; gespeichert wird nur der Hash. | Spalte | Typ | Hinweise | |---|---|---| | `id` | uuid | Primärschlüssel | | `userId` | uuid | Fremdschlüssel auf `users.id` | | `keyHash` | varchar | scrypt-Hash des Schlüssels | | `name` | varchar | Vom Benutzer vergebene Bezeichnung | | `createdAt` | timestamp | Erstellungszeitpunkt | | `lastUsedAt` | timestamp | Bei jeder authentifizierten Anfrage aktualisiert | Schlüssel haben das Präfix `si_` gefolgt von 96 Hex-Zeichen (48 zufällige Bytes). ### pipelines {#pipelines} Gespeicherte Tool-Ketten, die Benutzer in der Oberfläche erstellen. | Spalte | Typ | Hinweise | |---|---|---| | `id` | uuid | Primärschlüssel | | `name` | varchar | Pipeline-Name | | `description` | varchar | Optionale Beschreibung | | `steps` | jsonb | Array von `{ toolId, settings }`-Objekten | | `createdAt` | timestamp | Erstellungszeitpunkt | ### user\_files {#user-files} Persistente Dateibibliothek. Ein gespeicherter Edit wird standardmäßig als eigenständige Root-Zeile eingefügt ("Als neu speichern": `version` 1, `parentId` null, sodass das Original weiterhin gelistet bleibt), oder als übergeordnet verknüpfte Version, wenn du das Original überschreibst (`parentId` gesetzt, `version` erhöht, das Original wird abgelöst). Die Spalte `toolChain` erfasst die angewendeten Werkzeuge. | Spalte | Typ | Beschreibung | |--------|------|-------------| | `id` | uuid | Primärschlüssel | | `userId` | uuid | FK auf users (CASCADE DELETE) | | `originalName` | varchar | Ursprünglicher Upload-Dateiname | | `storedName` | varchar | Dateiname auf dem Datenträger | | `mimeType` | varchar | MIME-Typ | | `size` | integer | Dateigröße in Bytes | | `width` | integer | Bildbreite in px | | `height` | integer | Bildhöhe in px | | `version` | integer | Versionsnummer (1 = Original) | | `parentId` | uuid oder null | FK auf user\_files (übergeordnete Version) | | `toolChain` | jsonb | Tool-IDs, die in Reihenfolge angewendet wurden, um diese Version zu erzeugen | | `createdAt` | timestamp | Erstellungszeitpunkt | ### jobs {#jobs} Verfolgt Verarbeitungs-Jobs für Fortschrittsanzeige und Bereinigung. | Spalte | Typ | Hinweise | |---|---|---| | `id` | uuid | Primärschlüssel | | `type` | varchar | Tool- oder Pipeline-Bezeichner | | `status` | varchar | `queued`, `processing`, `completed` oder `failed` | | `progress` | real | Anteil 0.0-1.0 | | `inputFiles` | jsonb | Array von Eingabedatei-Pfaden | | `outputPath` | varchar | Pfad zur Ergebnisdatei | | `settings` | jsonb | Verwendete Tool-Einstellungen | | `error` | varchar | Fehlermeldung bei Fehlschlag | | `createdAt` | timestamp | Erstellungszeitpunkt | | `completedAt` | timestamp | Abschlusszeitpunkt | ### settings {#settings} Schlüssel-Wert-Speicher für serverweite Einstellungen, die Admins über die Oberfläche ändern können. | Spalte | Typ | Hinweise | |---|---|---| | `key` | varchar | Primärschlüssel | | `value` | varchar | Einstellungswert | | `updatedAt` | timestamp | Zeitpunkt der letzten Aktualisierung | ### roles {#roles} Benutzerdefinierte Rollen mit granularen Berechtigungen. | Spalte | Typ | Hinweise | |---|---|---| | `id` | uuid | Primärschlüssel | | `name` | varchar | Eindeutiger Rollenname | | `description` | varchar | Optionale Beschreibung | | `permissions` | jsonb | Array von Berechtigungs-Strings | | `createdAt` | timestamp | Erstellungszeitpunkt | ### audit\_log {#audit-log} Protokoll sicherheitsrelevanter Aktionen. | Spalte | Typ | Hinweise | |---|---|---| | `id` | uuid | Primärschlüssel | | `userId` | uuid | FK auf users | | `action` | varchar | Aktionstyp | | `details` | jsonb | Aktionsspezifische Daten | | `createdAt` | timestamp | Zeitpunkt der Aktion | ### user\_preferences {#user-preferences} Oberflächenzustand pro Benutzer, abgelegt unter einem Präferenznamen. Speichert die angehefteten Tools der Startseite, die über `PUT /api/v1/preferences` geschrieben werden. | Spalte | Typ | Hinweise | |---|---|---| | `userId` | text | FK auf users, kaskadierendes Löschen. Zusammen mit `key` der Primärschlüssel | | `key` | text | Name der Präferenz. Zusammen mit `userId` der Primärschlüssel | | `value` | jsonb | Inhalt der Präferenz | | `updatedAt` | timestamp | Zeitpunkt des letzten Schreibvorgangs | ## Migrationen {#migrations} Drizzle übernimmt die Schema-Migrationen. Die Migrationsdateien liegen in `apps/api/drizzle/`. Während der Entwicklung: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` In der Produktion werden ausstehende Migrationen beim Start automatisch angewendet. ## Sichern und Wiederherstellen von {#backup-and-restore} Die relationale Datenbank befindet sich im `SnapOtter-pgdata`-Volume des Postgres-Containers, nicht im `/data`-Volume der App. **Logische Sicherung mit Validierung (empfohlen)** ```bash # Dump into PostgreSQL's portable custom archive format docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore into a fresh/disposable target first and fail on the first SQL error docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Dieser Datenbank-Dump enthält keine gespeicherten Bibliotheksobjekte im `/data/files`- oder dauerhaften BullMQ-Status in Redis. Sichern und wiederherstellen Sie diese mit dem koordinierten Verfahren in [Sicherheit und Härtung](/de/guide/security#backup-and-recovery). **Schnappschuss des kalten Volumens** ```bash # Stop every service first, then use your storage platform to snapshot the # PostgreSQL, app-data, and Redis volumes as one crash-consistent set. docker compose -f docker/docker-compose.yml stop ``` Kopieren Sie kein Live-PostgreSQL-Datenverzeichnis mit `tar`. Verfassen Sie Volume-Namen mit Präfixen nach Projekt. Lösen Sie daher die gemounteten Volume-IDs von `docker inspect` oder Ihrer Speicherplattform auf, anstatt die wörtliche Bezeichnung `SnapOtter-pgdata` anzunehmen. ### Migration von 1.x (SQLite) {#migrating-from-1-x-sqlite} Das Upgrade von SnapOtter 1.x hat einen eigenen Leitfaden: siehe [Upgrade von 1.x auf 2.0](./upgrading). Kurz gesagt: Verwende dein bestehendes Volume `/data` weiter, und 2.0 erkennt und importiert `/data/snapotter.db` beim ersten Start automatisch (oder setze `SQLITE_MIGRATE_PATH`, um explizit darauf zu verweisen). Sichere zuerst das gesamte Volume `/data`, nicht nur `snapotter.db`: 1.x nutzt den SQLite-WAL-Modus, sodass ein gestoppter Container einen Großteil seiner Daten oft in `snapotter.db-wal` neben einer fast leeren `snapotter.db` ablegt. --- --- url: https://docs.snapotter.com/fr/tools/audio/pitch-shift.md description: Monter ou baisser la hauteur de l'audio par demi-tons sans changer la vitesse. --- # Décalage de hauteur {#pitch-shift} Monter ou baisser la hauteur d'un fichier audio d'un nombre de demi-tons sans changer sa vitesse de lecture. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/audio/pitch-shift` Accepte des données de formulaire multipart avec un fichier audio et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | semitones | integer | Non | `3` | Demi-tons à décaler (-12 à 12). Doit être différent de zéro. | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/pitch-shift \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"semitones": -5}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Les valeurs positives montent la hauteur ; les valeurs négatives la baissent. * Un décalage de 12 demi-tons équivaut à une octave vers le haut ; -12 équivaut à une octave vers le bas. * La durée de lecture reste identique quelle que soit l'ampleur du décalage. * La sortie conserve généralement le conteneur d'entrée. Une entrée AAC est écrite en M4A, et les entrées à décodage seul non prises en charge se replient sur le MP3. --- --- url: https://docs.snapotter.com/fr/tools/audio/split-audio.md description: >- Découpe l'audio par intervalles de temps, parts égales ou détection de silence. --- # Découper l'audio {#split-audio} Découpe un fichier audio en segments par intervalles de temps fixes, parts égales ou détection automatique du silence. Renvoie une archive ZIP des segments. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/audio/split-audio` Accepte des données de formulaire multipart avec un fichier audio et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | mode | string | Non | `"time"` | Stratégie de découpage : `time`, `parts`, `silence` | | segmentS | number | Non | `60` | Longueur de segment en secondes, 1 à 3600 (utilisé lorsque le mode est `time`) | | parts | integer | Non | `2` | Nombre de parts égales, 2 à 20 (utilisé lorsque le mode est `parts`) | | thresholdDb | number | Non | `-40` | Seuil de silence en dB, -80 à -20 (utilisé lorsque le mode est `silence`) | | minSilenceS | number | Non | `0.3` | Écart de silence minimal en secondes, 0,1 à 10 (utilisé lorsque le mode est `silence`) | ## Exemple de requête {#example-request} Découper en segments de 30 secondes : ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "time", "segmentS": 30}' ``` Découper par détection de silence : ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "silence", "thresholdDb": -35, "minSilenceS": 0.5}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio_parts.zip", "originalSize": 4500000, "processedSize": 4600000 } ``` ## Remarques {#notes} * Le `downloadUrl` pointe vers une archive ZIP contenant tous les segments. * Seuls les paramètres pertinents pour le `mode` choisi sont utilisés ; les autres sont ignorés. * Les noms de fichiers des segments sont numérotés de façon séquentielle (par ex. `part-000.mp3`, `part-001.mp3`). * Le format de sortie correspond au format d'entrée. --- --- url: https://docs.snapotter.com/fr/tools/files/split-csv.md description: Découpe un CSV en fichiers plus petits selon le nombre de lignes. --- # Découper un CSV {#split-csv} Découpe un gros fichier CSV ou TSV en fichiers plus petits selon le nombre de lignes. Renvoie une archive ZIP contenant les parties. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/split-csv` Accepte des données de formulaire multipart contenant un fichier CSV et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | rowsPerFile | entier | Non | `1000` | Nombre de lignes de données par fichier de sortie (1 à 1 000 000) | | keepHeader | booléen | Non | `true` | Répète la ligne d'en-tête dans chaque fichier de sortie | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Remarques {#notes} * La sortie est toujours une archive ZIP contenant les parties du CSV découpé, nommées séquentiellement (par exemple `part-1.csv`, `part-2.csv`). * Lorsque `keepHeader` vaut `true`, chaque partie inclut la ligne d'en-tête d'origine, de sorte que chaque fichier peut être utilisé indépendamment. * Les fichiers CSV et TSV sont tous deux acceptés en entrée. * Le nombre de lignes fait uniquement référence aux lignes de données ; la ligne d'en-tête n'est pas comptabilisée. --- --- url: https://docs.snapotter.com/fr/tools/image/split.md description: >- Découpe une image en tuiles de grille selon des lignes et des colonnes ou selon une taille en pixels, renvoyées sous forme d'archive ZIP. --- # Découper une image {#image-splitting} Découpe une seule image en tuiles de grille selon un nombre de colonnes/lignes ou selon des dimensions en pixels précises. Renvoie une archive ZIP contenant toutes les tuiles. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/split` ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | columns | integer | Non | 3 | Nombre de colonnes de découpage (1 à 100) | | rows | integer | Non | 3 | Nombre de lignes de découpage (1 à 100) | | tileWidth | integer | Non | - | Largeur des tuiles en pixels (min 10). Remplace `columns` lorsque `tileWidth` et `tileHeight` sont tous deux définis. | | tileHeight | integer | Non | - | Hauteur des tuiles en pixels (min 10). Remplace `rows` lorsque `tileWidth` et `tileHeight` sont tous deux définis. | | outputFormat | string | Non | `"original"` | Format de sortie des tuiles : `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | Non | 90 | Qualité de sortie pour les formats avec perte (1 à 100) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Exemple de réponse {#example-response} La réponse est diffusée directement sous forme de fichier ZIP avec `Content-Type: application/zip`. Le nom de fichier suit le modèle `split-.zip`. Chaque tuile à l'intérieur du ZIP est nommée `_r_c.` (par exemple `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Remarques {#notes} * Accepte un seul fichier image. * Prend en charge les formats d'entrée HEIC, RAW, PSD et SVG (décodés automatiquement). * Lorsque `tileWidth` et `tileHeight` sont tous deux fournis, ils sont prioritaires sur `columns`/`rows`. Les dimensions de la grille sont calculées comme `ceil(imageWidth / tileWidth)` et `ceil(imageHeight / tileHeight)`. * Les tuiles de bord (colonne la plus à droite, ligne du bas) peuvent être plus petites que la taille de tuile spécifiée si les dimensions de l'image ne sont pas divisibles de façon égale. * La taille maximale de la grille est plafonnée à 100x100 (10 000 tuiles). * La réponse diffuse le ZIP directement, il n'y a donc pas de corps de réponse JSON. Utilisez `--output` avec curl pour enregistrer le fichier. --- --- url: https://docs.snapotter.com/tr/changelog.md description: >- SnapOtter için sürüm notları ve versiyon geçmişi. Her sürümde nelerin yeni, iyileştirilmiş ve düzeltilmiş olduğunu görün. --- # Değişiklik Günlüğü {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0, görüntü araç setini beş modalite (Image, Video, Audio, PDF ve Files) genelinde 200+ araçtan oluşan tam bir dosya işleme paketine dönüştürür; Postgres 17 ve Redis destekli bir iş kuyruğu üzerinde yeniden inşa edilmiştir ve tek komutlu bir `docker run` ile gelir. Bu önemli bir sürümdür; 1.x'ten yükseltmeden önce Kırılma değişikliklerini okuyun. ### Yeni özellikler {#new-features} * **Dört yeni araç modalitesi**: Video, Audio, PDF ve Files, Image'e katılarak kataloğu 200+ araca çıkarır. * **Kalıcı arka plan işleri**: Redis destekli bir kuyruk (BullMQ) her aracı, canlı SSE ilerlemesiyle izlenen bir iş olarak çalıştırır. * **Hepsi-bir-arada tek konteyner modu**: Tek bir `docker run`, gömülü Postgres ve Redis ile eksiksiz bir örneği başlatır. * **İstek üzerine AI paketleri**: Arka plan kaldırma, OCR, transkripsiyon, büyütme, yüz algılama ve iyileştirme, nesne silici, renklendirme ve fotoğraf restorasyonu arayüzden kurulur. GPU hızlandırma her çerçeve için ayrı algılanır. * **Sign PDF**: Bir imzayı çizin, yazın veya yükleyin ve tarayıcıda bir PDF üzerine yerleştirin. * **Automate**: Araçları zincirleyen, dokuz hazır şablonla gelen görsel bir işlem hattı oluşturucu. * **83 tek tıkla dönüştürme ön ayarı**: Bulanık aramayla birlikte özel JPG-to-PNG, MP4-to-GIF ve benzeri dönüştürücüler. * **Katman tabanlı görüntü düzenleyici**: `/editor` adresinde fırçalar, şekiller, ayarlamalar, filtreler ve eğrilerle donatılmış, Konva destekli bir düzenleyici. * **Files kütüphanesi**: Herhangi bir sonucu kaydedin ve başka bir araca girdi olarak yeniden kullanın. * Sabitlenmiş araçlar, tuval içi yakınlaştırma ve kaydırma, 21 dil ve kurumsal yetenekler (OIDC/SSO, SAML, SCIM, S3 depolama, araç başına izinler, denetim dışa aktarma, dağıtık izleme). ### İyileştirmeler {#improvements} * Çalışan bir işlemi iptal edin. (#137) * LibRaw aracılığıyla DNG dahil tam çözünürlüklü RAW kod çözme. (#289) * Root olmayan ve yabancı-UID dağıtımları (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Doğru AI kurulum algılama ve sağlamlaştırılmış bir kurulum akışı. (#214, #352) * Gizlilik sağlamlaştırma: otomatik üçüncü taraf dış trafik yok, artı isteğe bağlı katı-çevrimdışı modu. * Analitik kapalıyken bile her zaman açık geri bildirim düğmesi. ### Hata düzeltmeleri {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` araç rotaları için hız sınırlamayı yeniden devre dışı bırakır. (#271) * Docker imajı içindeki AI virtualenv yolları onarıldı. (#390) * sharp 0.35.2+ uyumluluğu. (#362) * Görüntü düzenleyici düzen düzeltmeleri: cetveller, doldurma davranışı, kenar çubuğu ve tuval boyutlandırma. (#258, #259) * İtalyanca çeviri tamamlandı. (#231, #206, #425) * Audio normalize ve loudnorm kaynak örnekleme hızını korur. * SSRF sağlamlaştırma: sayısal IPv6 CIDR eşleştirme ve genişletilmiş bir URL ön taraması. (#287) * Oluşturulan PDF'lere Producer olarak SnapOtter damgası eklenir. * mediapipe, Python 3.13 ve Debian 13 üzerine kurulur. ### Kırılma değişiklikleri {#breaking-changes} 2.0, gömülü SQLite veritabanını Postgres 17 ile değiştirir ve iş kuyruğu için Redis 8 ekler. 1.x verileriniz ilk açılışta otomatik olarak taşınır, ancak konteyner yığını değiştiği için önce tüm `/data` biriminizi yedekleyin (1.x, SQLite'ı WAL modunda çalıştırır, dolayısıyla işlenmiş veriler genellikle `snapotter.db-wal` içinde bulunur). Ardından tek konteyner imajını (gömülü Postgres ve Redis, yalnızca root) veya Compose yığınını (uygulama artı Postgres 17 ve Redis 8) seçin. [taşıma kılavuzuna](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) ve [yükseltme kılavuzuna](/tr/guide/upgrading) bakın. ### Yükseltme {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Veya Docker Compose ile: ```bash docker compose pull && docker compose up -d ``` [GitHub'daki tam fark](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Yeni HTML to Image aracı, WCAG 2.2 AA erişilebilirliği, sızma testinden gelen güvenlik sağlamlaştırması ve 5 kritik Docker düzeltmesi. ### Yeni özellikler {#new-features-1} * **HTML to Image**: URL'lerin veya ham HTML'in ekran görüntülerini PNG/JPEG/WebP olarak yakalayın. Tam sayfa yakalamalar, özel görünüm alanları, koyu mod. * **Docker \_FILE gizli sözleşmesi**: Hassas ortam değişkenlerini düz metin yerine dosya olarak bağlayın. (#205) * **Kurumsal lisanslama ve S3 depolama**: İsteğe bağlı ticari lisans anahtarı ve S3 uyumlu nesne depolama. * **Şekil düzenleyici iyileştirmeleri**: Doldurma/kontur şeffaflığı, RGBA renk seçici, kesik çizgi stilleri. * **Önceden derlenmiş sürüm arşivleri**: Docker dışı kurulumlar (Proxmox, çıplak donanım, LXC) için GitHub Releases'ten tarball indirin. (#202) ### İyileştirmeler {#improvements-1} * **WCAG 2.2 AA erişilebilirliği**: Gezinmeyi atlama, odak yakalama, aria-live bölgeleri, azaltılmış hareket desteği, doğru kontrast oranları. (#209) * **Mobil uyumluluk**: Duyarlı ayarlar, mobil sekme geçişinde SSE otomatik yeniden bağlanma. (#203, #204) * **Arka plan kaldırma kalitesi**: Kenar yumuşatma, renk arındırma, çıktı formatı seçimi. * **İtalyanca çeviri**: @albanobattistella tarafından ~145 yeni dize. (#206) * **Araç başına API belgeleri**: Parametreler, örnekler ve yanıt formatlarıyla 53 belge sayfası. * **AI modeli indirmeleri**: HuggingFace için üstel geri çekilmeli yeniden deneme mantığı. (#201) ### Hata düzeltmeleri {#bug-fixes-1} * Yeni Docker konteynerleri tamamen kullanılamaz durumdaydı (hız sınırı tüm istekleri engelliyordu). * Yüz algılama AI araçları (blur-faces, red-eye-removal, enhance-faces, passport-photo) tüm platformlarda başarısız oluyordu. * HEIC dosyaları ARM'da bozuktu (libheif sembol uyuşmazlığı). * Upscale ve restore-photo AI paketleri ARM'da kurulamıyordu. * OCR, GPU konteynerlerinde yanlış CUDA sürümünü kullanıyordu. * Onaltılık IPv4 eşlemeli IPv6 adresleri aracılığıyla SSRF koruma atlatması. (Katkı: @tonghuaroot) * Yardımcı görüntülerle iPhone HEIC kod çözme. (#183, #199) * 8GB GPU'larda Real-ESRGAN CUDA bellek yetersizliği. (#200) * 6 üretim Sentry hatası ve 7 QA hatası. (#208) ### Güvenlik {#security} * 10 sızma testi bulgusu giderildi (XFF atlatması, hatalı biçimlendirilmiş JSON çökmeleri, sınırsız işlem hatları, denetim günlüğü XSS, TRACE yöntemi ve daha fazlası). (#207) * SSRF onaltılık IPv6 atlatması engellendi. (Katkı: @tonghuaroot) * Dockerfile temel imajları özet ile sabitlendi. ### Yükseltme {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Veya Docker Compose ile: ```bash docker compose pull && docker compose up -d ``` [GitHub'daki tam fark](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Canlı demo, araç başına giriş sayfaları ve bir dizi cilalama düzeltmesi. ### Yeni özellikler {#new-features-2} * **Canlı demo** - [demo.snapotter.com](https://demo.snapotter.com) insanların hiçbir şey kurmadan SnapOtter'ı denemesini sağlar. * **Araçlar dizin sayfası** - Arama ve kategori filtreleriyle `/tools` adresinde 50+ aracın tümüne göz atın. * **50+ SEO giriş sayfası** - Her aracın artık SSS'ler, kullanım senaryoları ve karşılaştırma tablolarıyla özel bir giriş sayfası var. * **Arka plan önizlemesi** - Öncesi-sonrası kaydırıcı, şeffaf görüntülerin arkasında damalı bir arka plan gösterir. * **Güçlü parola oluşturucu** - Üye Ekle formunda tek tıklık düğme. ### Hata düzeltmeleri {#bug-fixes-2} * HEIC/HEIF bilgi aracı artık başarısız olmuyor (ön kod çözme eklendi). * AI modeli paketi kurulumu daha iyi hata mesajları gösterir ve kaynak sınırlarına uyar. * Kütüphane küçük resimleri doğru yükleniyor (kimlik doğrulama başlıkları eksikti). * Açılır menüler People ve Teams ayarları tablolarında artık kırpılmıyor. * Boyut karşılaştırma yüzdesi sıkıştırma dışı araçlarda gizlendi. * Yinelenen gizlilik politikası bağlantısı kaldırıldı. * AI özellikleri ayarları için İtalyanca çeviri eklendi. * Yeniden adlandırılan Lucide simgeleri güncellendi (Wand2, Columns). ### Altyapı {#infrastructure} * OpenSSF Scorecard 4.3'ten ~7.0'a sağlamlaştırıldı. * CI testleri, küçültülmüş sabitlemelerle 4 parçaya paralelleştirildi. * 41 bağımlılık güncellemesi. ### Yükseltme {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Veya Docker Compose ile: ```bash docker compose pull && docker compose up -d ``` [GitHub'daki tam fark](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Beş yeni araç, tam bir görüntü düzenleyici, SSO oturum açma, 20 dil. Muhtemelen üç ayrı sürüm olmalıydı, ama işte buradayız. ### Yeni özellikler {#new-features-3} * **Görüntü düzenleyici** - Katmanlar, fırçalar, şekiller, ayarlamalar, filtreler, eğriler, klavye kısayolları. Tarayıcınızda çalışır, donanımınızda işler. * **OIDC / SSO kimlik doğrulama** - Google, GitHub, Okta veya herhangi bir OpenID Connect sağlayıcısıyla oturum açın. Birkaç ortam değişkeni ayarlayın; ekibiniz mevcut hesaplarını kullansın. * **Meme oluşturucu** - opentype.js aracılığıyla metin oluşturma ile 100 yerleşik şablon. Ya da kendi görüntünüzü yükleyin. * **Beautify** - Bir ekran görüntüsü bırakın, cilalı bir görüntü alın. Cihaz çerçeveleri (macOS, Windows, tarayıcı), gölgeler, gradyanlar, sosyal medya ön ayarları. * **Renk körlüğü simülasyonu** - Görüntülerin protanopi, döteranopi, tritanopi ve diğer renk görme eksiklikleriyle nasıl göründüğünü önizleyin. * **PNG şeffaflık düzeltici** - Sahte şeffaf PNG'leri algılar ve BiRefNet HR-matting ile düzeltir. LaMa inpainting aracılığıyla isteğe bağlı filigran kaldırma. * **AI tuval genişletme** - Görüntü sınırlarını AI dolgusuyla genişletin. Ne kadar GPU süresi harcamak istediğinize bağlı olarak üç kalite katmanı (hızlı, dengeli, kaliteli). * **20 dil** - Arapça, Çince (Basitleştirilmiş/Geleneksel), Çekçe, Felemenkçe, Fransızca, Almanca, Hintçe, Endonezce, İtalyanca, Japonca, Korece, Lehçe, Portekizce, Rusça, İspanyolca, Tayca, Türkçe, Ukraynaca, Vietnamca. Arapça için RTL çalışır. * **URL içe aktarma** - URL'leri bırakma alanına yapıştırın veya bir listeden toplu içe aktarın. SSRF korumasıyla sunucu tarafında getirme. * **Çok dosyalı silici** - Birden fazla görüntü üzerinde silme maskeleri çizin, hepsini tek tıkla işleyin. Fırça darbeleri görüntü başına kalıcıdır. * **İşlem hattı içe/dışa aktarma** - Araç zincirlerini JSON olarak kaydedin, başkalarıyla paylaşın. * **17 yeni kamera RAW formatı** exiftool aracılığıyla, ayrıca QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ ve APNG girişi. BMP, ICO, JP2, QOI için yeni çıktı kodekleri. AVIF, TIFF, GIF, JXL ve PSD dışa aktarma, önceden kaybedilmiş bir daldan kurtarıldı. ### İyileştirmeler {#improvements-2} * **Görüntü iyileştirme** - Eski işlem hattı CLAHE + normalise + gamma ile değiştirildi. Yeni Deep Enhance geçişi, daha agresif sonuçlar için AI modelini kullanır. * **Fotoğraf restorasyonu** - Çizik algılama, 8 açılı Otsu filtrelemesiyle yeniden yazıldı. LaMa inpainting artık yerel çözünürlükte çalışır. * **Her yerde egzotik formatlar** - OCR, image-to-PDF, favicon oluşturucu, kompozisyon, birleştirme ve vektörleştirmenin tümü artık HEIC, RAW, PSD kodunu çözer. * **Compress** - Hedef boyut toleransı %5'ten %1'e sıkılaştırıldı. Hedef boyut varsayılan moddur. Adım düğmeleri ve KB/MB birim seçici eklendi. * **Sentry temizliği** - 644 eyleme geçirilemeyen olay filtrelendi. Gerçek hatalar artık düzgün ele alınıyor. * **GPU algılama** - CUDA'nın mevcut olduğu ancak nvidia-smi'nin olmadığı konteynerler için daha iyi tanılama. * **Kimlik-doğrulama-devre-dışı modu** - Anonim kullanıcı, veritabanına admin rolüyle eklenir. API anahtarları, işlem hatları ve kullanıcı dosyaları artık FK kısıtlamalarında bozulmuyor. * Birim, entegrasyon ve E2E genelinde **2.705+ yeni test**. ### Hata düzeltmeleri {#bug-fixes-3} * CPU'da büyütme, NAS kutularında ve düşük güçlü donanımda artık zaman aşımına uğramıyor. * QR kodu logosu artık önizlemenin kalıcı olarak kaybolmasına neden olmuyor. * Uzun dikey görüntüler için kırpma taşması düzeltildi. * TIFF alfa dosyaları, bozulma üretmek yerine doğru şekilde PNG çıktısını zorlar. * HDR/EXR kod çözme, CLAHE'den önce 8 bite dönüştürerek kod çözme hatalarını düzeltir. * Yüz işaretleri girdi arabellekleri, Python yardımcı işleminden önce PNG'ye dönüştürülerek çökmeler düzeltildi. * Yinelenenleri bul, karışık formatlı yığınları ve ağ hatalarını ele alır. * Beautify önizlemesi gerçek zamanlı güncellenir. * Birleştirme ve vektörleştirme için ilerleme çubukları. * SVGZ, SVG-to-raster tarafından ele alınır. * ASCII olmayan dosya adları, yüzde kodlamalı X-File-Results başlığı aracılığıyla düzeltildi. ### Yükseltme {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Veya Docker Compose ile: ```bash docker compose pull && docker compose up -d ``` [GitHub'daki tam fark](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} GPU otomatik algılamalı birleşik Docker imajı. Tek imaj hem CPU hem de GPU iş yüklerini yönetir. Compose, günlük döndürmeli tek bir dosyaya basitleştirildi. Model ön indirmeleri artık doğrulama ve bir duman testi içeriyor. *** ## v1.13.0 {#v1-13-0} Rol tabanlı erişim denetimi (RBAC). 14 ayrıntılı izin, üç yerleşik rol (admin, editor, user), özel rol desteği. Tüm API rotalarında izin kontrolleri. Kullanıcı izinlerine göre filtrelenen ön uç sekmeleri. *** ## v1.12.0 {#v1-12-0} PDF to Image aracı. PDF sayfalarını özel DPI'da PNG, JPEG, WebP veya TIFF'e dönüştürün. GPU otomatik algılamalı birleşik Docker imajı. *** ## v1.11.0 {#v1-11-0} AI dostu belgeler için vitepress-plugin-llms aracılığıyla otomatik oluşturulan llms.txt. *** ## v1.10.0 {#v1-10-0} Yüz korumalı içerik farkında yeniden boyutlandırma (dikiş oyma). Önemli içeriği koruyarak görüntüleri yeniden boyutlandırın. *** ## v1.9.0 {#v1-9-0} Stitch / Combine aracı. Görüntüleri yan yana, dikey olarak üst üste veya özel bir ızgarada birleştirin. *** ## v1.8.0 {#v1-8-0} Edit Metadata aracı. EXIF, IPTC ve XMP meta verilerini ayrıntılı bir çıkarma/koruma arayüzüyle görüntüleyin ve düzenleyin. *** ## Eski sürümler {#older-releases} Yama sürümleri dahil tam işleme düzeyi değişiklik günlüğü için [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases) sayfasına bakın. --- --- url: https://docs.snapotter.com/sv/tools/image/split.md description: >- Dela en bild i rutnätsplattor efter rader och kolumner eller efter pixelstorlek, returnerat som ett ZIP-arkiv. --- # Dela bild {#image-splitting} Dela en enda bild i rutnätsplattor efter antal kolumner/rader eller efter specifika pixeldimensioner. Returnerar ett ZIP-arkiv som innehåller alla plattor. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/split` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | columns | integer | No | 3 | Antal kolumner att dela upp i (1 till 100) | | rows | integer | No | 3 | Antal rader att dela upp i (1 till 100) | | tileWidth | integer | No | - | Plattbredd i pixlar (min 10). Åsidosätter `columns` när både `tileWidth` och `tileHeight` är angivna. | | tileHeight | integer | No | - | Platthöjd i pixlar (min 10). Åsidosätter `rows` när både `tileWidth` och `tileHeight` är angivna. | | outputFormat | string | No | `"original"` | Utdataformat för plattor: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Utdatakvalitet för destruktiva format (1 till 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Example Response {#example-response} Svaret strömmas direkt som en ZIP-fil med `Content-Type: application/zip`. Filnamnet följer mönstret `split-.zip`. Varje platta inuti ZIP-filen namnges `_r_c.` (t.ex. `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Notes {#notes} * Tar emot en enda bildfil. * Stöder indataformaten HEIC, RAW, PSD och SVG (avkodas automatiskt). * När både `tileWidth` och `tileHeight` anges har de företräde framför `columns`/`rows`. Rutnätsdimensionerna beräknas som `ceil(imageWidth / tileWidth)` och `ceil(imageHeight / tileHeight)`. * Kantplattor (kolumnen längst till höger, understa raden) kan vara mindre än den angivna plattstorleken om bildens dimensioner inte är jämnt delbara. * Maximal rutnätsstorlek är begränsad till 100x100 (10 000 plattor). * Svaret strömmar ZIP-filen direkt, så det finns ingen JSON-svarskropp. Använd `--output` med curl för att spara filen. --- --- url: https://docs.snapotter.com/sv/tools/files/split-csv.md description: Dela upp en CSV i mindre filer efter antal rader. --- # Dela upp CSV {#split-csv} Dela upp en stor CSV- eller TSV-fil i mindre filer efter antal rader. Returnerar ett ZIP-arkiv som innehåller delarna. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/files/split-csv` Tar emot multipart-formulärdata med en CSV-fil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | rowsPerFile | heltal | Nej | `1000` | Antal datarader per utdatafil (1-1 000 000) | | keepHeader | boolean | Nej | `true` | Upprepa rubrikraden i varje utdatafil | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Anteckningar {#notes} * Utdata är alltid ett ZIP-arkiv som innehåller de uppdelade CSV-delarna, namngivna i följd (t.ex. `part-1.csv`, `part-2.csv`). * När `keepHeader` är `true` inkluderar varje del den ursprungliga rubrikraden så att varje fil kan användas fristående. * Både CSV- och TSV-filer godtas som indata. * Radantalet avser endast datarader; rubrikraden räknas inte. --- --- url: https://docs.snapotter.com/vi/tools/image/image-pad.md description: Đệm một ảnh về tỷ lệ khung hình đích với nền màu đặc, trong suốt hoặc mờ. --- # Đệm ảnh {#image-pad} Đệm một ảnh về tỷ lệ khung hình đích bằng cách thêm nền màu đặc, trong suốt hoặc mờ xung quanh nó. Hữu ích để đưa ảnh vào các tỷ lệ khung hình cố định cho mạng xã hội hoặc in ấn mà không cần cắt. ## Điểm cuối API {#api-endpoint} `POST /api/v1/tools/image/image-pad` Chấp nhận dữ liệu biểu mẫu multipart với một tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | target | string | Không | `"1:1"` | Tỷ lệ khung hình đích: `16:9`, `9:16`, `1:1`, `4:3`, `3:4`, hoặc `custom` | | ratioW | integer | Không | `1` | Chiều rộng tỷ lệ tùy chỉnh (1-100, dùng khi target là `custom`) | | ratioH | integer | Không | `1` | Chiều cao tỷ lệ tùy chỉnh (1-100, dùng khi target là `custom`) | | background | string | Không | `"color"` | Chế độ nền: `color`, `transparent`, hoặc `blur` | | color | string | Không | `"#ffffff"` | Màu nền dạng hex (khi background là `color`) | | padding | integer | Không | `0` | Khoảng đệm bổ sung tính theo phần trăm canvas (0-50) | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 3100000 } ``` ## Ghi chú {#notes} * Chế độ nền `blur` tạo một bản sao mờ của ảnh gốc làm phần đệm lấp đầy, cho ra kết quả gắn kết về mặt hình ảnh. * Khi dùng nền `transparent`, đầu ra được chuyển sang PNG để giữ kênh alpha. * Định dạng đầu ra khớp với định dạng đầu vào trừ khi có liên quan đến độ trong suốt. Đầu vào HEIC, RAW, PSD và SVG được giải mã tự động trước khi xử lý. * Đặt `target` thành `custom` và cung cấp `ratioW` và `ratioH` cho các tỷ lệ khung hình tùy ý (ví dụ, `ratioW: 3, ratioH: 2` cho 3:2). --- --- url: https://docs.snapotter.com/fr/guide/deployment.md description: >- Déployez SnapOtter en production avec Docker. Exigences matérielles, configuration GPU et configs de reverse proxy pour Nginx, Traefik et Cloudflare. --- # Déploiement {#deployment} SnapOtter se déploie sous la forme d'une pile Docker Compose à 3 conteneurs : l'image applicative SnapOtter, PostgreSQL 17 et Redis 8. L'image applicative prend en charge **linux/amd64** (avec NVIDIA CUDA pour l'accélération de l'IA) et **linux/arm64** (CPU), elle s'exécute donc nativement sur les serveurs Intel/AMD, les Mac Apple Silicon et les appareils ARM comme le Raspberry Pi 4/5. L'accélération par iGPU Intel/AMD via VA-API, Quick Sync ou OpenCL n'est pas prise en charge pour l'inférence IA aujourd'hui. Consultez [Image Docker](./docker-tags) pour la configuration GPU, les exemples Docker Compose et l'épinglage de version. ::: info Compatibilité de l’OCR coréen L’OCR rapide prend en charge `auto`, `en`, `de`, `es`, `fr`, `zh` et `ja`, mais pas le coréen (`ko`). Le coréen nécessite le pack OCR précis et `balanced` ou `best`. Le pack fonctionne dans les conteneurs Linux amd64 et arm64 officiels, y compris sur les hôtes NVIDIA où l’OCR reste exécuté sur le CPU. Un système non pris en charge reçoit une erreur de compatibilité explicite, sans repli silencieux vers `fast`. Le coréen avec `fast` ou l’alias historique `tesseract` est refusé avant la mise en file avec `FEATURE_INCOMPATIBLE` et `fast-korean-unsupported`. ::: ## Démarrage rapide (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` L'application est ensuite disponible sur `http://localhost:1349`. > **Limites de débit Docker Hub ?** Remplacez `snapotter/snapotter:latest` par `ghcr.io/snapotter-hq/snapotter:latest` pour récupérer l'image depuis GitHub Container Registry à la place. Les deux registres reçoivent la même image à chaque publication. ## Démarrage rapide (NVIDIA CUDA) {#quick-start-nvidia-cuda} Pour l’accélération NVIDIA CUDA sur les outils d’IA pris en charge (suppression de l’arrière-plan, mise à l’échelle, amélioration du visage) : ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Changez ceci pour les déploiements non locaux POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### Vérifier l'accélération GPU {#verify-gpu-acceleration} Vérifiez la détection CUDA dans les journaux : ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` Si les outils d'IA s'exécutent sur le processeur même si `--gpus all` et NVIDIA Container Toolkit sont correctement configurés, réinstallez le bundle concerné (par exemple Suppression de l'arrière-plan) depuis **Paramètres → Fonctionnalités IA**. Le programme d'installation restaure la version GPU d'ONNX Runtime, qu'une version CPU uniquement extraite par un autre ensemble (tel que la transcription) peut autrement masquer dans l'environnement d'IA partagé. Si la réinstallation à partir de l'interface utilisateur ne restaure pas le GPU sur une image plus ancienne, consultez la réparation manuelle dans \[numéro 490] (https://github.com/snapotter-hq/SnapOtter/issues/490). ## Exigences matérielles {#hardware-requirements} Ces chiffres proviennent de tests de performance sur toute une gamme de systèmes, d'un poste de travail amd64 moderne équipé d'une NVIDIA RTX 4070 jusqu'à un Raspberry Pi, en exécutant l'intégralité du catalogue d'outils sur chacun et en balayant les limites de ressources Docker pour trouver le plancher réel. Vous tournez au bas de ces niveaux (un Pi, un vieux portable, un VPS de 2 Go) ? [Configurations à ressources limitées](/fr/guide/low-resource) transforme ces chiffres en un pas à pas concret avec des plafonds ajustés. ### Référence rapide {#quick-reference} | Niveau | Cas d'usage | CPU | RAM | GPU | Stockage | |------|----------|-----|-----|-----|---------| | Minimum | Outils image, fichiers et PDF légers ; utilisateur unique ; petits lots | 2 cœurs | 2 Go | Aucun | ~7 Go | | Recommandé | Les cinq modalités, y compris vidéo, PDF et IA sur CPU ; lots ; quelques utilisateurs | 4 cœurs | 4 Go | Aucun | ~25 Go | | Complet | Tout à pleine vitesse, y compris IA sur GPU ; grands lots ; nombreux utilisateurs | 6-8 cœurs | 8 Go | NVIDIA 8 Go+ de VRAM (12 Go confortable) | ~35 Go | **Architecture : 64 bits uniquement** (`linux/amd64` ou `linux/arm64`). SnapOtter s'exécute nativement sur les serveurs Intel/AMD, les Mac Apple Silicon et les cartes ARM 64 bits, y compris le **Raspberry Pi 4 et 5** (4-8 Go). Il **ne** fonctionne **pas** sur ARM 32 bits (`armv7`/`armhf`), aucune image n'étant construite pour cette cible, ni sur les cartes de la classe 512 Mo comme le Pi Zero, qui sont sous le plancher mémoire (voir ci-dessous). ### Minimum (outils image, fichiers et PDF légers ; sans IA) {#minimum-image-files-and-light-pdf-tools-no-ai} | Ressource | Exigence | |---|---| | CPU | 2 cœurs | | RAM | 2 Go | | Disque | ~5,5 Go (image) + volume de données | | GPU | Non requis | Les 222 outils non-IA du catalogue - image (redimensionner, rogner, convertir, compresser, ajuster, filigraner), vidéo (couper, rendre muet, remultiplexer), audio (convertir, normaliser, couper), PDF (fusionner, diviser, compresser, pivoter, protéger), conversions de fichiers et préréglages de conversion dédiés - s'exécutent sur du matériel modeste. La plupart des opérations se terminent en bien moins d'une seconde, même sur un gros fichier : une image de 2,7 Mo est redimensionnée en ~0,05 s et réencodée en WebP en ~2 s. Le plancher mémoire est réel, d'après un balayage des limites de ressources Docker : **512 Mo ne peuvent pas démarrer la pile** (même un simple redimensionnement d'image est tué), **1 Go** gère les opérations sur un seul fichier mais un lot multi-fichiers manque de mémoire, et **2 Go / 2 cœurs** est la plus petite configuration qui gère les lots confortablement. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **La seule exception gourmande en CPU est le réencodage vidéo.** Les opérations de copie de flux (couper, rendre muet, remultiplexage de conteneur) sont instantanées, mais le transcodage vers un codec différent est limité par le CPU. Un clip 1080p / 45 secondes réencodé en VP9 (WebM) prend environ **~40 s** sur un CPU moderne rapide, ~45 s sur Apple Silicon, ~80 s sur un ancien 4 cœurs mobile et **~130 s** sur un ancien serveur 4 cœurs. Si votre charge de travail est axée sur la vidéo, privilégiez les cœurs CPU et la fréquence d'horloge, ou augmentez la limite `cpus:` du conteneur : le compose fourni plafonne l'application à 4 cœurs par défaut (8 sur le compose GPU). ### Recommandé (outils IA sur CPU) {#recommended-ai-tools-on-cpu} | Ressource | Exigence | |---|---| | CPU | 4 cœurs | | RAM | 4 Go | | Disk | 3 Go (image) + environ 20 Go (tous les packs AI en option) + espace de travail | | GPU | Non requis (repli sur CPU) | **L'installation et l'exécution des plus gros bundles d'IA sont ce qui pousse la recommandation à 4 Go de RAM.** Sans packs optionnels installés, l'application reste inactive autour de 360 ​​Mo. Les anciens outils Python partagent un sidecar, tandis que les outils OCR précis utilisent un dispatcher dédié à longue durée de vie épinglé à la génération active immuable. Avant l'activation, le programme d'installation exécute un smoke test sur le candidat. Il passe ensuite de manière atomique au nouveau dispatcher et draine le dispatcher précédent avant garbage collection. Chaque artefact OCR précis officiel doit transmettre son release suite le plus défavorable dans un 4 GiB cgroup, tandis que la recommandation d'hôte de 4 Go laisse une marge pour l'application Node.js, Postgres, Redis, les files d'attente et le travail simultané. La plupart des outils IA sont parfaitement utilisables sur CPU ; deux ou trois veulent vraiment un GPU. Mesuré sur un CPU 4 cœurs moderne : | Outil IA | Temps CPU | Utilisable sur CPU ? | |---|---|---| | Détection de visages (flouter les visages, recadrage intelligent, yeux rouges), suppression du bruit | moins de 1 s | Oui | | OCR, transcription, sous-titres | 1-3 s | Oui | | Coloriser, amélioration des visages | ~10 s | Oui | | Suppression / remplacement / floutage d'arrière-plan | ~29 s | Oui (il faudra patienter) | | Agrandissement IA (RealESRGAN) | ~33 s sur petit format ; plusieurs minutes sur les grandes images | Limite - GPU fortement recommandé | | Restauration de photo (pipeline complet) | plusieurs minutes | Non - nécessite un GPU ou un CPU rapide à nombreux cœurs | SnapOtter n'intègre volontairement pas ces téléchargements de modèles dans l'image Docker. Les bundles IA ne sont récupérés que lorsqu'un administrateur active l'outil concerné, stockés dans le volume persistant `/data/ai` et partagés par chaque outil qui dépend de la même pile de modèles. Cela maintient l'image finale du conteneur petite tout en permettant à une installation IA complète d'atteindre les chiffres de stockage plus élevés ci-dessous. Certains outils dépendent de plus d'un bundle partagé. Par exemple, Photo d'identité a besoin à la fois de `background-removal` et de `face-detection` ; si `background-removal` est déjà installé, activer Photo d'identité ne télécharge que le bundle `face-detection` manquant. La même réutilisation s'applique à tous les outils IA. Estimations de stockage du pack AI en option : | Bundle | Taille disque | |---|---| | Suppression d'arrière-plan | 4-5 Go | | Agrandissement + Amélioration des visages + Suppression du bruit | 5-6 Go | | Détection de visages | 200-300 Mo | | Gomme d'objets + Coloriser | 1-2 Go | | OCR précis (`balanced`/`best`) | ~208-234 MiB téléchargé / ~409-488 MiB installé | | Restauration de photo | 4-5 Go | | Transcription | ~600 Mo | | **Tous les forfaits** | **~20 Go installés** | Fast OCR est intégré à l'image via Tesseract, ajoute environ 25 MiB et ne nécessite pas le pack OCR en option ni ses 4 exigences de mémoire GiB. Le pack précis est disponible dans les conteneurs officiels Linux amd64 et arm64 et exécute ONNX Runtime sur CPU. Les hôtes NVIDIA utilisent le même environnement d'exécution CPU OCR, donc OCR ne dépend pas de la version CUDA ou de l'architecture GPU. Le temps d'exécution précis nécessite au moins 4 GiB de mémoire effective : la limite cgroup du conteneur configuré, sinon la mémoire hôte. SnapOtter rejette les systèmes inférieurs au minimum de compatibilité signé avant de télécharger le pack. L'installation d'un pack précis est également rejetée sur les archives bare-metal/préconstruites dont les libc et Python ABI ne peuvent pas être garanties. Les répliques qui partagent le même `DATA_DIR` doivent utiliser la même architecture de processeur ; épinglez les déploiements à plusieurs répliques à des nœuds compatibles au moyen de l'affinité de nœuds. Les répliques amd64/arm64 mixtes nécessitent des volumes de données distincts et des déploiements SnapOtter indépendants. Le runtime précis conserve une génération active et purge son cache de téléchargement après l'activation. Pour cette version, une première installation nécessite temporairement environ 620-720 MiB pour l'archive plus le staging, et une mise à niveau peut culminer près de 1,2 GiB tandis que l'ancienne génération reste active. Le programme d'installation calcule les exigences exactes à partir de l'index signé et des générations actuelles avant le téléchargement ou l'extraction, et échoue prématurément si le volume de données est trop petit. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Complet (outils IA sur NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | Ressource | Exigence | |---|---| | CPU | 6-8 cœurs (la préparation vidéo + la concurrence s'exécutent sur CPU même avec l'IA sur GPU) | | RAM | 8 Go | | GPU | NVIDIA avec 8+ Go de VRAM (12 Go recommandé) | | Disque | ~35 Go au total | Un GPU NVIDIA (CUDA) accélère considérablement les modèles IA lourds. Mesuré sur une RTX 4070 par rapport à un CPU moderne : | Outil IA | Accélération avec GPU | Notes | |---|---|---| | Agrandissement IA (RealESRGAN 2×) | **~47×** | Le plus gros gain - moins d'une seconde contre ~33 s (plusieurs minutes sur les grandes images) | | Amélioration des visages (CodeFormer) | **~12×** | ~0,9 s contre ~11 s | | Transcription (Whisper) | ~4,5× | | | Suppression / remplacement / floutage d'arrière-plan | ~4× | ~7 s sur GPU contre ~29 s sur CPU | | Coloriser | ~1,8× | | | OCR, détection de visages, yeux rouges, suppression du bruit | ~1× | Déjà rapide sur CPU - un GPU n'apporte rien | | Restauration de photo | aucune | Limité par le CPU même sur un GPU (0 % d'utilisation du GPU) ; un CPU rapide compte plus qu'un GPU ici | Les outils qui valent un GPU sont **l'agrandissement, l'amélioration des visages, la transcription et la suppression d'arrière-plan**. La détection de visages, l'OCR et les yeux rouges sont limités par le CPU et déjà rapides, un GPU n'apporte donc rien. L'utilisation de VRAM en pic atteint 7,5 Go pendant un agrandissement avec amélioration des visages. Un GPU NVIDIA de 6 Go convient pour la plupart des outils IA pris individuellement, mais échouera sur l'agrandissement. 8-12 Go de VRAM gèrent tout. L'accélération par iGPU Intel/AMD via VA-API, Quick Sync ou OpenCL n'est pas prise en charge pour l'inférence IA aujourd'hui. Mapper `/dev/dri` dans le conteneur n'active pas l'accélération GPU de l'IA ; SnapOtter exécutera les outils IA sur CPU sauf si NVIDIA CUDA est disponible. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Utilisateurs simultanés {#concurrent-users} Requêtes de redimensionnement d'image parallèles sur le conteneur applicatif plafonné à 4 cœurs par défaut : | Requêtes simultanées | Temps de réponse moyen | Erreurs | |---|---|---| | 1 | 0,4 s | 0 | | 5 | 1,2 s | 0 | | 10 | 2,1 s | 0 | Le temps de réponse se dégrade de manière sous-linéaire sans erreur à mesure que le pool de workers sature. Augmenter la limite `cpus:` du conteneur applicatif (ou utiliser un hôte avec plus de cœurs) relève le plafond. Notez que les tâches lourdes (transcodage vidéo, IA sur CPU) mobilisent un worker pendant toute leur durée, dimensionnez donc le CPU selon votre nombre attendu de tâches lourdes simultanées, et pas seulement selon le nombre de requêtes. ### Formats d'image pris en charge {#supported-image-formats} SnapOtter prend en charge **55+ formats d'entrée** et **14 formats de sortie**, dont les fichiers RAW de 20+ marques d'appareils photo, les formats professionnels (PSD, EPS, OpenEXR, HDR), les codecs modernes (JPEG XL, AVIF, HEIC, QOI) et les formats scientifiques/de jeu (FITS, DDS). Consultez la [liste complète des formats](/fr/guide/supported-formats) pour les détails sur chaque format pris en charge, le décodeur utilisé et les contrôles de qualité disponibles. ### Limitations connues {#known-limitations} * **Le redimensionnement sensible au contenu** plante sur les grandes images (>5 MP) en raison d'une limitation du binaire caire. Fonctionne bien avec des images plus petites. * **Le décodage HEIF** prend 13-23 secondes. HEIC (la variante d'Apple) est bien plus rapide, à 0,3-0,9 seconde. * **L'agrandissement** expire sur CPU pour tout ce qui dépasse les petites images. GPU requis pour un usage pratique. * **L'amélioration des visages CodeFormer** est nettement plus lente que GFPGAN (53 s contre 2 s sur GPU). GFPGAN est recommandé pour la plupart des cas d'usage. ## Volumes {#volumes} | Montage / Volume | Rôle | Requis ? | |---|---|---| | `/data` (app) | Modèles IA, venv Python, fichiers utilisateur | **Oui** - perte de fichiers sans lui | | `/tmp/workspace` (app) | Fichiers de traitement temporaires (nettoyés automatiquement) | Recommandé | | `SnapOtter-pgdata` (postgres) | Répertoire de données PostgreSQL (utilisateurs, paramètres, pipelines, tâches) | **Oui** - perte de données sans lui | | `SnapOtter-redisdata` (redis) | Fichier append-only Redis pour des files de tâches durables | Recommandé | ### Montages liés (bind mounts) vs volumes nommés {#bind-mounts-vs-named-volumes} **Volumes nommés** (recommandés) - Docker gère les permissions automatiquement : ```yaml volumes: - SnapOtter-data:/data ``` **Montages liés** - Vous gérez les permissions. Réglez `PUID`/`PGID` pour correspondre à votre utilisateur hôte : ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Permissions de stockage {#storage-permissions} SnapOtter écrit à deux emplacements à l'exécution : `/data` (fichiers utilisateur, journaux, modèles IA et le venv Python) et `/tmp/workspace` (espace de travail temporaire de traitement). Les deux doivent être accessibles en écriture par l'utilisateur sous lequel le conteneur s'exécute. Si l'un ne l'est pas, le conteneur **échoue rapidement au démarrage** avec un message nommant le répertoire, l'UID/GID en cours d'exécution et comment corriger, au lieu de démarrer « en bonne santé » puis d'échouer au premier téléversement avec une erreur cryptique. La façon dont les permissions sont gérées dépend de la manière dont le conteneur est lancé : **Par défaut (démarre en root, redescend vers `snapotter`)** - le point d'entrée démarre en root, corrige la propriété des volumes montés, puis redescend vers l'utilisateur non privilégié `snapotter` via `gosu`. Les volumes nommés fonctionnent sans aucune configuration. Pour les montages liés, réglez `PUID`/`PGID` sur votre utilisateur hôte (ci-dessus) afin que les fichiers qu'il écrit vous appartiennent. **Kubernetes / OpenShift (non-root via `runAsUser`)** - lancé directement en tant qu'utilisateur non-root, le conteneur ne peut pas chown les volumes lui-même, l'orchestrateur doit donc les rendre accessibles en écriture. Réglez `fsGroup` : ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` Les répertoires accessibles en écriture de l'image appartiennent au groupe GID 0 et sont accessibles en écriture par le groupe, de sorte qu'un pod s'exécutant avec un **UID arbitraire** plus le groupe supplémentaire root (le défaut OpenShift) peut écrire sans `chown`. **TrueNAS Scale (et autres configurations à « UID étranger »)** - TrueNAS exécute les applications sous un utilisateur non-root (souvent `568:568`) et monte des jeux de données hôtes appartenant à un autre utilisateur, de sorte que ni le point d'entrée ni `fsGroup` ne les rendent accessibles en écriture par lui-même. Choisissez l'une des options : * **Exécuter l'application en root** (recommandé) - laissez l'utilisateur de l'application non défini ou réglez-le sur `0`, et laissez le point d'entrée par défaut corriger les permissions et redescendre vers `snapotter`. * **Exécuter en tant qu'UID `999`** - réglez l'utilisateur/groupe de l'application sur `999:999` (l'utilisateur intégré `snapotter` de SnapOtter) pour qu'il corresponde à la propriété de l'image. * **`chown` le jeu de données hôte** vers l'UID sous lequel le conteneur s'exécute, depuis le shell TrueNAS : ```bash # Utilisez l'UID de l'erreur de démarrage (ou exécutez `id` dans le conteneur) chown -R 568:568 /mnt// ``` L'erreur de démarrage nomme l'UID exact à utiliser, le chemin le plus rapide est donc de démarrer l'application une fois, de lire le message, puis d'exécuter `chown` (ou d'ajuster l'utilisateur) en conséquence. ## Variables d'environnement {#environment-variables} | Variable | Défaut | Description | |---|---|---| | `AUTH_ENABLED` | `true` | Activer/désactiver l'exigence de connexion | | `DEFAULT_USERNAME` | `admin` | Nom d'utilisateur admin initial | | `DEFAULT_PASSWORD` | `admin` | Mot de passe admin initial (changement forcé à la première connexion) | | `MAX_UPLOAD_SIZE_MB` | `0` (illimité) | Limite de téléversement par fichier en Mo. L'image est livrée avec `0` ; une compilation depuis les sources démarre à 100 | | `MAX_BATCH_SIZE` | `0` (illimité) | Nombre max de fichiers par requête de lot. L'image est livrée avec `0` ; une compilation depuis les sources démarre à 100 | | `RATE_LIMIT_PER_MIN` | `1000` | Requêtes API par minute et par IP (mettez 0 pour désactiver) | | `MAX_USERS` | `0` (illimité) | Nombre maximal de comptes utilisateur | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Quels pairs peuvent définir l'IP du client via `X-Forwarded-For`. Réseaux privés uniquement par défaut | | `PUID` | `999` | Exécuter sous cet UID (pour les permissions de montage lié) | | `PGID` | `999` | Exécuter sous ce GID (pour les permissions de montage lié) | | `LOG_LEVEL` | `info` | Verbosité des journaux : fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (auto) | Nombre max de tâches de traitement IA en parallèle | | `SESSION_DURATION_HOURS` | `168` | Durée de vie de la session de connexion (7 jours) | | `CORS_ORIGIN` | (vide) | Origines autorisées séparées par des virgules, ou vide pour même origine | ### Proxy sortant et CA privée {#outbound-proxy-and-private-ca} Le conteneur officiel permet la prise en charge du proxy d'environnement de Node. Si SnapOtter doit atteindre le référentiel d'exécution OCR ou d'autres services HTTPS via un proxy d'entreprise, définissez `HTTPS_PROXY` (et `HTTP_PROXY` si nécessaire). Définissez `NO_PROXY` sur une liste d'hôtes séparés par des virgules qui doivent être atteints directement, tels que Postgres, Redis et le stockage d'objets interne. Si le proxy ou un service interne est signé par une autorité de certification privée, montez le certificat CA en lecture seule et pointez `NODE_EXTRA_CA_CERTS` vers celui-ci. Le fichier doit exister au démarrage du processus Node : ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Conservez les informations d'identification du proxy en dehors du fichier Compose (par exemple dans un fichier `.env` protégé ou secret). Ne désactivez pas la vérification TLS : l'index OCR signé authentifie les métadonnées de version, tandis que la validation TLS normale protège toujours le transport et toutes les autres requêtes sortantes. ## Vérification d'état (health check) {#health-check} Le conteneur inclut une vérification d'état intégrée : ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Reverse proxy {#reverse-proxy} `TRUST_PROXY` vaut `loopback,linklocal,uniquelocal` par défaut : SnapOtter ne croit donc l'en-tête `X-Forwarded-For` que s'il vient d'un pair situé sur un réseau privé. Un reverse proxy sur le même hôte, sur un réseau Docker ou sur votre LAN est digne de confiance d'emblée, ce qui fait que la limitation de débit, le limiteur de force brute à la connexion, le journal d'audit et la liste d'IP autorisées de l'édition enterprise voient tous l'IP client réelle sans aucune configuration. Ne mettez `TRUST_PROXY=true` que lorsque le proxy placé devant atteint SnapOtter depuis une adresse **publique**, un répartiteur de charge cloud sur un autre réseau par exemple. Sur une instance directement exposée, cette valeur rend `request.ip` contrôlable par un attaquant, car un appelant qui fait tourner l'en-tête obtient un nouveau compteur de limitation de débit à chaque requête. Deux choses à savoir avant de vous lancer dans la mesure des IP clientes. Docker Desktop sur macOS et Windows sert un port publié via un proxy en espace utilisateur qui réécrit toutes les adresses source vers la passerelle de la VM `192.168.65.1` ; aucune valeur de `TRUST_PROXY` n'y récupère le client réel, déployez donc sous Linux tout ce qui est exposé à internet. Et sur n'importe quelle plateforme, atteindre un port publié via `localhost` est observé comme la passerelle du pont plutôt que comme votre client : un test en localhost ne vous apprend donc rien sur la façon dont un vrai client est attribué. Le tableau complet des valeurs de `TRUST_PROXY` et la mise en garde sur Docker Desktop se trouvent dans [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy). Deux choses comptent pour chaque proxy ci-dessous : autoriser les corps de requêtes volumineux (téléchargements) et ne pas mettre les réponses en mémoire tampon. Un proxy tamponnant les réponses interrompt la progression de SSE et, plus visiblement, fait "démarrer mais ne jamais terminer" le téléchargement d'un fichier volumineux, car le proxy conserve l'intégralité du fichier avant de le transmettre. SnapOtter envoie `X-Accel-Buffering: no` lors des téléchargements afin que nginx les diffuse même si la mise en mémoire tampon est laissée ailleurs, mais les proxys autres que nginx doivent désactiver explicitement la mise en mémoire tampon des réponses (indiquée dans chaque configuration ci-dessous). Si un téléchargement s'arrête en cours de route, un proxy de mise en mémoire tampon devant est la première chose à vérifier. ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Diffusez les réponses au lieu de la mise en mémoire tampon : nécessaire pour la progression de SSE (par lots, IA, installations de fonctionnalités) et pour les téléchargements de fichiers volumineux. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Ajoutez un nouveau Proxy Host 2. Réglez Domain Name sur votre domaine 3. Réglez Scheme sur `http`, Forward Hostname sur `SnapOtter` (ou l'IP de votre conteneur), Forward Port sur `1349` 4. Activez la prise en charge WebSocket 5. Sous Advanced, ajoutez : `client_max_body_size 500M;` et `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` désactive la mise en mémoire tampon des réponses, qui est requise pour les événements de progression SSE (traitement par lots, outils d'IA, installations de fonctionnalités) et pour que les téléchargements de fichiers volumineux soient diffusés au lieu de se bloquer. Les délais d'attente prolongés permettent de télécharger des fichiers volumineux sans que Caddy ne ferme la connexion prématurément. ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Remarque : Cloudflare impose une limite de téléversement de 100 Mo sur les offres gratuites. Réglez `MAX_UPLOAD_SIZE_MB=100` en conséquence. ## CI/CD {#ci-cd} Le dépôt GitHub comporte trois workflows : * **ci.yml** - S'exécute automatiquement à chaque push et PR. Effectue le lint, la vérification de types, les tests, la construction et la validation de l'image Docker (sans push). * **release.yml** - Déclenché manuellement via `workflow_dispatch`. Exécute semantic-release pour créer un tag de version et une release GitHub, puis construit une image Docker multi-architecture (amd64 + arm64) et la pousse vers Docker Hub (`snapotter/snapotter`) et GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`). * **deploy-docs.yml** - Construit ce site de documentation et le déploie sur Cloudflare Pages lors d'un push vers `main`. Pour créer une release, allez dans **Actions > Release > Run workflow** dans l'interface GitHub, ou exécutez : ```bash gh workflow run release.yml ``` Semantic-release détermine la version à partir de l'historique des commits. Le tag Docker `latest` pointe toujours vers la release la plus récente. ## Analytique {#analytics} SnapOtter inclut une analytique produit anonyme (schémas d'utilisation des outils, rapports d'erreurs) pour aider à détecter les bugs et améliorer les fonctionnalités. Elle est activée par défaut. Vos fichiers, leurs noms et vos données personnelles n'en font jamais partie. SnapOtter fonctionne normalement avec l'analytique désactivée. ### Désactiver l'analytique {#disabling-analytics} Le retrait à l'exécution est un basculement admin en un clic. Ouvrez Settings > System > Privacy et désactivez Anonymous Product Analytics. Cela s'arrête immédiatement pour toute l'instance, sans reconstruction requise. Pour une image qui ne peut jamais émettre d'analytique, définissez l'arrêt matériel au moment de la construction en clonant le dépôt et en le reconstruisant : ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` Ou ajoutez l'argument de construction à votre `docker-compose.yml` existant : ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/de/guide/deployment.md description: >- SnapOtter mit Docker in die Produktion bringen. Hardware-Anforderungen, GPU-Einrichtung und Reverse-Proxy-Konfigurationen für Nginx, Traefik und Cloudflare. --- # Deployment {#deployment} SnapOtter wird als Docker-Compose-Stack aus 3 Containern bereitgestellt: dem SnapOtter-App-Image, PostgreSQL 17 und Redis 8. Das App-Image unterstützt **linux/amd64** (mit NVIDIA CUDA für KI-Beschleunigung) und **linux/arm64** (CPU), sodass es nativ auf Intel/AMD-Servern, Apple-Silicon-Macs und ARM-Geräten wie dem Raspberry Pi 4/5 läuft. Intel/AMD-iGPU-Beschleunigung über VA-API, Quick Sync oder OpenCL wird für KI-Inferenz derzeit nicht unterstützt. Siehe [Docker-Image](./docker-tags) für GPU-Einrichtung, Docker-Compose-Beispiele und Versionsfixierung. ::: info Kompatibilität für koreanische OCR Fast OCR unterstützt `auto`, `en`, `de`, `es`, `fr`, `zh` und `ja`, aber kein Koreanisch (`ko`). Koreanisch benötigt das genaue OCR-Paket und `balanced` oder `best`. Das Paket läuft in offiziellen Linux-amd64- und arm64-Containern, auch auf NVIDIA-Hosts weiterhin auf der CPU. Nicht unterstützte Systeme erhalten einen eindeutigen Kompatibilitätsfehler und keinen stillen Rückfall auf `fast`. Koreanisch mit `fast` oder dem alten Alias `tesseract` wird vor dem Einreihen mit `FEATURE_INCOMPATIBLE` und `fast-korean-unsupported` abgelehnt. ::: ## Schnellstart (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` Die App ist dann unter `http://localhost:1349` erreichbar. > **Docker-Hub-Ratenbegrenzungen?** Ersetze `snapotter/snapotter:latest` durch `ghcr.io/snapotter-hq/snapotter:latest`, um stattdessen aus der GitHub Container Registry zu ziehen. Beide Registries erhalten bei jedem Release dasselbe Image. ## Schnellstart (NVIDIA CUDA) {#quick-start-nvidia-cuda} Für NVIDIA CUDA Beschleunigung auf unterstützten KI-Tools (Hintergrundentfernung, Hochskalierung, Gesichtsverbesserung): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Ändern Sie dies für nicht lokale Bereitstellungen POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### Überprüfen Sie die GPU-Beschleunigung {#verify-gpu-acceleration} Überprüfen Sie die CUDA-Erkennung in den Protokollen: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` Wenn KI-Tools auf der CPU ausgeführt werden, obwohl `--gpus all` und das NVIDIA Container Toolkit korrekt eingerichtet sind, installieren Sie das betroffene Bundle (z. B. Hintergrundentfernung) über **Einstellungen → KI-Funktionen** neu. Das Installationsprogramm stellt den GPU-Build von ONNX Runtime wieder her, den ein reiner CPU-Build, der von einem anderen Bundle (z. B. Transkription) abgerufen wird, andernfalls in der gemeinsam genutzten KI-Umgebung abbilden kann. Wenn die Neuinstallation über die Benutzeroberfläche die GPU auf einem älteren Image nicht wiederherstellt, lesen Sie die manuelle Reparatur in [Problem Nr. 490](https://github.com/snapotter-hq/SnapOtter/issues/490). ## Hardware-Anforderungen {#hardware-requirements} Diese Werte stammen aus Benchmarks über eine Reihe von Systemen hinweg, von einer modernen amd64-Workstation mit einer NVIDIA RTX 4070 bis hinunter zu einem Raspberry Pi. Auf jedem wurde der gesamte Tool-Katalog ausgeführt und die Docker-Ressourcenlimits durchlaufen, um die tatsächliche Untergrenze zu ermitteln. Du betreibst SnapOtter am unteren Ende dieser Stufen (ein Pi, ein alter Laptop, ein 2-GB-VPS)? [Ressourcenarme Setups](/de/guide/low-resource) macht aus diesen Zahlen eine konkrete Schritt-für-Schritt-Anleitung mit abgestimmten Limits. ### Kurzübersicht {#quick-reference} | Stufe | Anwendungsfall | CPU | RAM | GPU | Speicher | |------|----------|-----|-----|-----|---------| | Minimum | Bild-, Datei- und leichte PDF-Tools; ein Benutzer; kleine Stapel | 2 Kerne | 2 GB | Keine | ~7 GB | | Empfohlen | Alle fünf Modalitäten inkl. Video, PDF und KI auf CPU; Stapel; einige Benutzer | 4 Kerne | 4 GB | Keine | ~25 GB | | Voll | Alles in voller Geschwindigkeit inkl. GPU-KI; große Stapel; viele Benutzer | 6-8 Kerne | 8 GB | NVIDIA 8 GB+ VRAM (12 GB komfortabel) | ~35 GB | **Architektur: nur 64-Bit** (`linux/amd64` oder `linux/arm64`). SnapOtter läuft nativ auf Intel/AMD-Servern, Apple-Silicon-Macs und 64-Bit-ARM-Boards einschließlich des **Raspberry Pi 4 und 5** (4-8 GB). Es läuft **nicht** auf 32-Bit-ARM (`armv7`/`armhf`) - dafür wird kein Image gebaut - und auch nicht auf Boards der 512-MB-Klasse wie dem Pi Zero, die unter der Speicheruntergrenze liegen (siehe unten). ### Minimum (Bild-, Datei- und leichte PDF-Tools; keine KI) {#minimum-image-files-and-light-pdf-tools-no-ai} | Ressource | Anforderung | |---|---| | CPU | 2 Kerne | | RAM | 2 GB | | Festplatte | ~5,5 GB (Image) + Datenvolume | | GPU | Nicht erforderlich | Alle 222 Nicht-KI-Katalog-Tools - Bild (Größe ändern, zuschneiden, konvertieren, komprimieren, anpassen, Wasserzeichen), Video (trimmen, stummschalten, remuxen), Audio (konvertieren, normalisieren, trimmen), PDF (zusammenführen, teilen, komprimieren, drehen, schützen), Dateikonvertierungen und dedizierte Konvertierungsvorlagen - laufen auf bescheidener Hardware. Die meisten Vorgänge sind selbst bei einer großen Datei in deutlich unter einer Sekunde abgeschlossen: Ein 2,7 MB großes Bild wird in ~0,05 s in der Größe geändert und in ~2 s zu WebP neu kodiert. Die Speicheruntergrenze ist real, aus einem Durchlauf der Docker-Ressourcenlimits: **512 MB können den Stack nicht starten** (selbst eine einzelne Bildgrößenänderung wird abgebrochen), **1 GB** bewältigt Einzeldatei-Vorgänge, aber einem Mehrdatei-Stapel geht der Speicher aus, und **2 GB / 2 Kerne** ist die kleinste Konfiguration, die Stapel komfortabel bewältigt. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **Die eine CPU-intensive Ausnahme ist die Video-Neukodierung.** Stream-Copy-Vorgänge (trimmen, stummschalten, Container-Remux) sind sofort erledigt, aber das Transkodieren in einen anderen Codec ist CPU-gebunden. Ein 1080p-Clip von 45 Sekunden, der zu VP9 (WebM) neu kodiert wird, benötigt auf einer schnellen modernen CPU etwa **~40 s**, ~45 s auf Apple Silicon, ~80 s auf einer älteren mobilen 4-Kern-CPU und **~130 s** auf einem älteren 4-Kern-Server. Wenn deine Arbeitslast videolastig ist, priorisiere CPU-Kerne und Taktrate oder erhöhe das `cpus:`-Limit des Containers - das mitgelieferte Compose begrenzt die App standardmäßig auf 4 Kerne (8 beim GPU-Compose). ### Empfohlen (KI-Tools auf CPU) {#recommended-ai-tools-on-cpu} | Ressource | Anforderung | |---|---| | CPU | 4 Kerne | | RAM | 4 GB | | Disk | 3 GB (Bild) + ca. 20 GB (alle optionalen AI-Pakete) + Arbeitsbereich | | GPU | Nicht erforderlich (CPU-Fallback) | **Durch die Installation und Ausführung der größeren AI-Bundles erhöht sich die Empfehlung auf 4 GB RAM.** Wenn keine optionalen Pakete installiert sind, verbraucht die App etwa 360 MB im Leerlauf. Ältere Python-Tools teilen sich ein sidecar, während genaues OCR ein dediziertes, langlebiges dispatcher verwendet, das an die aktive unveränderliche Generation angeheftet ist. Vor der Aktivierung führt das Installationsprogramm einen smoke test für den Kandidaten aus. Anschließend wechselt es atomar zum neuen dispatcher und leert das vorherige dispatcher vor garbage collection. Jedes offizielle akkurate OCR-Artefakt muss seinen schlimmsten Fall release suite innerhalb eines 4 GiB cgroup bestehen, während die 4-GB-Hostempfehlung Spielraum für die Node.js-Anwendung, Postgres, Redis, Warteschlangen und gleichzeitige Arbeit lässt. Die meisten KI-Tools sind auf der CPU einwandfrei nutzbar; einige wenige wollen wirklich eine GPU. Gemessen auf einer modernen 4-Kern-CPU: | KI-Tool | CPU-Zeit | Auf CPU nutzbar? | |---|---|---| | Gesichtserkennung (Gesichter unkenntlich machen, intelligenter Zuschnitt, Rote-Augen), Rauschentfernung | unter 1 s | Ja | | OCR, Transkription, Untertitel | 1-3 s | Ja | | Kolorieren, Gesichtsverbesserung | ~10 s | Ja | | Hintergrundentfernung / -ersetzung / -unschärfe | ~29 s | Ja (du wirst warten) | | KI-Hochskalierung (RealESRGAN) | ~33 s klein; Minuten bei großen Bildern | Grenzwertig - GPU dringend empfohlen | | Fotorestaurierung (vollständige Pipeline) | mehrere Minuten | Nein - benötigt eine GPU oder eine schnelle Many-Core-CPU | SnapOtter backt diese Modell-Downloads bewusst nicht in das Docker-Image ein. KI-Bundles werden nur heruntergeladen, wenn ein Administrator das zugehörige Tool aktiviert, im persistenten `/data/ai`-Volume gespeichert und von jedem Tool geteilt, das vom selben Modell-Stack abhängt. Das hält das finale Container-Image klein und lässt eine vollständige KI-Installation dennoch die größeren Speicherwerte unten erreichen. Manche Tools hängen von mehr als einem geteilten Bundle ab. Passfoto benötigt beispielsweise sowohl `background-removal` als auch `face-detection`; wenn `background-removal` bereits installiert ist, lädt das Aktivieren von Passfoto nur das fehlende `face-detection`-Bundle herunter. Dieselbe Wiederverwendung gilt für alle KI-Tools. Schätzungen zur Lagerung optionaler KI-Pakete: | Bundle | Festplattengröße | |---|---| | Hintergrundentfernung | 4-5 GB | | Hochskalierung + Gesichtsverbesserung + Rauschentfernung | 5-6 GB | | Gesichtserkennung | 200-300 MB | | Objekt-Radierer + Kolorieren | 1-2 GB | | Präzise OCR (`balanced`/`best`) | ~208-234 MiB herunterladen / ~409-488 MiB installiert | | Fotorestaurierung | 4-5 GB | | Transkription | ~600 MB | | **Alle Pakete** | **~20 GB installiert** | Das schnelle OCR wird über Tesseract in das Image integriert, fügt etwa 25 MiB hinzu und erfordert weder das optionale OCR-Paket noch dessen Speicherbedarf von 4 GiB. Das genaue Paket ist in den offiziellen Linux amd64- und arm64-Containern verfügbar und führt ONNX Runtime auf CPU aus. NVIDIA-Hosts verwenden dieselbe CPU OCR-Laufzeit, sodass OCR nicht von der CUDA-Version oder der GPU-Architektur abhängt. Die genaue Laufzeit erfordert mindestens 4 GiB effektiven Speicher: das konfigurierte Container-cgroup-Limit, andernfalls Host-Speicher. SnapOtter lehnt Systeme unterhalb dieses signierten Kompatibilitätsminimums ab, bevor das Paket heruntergeladen wird. Die Installation von Accurate-Packs wird auch für bare-metal/vorgefertigte Archive abgelehnt, deren libc und Python ABI nicht garantiert werden kann. Replikate, die dasselbe `DATA_DIR` verwenden, müssen dieselbe CPU-Architektur nutzen; fixieren Sie Bereitstellungen mit mehreren Replikaten per Node-Affinität auf kompatible Knoten. Gemischte amd64-/arm64-Replikate benötigen separate Daten-Volumes und unabhängige SnapOtter-Bereitstellungen. Die genaue Laufzeit behält eine aktive Generation bei und löscht den Download-Cache nach der Aktivierung. Für diese Veröffentlichung Eine Erstinstallation benötigt vorübergehend etwa 620–720 MiB für das Archiv plus Staging. und ein Upgrade kann in der Nähe von 1,2 GiB seinen Höhepunkt erreichen, während die alte Generation aktiv bleibt. Das Installationsprogramm berechnet den genauen Bedarf aus dem signierten Index und den aktuellen Generationen vor dem Herunterladen oder Extrahieren und schlägt vorzeitig fehl, wenn das Datenvolumen zu klein ist. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Voll (KI-Tools auf NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | Ressource | Anforderung | |---|---| | CPU | 6-8 Kerne (Video-Vorbereitung + Nebenläufigkeit laufen auch bei GPU-KI auf der CPU) | | RAM | 8 GB | | GPU | NVIDIA mit 8+ GB VRAM (12 GB empfohlen) | | Festplatte | ~35 GB gesamt | Eine NVIDIA-GPU (CUDA) beschleunigt die schweren KI-Modelle dramatisch. Gemessen auf einer RTX 4070 gegenüber einer modernen CPU: | KI-Tool | Beschleunigung mit GPU | Hinweise | |---|---|---| | KI-Hochskalierung (RealESRGAN 2×) | **~47×** | Der größte Gewinn - unter einer Sekunde statt ~33 s (Minuten bei großen Bildern) | | Gesichtsverbesserung (CodeFormer) | **~12×** | ~0,9 s statt ~11 s | | Transkription (Whisper) | ~4,5× | | | Hintergrundentfernung / -ersetzung / -unschärfe | ~4× | ~7 s auf GPU statt ~29 s auf CPU | | Kolorieren | ~1,8× | | | OCR, Gesichtserkennung, Rote-Augen, Rauschentfernung | ~1× | Bereits schnell auf der CPU - eine GPU hilft nicht | | Fotorestaurierung | keine | CPU-gebunden selbst auf einer GPU (0 % GPU-Auslastung); eine schnelle CPU zählt hier mehr als eine GPU | Die Tools, für die sich eine GPU lohnt, sind **Hochskalierung, Gesichtsverbesserung, Transkription und Hintergrundentfernung**. Gesichtserkennung, OCR und Rote-Augen sind CPU-gebunden und bereits schnell, sodass eine GPU nichts bringt. Die VRAM-Spitzennutzung erreicht 7,5 GB während der Hochskalierung mit Gesichtsverbesserung. Eine 6-GB-NVIDIA-GPU funktioniert für die meisten KI-Tools einzeln, scheitert aber bei der Hochskalierung. 8-12 GB VRAM bewältigen alles. Intel/AMD-iGPU-Beschleunigung über VA-API, Quick Sync oder OpenCL wird für KI-Inferenz derzeit nicht unterstützt. Das Einbinden von `/dev/dri` in den Container aktiviert keine KI-GPU-Beschleunigung; SnapOtter führt KI-Tools auf der CPU aus, sofern nicht NVIDIA CUDA verfügbar ist. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Gleichzeitige Benutzer {#concurrent-users} Parallele Bildgrößenänderungs-Anfragen gegen den standardmäßig auf 4 Kerne begrenzten App-Container: | Gleichzeitige Anfragen | Durchschn. Antwortzeit | Fehler | |---|---|---| | 1 | 0,4 s | 0 | | 5 | 1,2 s | 0 | | 10 | 2,1 s | 0 | Die Antwortzeit verschlechtert sich sublinear ohne Fehler, während der Worker-Pool gesättigt wird. Das Anheben des `cpus:`-Limits des App-Containers (oder die Verwendung eines Hosts mit mehr Kernen) hebt die Obergrenze an. Beachte, dass schwere Jobs (Video-Transkodierung, CPU-KI) einen Worker für ihre gesamte Dauer belegen, also dimensioniere die CPU nach deiner erwarteten Anzahl gleichzeitiger schwerer Jobs, nicht nur nach der Anfragezahl. ### Unterstützte Bildformate {#supported-image-formats} SnapOtter unterstützt **55+ Eingabeformate** und **14 Ausgabeformate**, einschließlich RAW-Dateien von 20+ Kameramarken, professionellen Formaten (PSD, EPS, OpenEXR, HDR), modernen Codecs (JPEG XL, AVIF, HEIC, QOI) sowie wissenschaftlichen und Gaming-Formaten (FITS, DDS). Siehe die [vollständige Formatliste](/de/guide/supported-formats) für Details zu jedem unterstützten Format, dem verwendeten Decoder und den verfügbaren Qualitätsreglern. ### Bekannte Einschränkungen {#known-limitations} * **Inhaltsbewusste Größenänderung** stürzt bei großen Bildern (>5 MP) aufgrund einer Einschränkung im caire-Binary ab. Funktioniert bei kleineren Bildern einwandfrei. * **HEIF-Dekodierung** dauert 13-23 Sekunden. HEIC (Apples Variante) ist mit 0,3-0,9 Sekunden deutlich schneller. * **Hochskalierung** läuft auf der CPU bei allem jenseits kleiner Bilder in eine Zeitüberschreitung. GPU für den praktischen Einsatz erforderlich. * **CodeFormer**-Gesichtsverbesserung ist deutlich langsamer als GFPGAN (53 s statt 2 s auf GPU). GFPGAN wird für die meisten Anwendungsfälle empfohlen. ## Volumes {#volumes} | Mount / Volume | Zweck | Erforderlich? | |---|---|---| | `/data` (App) | KI-Modelle, Python-venv, Benutzerdateien | **Ja** - Dateiverlust ohne es | | `/tmp/workspace` (App) | Temporäre Verarbeitungsdateien (automatisch bereinigt) | Empfohlen | | `SnapOtter-pgdata` (Postgres) | PostgreSQL-Datenverzeichnis (Benutzer, Einstellungen, Pipelines, Jobs) | **Ja** - Datenverlust ohne es | | `SnapOtter-redisdata` (Redis) | Redis-Append-Only-Datei für dauerhafte Job-Warteschlangen | Empfohlen | ### Bind-Mounts vs. benannte Volumes {#bind-mounts-vs-named-volumes} **Benannte Volumes** (empfohlen) - Docker verwaltet die Berechtigungen automatisch: ```yaml volumes: - SnapOtter-data:/data ``` **Bind-Mounts** - Du verwaltest die Berechtigungen. Setze `PUID`/`PGID` passend zu deinem Host-Benutzer: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Speicherberechtigungen {#storage-permissions} SnapOtter schreibt zur Laufzeit an zwei Orte: `/data` (Benutzerdateien, Logs, KI-Modelle und das Python-venv) und `/tmp/workspace` (temporärer Verarbeitungs-Scratch). Beide müssen für den Benutzer, unter dem der Container läuft, beschreibbar sein. Ist eines von beiden es nicht, **scheitert der Container beim Start sofort** mit einer Meldung, die das Verzeichnis, die laufende UID/GID und die Behebung nennt - statt "gesund" hochzufahren und dann beim ersten Upload mit einem kryptischen Fehler zu scheitern. Wie Berechtigungen gehandhabt werden, hängt davon ab, wie der Container gestartet wird: **Standard (startet als root, fällt auf `snapotter` zurück)** - der Entrypoint startet als root, korrigiert die Eigentümerschaft der eingebundenen Volumes und fällt dann über `gosu` auf den unprivilegierten `snapotter`-Benutzer zurück. Benannte Volumes funktionieren ohne Konfiguration. Setze für Bind-Mounts `PUID`/`PGID` auf deinen Host-Benutzer (oben), damit die geschriebenen Dateien dir gehören. **Kubernetes / OpenShift (non-root über `runAsUser`)** - direkt als Non-Root-Benutzer gestartet, kann der Container die Volumes nicht selbst chownen, daher muss der Orchestrator sie beschreibbar machen. Setze `fsGroup`: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` Die beschreibbaren Verzeichnisse des Images gehören der Gruppe GID 0 und sind gruppenbeschreibbar, sodass ein Pod, der mit einer **beliebigen UID** plus der Root-Zusatzgruppe (dem OpenShift-Standard) läuft, ohne `chown` schreiben kann. **TrueNAS Scale (und andere "Fremd-UID"-Setups)** - TrueNAS führt Apps als Non-Root-Benutzer aus (oft `568:568`) und bindet Host-Datasets ein, die einem anderen Benutzer gehören, sodass weder der Entrypoint noch `fsGroup` sie von sich aus beschreibbar macht. Wähle eine Option: * **Führe die App als root aus** (empfohlen) - lasse den Benutzer der App ungesetzt oder setze ihn auf `0` und lass den Standard-Entrypoint die Berechtigungen korrigieren und auf `snapotter` zurückfallen. * **Führe als UID `999` aus** - setze Benutzer/Gruppe der App auf `999:999` (SnapOtters eingebauter `snapotter`-Benutzer), sodass sie zur Eigentümerschaft des Images passt. * **`chown` das Host-Dataset** auf die UID, unter der der Container läuft, aus der TrueNAS-Shell: ```bash # Verwende die UID aus dem Startfehler (oder führe `id` im Container aus) chown -R 568:568 /mnt// ``` Der Startfehler nennt die genau zu verwendende UID, daher ist der schnellste Weg, die App einmal zu starten, die Meldung zu lesen und dann entsprechend `chown` (oder den Benutzer anzupassen). ## Umgebungsvariablen {#environment-variables} | Variable | Standard | Beschreibung | |---|---|---| | `AUTH_ENABLED` | `true` | Login-Pflicht aktivieren/deaktivieren | | `DEFAULT_USERNAME` | `admin` | Anfänglicher Admin-Benutzername | | `DEFAULT_PASSWORD` | `admin` | Anfängliches Admin-Passwort (erzwungene Änderung beim ersten Login) | | `MAX_UPLOAD_SIZE_MB` | `0` (unbegrenzt) | Upload-Limit pro Datei in MB. Das Image kommt mit `0`; ein Build aus dem Quellcode startet bei 100 | | `MAX_BATCH_SIZE` | `0` (unbegrenzt) | Max. Dateien pro Stapelanfrage. Das Image kommt mit `0`; ein Build aus dem Quellcode startet bei 100 | | `RATE_LIMIT_PER_MIN` | `1000` | API-Anfragen pro Minute und IP (0 zum Deaktivieren) | | `MAX_USERS` | `0` (unbegrenzt) | Maximale Benutzerkonten | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Welche Gegenstellen die Client-IP über `X-Forwarded-For` setzen dürfen. Standardmäßig nur private Netze | | `PUID` | `999` | Als diese UID ausführen (für Bind-Mount-Berechtigungen) | | `PGID` | `999` | Als diese GID ausführen (für Bind-Mount-Berechtigungen) | | `LOG_LEVEL` | `info` | Log-Ausführlichkeit: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (auto) | Max. parallele KI-Verarbeitungsjobs | | `SESSION_DURATION_HOURS` | `168` | Lebensdauer der Login-Sitzung (7 Tage) | | `CORS_ORIGIN` | (leer) | Kommagetrennte erlaubte Ursprünge oder leer für Same-Origin | ### Ausgehender Proxy und private CA {#outbound-proxy-and-private-ca} Der offizielle Container ermöglicht die Umgebungs-Proxy-Unterstützung von Node. Wenn SnapOtter das OCR-Laufzeit-Repository oder andere HTTPS-Dienste über einen Unternehmens-Proxy erreichen muss, legen Sie `HTTPS_PROXY` (und bei Bedarf `HTTP_PROXY`) fest. Legen Sie `NO_PROXY` auf eine durch Kommas getrennte Liste von Hosts fest, die direkt erreicht werden müssen, z. B. Postgres, Redis und internen Objektspeicher. Wenn der Proxy oder ein interner Dienst von einer privaten Zertifizierungsstelle signiert ist, mounten Sie das CA-Zertifikat schreibgeschützt und verweisen Sie `NODE_EXTRA_CA_CERTS` darauf. Die Datei muss vorhanden sein, wenn der Node-Prozess startet: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Bewahren Sie die Proxy-Anmeldeinformationen außerhalb der Compose-Datei auf (z. B. in einer geschützten `.env`-Datei oder einem geschützten Geheimnis). Deaktivieren Sie die TLS-Überprüfung nicht: Der signierte OCR-Index authentifiziert Release-Metadaten, während die normale TLS-Validierung weiterhin den Transport und alle anderen ausgehenden Anforderungen schützt. ## Health-Check {#health-check} Der Container enthält einen eingebauten Health-Check: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Reverse-Proxy {#reverse-proxy} `TRUST_PROXY` steht standardmäßig auf `loopback,linklocal,uniquelocal`, sodass SnapOtter `X-Forwarded-For` nur einer Gegenstelle aus einem privaten Netz glaubt. Einem Reverse-Proxy auf demselben Host, in einem Docker-Netzwerk oder im LAN wird also von Haus aus vertraut, womit Ratenbegrenzung, die Brute-Force-Sperre beim Login, das Audit-Log und die Enterprise-IP-Allowlist ohne jede Konfiguration die echte Client-IP sehen. Setze `TRUST_PROXY=true` nur dann, wenn der vorgeschaltete Proxy SnapOtter von einer **öffentlichen** Adresse aus erreicht, etwa ein Cloud-Load-Balancer in einem anderen Netz. Auf einer direkt exponierten Instanz macht dieser Wert `request.ip` angreifergesteuert, denn wer den Header durchrotiert, bekommt pro Anfrage einen frischen Zähler für die Ratenbegrenzung. Zwei Dinge solltest du wissen, bevor du Client-IPs misst. Docker Desktop unter macOS und Windows bedient einen veröffentlichten Port über einen Userland-Proxy, der jede Quelladresse auf das VM-Gateway `192.168.65.1` umschreibt; dort holt kein Wert von `TRUST_PROXY` den echten Client zurück, also setze alles Internet-Zugängliche unter Linux auf. Und auf jeder Plattform wird ein Zugriff auf einen veröffentlichten Port über `localhost` als Bridge-Gateway statt als dein Client gesehen, ein Test über localhost sagt also nichts darüber aus, wie ein echter Client zugeordnet wird. Die vollständige Tabelle der `TRUST_PROXY`-Werte und den Docker-Desktop-Vorbehalt findest du in [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy). Für jeden unten aufgeführten Proxy sind zwei Dinge wichtig: Erlauben Sie große Anforderungstexte (Uploads) und puffern Sie keine Antworten. Ein antwortpuffernder Proxy unterbricht den SSE-Fortschritt und führt, was sichtbarer ist, dazu, dass der Download einer großen Datei „startet, aber nie beendet“ wird, da der Proxy die gesamte Datei speichert, bevor er sie weitergibt. SnapOtter sendet `X-Accel-Buffering: no` bei Downloads, sodass nginx sie streamt, auch wenn die Pufferung an anderer Stelle beibehalten wird. Bei anderen Proxys als nginx muss die Antwortpufferung jedoch explizit deaktiviert werden (siehe unten in jeder Konfiguration). Wenn ein Download teilweise ins Stocken gerät, ist als erstes zu überprüfen, ob ein Puffer-Proxy vorgeschaltet ist. ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Antworten streamen statt puffern: Wird für den SSE-Fortschritt (Batch, KI, Feature-Installationen) und für das Herunterladen großer Dateien benötigt. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Füge einen neuen Proxy Host hinzu 2. Setze den Domain Name auf deine Domain 3. Setze Scheme auf `http`, Forward Hostname auf `SnapOtter` (oder deine Container-IP), Forward Port auf `1349` 4. Aktiviere WebSocket-Unterstützung 5. Füge unter Advanced hinzu: `client_max_body_size 500M;` und `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` deaktiviert die Antwortpufferung, die für SSE-Fortschrittsereignisse (Stapelverarbeitung, KI-Tools, Funktionsinstallationen) und für das Durchströmen großer Dateidownloads erforderlich ist, anstatt zum Stillstand zu kommen. Durch die verlängerten Zeitüberschreitungen können große Datei-Uploads abgeschlossen werden, ohne dass Caddy die Verbindung vorzeitig schließt. ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Hinweis: Cloudflare hat auf kostenlosen Tarifen ein Upload-Limit von 100 MB. Setze `MAX_UPLOAD_SIZE_MB=100` passend dazu. ## CI/CD {#ci-cd} Das GitHub-Repository hat drei Workflows: * **ci.yml** - Läuft automatisch bei jedem Push und PR. Lintet, typechecked, testet, baut und validiert das Docker-Image (ohne Push). * **release.yml** - Wird manuell über `workflow_dispatch` ausgelöst. Führt semantic-release aus, um ein Versions-Tag und ein GitHub-Release zu erstellen, baut dann ein Multi-Arch-Docker-Image (amd64 + arm64) und pusht zu Docker Hub (`snapotter/snapotter`) und zur GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`). * **deploy-docs.yml** - Baut diese Dokumentations-Site und stellt sie bei Push auf `main` auf Cloudflare Pages bereit. Um ein Release zu erstellen, gehe in der GitHub-Oberfläche auf **Actions > Release > Run workflow** oder führe aus: ```bash gh workflow run release.yml ``` Semantic-release bestimmt die Version aus der Commit-Historie. Das `latest`-Docker-Tag zeigt immer auf das jüngste Release. ## Analytics {#analytics} SnapOtter enthält anonyme Produkt-Analytics (Tool-Nutzungsmuster, Fehlerberichte), um Bugs zu erkennen und Funktionen zu verbessern. Sie sind standardmäßig aktiviert. Deine Dateien, Dateinamen und persönlichen Daten sind niemals Teil davon. SnapOtter funktioniert mit deaktivierten Analytics normal. ### Analytics deaktivieren {#disabling-analytics} Das Laufzeit-Opt-out ist ein Admin-Umschalter mit einem Klick. Öffne Einstellungen > System > Datenschutz und schalte Anonyme Produkt-Analytics aus. Es stoppt sofort für die gesamte Instanz, kein Neuaufbau erforderlich. Für ein Image, das niemals Analytics senden kann, setze das Build-Time-Hard-Off, indem du das Repository klonst und neu baust: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` Oder füge das Build-Argument zu deinem vorhandenen `docker-compose.yml` hinzu: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/hi/guide/deployment.md description: >- SnapOtter को Docker के साथ प्रोडक्शन में डिप्लॉय करें। हार्डवेयर आवश्यकताएँ, GPU सेटअप, और Nginx, Traefik, तथा Cloudflare के लिए रिवर्स प्रॉक्सी कॉन्फ़िग। --- # Deployment {#deployment} SnapOtter एक 3-कंटेनर Docker Compose स्टैक के रूप में डिप्लॉय होता है: SnapOtter ऐप इमेज, PostgreSQL 17, और Redis 8। ऐप इमेज **linux/amd64** (AI त्वरण के लिए NVIDIA CUDA के साथ) और **linux/arm64** (CPU) को सपोर्ट करती है, इसलिए यह Intel/AMD सर्वरों, Apple Silicon Macs, और Raspberry Pi 4/5 जैसे ARM डिवाइसों पर मूल रूप से चलती है। VA-API, Quick Sync, या OpenCL के माध्यम से Intel/AMD iGPU त्वरण आज AI इन्फ़रेंस के लिए सपोर्ट नहीं किया जाता। GPU सेटअप, Docker Compose उदाहरणों, और वर्शन पिनिंग के लिए [Docker Image](./docker-tags) देखें। ::: info कोरियाई OCR संगतता तेज़ OCR `auto`, `en`, `de`, `es`, `fr`, `zh` और `ja` का समर्थन करता है, लेकिन कोरियाई (`ko`) का नहीं। कोरियाई के लिए सटीक OCR पैक और `balanced` या `best` आवश्यक है। पैक आधिकारिक Linux amd64 और arm64 कंटेनरों पर चलता है; NVIDIA होस्ट पर भी OCR CPU पर ही चलता है। असमर्थित सिस्टम स्पष्ट संगतता त्रुटि लौटाते हैं और चुपचाप `fast` पर वापस नहीं जाते। कोरियाई के साथ `fast` या पुराने `tesseract` नाम को कतार में डालने से पहले `FEATURE_INCOMPATIBLE` और `fast-korean-unsupported` के साथ अस्वीकार किया जाता है। ::: ## Quick Start (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` इसके बाद ऐप `http://localhost:1349` पर उपलब्ध होता है। > **Docker Hub रेट लिमिट?** GitHub Container Registry से पुल करने के लिए `snapotter/snapotter:latest` को `ghcr.io/snapotter-hq/snapotter:latest` से बदलें। दोनों रजिस्ट्री हर रिलीज़ पर वही इमेज प्राप्त करती हैं। ## Quick Start (NVIDIA CUDA) {#quick-start-nvidia-cuda} समर्थित AI टूल पर NVIDIA CUDA त्वरण के लिए (पृष्ठभूमि हटाना, अपस्केलिंग, चेहरा निखारना): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # गैर-स्थानीय तैनाती के लिए इसे बदलें POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### GPU त्वरण सत्यापित करें {#verify-gpu-acceleration} लॉग में CUDA पहचान की जाँच करें: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` यदि `--gpus all` और NVIDIA कंटेनर टूलकिट सही तरीके से सेट होने के बावजूद AI उपकरण CPU पर चलते हैं, तो **सेटिंग्स → AI फीचर्स** से प्रभावित बंडल (उदाहरण के लिए बैकग्राउंड रिमूवल) को फिर से इंस्टॉल करें। इंस्टॉलर ONNX रनटाइम के GPU बिल्ड को पुनर्स्थापित करता है, जिसे केवल CPU बिल्ड किसी अन्य बंडल (जैसे ट्रांसक्रिप्शन) द्वारा खींचा जाता है अन्यथा साझा AI वातावरण में छाया कर सकता है। यदि यूआई से पुनः इंस्टॉल करने से पुरानी छवि पर जीपीयू बहाल नहीं होता है, तो [अंक #490](https://github.com/snapotter-hq/SnapOtter/issues/490) में मैन्युअल मरम्मत देखें। ## Hardware Requirements {#hardware-requirements} ये संख्याएँ कई तरह के सिस्टमों पर किए गए बेंचमार्क से आती हैं, एक आधुनिक amd64 वर्कस्टेशन (NVIDIA RTX 4070 के साथ) से लेकर एक Raspberry Pi तक, जिनमें से हर एक पर पूरा टूल कैटलॉग चलाया गया और असली न्यूनतम सीमा खोजने के लिए Docker रिसोर्स लिमिट को स्वीप किया गया। इन टियरों के छोटे सिरे पर चला रहे हैं (कोई Pi, पुराना लैपटॉप, 2 GB VPS)? [कम संसाधन वाले सेटअप](/hi/guide/low-resource) इन संख्याओं को ट्यून की गई सीमाओं के साथ एक ठोस वॉकथ्रू में बदल देता है। ### Quick Reference {#quick-reference} | टियर | उपयोग परिदृश्य | CPU | RAM | GPU | स्टोरेज | |------|----------|-----|-----|-----|---------| | न्यूनतम | इमेज, फ़ाइलें, और हल्के PDF टूल; एकल उपयोगकर्ता; छोटे बैच | 2 कोर | 2 GB | कोई नहीं | ~7 GB | | अनुशंसित | वीडियो, PDF, और CPU पर AI सहित सभी पाँच मोडैलिटी; बैच; कुछ उपयोगकर्ता | 4 कोर | 4 GB | कोई नहीं | ~25 GB | | पूर्ण | GPU AI सहित सब कुछ तेज़ गति से; बड़े बैच; अनेक उपयोगकर्ता | 6-8 कोर | 8 GB | NVIDIA 8 GB+ VRAM (12 GB आरामदायक) | ~35 GB | **आर्किटेक्चर: केवल 64-बिट** (`linux/amd64` या `linux/arm64`)। SnapOtter Intel/AMD सर्वरों, Apple Silicon Macs, और 64-बिट ARM बोर्डों पर मूल रूप से चलता है, जिनमें **Raspberry Pi 4 और 5** (4-8 GB) शामिल हैं। यह 32-बिट ARM (`armv7`/`armhf`) पर **नहीं** चलता, इसके लिए कोई इमेज बनाई ही नहीं जाती, और न ही Pi Zero जैसे 512 MB-श्रेणी के बोर्डों पर, जो मेमोरी की न्यूनतम सीमा से नीचे हैं (नीचे देखें)। ### Minimum (इमेज, फ़ाइलें, और हल्के PDF टूल; कोई AI नहीं) {#minimum-image-files-and-light-pdf-tools-no-ai} | रिसोर्स | आवश्यकता | |---|---| | CPU | 2 कोर | | RAM | 2 GB | | डिस्क | ~5.5 GB (इमेज) + डेटा वॉल्यूम | | GPU | आवश्यक नहीं | सभी 222 गैर-AI कैटलॉग टूल - इमेज (रिसाइज़, क्रॉप, कन्वर्ट, कंप्रेस, एडजस्ट, वॉटरमार्क), वीडियो (ट्रिम, म्यूट, रीमक्स), ऑडियो (कन्वर्ट, नॉर्मलाइज़, ट्रिम), PDF (मर्ज, स्प्लिट, कंप्रेस, रोटेट, प्रोटेक्ट), फ़ाइल रूपांतरण, और समर्पित रूपांतरण प्रीसेट - मामूली हार्डवेयर पर चलते हैं। अधिकांश ऑपरेशन एक बड़ी फ़ाइल पर भी एक सेकंड से काफ़ी कम समय में पूरे हो जाते हैं: एक 2.7 MB इमेज ~0.05 s में रिसाइज़ होती है और ~2 s में WebP में री-एनकोड होती है। मेमोरी की न्यूनतम सीमा असली है, यह एक Docker रिसोर्स-लिमिट स्वीप से आती है: **512 MB स्टैक शुरू नहीं कर सकता** (एक अकेली इमेज रिसाइज़ भी मार दी जाती है), **1 GB** एकल-फ़ाइल ऑपरेशन संभालता है पर मल्टी-फ़ाइल बैच में मेमोरी खत्म हो जाती है, और **2 GB / 2 कोर** सबसे छोटा कॉन्फ़िगरेशन है जो बैच को आराम से संभालता है। ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **एकमात्र CPU-भारी अपवाद वीडियो री-एनकोडिंग है।** स्ट्रीम-कॉपी ऑपरेशन (ट्रिम, म्यूट, कंटेनर रीमक्स) तत्काल होते हैं, पर किसी अलग कोडेक में ट्रांसकोडिंग CPU-बद्ध है। एक 1080p / 45-सेकंड क्लिप को VP9 (WebM) में री-एनकोड करने में एक तेज़ आधुनिक CPU पर लगभग **~40 s**, Apple Silicon पर ~45 s, एक पुराने मोबाइल 4-कोर पर ~80 s, और एक पुराने 4-कोर सर्वर पर **~130 s** लगते हैं। यदि आपका वर्कलोड वीडियो-भारी है, तो CPU कोर और क्लॉक स्पीड को प्राथमिकता दें, या कंटेनर की `cpus:` लिमिट बढ़ाएँ, शिप किया गया compose ऐप को डिफ़ॉल्ट रूप से 4 कोर पर सीमित करता है (GPU compose पर 8)। ### Recommended (CPU पर AI टूल) {#recommended-ai-tools-on-cpu} | रिसोर्स | आवश्यकता | |---|---| | CPU | 4 कोर | | RAM | 4 GB | | Disk | 3 जीबी (छवि) + लगभग 20 जीबी (सभी वैकल्पिक एआई पैक) + कार्यक्षेत्र | | GPU | आवश्यक नहीं (CPU फ़ॉलबैक) | **बड़े AI बंडलों को इंस्टॉल करना और चलाना अनुशंसा को 4 जीबी RAM तक बढ़ा देता है।** कोई वैकल्पिक पैक इंस्टॉल नहीं होने से ऐप लगभग 360 एमबी निष्क्रिय रहता है। लीगेसी Python उपकरण एक sidecar साझा करते हैं, जबकि सटीक OCR सक्रिय अपरिवर्तनीय पीढ़ी पर पिन किए गए एक समर्पित लंबे समय तक चलने वाले dispatcher का उपयोग करता है। सक्रियण से पहले, इंस्टॉलर उम्मीदवार पर एक smoke test चलाता है। इसके बाद यह परमाणु रूप से नए dispatcher पर स्विच हो जाता है और garbage collection से पहले पिछले dispatcher को हटा देता है। प्रत्येक आधिकारिक सटीक-ओसीआर आर्टिफैक्ट को 4 GiB cgroup के अंदर अपनी सबसे खराब स्थिति release suite से गुजरना होगा, जबकि 4 जीबी होस्ट अनुशंसा Node.js एप्लिकेशन, Postgres, Redis, कतारों और समवर्ती कार्य के लिए हेडरूम छोड़ती है। अधिकांश AI टूल CPU पर पूरी तरह उपयोगी हैं; कुछ को वास्तव में GPU चाहिए। एक आधुनिक 4-कोर CPU पर मापा गया: | AI टूल | CPU समय | CPU पर उपयोगी? | |---|---|---| | फ़ेस डिटेक्शन (blur-faces, smart-crop, red-eye), noise-removal | 1 s से कम | हाँ | | OCR, ट्रांसक्रिप्शन, सबटाइटल | 1-3 s | हाँ | | Colorize, फ़ेस एन्हांसमेंट | ~10 s | हाँ | | बैकग्राउंड हटाना / बदलना / ब्लर | ~29 s | हाँ (आपको इंतज़ार करना होगा) | | AI अपस्केल (RealESRGAN) | ~33 s छोटी; बड़ी इमेजों पर मिनट | सीमांत, GPU दृढ़ता से अनुशंसित | | फ़ोटो रीस्टोरेशन (पूरी पाइपलाइन) | कई मिनट | नहीं, GPU या एक तेज़ मल्टी-कोर CPU चाहिए | SnapOtter जानबूझकर इन मॉडल डाउनलोड को Docker इमेज में नहीं बेक करता। AI बंडल केवल तभी खींचे जाते हैं जब कोई व्यवस्थापक संबंधित टूल सक्षम करता है, इन्हें स्थायी `/data/ai` वॉल्यूम में संग्रहीत किया जाता है, और उसी मॉडल स्टैक पर निर्भर हर टूल द्वारा साझा किया जाता है। इससे अंतिम कंटेनर इमेज छोटी रहती है, जबकि एक पूर्ण AI इंस्टॉलेशन नीचे दी गई बड़ी स्टोरेज संख्याओं तक पहुँच सकता है। कुछ टूल एक से अधिक साझा बंडल पर निर्भर होते हैं। उदाहरण के लिए, Passport Photo को `background-removal` और `face-detection` दोनों चाहिए; यदि `background-removal` पहले से इंस्टॉल है, तो Passport Photo सक्षम करने पर केवल गायब `face-detection` बंडल डाउनलोड होता है। यही पुनः उपयोग सभी AI टूलों पर लागू होता है। वैकल्पिक एआई पैक भंडारण अनुमान: | बंडल | डिस्क आकार | |---|---| | बैकग्राउंड हटाना | 4-5 GB | | अपस्केल + फ़ेस एन्हांस + नॉइज़ हटाना | 5-6 GB | | फ़ेस डिटेक्शन | 200-300 MB | | ऑब्जेक्ट इरेज़र + Colorize | 1-2 GB | | सटीक OCR (`balanced`/`best`) | ~208-234 MiB डाउनलोड / ~409-488 MiB स्थापित | | फ़ोटो रीस्टोरेशन | 4-5 GB | | प्रतिलिपि | ~600 एमबी | | **सभी बंडल** | **~20 जीबी स्थापित** | तेज़ OCR को Tesseract के माध्यम से छवि में बनाया गया है, लगभग 25 MiB जोड़ता है, और वैकल्पिक OCR पैक या इसकी 4 GiB मेमोरी आवश्यकता की आवश्यकता नहीं है। सटीक पैक आधिकारिक Linux amd64 और arm64 कंटेनर में उपलब्ध है और CPU पर ONNX Runtime चलाता है। NVIDIA होस्ट उसी CPU OCR रनटाइम का उपयोग करते हैं, इसलिए OCR CUDA संस्करण या GPU आर्किटेक्चर पर निर्भर नहीं होता है। सटीक रनटाइम के लिए कम से कम 4 GiB प्रभावी मेमोरी की आवश्यकता होती है: कॉन्फ़िगर कंटेनर cgroup सीमा, अन्यथा होस्ट मेमोरी। SnapOtter पैक डाउनलोड करने से पहले हस्ताक्षरित न्यूनतम संगतता से नीचे के सिस्टम को अस्वीकार कर देता है। सटीक-पैक इंस्टॉलेशन को bare-metal/प्रीबिल्ट आर्काइव्स पर भी अस्वीकार कर दिया गया है, जिनके libc और Python ABI की गारंटी नहीं दी जा सकती है। एक ही `DATA_DIR` साझा करने वाली रेप्लिकाओं को समान CPU आर्किटेक्चर का उपयोग करना चाहिए; नोड अफ़िनिटी की मदद से मल्टी-रेप्लिका डिप्लॉयमेंट को संगत नोड पर पिन करें। मिश्रित amd64/arm64 रेप्लिकाओं के लिए अलग-अलग डेटा वॉल्यूम और स्वतंत्र SnapOtter डिप्लॉयमेंट आवश्यक हैं। सटीक रनटाइम एक सक्रिय पीढ़ी को बनाए रखता है और सक्रियण के बाद इसके डाउनलोड कैश को शुद्ध करता है। इस रिलीज़ के लिए, पहली स्थापना के लिए संग्रह प्लस स्टेजिंग के लिए अस्थायी रूप से लगभग 620-720 MiB की आवश्यकता होती है, और पुरानी पीढ़ी के सक्रिय रहने पर अपग्रेड 1.2 GiB के करीब पहुंच सकता है। इंस्टॉलर डाउनलोड करने या निकालने से पहले हस्ताक्षरित इंडेक्स और वर्तमान पीढ़ियों से सटीक आवश्यकता की गणना करता है, और यदि डेटा वॉल्यूम बहुत छोटा है तो जल्दी विफल हो जाता है। ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Full (NVIDIA CUDA पर AI टूल) {#full-ai-tools-on-nvidia-cuda} | रिसोर्स | आवश्यकता | |---|---| | CPU | 6-8 कोर (GPU AI के साथ भी वीडियो तैयारी + समवर्तीता CPU पर चलती है) | | RAM | 8 GB | | GPU | 8+ GB VRAM वाला NVIDIA (12 GB अनुशंसित) | | डिस्क | कुल ~35 GB | एक NVIDIA GPU (CUDA) भारी AI मॉडलों को नाटकीय रूप से तेज़ कर देता है। एक RTX 4070 बनाम एक आधुनिक CPU पर मापा गया: | AI टूल | GPU के साथ तेज़ी | टिप्पणियाँ | |---|---|---| | AI अपस्केल (RealESRGAN 2×) | **~47×** | सबसे बड़ा फ़ायदा, एक सेकंड से कम बनाम ~33 s (बड़ी इमेजों पर मिनट) | | फ़ेस एन्हांसमेंट (CodeFormer) | **~12×** | ~0.9 s बनाम ~11 s | | ट्रांसक्रिप्शन (Whisper) | ~4.5× | | | बैकग्राउंड हटाना / बदलना / ब्लर | ~4× | GPU पर ~7 s बनाम CPU पर ~29 s | | Colorize | ~1.8× | | | OCR, फ़ेस डिटेक्शन, red-eye, noise-removal | ~1× | CPU पर पहले से तेज़, GPU मदद नहीं करता | | फ़ोटो रीस्टोरेशन | कोई नहीं | GPU पर भी CPU-बद्ध (0% GPU उपयोग); यहाँ GPU से ज़्यादा एक तेज़ CPU मायने रखता है | GPU के लायक टूल हैं **अपस्केल, फ़ेस एन्हांसमेंट, ट्रांसक्रिप्शन, और बैकग्राउंड हटाना**। फ़ेस डिटेक्शन, OCR, और red-eye CPU-बद्ध हैं और पहले से तेज़ हैं, इसलिए GPU कुछ नहीं जोड़ता। फ़ेस एन्हांसमेंट के साथ अपस्केल के दौरान चरम VRAM उपयोग 7.5 GB तक पहुँचता है। एक 6 GB NVIDIA GPU अधिकांश AI टूलों के लिए अलग-अलग काम करता है पर अपस्केल पर विफल होगा। 8-12 GB VRAM सब कुछ संभालता है। VA-API, Quick Sync, या OpenCL के माध्यम से Intel/AMD iGPU त्वरण आज AI इन्फ़रेंस के लिए सपोर्ट नहीं किया जाता। कंटेनर में `/dev/dri` को मैप करने से AI GPU त्वरण सक्षम नहीं होता; NVIDIA CUDA उपलब्ध न होने पर SnapOtter AI टूलों को CPU पर चलाएगा। ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Concurrent Users {#concurrent-users} डिफ़ॉल्ट 4-कोर-सीमित ऐप कंटेनर के विरुद्ध समानांतर इमेज-रिसाइज़ अनुरोध: | समवर्ती अनुरोध | औसत प्रतिक्रिया समय | त्रुटियाँ | |---|---|---| | 1 | 0.4s | 0 | | 5 | 1.2s | 0 | | 10 | 2.1s | 0 | जैसे-जैसे वर्कर पूल संतृप्त होता है, प्रतिक्रिया समय बिना किसी त्रुटि के उप-रैखिक रूप से घटता है। ऐप कंटेनर की `cpus:` लिमिट बढ़ाने से (या अधिक कोर वाले होस्ट का उपयोग करने से) यह सीमा ऊपर उठती है। ध्यान दें कि भारी जॉब (वीडियो ट्रांसकोड, CPU AI) अपनी पूरी अवधि के लिए एक वर्कर को पकड़े रखते हैं, इसलिए CPU का आकार अपने अपेक्षित समवर्ती भारी जॉब की संख्या के अनुसार तय करें, केवल अनुरोध संख्या के अनुसार नहीं। ### Supported Image Formats {#supported-image-formats} SnapOtter **55+ इनपुट फ़ॉर्मैट** और **14 आउटपुट फ़ॉर्मैट** को सपोर्ट करता है, जिनमें 20+ कैमरा ब्रांडों की RAW फ़ाइलें, पेशेवर फ़ॉर्मैट (PSD, EPS, OpenEXR, HDR), आधुनिक कोडेक (JPEG XL, AVIF, HEIC, QOI), और वैज्ञानिक/गेमिंग फ़ॉर्मैट (FITS, DDS) शामिल हैं। हर सपोर्टेड फ़ॉर्मैट, उपयोग किए गए डिकोडर, और उपलब्ध क्वालिटी नियंत्रणों के विवरण के लिए [पूर्ण फ़ॉर्मैट सूची](/hi/guide/supported-formats) देखें। ### Known Limitations {#known-limitations} * **Content-aware resize** caire बाइनरी की एक सीमा के कारण बड़ी इमेजों (>5 MP) पर क्रैश हो जाता है। छोटी इमेजों के साथ ठीक काम करता है। * **HEIF डिकोड** में 13-23 सेकंड लगते हैं। HEIC (Apple का वेरिएंट) 0.3-0.9 सेकंड पर बहुत तेज़ है। * **Upscale** छोटी इमेजों से परे किसी भी चीज़ के लिए CPU पर टाइम आउट हो जाता है। व्यावहारिक उपयोग के लिए GPU आवश्यक है। * **CodeFormer** फ़ेस एन्हांसमेंट GFPGAN से काफ़ी धीमा है (GPU पर 53s बनाम 2s)। अधिकांश उपयोग परिदृश्यों के लिए GFPGAN अनुशंसित है। ## Volumes {#volumes} | माउंट / वॉल्यूम | उद्देश्य | आवश्यक? | |---|---|---| | `/data` (ऐप) | AI मॉडल, Python venv, उपयोगकर्ता फ़ाइलें | **हाँ**, इसके बिना फ़ाइल हानि | | `/tmp/workspace` (ऐप) | अस्थायी प्रोसेसिंग फ़ाइलें (स्वतः-साफ़) | अनुशंसित | | `SnapOtter-pgdata` (postgres) | PostgreSQL डेटा डायरेक्टरी (उपयोगकर्ता, सेटिंग्स, पाइपलाइन, जॉब) | **हाँ**, इसके बिना डेटा हानि | | `SnapOtter-redisdata` (redis) | टिकाऊ जॉब क्यू के लिए Redis append-only फ़ाइल | अनुशंसित | ### Bind mounts vs. named volumes {#bind-mounts-vs-named-volumes} **नामित वॉल्यूम** (अनुशंसित), Docker स्वचालित रूप से अनुमतियाँ प्रबंधित करता है: ```yaml volumes: - SnapOtter-data:/data ``` **बाइंड माउंट**, आप अनुमतियाँ प्रबंधित करते हैं। अपने होस्ट उपयोगकर्ता से मिलाने के लिए `PUID`/`PGID` सेट करें: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Storage permissions {#storage-permissions} SnapOtter रनटाइम पर दो स्थानों पर लिखता है: `/data` (उपयोगकर्ता फ़ाइलें, लॉग, AI मॉडल और Python venv) और `/tmp/workspace` (अस्थायी प्रोसेसिंग स्क्रैच)। दोनों उस उपयोगकर्ता द्वारा लिखने योग्य होने चाहिए जिसके रूप में कंटेनर चलता है। यदि कोई एक नहीं है, तो कंटेनर स्टार्टअप पर **तुरंत विफल हो जाता है**, एक संदेश के साथ जो डायरेक्टरी, चल रहे UID/GID, और इसे कैसे ठीक करें बताता है, बजाय "healthy" के रूप में बूट होकर फिर पहले अपलोड पर एक रहस्यमय त्रुटि के साथ विफल होने के। अनुमतियाँ कैसे संभाली जाती हैं यह इस पर निर्भर करता है कि कंटेनर कैसे लॉन्च किया गया है: **डिफ़ॉल्ट (root के रूप में शुरू, `snapotter` पर गिरता है)**, एंट्रीपॉइंट root के रूप में शुरू होता है, माउंट किए गए वॉल्यूम के स्वामित्व को ठीक करता है, फिर `gosu` के माध्यम से अनप्रिविलेज्ड `snapotter` उपयोगकर्ता पर गिर जाता है। नामित वॉल्यूम बिना किसी कॉन्फ़िगरेशन के काम करते हैं। बाइंड माउंट के लिए, `PUID`/`PGID` को अपने होस्ट उपयोगकर्ता (ऊपर) पर सेट करें ताकि यह जो फ़ाइलें लिखे उनका स्वामित्व आपका हो। **Kubernetes / OpenShift (`runAsUser` के माध्यम से गैर-root)**, सीधे एक गैर-root उपयोगकर्ता के रूप में लॉन्च होने पर, कंटेनर स्वयं वॉल्यूम को chown नहीं कर सकता, इसलिए ऑर्केस्ट्रेटर को उन्हें लिखने योग्य बनाना होगा। `fsGroup` सेट करें: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` इमेज की लिखने योग्य डायरेक्टरियाँ GID 0 द्वारा समूह-स्वामित्व वाली और समूह-लिखने योग्य हैं, इसलिए एक **मनमाने UID** प्लस root अनुपूरक समूह (OpenShift डिफ़ॉल्ट) के साथ चलने वाला पॉड बिना किसी `chown` के लिख सकता है। **TrueNAS Scale (और अन्य "विदेशी UID" सेटअप)**, TrueNAS ऐप्स को एक गैर-root उपयोगकर्ता (अक्सर `568:568`) के रूप में चलाता है और एक अलग उपयोगकर्ता के स्वामित्व वाले होस्ट डेटासेट माउंट करता है, इसलिए न तो एंट्रीपॉइंट और न ही `fsGroup` उन्हें स्वयं लिखने योग्य बनाता है। एक चुनें: * **ऐप को root के रूप में चलाएँ** (अनुशंसित), ऐप के उपयोगकर्ता को अनसेट छोड़ दें या इसे `0` पर सेट करें, और डिफ़ॉल्ट एंट्रीपॉइंट को अनुमतियाँ ठीक करने और `snapotter` पर गिरने दें। * **UID `999` के रूप में चलाएँ**, ऐप के उपयोगकर्ता/समूह को `999:999` (SnapOtter का बिल्ट-इन `snapotter` उपयोगकर्ता) पर सेट करें ताकि यह इमेज के स्वामित्व से मेल खाए। * होस्ट डेटासेट को उस UID पर **`chown`** करें जिसके रूप में कंटेनर चलता है, TrueNAS शेल से: ```bash # Use the UID from the startup error (or run `id` inside the container) chown -R 568:568 /mnt// ``` स्टार्टअप त्रुटि उपयोग करने के लिए सटीक UID बताती है, इसलिए सबसे तेज़ रास्ता है ऐप को एक बार शुरू करना, संदेश पढ़ना, फिर तदनुसार `chown` करना (या उपयोगकर्ता समायोजित करना)। ## Environment Variables {#environment-variables} | वेरिएबल | डिफ़ॉल्ट | विवरण | |---|---|---| | `AUTH_ENABLED` | `true` | लॉगिन आवश्यकता सक्षम/अक्षम करें | | `DEFAULT_USERNAME` | `admin` | प्रारंभिक व्यवस्थापक उपयोगकर्ता नाम | | `DEFAULT_PASSWORD` | `admin` | प्रारंभिक व्यवस्थापक पासवर्ड (पहले लॉगिन पर बदलना अनिवार्य) | | `MAX_UPLOAD_SIZE_MB` | `0` (असीमित) | प्रति-फ़ाइल अपलोड सीमा MB में। इमेज `0` के साथ आती है; स्रोत से बनाया गया बिल्ड 100 से शुरू होता है | | `MAX_BATCH_SIZE` | `0` (असीमित) | प्रति बैच अनुरोध अधिकतम फ़ाइलें। इमेज `0` के साथ आती है; स्रोत से बनाया गया बिल्ड 100 से शुरू होता है | | `RATE_LIMIT_PER_MIN` | `1000` | प्रति IP प्रति मिनट API अनुरोध (अक्षम करने के लिए 0 सेट करें) | | `MAX_USERS` | `0` (असीमित) | अधिकतम उपयोगकर्ता खाते | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | `X-Forwarded-For` के ज़रिए क्लाइंट IP कौन से पीयर सेट कर सकते हैं। डिफ़ॉल्ट रूप से केवल निजी नेटवर्क | | `PUID` | `999` | इस UID के रूप में चलाएँ (बाइंड माउंट अनुमतियों के लिए) | | `PGID` | `999` | इस GID के रूप में चलाएँ (बाइंड माउंट अनुमतियों के लिए) | | `LOG_LEVEL` | `info` | लॉग वर्बोसिटी: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (auto) | अधिकतम समानांतर AI प्रोसेसिंग जॉब | | `SESSION_DURATION_HOURS` | `168` | लॉगिन सत्र जीवनकाल (7 दिन) | | `CORS_ORIGIN` | (खाली) | अल्पविराम-पृथक अनुमत ऑरिजिन, या समान-ऑरिजिन के लिए खाली | ### आउटबाउंड प्रॉक्सी और निजी CA {#outbound-proxy-and-private-ca} आधिकारिक कंटेनर नोड के पर्यावरण-प्रॉक्सी समर्थन को सक्षम करता है। यदि SnapOtter को कॉर्पोरेट प्रॉक्सी के माध्यम से OCR रनटाइम रिपॉजिटरी या अन्य HTTPS सेवाओं तक पहुंचना है, तो `HTTPS_PROXY` (और जरूरत पड़ने पर `HTTP_PROXY`) सेट करें। `NO_PROXY` को उन होस्ट की अल्पविराम से अलग की गई सूची में सेट करें जिन तक सीधे पहुंचना चाहिए, जैसे Postgres, Redis और आंतरिक ऑब्जेक्ट स्टोरेज। यदि प्रॉक्सी या आंतरिक सेवा एक निजी प्रमाणपत्र प्राधिकारी द्वारा हस्ताक्षरित है, तो CA प्रमाणपत्र को केवल पढ़ने के लिए माउंट करें और उस पर `NODE_EXTRA_CA_CERTS` इंगित करें। नोड प्रक्रिया शुरू होने पर फ़ाइल मौजूद होनी चाहिए: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` प्रॉक्सी क्रेडेंशियल को Compose फ़ाइल के बाहर रखें (उदाहरण के लिए संरक्षित `.env` फ़ाइल या गुप्त में)। टीएलएस सत्यापन को अक्षम न करें: हस्ताक्षरित OCR सूचकांक रिलीज मेटाडेटा को प्रमाणित करता है, जबकि सामान्य टीएलएस सत्यापन अभी भी परिवहन और हर अन्य आउटबाउंड अनुरोध की सुरक्षा करता है। ## Health Check {#health-check} कंटेनर में एक बिल्ट-इन हेल्थ चेक शामिल है: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Reverse Proxy {#reverse-proxy} `TRUST_PROXY` का डिफ़ॉल्ट `loopback,linklocal,uniquelocal` है, इसलिए SnapOtter `X-Forwarded-For` पर तभी भरोसा करता है जब वह किसी निजी नेटवर्क के पीयर से आया हो। उसी होस्ट पर, किसी Docker नेटवर्क पर या आपके LAN पर मौजूद रिवर्स प्रॉक्सी शुरू से ही भरोसेमंद माना जाता है, यानी रेट लिमिटिंग, लॉगिन की ब्रूट-फ़ोर्स रोक, ऑडिट लॉग और enterprise संस्करण की IP अनुमति-सूची, सभी बिना किसी कॉन्फ़िगरेशन के असली क्लाइंट IP देखते हैं। `TRUST_PROXY=true` तभी सेट करें जब आगे लगा प्रॉक्सी SnapOtter तक किसी **सार्वजनिक** पते से पहुँचता हो, जैसे किसी दूसरे नेटवर्क का क्लाउड लोड बैलेंसर। सीधे उजागर इंस्टेंस पर यह मान `request.ip` को हमलावर के नियंत्रण में दे देता है, क्योंकि हेडर बदलता रहने वाला कॉलर हर अनुरोध पर नई रेट-लिमिट गिनती पा जाता है। क्लाइंट IP नापने से पहले दो बातें जान लें। macOS और Windows पर Docker Desktop प्रकाशित पोर्ट को यूज़रलैंड प्रॉक्सी के ज़रिए परोसता है, जो हर स्रोत पते को VM गेटवे `192.168.65.1` में बदल देता है; वहाँ `TRUST_PROXY` का कोई भी मान असली क्लाइंट वापस नहीं ला सकता, इसलिए इंटरनेट से जुड़ी हर चीज़ Linux पर तैनात करें। और किसी भी प्लेटफ़ॉर्म पर, प्रकाशित पोर्ट तक `localhost` से पहुँचना आपके क्लाइंट के बजाय ब्रिज गेटवे के रूप में दिखता है, इसलिए localhost से किया गया परीक्षण यह नहीं बताता कि असली क्लाइंट को कैसे गिना जाएगा। `TRUST_PROXY` के मानों की पूरी तालिका और Docker Desktop से जुड़ी चेतावनी [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy) में हैं। नीचे दी गई प्रत्येक प्रॉक्सी के लिए दो चीजें मायने रखती हैं: बड़े अनुरोध निकायों (अपलोड) की अनुमति दें, और प्रतिक्रियाओं को बफर न करें। एक प्रतिक्रिया-बफ़रिंग प्रॉक्सी SSE प्रगति को तोड़ देती है और, अधिक स्पष्ट रूप से, एक बड़ी फ़ाइल डाउनलोड को "शुरू लेकिन कभी ख़त्म नहीं" करती है, क्योंकि प्रॉक्सी इसे आगे बढ़ाने से पहले पूरी फ़ाइल को रखती है। SnapOtter डाउनलोड पर `X-Accel-Buffering: no` भेजता है इसलिए nginx उन्हें स्ट्रीम करता है, भले ही बफ़रिंग कहीं और छोड़ दी गई हो, लेकिन nginx के अलावा अन्य प्रॉक्सी को प्रतिक्रिया बफ़रिंग को स्पष्ट रूप से अक्षम करने की आवश्यकता होती है (नीचे प्रत्येक कॉन्फ़िगरेशन में दिखाया गया है)। यदि कोई डाउनलोड आंशिक रूप से रुक जाता है, तो सामने एक बफ़रिंग प्रॉक्सी जांचने वाली पहली चीज़ है। ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # बफ़रिंग के बजाय स्ट्रीम प्रतिक्रियाएँ: SSE प्रगति (बैच, AI, फ़ीचर इंस्टॉल) और बड़ी फ़ाइल डाउनलोड के लिए आवश्यक। proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. एक नया Proxy Host जोड़ें 2. Domain Name को अपने डोमेन पर सेट करें 3. Scheme को `http` पर, Forward Hostname को `SnapOtter` (या अपने कंटेनर IP) पर, Forward Port को `1349` पर सेट करें 4. WebSocket सपोर्ट सक्षम करें 5. Advanced के अंतर्गत, जोड़ें: `client_max_body_size 500M;` और `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` प्रतिक्रिया बफरिंग को अक्षम कर देता है, जो SSE प्रगति घटनाओं (बैच प्रोसेसिंग, एआई टूल्स, फीचर इंस्टॉल) और बड़ी फ़ाइल डाउनलोड को रोकने के बजाय स्ट्रीम करने के लिए आवश्यक है। विस्तारित टाइमआउट Caddy कनेक्शन को जल्दी बंद किए बिना बड़ी फ़ाइल अपलोड को पूरा करने की अनुमति देता है। ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` नोट: Cloudflare की फ़्री योजनाओं पर 100 MB अपलोड सीमा है। मिलाने के लिए `MAX_UPLOAD_SIZE_MB=100` सेट करें। ## CI/CD {#ci-cd} GitHub रिपॉज़िटरी में तीन वर्कफ़्लो हैं: * **ci.yml** - हर push और PR पर स्वचालित रूप से चलता है। लिंट, टाइपचेक, टेस्ट, बिल्ड करता है, और Docker इमेज को वैलिडेट करता है (बिना push किए)। * **release.yml** - `workflow_dispatch` के माध्यम से मैन्युअल रूप से ट्रिगर होता है। एक वर्शन टैग और GitHub रिलीज़ बनाने के लिए semantic-release चलाता है, फिर एक मल्टी-आर्च Docker इमेज (amd64 + arm64) बनाता है और Docker Hub (`snapotter/snapotter`) तथा GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`) पर push करता है। * **deploy-docs.yml** - `main` पर push होने पर इस दस्तावेज़ीकरण साइट को बनाता है और Cloudflare Pages पर डिप्लॉय करता है। एक रिलीज़ बनाने के लिए, GitHub UI में **Actions > Release > Run workflow** पर जाएँ, या चलाएँ: ```bash gh workflow run release.yml ``` Semantic-release कमिट इतिहास से वर्शन निर्धारित करता है। `latest` Docker टैग हमेशा सबसे हाल की रिलीज़ की ओर इंगित करता है। ## Analytics {#analytics} SnapOtter में बग पकड़ने और फ़ीचर सुधारने में मदद के लिए अनाम उत्पाद एनालिटिक्स (टूल उपयोग पैटर्न, त्रुटि रिपोर्ट) शामिल है। यह डिफ़ॉल्ट रूप से चालू है। आपकी फ़ाइलें, फ़ाइल नाम, और व्यक्तिगत डेटा कभी इसका हिस्सा नहीं होते। SnapOtter एनालिटिक्स अक्षम होने पर भी सामान्य रूप से काम करता है। ### Disabling analytics {#disabling-analytics} रनटाइम ऑप्ट-आउट एक-क्लिक व्यवस्थापक टॉगल है। Settings > System > Privacy खोलें और Anonymous Product Analytics बंद कर दें। यह पूरे इंस्टेंस के लिए तुरंत रुक जाता है, किसी रीबिल्ड की आवश्यकता नहीं। एक ऐसी इमेज के लिए जो कभी एनालिटिक्स उत्सर्जित नहीं कर सकती, रिपॉज़िटरी क्लोन करके और रीबिल्ड करके बिल्ड-टाइम हार्ड-ऑफ़ सेट करें: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` या अपने मौजूदा `docker-compose.yml` में बिल्ड आर्ग जोड़ें: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/id/guide/deployment.md description: >- Deploy SnapOtter ke produksi dengan Docker. Persyaratan perangkat keras, penyiapan GPU, dan konfigurasi reverse proxy untuk Nginx, Traefik, dan Cloudflare. --- # Deployment {#deployment} SnapOtter diterapkan sebagai stack Docker Compose 3 kontainer: image aplikasi SnapOtter, PostgreSQL 17, dan Redis 8. Image aplikasi mendukung **linux/amd64** (dengan NVIDIA CUDA untuk akselerasi AI) dan **linux/arm64** (CPU), sehingga berjalan secara native di server Intel/AMD, Mac Apple Silicon, dan perangkat ARM seperti Raspberry Pi 4/5. Akselerasi iGPU Intel/AMD melalui VA-API, Quick Sync, atau OpenCL saat ini tidak didukung untuk inferensi AI. Lihat [Docker Image](./docker-tags) untuk penyiapan GPU, contoh Docker Compose, dan penyematan versi. ::: info Kompatibilitas OCR bahasa Korea OCR Cepat mendukung `auto`, `en`, `de`, `es`, `fr`, `zh`, dan `ja`, tetapi tidak mendukung bahasa Korea (`ko`). Bahasa Korea memerlukan paket OCR Akurat dan `balanced` atau `best`. Paket berjalan pada kontainer resmi Linux amd64 dan arm64, termasuk host NVIDIA dengan OCR tetap memakai CPU. Sistem yang tidak didukung menerima kesalahan kompatibilitas yang jelas dan tidak pernah diam-diam kembali ke `fast`. Bahasa Korea dengan `fast` atau alias lama `tesseract` ditolak sebelum antre dengan `FEATURE_INCOMPATIBLE` dan `fast-korean-unsupported`. ::: ## Quick Start (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` Aplikasi kemudian tersedia di `http://localhost:1349`. > **Terkena batas laju Docker Hub?** Ganti `snapotter/snapotter:latest` dengan `ghcr.io/snapotter-hq/snapotter:latest` untuk menarik dari GitHub Container Registry sebagai gantinya. Kedua registry menerima image yang sama pada setiap rilis. ## Quick Start (NVIDIA CUDA) {#quick-start-nvidia-cuda} Untuk akselerasi NVIDIA CUDA pada alat AI yang didukung (penghapusan latar belakang, peningkatan skala, penyempurnaan wajah): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Ubah ini untuk penerapan non-lokal POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### Verifikasi akselerasi GPU {#verify-gpu-acceleration} Periksa deteksi CUDA di log: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` Jika alat AI berjalan di CPU meskipun `--gpus all` dan NVIDIA Container Toolkit telah dikonfigurasi dengan benar, instal ulang bundel yang terpengaruh (misalnya Penghapusan Latar Belakang) dari **Pengaturan → Fitur AI**. Penginstal memulihkan build GPU ONNX Runtime, yang mana build khusus CPU yang ditarik oleh bundel lain (seperti transkripsi) dapat membayangi lingkungan AI bersama. Jika menginstal ulang dari UI tidak memulihkan GPU pada image lama, lihat perbaikan manual di [masalah #490](https://github.com/snapotter-hq/SnapOtter/issues/490). ## Persyaratan Perangkat Keras {#hardware-requirements} Angka-angka ini berasal dari benchmark di berbagai sistem, mulai dari workstation amd64 modern dengan NVIDIA RTX 4070 hingga Raspberry Pi, menjalankan seluruh katalog perkakas pada masing-masing dan menyapu batas sumber daya Docker untuk menemukan batas bawah yang sebenarnya. Berjalan di ujung kecil tingkatan ini (Pi, laptop lama, VPS 2 GB)? [Penyiapan Sumber Daya Rendah](/id/guide/low-resource) mengubah angka-angka ini menjadi panduan konkret dengan batas yang sudah disetel. ### Referensi Singkat {#quick-reference} | Tingkat | Kasus Penggunaan | CPU | RAM | GPU | Penyimpanan | |------|----------|-----|-----|-----|---------| | Minimum | Perkakas gambar, file, dan PDF ringan; satu pengguna; batch kecil | 2 core | 2 GB | Tidak ada | ~7 GB | | Direkomendasikan | Kelima modalitas termasuk video, PDF, dan AI di CPU; batch; beberapa pengguna | 4 core | 4 GB | Tidak ada | ~25 GB | | Penuh | Semuanya dengan kecepatan termasuk AI GPU; batch besar; banyak pengguna | 6-8 core | 8 GB | NVIDIA 8 GB+ VRAM (12 GB nyaman) | ~35 GB | **Arsitektur: hanya 64-bit** (`linux/amd64` atau `linux/arm64`). SnapOtter berjalan secara native di server Intel/AMD, Mac Apple Silicon, dan board ARM 64-bit termasuk **Raspberry Pi 4 dan 5** (4-8 GB). SnapOtter **tidak** berjalan di ARM 32-bit (`armv7`/`armhf`), tidak ada image yang dibuat untuknya, maupun di board kelas 512 MB seperti Pi Zero, yang berada di bawah batas bawah memori (lihat di bawah). ### Minimum (perkakas gambar, file, dan PDF ringan; tanpa AI) {#minimum-image-files-and-light-pdf-tools-no-ai} | Sumber Daya | Persyaratan | |---|---| | CPU | 2 core | | RAM | 2 GB | | Disk | ~5.5 GB (image) + volume data | | GPU | Tidak diperlukan | Semua 222 perkakas katalog non-AI, yaitu gambar (resize, crop, convert, compress, adjust, watermark), video (trim, mute, remux), audio (convert, normalize, trim), PDF (merge, split, compress, rotate, protect), konversi file, dan preset konversi khusus, berjalan pada perangkat keras sederhana. Sebagian besar operasi selesai jauh di bawah satu detik bahkan pada file besar: gambar 2.7 MB diubah ukurannya dalam ~0.05 d dan dikodekan ulang ke WebP dalam ~2 d. Batas bawah memori itu nyata, dari penyapuan batas sumber daya Docker: **512 MB tidak dapat memulai stack** (bahkan satu resize gambar pun dihentikan), **1 GB** menangani operasi satu file tetapi batch multi-file kehabisan memori, dan **2 GB / 2 core** adalah konfigurasi terkecil yang menangani batch dengan nyaman. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **Satu-satunya pengecualian yang berat CPU adalah pengkodean ulang video.** Operasi stream-copy (trim, mute, remux kontainer) instan, tetapi transcoding ke codec berbeda bergantung pada CPU. Klip 1080p / 45 detik yang dikodekan ulang ke VP9 (WebM) memakan waktu kira-kira **~40 d** pada CPU modern yang cepat, ~45 d di Apple Silicon, ~80 d pada 4-core mobile lama, dan **~130 d** pada server 4-core lama. Jika beban kerja Anda banyak video, prioritaskan core CPU dan kecepatan clock, atau naikkan batas `cpus:` kontainer. Compose yang disertakan membatasi aplikasi pada 4 core secara default (8 pada compose GPU). ### Direkomendasikan (perkakas AI di CPU) {#recommended-ai-tools-on-cpu} | Sumber Daya | Persyaratan | |---|---| | CPU | 4 core | | RAM | 4 GB | | Disk | 3 GB (gambar) + sekitar 20 GB (semua paket AI opsional) + ruang kerja | | GPU | Tidak diperlukan (fallback CPU) | **Menginstal dan menjalankan paket AI yang lebih besar mendorong rekomendasi RAM menjadi 4 GB.** Tanpa paket opsional yang diinstal, aplikasi menganggur sekitar 360 MB. Alat Python yang lama berbagi sidecar, sedangkan OCR yang akurat menggunakan dispatcher khusus yang berumur panjang yang disematkan pada generasi aktif yang tidak dapat diubah. Sebelum aktivasi, penginstal menjalankan smoke test pada kandidat. Kemudian secara atom beralih ke dispatcher baru dan menguras dispatcher sebelumnya sebelum garbage collection. Setiap artefak OCR akurat resmi harus melewati release suite kasus terburuknya di dalam 4 GiB cgroup, sedangkan rekomendasi host 4 GB memberikan ruang utama untuk aplikasi Node.js, Postgres, Redis, antrean, dan pekerjaan bersamaan. Sebagian besar perkakas AI sepenuhnya dapat digunakan di CPU; beberapa benar-benar menginginkan GPU. Diukur pada CPU 4-core modern: | Perkakas AI | Waktu CPU | Dapat digunakan di CPU? | |---|---|---| | Deteksi wajah (blur-faces, smart-crop, red-eye), noise-removal | di bawah 1 d | Ya | | OCR, transkripsi, subtitle | 1-3 d | Ya | | Colorize, penyempurnaan wajah | ~10 d | Ya | | Penghapusan / penggantian / blur latar belakang | ~29 d | Ya (Anda akan menunggu) | | AI upscale (RealESRGAN) | ~33 d kecil; menit pada gambar besar | Marginal, GPU sangat direkomendasikan | | Restorasi foto (pipeline penuh) | beberapa menit | Tidak, butuh GPU atau CPU banyak-core yang cepat | SnapOtter sengaja tidak memasukkan unduhan model ini ke dalam image Docker. Bundle AI ditarik hanya ketika admin mengaktifkan perkakas terkait, disimpan di volume `/data/ai` yang persisten, dan dibagi oleh setiap perkakas yang bergantung pada stack model yang sama. Ini menjaga image kontainer akhir tetap kecil sekaligus tetap memungkinkan instalasi AI penuh mencapai angka penyimpanan yang lebih besar di bawah. Beberapa perkakas bergantung pada lebih dari satu bundle bersama. Misalnya, Passport Photo membutuhkan `background-removal` dan `face-detection`; jika `background-removal` sudah terpasang, mengaktifkan Passport Photo hanya mengunduh bundle `face-detection` yang hilang. Penggunaan ulang yang sama berlaku di semua perkakas AI. Perkiraan penyimpanan paket AI opsional: | Bundle | Ukuran Disk | |---|---| | Penghapusan latar belakang | 4-5 GB | | Upscale + Penyempurnaan wajah + Penghapusan noise | 5-6 GB | | Deteksi wajah | 200-300 MB | | Object eraser + Colorize | 1-2 GB | | OCR yang akurat (`balanced`/`best`) | ~208-234 unduhan MiB / ~409-488 MiB terpasang | | Restorasi foto | 4-5 GB | | Transkripsi | ~600 MB | | **Semua paket** | **~20 GB terpasang** | OCR yang cepat dimasukkan ke dalam gambar melalui Tesseract, menambahkan sekitar 25 MiB, dan tidak memerlukan paket OCR opsional atau persyaratan memori 4 GiB. Paket akurat tersedia dalam wadah resmi Linux amd64 dan arm64 dan menjalankan ONNX Runtime di CPU. Host NVIDIA menggunakan runtime CPU OCR yang sama, sehingga OCR tidak bergantung pada versi CUDA atau arsitektur GPU. Runtime yang akurat memerlukan setidaknya 4 GiB memori efektif: batas cgroup kontainer yang dikonfigurasi, jika tidak, memori host. SnapOtter menolak sistem di bawah minimum kompatibilitas yang ditandatangani sebelum mengunduh paket. Instalasi paket akurat juga ditolak pada arsip bare-metal/prebuilt yang libc dan Python ABI tidak dapat dijamin. Replika yang berbagi `DATA_DIR` yang sama harus menggunakan arsitektur CPU yang sama; sematkan deployment multi-replika ke node yang kompatibel dengan node affinity. Replika campuran amd64/arm64 memerlukan volume data terpisah dan deployment SnapOtter yang independen. Runtime yang akurat menjaga satu generasi tetap aktif dan membersihkan cache unduhannya setelah aktivasi. Untuk rilis ini, instalasi pertama untuk sementara memerlukan sekitar 620-720 MiB untuk arsip ditambah staging, dan peningkatan dapat mencapai puncaknya mendekati 1,2 GiB sementara generasi lama tetap aktif. Penginstal menghitung persyaratan yang tepat dari indeks yang ditandatangani dan generasi saat ini sebelum mengunduh atau mengekstraksi, dan gagal lebih awal jika volume data terlalu kecil. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Penuh (perkakas AI di NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | Sumber Daya | Persyaratan | |---|---| | CPU | 6-8 core (persiapan video + konkurensi berjalan di CPU bahkan dengan AI GPU) | | RAM | 8 GB | | GPU | NVIDIA dengan 8+ GB VRAM (12 GB direkomendasikan) | | Disk | ~35 GB total | GPU NVIDIA (CUDA) secara dramatis mempercepat model AI yang berat. Diukur pada RTX 4070 vs CPU modern: | Perkakas AI | Peningkatan kecepatan dengan GPU | Catatan | |---|---|---| | AI upscale (RealESRGAN 2×) | **~47×** | Kemenangan terbesar, di bawah satu detik vs ~33 d (menit pada gambar besar) | | Penyempurnaan wajah (CodeFormer) | **~12×** | ~0.9 d vs ~11 d | | Transkripsi (Whisper) | ~4.5× | | | Penghapusan / penggantian / blur latar belakang | ~4× | ~7 d di GPU vs ~29 d di CPU | | Colorize | ~1.8× | | | OCR, deteksi wajah, red-eye, noise-removal | ~1× | Sudah cepat di CPU, GPU tidak membantu | | Restorasi foto | tidak ada | Bergantung CPU bahkan di GPU (0% utilisasi GPU); CPU cepat lebih penting daripada GPU di sini | Perkakas yang layak menggunakan GPU adalah **upscale, penyempurnaan wajah, transkripsi, dan penghapusan latar belakang**. Deteksi wajah, OCR, dan red-eye bergantung CPU dan sudah cepat, jadi GPU tidak menambah apa pun. Penggunaan VRAM puncak mencapai 7.5 GB selama upscale dengan penyempurnaan wajah. GPU NVIDIA 6 GB bekerja untuk sebagian besar perkakas AI secara individual tetapi akan gagal pada upscale. VRAM 8-12 GB menangani semuanya. Akselerasi iGPU Intel/AMD melalui VA-API, Quick Sync, atau OpenCL saat ini tidak didukung untuk inferensi AI. Memetakan `/dev/dri` ke dalam kontainer tidak mengaktifkan akselerasi AI GPU; SnapOtter akan menjalankan perkakas AI di CPU kecuali NVIDIA CUDA tersedia. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Pengguna Bersamaan {#concurrent-users} Permintaan resize gambar paralel terhadap kontainer aplikasi yang dibatasi 4-core secara default: | Permintaan Bersamaan | Rata-rata Waktu Respons | Kesalahan | |---|---|---| | 1 | 0.4d | 0 | | 5 | 1.2d | 0 | | 10 | 2.1d | 0 | Waktu respons menurun secara sub-linear tanpa kesalahan saat pool worker menjadi jenuh. Menaikkan batas `cpus:` kontainer aplikasi (atau menggunakan host dengan lebih banyak core) mengangkat batas atas. Perhatikan bahwa job berat (transcode video, AI CPU) menahan satu worker selama durasi penuhnya, jadi ukur CPU sesuai jumlah job berat bersamaan yang Anda harapkan, bukan hanya jumlah permintaan. ### Format Gambar yang Didukung {#supported-image-formats} SnapOtter mendukung **55+ format input** dan **14 format output**, termasuk file RAW dari 20+ merek kamera, format profesional (PSD, EPS, OpenEXR, HDR), codec modern (JPEG XL, AVIF, HEIC, QOI), dan format ilmiah/gaming (FITS, DDS). Lihat [daftar format lengkap](/id/guide/supported-formats) untuk detail setiap format yang didukung, decoder yang digunakan, dan kontrol kualitas yang tersedia. ### Batasan yang Diketahui {#known-limitations} * **Content-aware resize** crash pada gambar besar (>5 MP) karena batasan pada binary caire. Bekerja baik dengan gambar yang lebih kecil. * **HEIF decode** memakan 13-23 detik. HEIC (varian Apple) jauh lebih cepat pada 0.3-0.9 detik. * **Upscale** kehabisan waktu di CPU untuk apa pun di luar gambar kecil. GPU diperlukan untuk penggunaan praktis. * **CodeFormer** penyempurnaan wajah jauh lebih lambat daripada GFPGAN (53d vs 2d di GPU). GFPGAN direkomendasikan untuk sebagian besar kasus penggunaan. ## Volume {#volumes} | Mount / Volume | Tujuan | Diperlukan? | |---|---|---| | `/data` (app) | Model AI, venv Python, file pengguna | **Ya**, kehilangan file tanpanya | | `/tmp/workspace` (app) | File pemrosesan sementara (dibersihkan otomatis) | Direkomendasikan | | `SnapOtter-pgdata` (postgres) | Direktori data PostgreSQL (pengguna, pengaturan, pipeline, job) | **Ya**, kehilangan data tanpanya | | `SnapOtter-redisdata` (redis) | File append-only Redis untuk antrean job yang durable | Direkomendasikan | ### Bind mount vs. named volume {#bind-mounts-vs-named-volumes} **Named volume** (direkomendasikan), Docker mengelola izin secara otomatis: ```yaml volumes: - SnapOtter-data:/data ``` **Bind mount**, Anda mengelola izin. Atur `PUID`/`PGID` agar cocok dengan pengguna host Anda: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Izin penyimpanan {#storage-permissions} SnapOtter menulis ke dua lokasi saat runtime: `/data` (file pengguna, log, model AI dan venv Python) dan `/tmp/workspace` (scratch pemrosesan sementara). Keduanya harus dapat ditulis oleh pengguna tempat kontainer berjalan. Jika salah satunya tidak, kontainer **gagal cepat saat startup** dengan pesan yang menyebutkan direktori, UID/GID yang berjalan, dan cara memperbaikinya, alih-alih boot "healthy" lalu gagal pada unggahan pertama dengan kesalahan samar. Bagaimana izin ditangani bergantung pada cara kontainer diluncurkan: **Default (mulai sebagai root, turun ke `snapotter`)**, entrypoint mulai sebagai root, memperbaiki kepemilikan volume yang di-mount, lalu turun ke pengguna `snapotter` yang tidak berhak istimewa melalui `gosu`. Named volume bekerja tanpa konfigurasi. Untuk bind mount, atur `PUID`/`PGID` ke pengguna host Anda (di atas) agar file yang ditulisnya dimiliki oleh Anda. **Kubernetes / OpenShift (non-root melalui `runAsUser`)**, diluncurkan langsung sebagai pengguna non-root, kontainer tidak dapat chown volume sendiri, jadi orkestrator harus membuatnya dapat ditulis. Atur `fsGroup`: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` Direktori yang dapat ditulis pada image dimiliki oleh grup GID 0 dan dapat ditulis grup, sehingga pod yang berjalan dengan **UID sembarang** ditambah grup suplementer root (default OpenShift) dapat menulis tanpa `chown`. **TrueNAS Scale (dan penyiapan "UID asing" lainnya)**, TrueNAS menjalankan aplikasi sebagai pengguna non-root (sering `568:568`) dan me-mount dataset host yang dimiliki oleh pengguna berbeda, sehingga baik entrypoint maupun `fsGroup` tidak membuatnya dapat ditulis dengan sendirinya. Pilih salah satu: * **Jalankan aplikasi sebagai root** (direkomendasikan), biarkan pengguna aplikasi tidak diatur atau atur ke `0`, dan biarkan entrypoint default memperbaiki izin dan turun ke `snapotter`. * **Jalankan sebagai UID `999`**, atur pengguna/grup aplikasi ke `999:999` (pengguna `snapotter` bawaan SnapOtter) agar cocok dengan kepemilikan image. * **`chown` dataset host** ke UID tempat kontainer berjalan, dari shell TrueNAS: ```bash # Gunakan UID dari kesalahan startup (atau jalankan `id` di dalam kontainer) chown -R 568:568 /mnt// ``` Kesalahan startup menyebutkan UID persis yang harus digunakan, jadi jalur tercepat adalah memulai aplikasi sekali, membaca pesannya, lalu `chown` (atau menyesuaikan pengguna) sesuai kebutuhan. ## Variabel Lingkungan {#environment-variables} | Variabel | Default | Deskripsi | |---|---|---| | `AUTH_ENABLED` | `true` | Aktifkan/nonaktifkan persyaratan login | | `DEFAULT_USERNAME` | `admin` | Username admin awal | | `DEFAULT_PASSWORD` | `admin` | Kata sandi admin awal (dipaksa ganti saat login pertama) | | `MAX_UPLOAD_SIZE_MB` | `0` (tak terbatas) | Batas unggahan per file dalam MB. Image dikirim dengan `0`; build dari kode sumber mulai dari 100 | | `MAX_BATCH_SIZE` | `0` (tak terbatas) | Maksimum file per permintaan batch. Image dikirim dengan `0`; build dari kode sumber mulai dari 100 | | `RATE_LIMIT_PER_MIN` | `1000` | Permintaan API per menit per IP (atur 0 untuk menonaktifkan) | | `MAX_USERS` | `0` (tak terbatas) | Maksimum akun pengguna | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Peer mana yang boleh menetapkan IP klien lewat `X-Forwarded-For`. Hanya jaringan privat secara default | | `PUID` | `999` | Jalankan sebagai UID ini (untuk izin bind mount) | | `PGID` | `999` | Jalankan sebagai GID ini (untuk izin bind mount) | | `LOG_LEVEL` | `info` | Verbositas log: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (otomatis) | Maksimum job pemrosesan AI paralel | | `SESSION_DURATION_HOURS` | `168` | Masa berlaku sesi login (7 hari) | | `CORS_ORIGIN` | (kosong) | Origin yang diizinkan dipisahkan koma, atau kosong untuk same-origin | ### Proksi keluar dan CA {#outbound-proxy-and-private-ca} pribadi Kontainer resmi mengaktifkan dukungan proxy lingkungan Node. Jika SnapOtter harus mencapai repositori runtime OCR atau layanan HTTPS lainnya melalui proksi perusahaan, atur `HTTPS_PROXY` (dan `HTTP_PROXY` bila diperlukan). Setel `NO_PROXY` ke daftar host yang dipisahkan koma yang harus dijangkau secara langsung, seperti Postgres, Redis, dan penyimpanan objek internal. Jika proksi atau layanan internal ditandatangani oleh otoritas sertifikat swasta, pasang sertifikat CA hanya-baca dan arahkan `NODE_EXTRA_CA_CERTS` ke sana. File tersebut harus ada ketika proses Node dimulai: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Simpan kredensial proxy di luar file Compose (misalnya di file atau rahasia `.env` yang dilindungi). Jangan nonaktifkan verifikasi TLS: indeks OCR yang ditandatangani mengautentikasi metadata rilis, sementara validasi TLS normal masih melindungi transportasi dan setiap permintaan keluar lainnya. ## Health Check {#health-check} Kontainer menyertakan health check bawaan: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Reverse Proxy {#reverse-proxy} `TRUST_PROXY` secara default bernilai `loopback,linklocal,uniquelocal`, jadi SnapOtter hanya memercayai `X-Forwarded-For` dari peer di jaringan privat. Reverse proxy di host yang sama, di jaringan Docker, atau di LAN Anda langsung dipercaya, sehingga pembatasan laju, pembatas brute force pada login, log audit, dan daftar IP yang diizinkan di edisi enterprise semuanya melihat IP klien yang sebenarnya tanpa konfigurasi apa pun. Setel `TRUST_PROXY=true` hanya jika proxy di depan menjangkau SnapOtter dari alamat **publik**, misalnya load balancer cloud di jaringan lain. Pada instance yang terekspos langsung, nilai itu membuat `request.ip` dikendalikan penyerang, karena pemanggil yang terus mengganti header mendapat penghitung batas laju baru di setiap permintaan. Ada dua hal yang perlu diketahui sebelum Anda mulai mengukur IP klien. Docker Desktop di macOS dan Windows menyajikan port yang dipublikasikan lewat proxy di ruang pengguna yang menulis ulang setiap alamat sumber menjadi gateway VM `192.168.65.1`, jadi di sana tidak ada nilai `TRUST_PROXY` yang bisa mengembalikan klien aslinya; terapkan di Linux untuk apa pun yang menghadap internet. Dan di platform mana pun, mencapai port yang dipublikasikan lewat `localhost` terlihat sebagai gateway bridge, bukan sebagai klien Anda, sehingga uji coba lewat localhost tidak memberi tahu apa pun tentang cara klien sungguhan diatribusikan. Tabel lengkap nilai `TRUST_PROXY` dan catatan tentang Docker Desktop ada di [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy). Ada dua hal yang penting untuk setiap proxy di bawah ini: izinkan badan permintaan yang besar (unggahan), dan jangan melakukan buffering terhadap tanggapan. Proksi buffering respons menghentikan kemajuan SSE dan, yang lebih terlihat, membuat pengunduhan file besar "mulai tetapi tidak pernah selesai", karena proksi menyimpan seluruh file sebelum meneruskannya. SnapOtter mengirimkan `X-Accel-Buffering: no` pada unduhan sehingga nginx mengalirkannya meskipun buffering dibiarkan di tempat lain, namun proxy selain nginx memerlukan buffering respons yang dinonaktifkan secara eksplisit (ditunjukkan pada setiap konfigurasi di bawah). Jika pengunduhan terhenti di tengah jalan, proxy buffering di depan adalah hal pertama yang harus diperiksa. ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Respons streaming alih-alih buffering: diperlukan untuk kemajuan SSE (batch, AI, pemasangan fitur) dan untuk download file besar. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Tambahkan Proxy Host baru 2. Atur Domain Name ke domain Anda 3. Atur Scheme ke `http`, Forward Hostname ke `SnapOtter` (atau IP kontainer Anda), Forward Port ke `1349` 4. Aktifkan dukungan WebSocket 5. Di bawah Advanced, tambahkan: `client_max_body_size 500M;` dan `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` menonaktifkan buffering respons, yang diperlukan untuk peristiwa kemajuan SSE (pemrosesan batch, alat AI, pemasangan fitur) dan untuk pengunduhan file besar agar dapat dilakukan streaming alih-alih terhenti. Batas waktu yang diperpanjang memungkinkan pengunggahan file besar selesai tanpa Caddy menutup koneksi lebih awal. ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Catatan: Cloudflare memiliki batas unggahan 100 MB pada paket gratis. Atur `MAX_UPLOAD_SIZE_MB=100` agar cocok. ## CI/CD {#ci-cd} Repositori GitHub memiliki tiga workflow: * **ci.yml**, Berjalan otomatis pada setiap push dan PR. Melakukan lint, typecheck, test, build, dan memvalidasi image Docker (tanpa push). * **release.yml**, Dipicu secara manual melalui `workflow_dispatch`. Menjalankan semantic-release untuk membuat tag versi dan rilis GitHub, lalu membangun image Docker multi-arch (amd64 + arm64) dan mendorong ke Docker Hub (`snapotter/snapotter`) dan GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`). * **deploy-docs.yml**, Membangun situs dokumentasi ini dan menerapkannya ke Cloudflare Pages saat push ke `main`. Untuk membuat rilis, buka **Actions > Release > Run workflow** di UI GitHub, atau jalankan: ```bash gh workflow run release.yml ``` Semantic-release menentukan versi dari riwayat commit. Tag Docker `latest` selalu menunjuk ke rilis terbaru. ## Analitik {#analytics} SnapOtter menyertakan analitik produk anonim (pola penggunaan perkakas, laporan kesalahan) untuk membantu menangkap bug dan meningkatkan fitur. Ini aktif secara default. File Anda, nama file, dan data pribadi tidak pernah menjadi bagian dari ini. SnapOtter bekerja normal dengan analitik dinonaktifkan. ### Menonaktifkan analitik {#disabling-analytics} Opt-out runtime adalah toggle admin satu klik. Buka Settings > System > Privacy dan matikan Anonymous Product Analytics. Analitik berhenti segera untuk seluruh instance, tanpa rebuild diperlukan. Untuk image yang tidak akan pernah memancarkan analitik, atur hard-off build-time dengan mengkloning repositori dan membangun ulang: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` Atau tambahkan build arg ke `docker-compose.yml` Anda yang sudah ada: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/th/guide/deployment.md description: >- ปรับใช้ SnapOtter สู่โปรดักชันด้วย Docker ความต้องการฮาร์ดแวร์ การตั้งค่า GPU และคอนฟิก reverse proxy สำหรับ Nginx, Traefik และ Cloudflare --- # Deployment {#deployment} SnapOtter ปรับใช้เป็นสแตก Docker Compose แบบ 3 คอนเทนเนอร์: อิมเมจแอป SnapOtter, PostgreSQL 17 และ Redis 8 อิมเมจแอปรองรับ **linux/amd64** (พร้อม NVIDIA CUDA สำหรับการเร่งความเร็ว AI) และ **linux/arm64** (CPU) จึงทำงานได้แบบเนทีฟบนเซิร์ฟเวอร์ Intel/AMD, Mac ที่ใช้ Apple Silicon และอุปกรณ์ ARM อย่าง Raspberry Pi 4/5 ปัจจุบันยังไม่รองรับการเร่งความเร็วด้วย iGPU ของ Intel/AMD ผ่าน VA-API, Quick Sync หรือ OpenCL สำหรับการอนุมาน AI ดู [Docker Image](./docker-tags) สำหรับการตั้งค่า GPU ตัวอย่าง Docker Compose และการปักหมุดเวอร์ชัน ::: info ความเข้ากันได้ของ OCR ภาษาเกาหลี OCR แบบเร็วรองรับ `auto`, `en`, `de`, `es`, `fr`, `zh` และ `ja` แต่ไม่รองรับภาษาเกาหลี (`ko`) ภาษาเกาหลีต้องใช้แพ็ก OCR แบบแม่นยำและ `balanced` หรือ `best` แพ็กทำงานบนคอนเทนเนอร์ Linux amd64 และ arm64 อย่างเป็นทางการ รวมถึงโฮสต์ NVIDIA ซึ่ง OCR ยังคงทำงานบน CPU ระบบที่ไม่รองรับจะส่งคืนข้อผิดพลาดความเข้ากันได้อย่างชัดเจนและไม่ย้อนกลับไปใช้ `fast` โดยเงียบ ๆ ภาษาเกาหลีร่วมกับ `fast` หรือนามแฝงเดิม `tesseract` จะถูกปฏิเสธก่อนเข้าคิวด้วย `FEATURE_INCOMPATIBLE` และ `fast-korean-unsupported` ::: ## Quick Start (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` จากนั้นแอปจะพร้อมใช้งานที่ `http://localhost:1349` > **โดน Docker Hub จำกัดอัตราการดึงหรือเปล่า?** แทนที่ `snapotter/snapotter:latest` ด้วย `ghcr.io/snapotter-hq/snapotter:latest` เพื่อดึงจาก GitHub Container Registry แทน ทั้งสอง registry จะได้รับอิมเมจเดียวกันในทุกรีลีส ## Quick Start (NVIDIA CUDA) {#quick-start-nvidia-cuda} สำหรับการเร่งความเร็ว NVIDIA CUDA บนเครื่องมือ AI ที่รองรับ (การลบพื้นหลัง การลดขนาด การปรับปรุงใบหน้า): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # เปลี่ยนสิ่งนี้สำหรับการปรับใช้ที่ไม่ใช่ภายในเครื่อง POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### ตรวจสอบการเร่งความเร็ว GPU {#verify-gpu-acceleration} ตรวจสอบการตรวจจับ CUDA ในบันทึก: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` หากเครื่องมือ AI ทำงานบน CPU แม้ว่า `--gpus all` และ NVIDIA Container Toolkit ได้รับการตั้งค่าอย่างถูกต้อง ให้ติดตั้งบันเดิลที่ได้รับผลกระทบอีกครั้ง (เช่น การลบพื้นหลัง) จาก **การตั้งค่า → คุณสมบัติ AI** โปรแกรมติดตั้งจะกู้คืนโครงสร้าง GPU ของรันไทม์ ONNX ซึ่งโครงสร้างเฉพาะ CPU ที่ดึงเข้ามาโดยบันเดิลอื่น (เช่น การถอดเสียง) อาจเกิดเงาในสภาพแวดล้อม AI ที่ใช้ร่วมกัน หากการติดตั้งใหม่จาก UI ไม่สามารถกู้คืน GPU บนอิมเมจเก่าได้ โปรดดูการซ่อมแซมด้วยตนเองใน [ปัญหา #490](https://github.com/snapotter-hq/SnapOtter/issues/490) ## Hardware Requirements {#hardware-requirements} ตัวเลขเหล่านี้มาจากการทดสอบประสิทธิภาพบนระบบหลากหลาย ตั้งแต่เวิร์กสเตชัน amd64 รุ่นใหม่ที่มี NVIDIA RTX 4070 ไปจนถึง Raspberry Pi โดยรันแคตตาล็อกเครื่องมือทั้งชุดบนแต่ละเครื่อง และกวาดค่าขีดจำกัดทรัพยากรของ Docker เพื่อหาขีดต่ำสุดที่แท้จริง หากใช้งานที่ปลายเล็กสุดของระดับเหล่านี้ (Pi แล็ปท็อปเครื่องเก่า หรือ VPS ขนาด 2 GB) หน้า [Low-Resource Setups](/th/guide/low-resource) จะเปลี่ยนตัวเลขเหล่านี้ให้เป็นคู่มือทีละขั้นที่เป็นรูปธรรม พร้อมขีดจำกัดที่ปรับจูนมาแล้ว ### Quick Reference {#quick-reference} | ระดับ | กรณีใช้งาน | CPU | RAM | GPU | พื้นที่เก็บข้อมูล | |------|----------|-----|-----|-----|---------| | ขั้นต่ำ | เครื่องมือรูปภาพ ไฟล์ และ PDF แบบเบา; ผู้ใช้คนเดียว; ชุดงานเล็ก | 2 คอร์ | 2 GB | ไม่มี | ~7 GB | | แนะนำ | ครบทั้งห้าโมดัลลิตี รวมถึงวิดีโอ, PDF และ AI บน CPU; ชุดงาน; ผู้ใช้ไม่กี่คน | 4 คอร์ | 4 GB | ไม่มี | ~25 GB | | เต็มรูปแบบ | ทุกอย่างแบบเร็ว รวมถึง GPU AI; ชุดงานขนาดใหญ่; ผู้ใช้จำนวนมาก | 6-8 คอร์ | 8 GB | NVIDIA VRAM 8 GB ขึ้นไป (12 GB จะสบายกว่า) | ~35 GB | **สถาปัตยกรรม: 64 บิตเท่านั้น** (`linux/amd64` หรือ `linux/arm64`) SnapOtter ทำงานแบบเนทีฟบนเซิร์ฟเวอร์ Intel/AMD, Mac ที่ใช้ Apple Silicon และบอร์ด ARM แบบ 64 บิต รวมถึง **Raspberry Pi 4 และ 5** (4-8 GB) มัน **ไม่** ทำงานบน ARM แบบ 32 บิต (`armv7`/`armhf`) เพราะไม่มีการสร้างอิมเมจสำหรับสถาปัตยกรรมนั้น และไม่ทำงานบนบอร์ดระดับ 512 MB อย่าง Pi Zero ซึ่งอยู่ต่ำกว่าขีดต่ำสุดของหน่วยความจำ (ดูด้านล่าง) ### Minimum (เครื่องมือรูปภาพ ไฟล์ และ PDF แบบเบา; ไม่มี AI) {#minimum-image-files-and-light-pdf-tools-no-ai} | ทรัพยากร | ความต้องการ | |---|---| | CPU | 2 คอร์ | | RAM | 2 GB | | ดิสก์ | ~5.5 GB (อิมเมจ) + วอลุ่มข้อมูล | | GPU | ไม่จำเป็น | เครื่องมือในแคตตาล็อกที่ไม่ใช่ AI ทั้ง 222 รายการ ได้แก่ รูปภาพ (ปรับขนาด, ครอป, แปลง, บีบอัด, ปรับแต่ง, ลายน้ำ), วิดีโอ (ตัด, ปิดเสียง, remux), เสียง (แปลง, นอร์มัลไลซ์, ตัด), PDF (รวม, แยก, บีบอัด, หมุน, ป้องกัน), การแปลงไฟล์ และพรีเซ็ตการแปลงเฉพาะทาง ล้วนทำงานได้บนฮาร์ดแวร์ธรรมดา การดำเนินการส่วนใหญ่เสร็จภายในเวลาต่ำกว่าหนึ่งวินาทีมากแม้กับไฟล์ขนาดใหญ่: รูปภาพขนาด 2.7 MB ปรับขนาดในเวลา ~0.05 วินาที และเข้ารหัสใหม่เป็น WebP ใน ~2 วินาที ขีดต่ำสุดของหน่วยความจำเป็นเรื่องจริง จากการกวาดค่าขีดจำกัดทรัพยากรของ Docker: **512 MB ไม่สามารถเริ่มสแตกได้** (แม้แต่การปรับขนาดรูปภาพไฟล์เดียวก็ถูกฆ่า), **1 GB** จัดการการดำเนินการไฟล์เดียวได้ แต่ชุดงานหลายไฟล์จะหน่วยความจำหมด และ **2 GB / 2 คอร์** คือคอนฟิกที่เล็กที่สุดซึ่งจัดการชุดงานได้อย่างสบาย ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **ข้อยกเว้นเดียวที่กิน CPU หนักคือการเข้ารหัสวิดีโอใหม่** การดำเนินการแบบ stream-copy (ตัด, ปิดเสียง, remux คอนเทนเนอร์) เกิดขึ้นทันที แต่การทรานส์โค้ดไปยัง codec อื่นถูกจำกัดด้วย CPU คลิป 1080p ยาว 45 วินาทีที่เข้ารหัสใหม่เป็น VP9 (WebM) ใช้เวลาราว **~40 วินาที** บน CPU รุ่นใหม่ที่เร็ว, ~45 วินาทีบน Apple Silicon, ~80 วินาทีบน mobile 4 คอร์รุ่นเก่า และ **~130 วินาที** บนเซิร์ฟเวอร์ 4 คอร์รุ่นเก่า หากงานของคุณเน้นวิดีโอ ให้เน้นจำนวนคอร์ CPU และความเร็วสัญญาณนาฬิกา หรือเพิ่มขีดจำกัด `cpus:` ของคอนเทนเนอร์ โดยค่าเริ่มต้น compose ที่ให้มาจำกัดแอปไว้ที่ 4 คอร์ (8 คอร์บน compose ของ GPU) ### Recommended (เครื่องมือ AI บน CPU) {#recommended-ai-tools-on-cpu} | ทรัพยากร | ความต้องการ | |---|---| | CPU | 4 คอร์ | | RAM | 4 GB | | Disk | 3 GB (รูปภาพ) + ประมาณ 20 GB (แพ็ก AI เสริมทั้งหมด) + พื้นที่ทำงาน | | GPU | ไม่จำเป็น (สำรองด้วย CPU) | **การติดตั้งและใช้งานชุด AI ที่ใหญ่ขึ้นคือสิ่งที่ผลักดันคำแนะนำไปที่ RAM ขนาด 4 GB** เมื่อไม่มีชุดเสริมติดตั้ง แอปจะมีพื้นที่ว่างประมาณ 360 MB เครื่องมือ Python รุ่นเก่าใช้ sidecar ร่วมกัน ในขณะที่ OCR ที่แม่นยำใช้ dispatcher ที่มีอายุการใช้งานยาวนานโดยเฉพาะซึ่งปักหมุดไว้กับรุ่นที่ไม่เปลี่ยนรูปแบบที่ใช้งานอยู่ ก่อนการเปิดใช้งาน ตัวติดตั้งจะรัน smoke test บนตัวเลือก จากนั้นจะสลับไปที่ dispatcher ใหม่แบบอะตอมมิก และระบาย dispatcher ก่อนหน้าก่อน garbage collection อาร์ติแฟกต์ OCR ที่แม่นยำอย่างเป็นทางการทุกรายการจะต้องผ่าน release suite ที่แย่ที่สุดภายใน 4 GiB cgroup ในขณะที่คำแนะนำโฮสต์ 4 GB จะเหลือพื้นที่ว่างสำหรับแอปพลิเคชัน Node.js, Postgres, Redis, คิว และงานที่เกิดขึ้นพร้อมกัน เครื่องมือ AI ส่วนใหญ่ใช้งานได้ดีบน CPU; มีบางตัวที่ต้องการ GPU จริงๆ วัดผลบน CPU 4 คอร์รุ่นใหม่: | เครื่องมือ AI | เวลาบน CPU | ใช้งานบน CPU ได้ไหม? | |---|---|---| | การตรวจจับใบหน้า (เบลอใบหน้า, ครอปอัจฉริยะ, ตาแดง), การลบสัญญาณรบกวน | ต่ำกว่า 1 วินาที | ได้ | | OCR, การถอดเสียง, คำบรรยาย | 1-3 วินาที | ได้ | | ลงสี, ปรับปรุงใบหน้า | ~10 วินาที | ได้ | | การลบ / แทนที่ / เบลอพื้นหลัง | ~29 วินาที | ได้ (ต้องรอ) | | การขยายภาพ AI (RealESRGAN) | ~33 วินาทีสำหรับภาพเล็ก; หลายนาทีสำหรับภาพใหญ่ | ก้ำกึ่ง แนะนำให้ใช้ GPU อย่างยิ่ง | | การฟื้นฟูภาพถ่าย (ไปป์ไลน์เต็มรูปแบบ) | หลายนาที | ไม่ได้ ต้องการ GPU หรือ CPU หลายคอร์ที่เร็ว | SnapOtter จงใจไม่อบการดาวน์โหลดโมเดลเหล่านี้ลงในอิมเมจ Docker บันเดิล AI จะถูกดึงเมื่อผู้ดูแลระบบเปิดใช้เครื่องมือที่เกี่ยวข้องเท่านั้น เก็บไว้ในวอลุ่มถาวร `/data/ai` และแชร์ร่วมกันโดยทุกเครื่องมือที่พึ่งพาชุดโมเดลเดียวกัน วิธีนี้ทำให้อิมเมจคอนเทนเนอร์สุดท้ายมีขนาดเล็ก ในขณะที่ยังปล่อยให้การติดตั้ง AI เต็มรูปแบบไปถึงตัวเลขพื้นที่เก็บข้อมูลที่ใหญ่ขึ้นด้านล่าง บางเครื่องมือพึ่งพาบันเดิลที่แชร์กันมากกว่าหนึ่งชุด ตัวอย่างเช่น Passport Photo ต้องการทั้ง `background-removal` และ `face-detection`; หากติดตั้ง `background-removal` ไว้แล้ว การเปิดใช้ Passport Photo จะดาวน์โหลดเฉพาะบันเดิล `face-detection` ที่ขาดไปเท่านั้น การนำกลับมาใช้ซ้ำแบบเดียวกันนี้ใช้กับเครื่องมือ AI ทั้งหมด การประมาณการพื้นที่จัดเก็บแพ็ค AI เพิ่มเติม: | บันเดิล | ขนาดดิสก์ | |---|---| | การลบพื้นหลัง | 4-5 GB | | การขยายภาพ + ปรับปรุงใบหน้า + ลบสัญญาณรบกวน | 5-6 GB | | การตรวจจับใบหน้า | 200-300 MB | | ลบวัตถุ + ลงสี | 1-2 GB | | OCR ที่แม่นยำ (`balanced`/`best`) | ~208-234 ดาวน์โหลด MiB / ~409-488 ติดตั้ง MiB แล้ว | | การฟื้นฟูภาพถ่าย | 4-5 GB | | การถอดเสียง | ~600เมกะไบต์ | | **ทุกชุด** | **ติดตั้งแล้ว ~20 GB** | Fast OCR ถูกสร้างไว้ในอิมเมจผ่าน Tesseract เพิ่มประมาณ 25 MiB และไม่ต้องใช้แพ็กเสริม OCR หรือข้อกำหนดหน่วยความจำ GiB 4 ตัว แพ็กที่ถูกต้องมีอยู่ในคอนเทนเนอร์ Linux amd64 และ arm64 อย่างเป็นทางการ และเรียกใช้ ONNX Runtime บน CPU โฮสต์ NVIDIA ใช้รันไทม์ CPU OCR เดียวกัน ดังนั้น OCR จึงไม่ขึ้นอยู่กับเวอร์ชัน CUDA หรือสถาปัตยกรรม GPU รันไทม์ที่ถูกต้องต้องใช้หน่วยความจำที่มีประสิทธิภาพอย่างน้อย 4 GiB: ขีดจำกัดคอนเทนเนอร์ cgroup ที่กำหนดค่าไว้ ไม่เช่นนั้นหน่วยความจำโฮสต์ SnapOtter ปฏิเสธระบบที่ต่ำกว่าซึ่งลงนามความเข้ากันได้ขั้นต่ำก่อนที่จะดาวน์โหลดแพ็ก การติดตั้งแพ็กที่แม่นยำยังถูกปฏิเสธในไฟล์เก็บถาวร bare-metal/ที่สร้างไว้ล่วงหน้าซึ่งไม่สามารถรับประกัน libc และ Python ABI ได้ รีพลิกาที่ใช้ `DATA_DIR` ร่วมกันต้องใช้สถาปัตยกรรม CPU เดียวกัน โดยตรึงการปรับใช้แบบหลายรีพลิกาไว้กับโหนดที่เข้ากันได้ด้วย node affinity รีพลิกา amd64/arm64 แบบผสมต้องใช้โวลุ่มข้อมูลแยกกันและการปรับใช้ SnapOtter ที่เป็นอิสระต่อกัน รันไทม์ที่แม่นยำจะคงรุ่นที่ใช้งานอยู่หนึ่งรุ่นและล้างแคชการดาวน์โหลดหลังจากเปิดใช้งาน สำหรับรีลีสนี้ การติดตั้งครั้งแรกต้องใช้ประมาณ 620-720 MiB ชั่วคราวสำหรับไฟล์เก็บถาวรและการจัดเตรียม และการอัปเกรดอาจถึงจุดสูงสุดเกือบ 1.2 GiB ในขณะที่รุ่นเก่ายังคงใช้งานอยู่ โปรแกรมติดตั้งจะคำนวณข้อกำหนดที่แน่นอนจากดัชนีที่ลงนามและรุ่นปัจจุบันก่อนที่จะดาวน์โหลดหรือแยกข้อมูล และจะล้มเหลวก่อนหากปริมาณข้อมูลน้อยเกินไป ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Full (เครื่องมือ AI บน NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | ทรัพยากร | ความต้องการ | |---|---| | CPU | 6-8 คอร์ (การเตรียมวิดีโอ + การทำงานพร้อมกันรันบน CPU แม้จะใช้ GPU AI) | | RAM | 8 GB | | GPU | NVIDIA ที่มี VRAM 8 GB ขึ้นไป (แนะนำ 12 GB) | | ดิสก์ | ~35 GB รวม | GPU ของ NVIDIA (CUDA) เร่งความเร็วโมเดล AI ที่หนักได้อย่างมาก วัดผลบน RTX 4070 เทียบกับ CPU รุ่นใหม่: | เครื่องมือ AI | ความเร็วที่เพิ่มขึ้นด้วย GPU | หมายเหตุ | |---|---|---| | การขยายภาพ AI (RealESRGAN 2×) | **~47×** | ชัยชนะที่ใหญ่ที่สุด ต่ำกว่าหนึ่งวินาที เทียบกับ ~33 วินาที (หลายนาทีสำหรับภาพใหญ่) | | การปรับปรุงใบหน้า (CodeFormer) | **~12×** | ~0.9 วินาที เทียบกับ ~11 วินาที | | การถอดเสียง (Whisper) | ~4.5× | | | การลบ / แทนที่ / เบลอพื้นหลัง | ~4× | ~7 วินาทีบน GPU เทียบกับ ~29 วินาทีบน CPU | | ลงสี | ~1.8× | | | OCR, การตรวจจับใบหน้า, ตาแดง, การลบสัญญาณรบกวน | ~1× | เร็วอยู่แล้วบน CPU GPU ไม่ช่วย | | การฟื้นฟูภาพถ่าย | ไม่มี | ถูกจำกัดด้วย CPU แม้บน GPU (ใช้ GPU 0%); CPU ที่เร็วสำคัญกว่า GPU ในกรณีนี้ | เครื่องมือที่คุ้มค่ากับ GPU คือ **การขยายภาพ, การปรับปรุงใบหน้า, การถอดเสียง และการลบพื้นหลัง** การตรวจจับใบหน้า, OCR และตาแดงถูกจำกัดด้วย CPU และเร็วอยู่แล้ว ดังนั้น GPU จึงไม่เพิ่มอะไร การใช้ VRAM สูงสุดพุ่งถึง 7.5 GB ระหว่างการขยายภาพพร้อมการปรับปรุงใบหน้า GPU ของ NVIDIA ขนาด 6 GB ใช้ได้กับเครื่องมือ AI ส่วนใหญ่ทีละตัว แต่จะล้มเหลวกับการขยายภาพ VRAM 8-12 GB จัดการได้ทุกอย่าง ปัจจุบันยังไม่รองรับการเร่งความเร็วด้วย iGPU ของ Intel/AMD ผ่าน VA-API, Quick Sync หรือ OpenCL สำหรับการอนุมาน AI การแมป `/dev/dri` เข้าไปในคอนเทนเนอร์ไม่ได้เปิดใช้การเร่งความเร็ว AI ด้วย GPU; SnapOtter จะรันเครื่องมือ AI บน CPU เว้นแต่จะมี NVIDIA CUDA ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Concurrent Users {#concurrent-users} คำขอปรับขนาดรูปภาพแบบขนานที่ยิงไปยังคอนเทนเนอร์แอปซึ่งจำกัดไว้ที่ 4 คอร์โดยค่าเริ่มต้น: | คำขอพร้อมกัน | เวลาตอบสนองเฉลี่ย | ข้อผิดพลาด | |---|---|---| | 1 | 0.4 วินาที | 0 | | 5 | 1.2 วินาที | 0 | | 10 | 2.1 วินาที | 0 | เวลาตอบสนองลดลงแบบต่ำกว่าเชิงเส้นโดยไม่มีข้อผิดพลาดเมื่อ worker pool เต็ม การเพิ่มขีดจำกัด `cpus:` ของคอนเทนเนอร์แอป (หรือใช้โฮสต์ที่มีคอร์มากกว่า) จะยกเพดานขึ้น โปรดทราบว่างานหนัก (การทรานส์โค้ดวิดีโอ, CPU AI) จะยึด worker ไว้ตลอดระยะเวลาทั้งหมด ดังนั้นให้กำหนดขนาด CPU ตามจำนวนงานหนักที่คาดว่าจะทำพร้อมกัน ไม่ใช่แค่จำนวนคำขอ ### Supported Image Formats {#supported-image-formats} SnapOtter รองรับ **รูปแบบอินพุต 55+ รูปแบบ** และ **รูปแบบเอาต์พุต 14 รูปแบบ** รวมถึงไฟล์ RAW จากกล้อง 20+ แบรนด์ รูปแบบระดับมืออาชีพ (PSD, EPS, OpenEXR, HDR), codec สมัยใหม่ (JPEG XL, AVIF, HEIC, QOI) และรูปแบบทางวิทยาศาสตร์/เกม (FITS, DDS) ดู [รายการรูปแบบทั้งหมด](/th/guide/supported-formats) สำหรับรายละเอียดของทุกรูปแบบที่รองรับ ตัวถอดรหัสที่ใช้ และตัวควบคุมคุณภาพที่มีให้ ### Known Limitations {#known-limitations} * **Content-aware resize** ล้มเหลวกับภาพขนาดใหญ่ (>5 MP) เนื่องจากข้อจำกัดในไบนารี caire ทำงานได้ดีกับภาพขนาดเล็กกว่า * **การถอดรหัส HEIF** ใช้เวลา 13-23 วินาที HEIC (รุ่นของ Apple) เร็วกว่ามากที่ 0.3-0.9 วินาที * **การขยายภาพ** หมดเวลาบน CPU สำหรับทุกอย่างที่เกินภาพขนาดเล็ก ต้องใช้ GPU สำหรับการใช้งานจริง * **CodeFormer** ปรับปรุงใบหน้าช้ากว่า GFPGAN อย่างมีนัยสำคัญ (53 วินาที เทียบกับ 2 วินาทีบน GPU) แนะนำ GFPGAN สำหรับกรณีใช้งานส่วนใหญ่ ## Volumes {#volumes} | เมานต์ / วอลุ่ม | วัตถุประสงค์ | จำเป็นไหม? | |---|---|---| | `/data` (แอป) | โมเดล AI, Python venv, ไฟล์ผู้ใช้ | **ใช่** ไฟล์จะสูญหายหากไม่มี | | `/tmp/workspace` (แอป) | ไฟล์ประมวลผลชั่วคราว (ทำความสะอาดอัตโนมัติ) | แนะนำ | | `SnapOtter-pgdata` (postgres) | ไดเรกทอรีข้อมูล PostgreSQL (ผู้ใช้, การตั้งค่า, ไปป์ไลน์, งาน) | **ใช่** ข้อมูลจะสูญหายหากไม่มี | | `SnapOtter-redisdata` (redis) | ไฟล์ append-only ของ Redis สำหรับคิวงานแบบทนทาน | แนะนำ | ### Bind mounts vs. named volumes {#bind-mounts-vs-named-volumes} **Named volumes** (แนะนำ) Docker จัดการสิทธิ์ให้โดยอัตโนมัติ: ```yaml volumes: - SnapOtter-data:/data ``` **Bind mounts** คุณจัดการสิทธิ์เอง ตั้งค่า `PUID`/`PGID` ให้ตรงกับผู้ใช้บนโฮสต์ของคุณ: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Storage permissions {#storage-permissions} SnapOtter เขียนลงสองตำแหน่งขณะรันไทม์: `/data` (ไฟล์ผู้ใช้, ล็อก, โมเดล AI และ Python venv) และ `/tmp/workspace` (พื้นที่ประมวลผลชั่วคราว) ทั้งสองตำแหน่งต้องเขียนได้โดยผู้ใช้ที่คอนเทนเนอร์รันอยู่ หากตำแหน่งใดเขียนไม่ได้ คอนเทนเนอร์จะ **ล้มเหลวทันทีตอนเริ่มทำงาน** พร้อมข้อความที่ระบุชื่อไดเรกทอรี, UID/GID ที่กำลังรัน และวิธีแก้ไข แทนที่จะบูตแบบ "สุขภาพดี" แล้วล้มเหลวตอนอัปโหลดครั้งแรกด้วยข้อผิดพลาดที่เข้าใจยาก วิธีจัดการสิทธิ์ขึ้นอยู่กับวิธีที่คอนเทนเนอร์ถูกเปิดใช้: **ค่าเริ่มต้น (เริ่มเป็น root แล้วลดสิทธิ์เป็น `snapotter`)** entrypoint เริ่มเป็น root แก้ไขความเป็นเจ้าของของวอลุ่มที่เมานต์ไว้ จากนั้นลดสิทธิ์เป็นผู้ใช้ `snapotter` ที่ไม่มีสิทธิ์พิเศษผ่าน `gosu` Named volumes ทำงานได้โดยไม่ต้องตั้งค่าใด สำหรับ bind mounts ให้ตั้งค่า `PUID`/`PGID` เป็นผู้ใช้บนโฮสต์ของคุณ (ด้านบน) เพื่อให้ไฟล์ที่มันเขียนเป็นของคุณ **Kubernetes / OpenShift (non-root ผ่าน `runAsUser`)** เมื่อเปิดใช้เป็นผู้ใช้ที่ไม่ใช่ root โดยตรง คอนเทนเนอร์ไม่สามารถ chown วอลุ่มได้เอง ดังนั้น orchestrator ต้องทำให้มันเขียนได้ ตั้งค่า `fsGroup`: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` ไดเรกทอรีที่เขียนได้ของอิมเมจเป็นของกลุ่ม GID 0 และกลุ่มสามารถเขียนได้ ดังนั้น pod ที่รันด้วย **UID ใดก็ได้** พร้อมกลุ่มเสริม root (ค่าเริ่มต้นของ OpenShift) สามารถเขียนได้โดยไม่ต้อง `chown` **TrueNAS Scale (และการตั้งค่า "UID ต่างถิ่น" อื่นๆ)** TrueNAS รันแอปเป็นผู้ใช้ที่ไม่ใช่ root (มักเป็น `568:568`) และเมานต์ dataset ของโฮสต์ที่เป็นของผู้ใช้อื่น ดังนั้นทั้ง entrypoint และ `fsGroup` ต่างก็ไม่ทำให้มันเขียนได้ด้วยตัวเอง เลือกอย่างใดอย่างหนึ่ง: * **รันแอปเป็น root** (แนะนำ) ปล่อยให้ผู้ใช้ของแอปไม่ได้ตั้งค่า หรือตั้งเป็น `0` แล้วให้ entrypoint ค่าเริ่มต้นแก้ไขสิทธิ์และลดสิทธิ์เป็น `snapotter` * **รันเป็น UID `999`** ตั้งค่าผู้ใช้/กลุ่มของแอปเป็น `999:999` (ผู้ใช้ `snapotter` ในตัวของ SnapOtter) เพื่อให้ตรงกับความเป็นเจ้าของของอิมเมจ * **`chown` dataset ของโฮสต์** เป็น UID ที่คอนเทนเนอร์รันอยู่ จากเชลล์ของ TrueNAS: ```bash # ใช้ UID จากข้อผิดพลาดตอนเริ่มทำงาน (หรือรัน `id` ในคอนเทนเนอร์) chown -R 568:568 /mnt// ``` ข้อผิดพลาดตอนเริ่มทำงานจะระบุ UID ที่แน่นอนให้ใช้ ดังนั้นเส้นทางที่เร็วที่สุดคือเริ่มแอปหนึ่งครั้ง อ่านข้อความ แล้ว `chown` (หรือปรับผู้ใช้) ตามนั้น ## Environment Variables {#environment-variables} | ตัวแปร | ค่าเริ่มต้น | คำอธิบาย | |---|---|---| | `AUTH_ENABLED` | `true` | เปิด/ปิดข้อกำหนดการล็อกอิน | | `DEFAULT_USERNAME` | `admin` | ชื่อผู้ใช้แอดมินเริ่มต้น | | `DEFAULT_PASSWORD` | `admin` | รหัสผ่านแอดมินเริ่มต้น (บังคับเปลี่ยนตอนล็อกอินครั้งแรก) | | `MAX_UPLOAD_SIZE_MB` | `0` (ไม่จำกัด) | ขีดจำกัดการอัปโหลดต่อไฟล์เป็น MB อิมเมจมาพร้อมค่า `0` ส่วนการบิลด์จากซอร์สเริ่มที่ 100 | | `MAX_BATCH_SIZE` | `0` (ไม่จำกัด) | จำนวนไฟล์สูงสุดต่อคำขอชุด อิมเมจมาพร้อมค่า `0` ส่วนการบิลด์จากซอร์สเริ่มที่ 100 | | `RATE_LIMIT_PER_MIN` | `1000` | คำขอ API ต่อนาทีต่อ IP (ตั้ง 0 เพื่อปิด) | | `MAX_USERS` | `0` (ไม่จำกัด) | จำนวนบัญชีผู้ใช้สูงสุด | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | เพียร์ใดบ้างที่ตั้งค่า IP ของไคลเอนต์ผ่าน `X-Forwarded-For` ได้ ค่าเริ่มต้นคือเฉพาะเครือข่ายส่วนตัวเท่านั้น | | `PUID` | `999` | รันเป็น UID นี้ (สำหรับสิทธิ์ bind mount) | | `PGID` | `999` | รันเป็น GID นี้ (สำหรับสิทธิ์ bind mount) | | `LOG_LEVEL` | `info` | ระดับความละเอียดของล็อก: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (อัตโนมัติ) | จำนวนงานประมวลผล AI แบบขนานสูงสุด | | `SESSION_DURATION_HOURS` | `168` | อายุของเซสชันการล็อกอิน (7 วัน) | | `CORS_ORIGIN` | (ว่าง) | origin ที่อนุญาตคั่นด้วยคอมมา หรือปล่อยว่างสำหรับ same-origin | ### พร็อกซีขาออกและ CA ส่วนตัว {#outbound-proxy-and-private-ca} คอนเทนเนอร์อย่างเป็นทางการเปิดใช้งานการสนับสนุนพร็อกซีสภาพแวดล้อมของโหนด หาก SnapOtter ต้องเข้าถึงพื้นที่เก็บข้อมูลรันไทม์ OCR หรือบริการ HTTPS อื่นๆ ผ่านพร็อกซีองค์กร ให้ตั้งค่า `HTTPS_PROXY` (และ `HTTP_PROXY` เมื่อจำเป็น) ตั้งค่า `NO_PROXY` เป็นรายการโฮสต์ที่คั่นด้วยเครื่องหมายจุลภาคที่ต้องเข้าถึงโดยตรง เช่น Postgres, Redis และที่เก็บข้อมูลอ็อบเจ็กต์ภายใน หากพร็อกซีหรือบริการภายในลงนามโดยผู้ออกใบรับรองส่วนตัว ให้ต่อเชื่อมใบรับรอง CA แบบอ่านอย่างเดียวแล้วชี้ `NODE_EXTRA_CA_CERTS` ไปที่ใบรับรองนั้น ไฟล์จะต้องมีอยู่เมื่อกระบวนการโหนดเริ่มต้น: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` เก็บข้อมูลรับรองพร็อกซีไว้นอกไฟล์ Compose (เช่น ในไฟล์ `.env` ที่ได้รับการป้องกันหรือเป็นความลับ) อย่าปิดใช้งานการตรวจสอบ TLS: ดัชนี OCR ที่ลงชื่อจะตรวจสอบความถูกต้องของข้อมูลเมตาที่เผยแพร่ ในขณะที่การตรวจสอบ TLS ปกติยังคงปกป้องการขนส่งและคำขอขาออกอื่นๆ ทั้งหมด ## Health Check {#health-check} คอนเทนเนอร์มี health check ในตัว: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Reverse Proxy {#reverse-proxy} `TRUST_PROXY` มีค่าเริ่มต้นเป็น `loopback,linklocal,uniquelocal` ดังนั้น SnapOtter จะเชื่อ `X-Forwarded-For` เฉพาะจากเพียร์ในเครือข่ายส่วนตัวเท่านั้น reverse proxy บนโฮสต์เดียวกัน บนเครือข่าย Docker หรือบน LAN ของคุณจึงได้รับความเชื่อถือตั้งแต่แรก นั่นหมายความว่าการจำกัดอัตรา ตัวจำกัดการเดารหัสผ่านตอนล็อกอิน บันทึกการตรวจสอบ และรายการ IP ที่อนุญาตในรุ่น enterprise ต่างเห็น IP จริงของไคลเอนต์โดยไม่ต้องตั้งค่าใด ๆ ตั้ง `TRUST_PROXY=true` เฉพาะเมื่อพร็อกซีที่อยู่ด้านหน้าเข้าถึง SnapOtter จากที่อยู่**สาธารณะ** เช่น โหลดบาลานเซอร์บนคลาวด์ที่อยู่คนละเครือข่าย บนอินสแตนซ์ที่เปิดออกสู่ภายนอกโดยตรง ค่านี้จะทำให้ `request.ip` ตกอยู่ในการควบคุมของผู้โจมตี เพราะผู้เรียกที่หมุนเปลี่ยนส่วนหัวไปเรื่อย ๆ จะได้ตัวนับขีดจำกัดอัตราใหม่ในทุกคำขอ มีสองเรื่องที่ควรรู้ก่อนจะลงมือวัด IP ของไคลเอนต์ Docker Desktop บน macOS และ Windows ให้บริการพอร์ตที่เผยแพร่ผ่านพร็อกซีในพื้นที่ผู้ใช้ ซึ่งเขียนที่อยู่ต้นทางทุกรายการใหม่เป็นเกตเวย์ของ VM `192.168.65.1` ที่นั่นจึงไม่มีค่า `TRUST_PROXY` ใดกู้ไคลเอนต์จริงกลับมาได้ ให้ติดตั้งบน Linux สำหรับทุกอย่างที่เปิดสู่อินเทอร์เน็ต และไม่ว่าจะแพลตฟอร์มใด การเข้าถึงพอร์ตที่เผยแพร่ผ่าน `localhost` จะถูกมองว่าเป็นเกตเวย์ของบริดจ์ ไม่ใช่ไคลเอนต์ของคุณ ดังนั้นการทดสอบผ่าน localhost จึงบอกอะไรไม่ได้เลยว่าไคลเอนต์จริงจะถูกระบุอย่างไร ตารางค่าทั้งหมดของ `TRUST_PROXY` และข้อควรระวังเรื่อง Docker Desktop อยู่ใน [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy) สองสิ่งที่สำคัญสำหรับทุกพร็อกซีด้านล่าง: อนุญาตเนื้อหาคำขอขนาดใหญ่ (อัปโหลด) และไม่บัฟเฟอร์การตอบสนอง พร็อกซีบัฟเฟอร์การตอบสนองจะทำลายความคืบหน้าของ SSE และทำให้การดาวน์โหลดไฟล์ขนาดใหญ่ "เริ่มต้นแต่ไม่สิ้นสุด" อย่างเห็นได้ชัด เนื่องจากพร็อกซีจะเก็บไฟล์ทั้งหมดก่อนที่จะส่งต่อ SnapOtter ส่ง `X-Accel-Buffering: no` ในการดาวน์โหลด ดังนั้น nginx สตรีมสิ่งเหล่านั้นแม้ว่าการบัฟเฟอร์จะถูกทิ้งไว้ที่อื่น แต่พรอกซีอื่นที่ไม่ใช่ nginx จำเป็นต้องปิดใช้งานการบัฟเฟอร์การตอบสนองอย่างชัดเจน (แสดงอยู่ในการกำหนดค่าแต่ละรายการด้านล่าง) หากการดาวน์โหลดค้างกลางคัน พร็อกซีการบัฟเฟอร์ที่อยู่ด้านหน้าคือสิ่งแรกที่ต้องตรวจสอบ ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # สตรีมการตอบสนองแทนการบัฟเฟอร์: จำเป็นสำหรับความคืบหน้าของ SSE (แบทช์, AI, การติดตั้งฟีเจอร์) และสำหรับการดาวน์โหลดไฟล์ขนาดใหญ่ proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. เพิ่ม Proxy Host ใหม่ 2. ตั้ง Domain Name เป็นโดเมนของคุณ 3. ตั้ง Scheme เป็น `http`, Forward Hostname เป็น `SnapOtter` (หรือ IP ของคอนเทนเนอร์), Forward Port เป็น `1349` 4. เปิดใช้การรองรับ WebSocket 5. ในส่วน Advanced ให้เพิ่ม: `client_max_body_size 500M;` และ `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` ปิดใช้งานการบัฟเฟอร์การตอบสนอง ซึ่งจำเป็นสำหรับเหตุการณ์ความคืบหน้าของ SSE (การประมวลผลเป็นชุด เครื่องมือ AI การติดตั้งคุณสมบัติ) และสำหรับการดาวน์โหลดไฟล์ขนาดใหญ่เพื่อสตรีมผ่านแทนที่จะหยุดชะงัก การหมดเวลาแบบขยายทำให้การอัพโหลดไฟล์ขนาดใหญ่เสร็จสิ้นโดยไม่ต้อง Caddy ปิดการเชื่อมต่อก่อนกำหนด ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` หมายเหตุ: Cloudflare มีขีดจำกัดการอัปโหลด 100 MB บนแผนฟรี ตั้งค่า `MAX_UPLOAD_SIZE_MB=100` ให้ตรงกัน ## CI/CD {#ci-cd} ที่เก็บ GitHub มีเวิร์กโฟลว์สามชุด: * **ci.yml** รันอัตโนมัติในทุก push และ PR ทำ lint, typecheck, ทดสอบ, build และตรวจสอบอิมเมจ Docker (โดยไม่ push) * **release.yml** ทริกเกอร์ด้วยตนเองผ่าน `workflow_dispatch` รัน semantic-release เพื่อสร้าง version tag และ GitHub release จากนั้นสร้างอิมเมจ Docker แบบหลายสถาปัตยกรรม (amd64 + arm64) และ push ไปยัง Docker Hub (`snapotter/snapotter`) และ GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`) * **deploy-docs.yml** สร้างไซต์เอกสารนี้และปรับใช้ไปยัง Cloudflare Pages เมื่อ push ไปยัง `main` หากต้องการสร้างรีลีส ให้ไปที่ **Actions > Release > Run workflow** ใน GitHub UI หรือรัน: ```bash gh workflow run release.yml ``` Semantic-release กำหนดเวอร์ชันจากประวัติคอมมิต แท็ก Docker `latest` ชี้ไปยังรีลีสล่าสุดเสมอ ## Analytics {#analytics} SnapOtter มีการวิเคราะห์ผลิตภัณฑ์แบบไม่ระบุตัวตน (รูปแบบการใช้เครื่องมือ, รายงานข้อผิดพลาด) เพื่อช่วยจับบั๊กและปรับปรุงฟีเจอร์ โดยเปิดใช้เป็นค่าเริ่มต้น ไฟล์ ชื่อไฟล์ และข้อมูลส่วนบุคคลของคุณไม่เคยเป็นส่วนหนึ่งของสิ่งนี้ SnapOtter ทำงานได้ตามปกติเมื่อปิดการวิเคราะห์ ### Disabling analytics {#disabling-analytics} การเลือกไม่เข้าร่วมขณะรันไทม์เป็นสวิตช์แอดมินแบบคลิกเดียว เปิด Settings > System > Privacy แล้วปิด Anonymous Product Analytics มันจะหยุดทันทีสำหรับทั้งอินสแตนซ์ โดยไม่ต้อง build ใหม่ สำหรับอิมเมจที่ไม่มีทางส่งการวิเคราะห์ได้เลย ให้ตั้งค่าการปิดแบบถาวรตอน build โดยโคลนที่เก็บและ build ใหม่: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` หรือเพิ่ม build arg ลงใน `docker-compose.yml` ที่มีอยู่ของคุณ: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/es/tools/pdf/unlock-pdf.md description: Elimina la protección con contraseña de un PDF. --- # Desbloquear PDF {#unlock-pdf} Elimina la protección con contraseña de un PDF cifrado proporcionando la contraseña correcta. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/unlock-pdf` Acepta datos de formulario multipart con un archivo PDF y un campo JSON `settings`. ## Parameters {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | password | string | Sí | - | Contraseña para descifrar el PDF (1-256 caracteres) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/unlock-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"password": "s3cret"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2500000, "processedSize": 2450000 } ``` ## Notes {#notes} * Se debe proporcionar la contraseña correcta; una contraseña incorrecta devuelve un error 400. * Tanto la contraseña de usuario como la de propietario funcionarán para el descifrado. * Las contraseñas se ocultan en los registros de auditoría. --- --- url: https://docs.snapotter.com/es/tools/image/blur-background.md description: Desenfoca el fondo manteniendo el sujeto nítido usando IA. --- # Desenfocar fondo {#blur-background} Desenfoca el fondo de una imagen manteniendo el sujeto nítido. El modelo de IA aísla el sujeto, aplica un desenfoque al fondo original y compone el sujeto nítido encima. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` Acepta datos de formulario multipart con un archivo de imagen y un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | intensity | integer | No | `50` | Intensidad del desenfoque (1-100) | | feather | integer | No | `0` | Radio de suavizado de bordes (0-20) | | format | string | No | `"png"` | Formato de salida: `png` o `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Sigue el progreso mediante SSE en `GET /api/v1/jobs/{jobId}/progress`. Cuando el trabajo se completa, el flujo SSE emite un evento `completed` con la URL de descarga. ## Notes {#notes} * Esta es una herramienta impulsada por IA que devuelve `202 Accepted` y procesa de forma asíncrona. Conéctate al endpoint SSE para recibir las actualizaciones de progreso y el resultado final. * Requiere que esté instalado el paquete de funciones **background-removal**. Devuelve `501` si el paquete no está disponible. * Los valores de intensidad más altos producen un efecto de desenfoque más fuerte. Los valores superiores a 80 crean una separación pronunciada de tipo bokeh. * Las entradas HEIC, RAW, PSD y SVG se decodifican automáticamente antes del procesamiento. --- --- url: https://docs.snapotter.com/es/tools/image/blur-faces.md description: >- Detecta y desenfoca caras automáticamente en imágenes con detección facial por IA para privacidad y anonimización conforme al RGPD. --- # Desenfocar rostros y datos sensibles {#face-pii-blur} Detecta y desenfoca caras automáticamente en imágenes usando detección facial impulsada por IA (MediaPipe). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Procesamiento:** Asíncrono (devuelve 202, consulta `/api/v1/jobs/{jobId}/progress` para conocer el estado mediante SSE) **Paquete de modelos:** `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | blurRadius | number | No | `30` | Radio de desenfoque aplicado a las caras detectadas (1-100) | | sensitivity | number | No | `0.5` | Sensibilidad de la detección facial (0-1). Los valores más bajos detectan menos caras con mayor confianza | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### No Faces Detected {#no-faces-detected} Si no se encuentran caras, el resultado incluye una advertencia: ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Notes {#notes} * Requiere que esté instalado el paquete de modelos `face-detection` (200-300 MB). * El formato de salida coincide automáticamente con el de entrada. * El array `faces` contiene las coordenadas del recuadro delimitador (x, y, width, height) de cada cara detectada. * Aumenta `sensitivity` (más cerca de 1.0) para detectar más caras, incluidas las parcialmente ocultas. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/blur-background.md description: Desfoque o fundo mantendo o objeto nítido usando IA. --- # Desfocar Fundo {#blur-background} Desfoque o fundo de uma imagem mantendo o objeto nítido. O modelo de IA isola o objeto, aplica um desfoque ao fundo original e compõe o objeto nítido por cima. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-background` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | intensity | integer | Não | `50` | Intensidade do desfoque (1-100) | | feather | integer | Não | `0` | Raio de suavização da borda (0-20) | | format | string | Não | `"png"` | Formato de saída: `png` ou `webp` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Acompanhe o progresso via SSE em `GET /api/v1/jobs/{jobId}/progress`. Quando o trabalho é concluído, o fluxo SSE emite um evento `completed` com a URL de download. ## Observações {#notes} * Esta é uma ferramenta baseada em IA que retorna `202 Accepted` e processa de forma assíncrona. Conecte-se ao endpoint SSE para receber atualizações de progresso e o resultado final. * Requer que o pacote de recurso **background-removal** esteja instalado. Retorna `501` se o pacote não estiver disponível. * Valores de intensidade mais altos produzem um efeito de desfoque mais forte. Valores acima de 80 criam uma separação pronunciada, semelhante a bokeh. * Entradas HEIC, RAW, PSD e SVG são decodificadas automaticamente antes do processamento. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/blur-faces.md description: >- Detecte e desfoque rostos em imagens automaticamente com detecção de rostos por IA para privacidade e anonimização em conformidade com o GDPR. --- # Desfocar Rostos e Dados Sensíveis {#face-pii-blur} Detecte e desfoque rostos em imagens automaticamente usando detecção de rostos por IA (MediaPipe). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Processamento:** Assíncrono (retorna 202, consulte `/api/v1/jobs/{jobId}/progress` para o status via SSE) **Pacote de modelo:** `face-detection` (200-300 MB) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | blurRadius | number | Não | `30` | Raio de desfoque aplicado aos rostos detectados (1-100) | | sensitivity | number | Não | `0.5` | Sensibilidade da detecção de rostos (0-1). Valores mais baixos detectam menos rostos com maior confiança | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Resposta {#response} ### Resposta Inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progresso (SSE em `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Resultado Final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### Nenhum Rosto Detectado {#no-faces-detected} Se nenhum rosto for encontrado, o resultado inclui um aviso: ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Observações {#notes} * Requer que o pacote de modelo `face-detection` esteja instalado (200-300 MB). * O formato de saída corresponde automaticamente ao formato de entrada. * O array `faces` contém as coordenadas da caixa delimitadora (x, y, largura, altura) para cada rosto detectado. * Aumente `sensitivity` (mais próximo de 1.0) para detectar mais rostos, incluindo os parcialmente ocultos. * Suporta os formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR por meio de decodificação automática. --- --- url: https://docs.snapotter.com/es/guide/deployment.md description: >- Despliega SnapOtter en producción con Docker. Requisitos de hardware, configuración de GPU y configuraciones de proxy inverso para Nginx, Traefik y Cloudflare. --- # Despliegue {#deployment} SnapOtter se despliega como una pila de Docker Compose de 3 contenedores: la imagen de la aplicación SnapOtter, PostgreSQL 17 y Redis 8. La imagen de la aplicación admite **linux/amd64** (con NVIDIA CUDA para aceleración de IA) y **linux/arm64** (CPU), así que se ejecuta de forma nativa en servidores Intel/AMD, Macs con Apple Silicon y dispositivos ARM como la Raspberry Pi 4/5. La aceleración por iGPU de Intel/AMD mediante VA-API, Quick Sync u OpenCL no es compatible con la inferencia de IA por ahora. Consulta [Imagen de Docker](./docker-tags) para la configuración de GPU, ejemplos de Docker Compose y fijación de versiones. ::: info Compatibilidad del OCR coreano OCR rápido admite `auto`, `en`, `de`, `es`, `fr`, `zh` y `ja`, pero no coreano (`ko`). El coreano requiere el paquete OCR preciso y `balanced` o `best`. El paquete funciona en los contenedores oficiales Linux amd64 y arm64, incluidos hosts NVIDIA, donde el OCR sigue usando la CPU. Los sistemas no compatibles reciben un error explícito y nunca vuelven silenciosamente a `fast`. Coreano con `fast` o el alias heredado `tesseract` se rechaza antes de encolarse con `FEATURE_INCOMPATIBLE` y `fast-korean-unsupported`. ::: ## Inicio rápido (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` La aplicación queda entonces disponible en `http://localhost:1349`. > **¿Límites de tasa de Docker Hub?** Reemplaza `snapotter/snapotter:latest` por `ghcr.io/snapotter-hq/snapotter:latest` para descargar desde GitHub Container Registry en su lugar. Ambos registros reciben la misma imagen en cada versión. ## Inicio rápido (NVIDIA CUDA) {#quick-start-nvidia-cuda} Para la aceleración de NVIDIA CUDA en herramientas de IA compatibles (eliminación de fondo, ampliación de escala, mejora de rostros): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Cambie esto para implementaciones no locales POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### Verificar la aceleración de la GPU {#verify-gpu-acceleration} Verifique la detección de CUDA en los registros: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` Si las herramientas de IA se ejecutan en la CPU aunque `--gpus all` y NVIDIA Container Toolkit estén configurados correctamente, reinstale el paquete afectado (por ejemplo, Eliminación de fondo) desde **Configuración → Funciones de IA**. El instalador restaura la compilación de GPU de ONNX Runtime, que de otro modo una compilación de solo CPU extraída por otro paquete (como la transcripción) puede ocultar en el entorno de IA compartido. Si la reinstalación desde la interfaz de usuario no restaura la GPU en una imagen anterior, consulte la reparación manual en \[problema n.° 490] (https://github.com/snapotter-hq/SnapOtter/issues/490). ## Requisitos de hardware {#hardware-requirements} Estos números provienen de pruebas de rendimiento en una variedad de sistemas, desde una estación de trabajo amd64 moderna con una NVIDIA RTX 4070 hasta una Raspberry Pi, ejecutando todo el catálogo de herramientas en cada uno y ajustando los límites de recursos de Docker para encontrar el mínimo real. ¿Estás en el extremo bajo de estos niveles (una Pi, un portátil viejo, un VPS de 2 GB)? [Configuraciones con recursos limitados](/es/guide/low-resource) convierte estos números en una guía paso a paso concreta con topes ajustados. ### Referencia rápida {#quick-reference} | Nivel | Caso de uso | CPU | RAM | GPU | Almacenamiento | |------|----------|-----|-----|-----|---------| | Mínimo | Herramientas de imagen, archivos y PDF ligeras; un solo usuario; lotes pequeños | 2 núcleos | 2 GB | Ninguna | ~7 GB | | Recomendado | Las cinco modalidades incl. vídeo, PDF e IA en CPU; lotes; algunos usuarios | 4 núcleos | 4 GB | Ninguna | ~25 GB | | Completo | Todo a velocidad incl. IA por GPU; lotes grandes; muchos usuarios | 6-8 núcleos | 8 GB | NVIDIA 8 GB+ VRAM (12 GB cómodo) | ~35 GB | **Arquitectura: solo 64 bits** (`linux/amd64` o `linux/arm64`). SnapOtter se ejecuta de forma nativa en servidores Intel/AMD, Macs con Apple Silicon y placas ARM de 64 bits, incluidas las **Raspberry Pi 4 y 5** (4-8 GB). **No** se ejecuta en ARM de 32 bits (`armv7`/`armhf`), no se compila ninguna imagen para ello, ni en placas de clase 512 MB como la Pi Zero, que quedan por debajo del mínimo de memoria (ver más abajo). ### Mínimo (herramientas de imagen, archivos y PDF ligeras; sin IA) {#minimum-image-files-and-light-pdf-tools-no-ai} | Recurso | Requisito | |---|---| | CPU | 2 núcleos | | RAM | 2 GB | | Disco | ~5,5 GB (imagen) + volumen de datos | | GPU | No requerida | Las 222 herramientas del catálogo sin IA (imagen: redimensionar, recortar, convertir, comprimir, ajustar, marca de agua; vídeo: recortar, silenciar, remultiplexar; audio: convertir, normalizar, recortar; PDF: combinar, dividir, comprimir, rotar, proteger; conversiones de archivos y ajustes de conversión predefinidos) se ejecutan en hardware modesto. La mayoría de las operaciones terminan en bastante menos de un segundo incluso con un archivo grande: una imagen de 2,7 MB se redimensiona en ~0,05 s y se recodifica a WebP en ~2 s. El mínimo de memoria es real, según un barrido de límites de recursos de Docker: **512 MB no pueden arrancar la pila** (incluso un solo redimensionamiento de imagen se cancela), **1 GB** maneja operaciones de un solo archivo pero un lote de varios archivos se queda sin memoria, y **2 GB / 2 núcleos** es la configuración más pequeña que maneja lotes con comodidad. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **La única excepción que exige mucha CPU es la recodificación de vídeo.** Las operaciones de copia de flujo (recortar, silenciar, remultiplexado de contenedor) son instantáneas, pero transcodificar a un códec diferente depende de la CPU. Un clip de 1080p / 45 segundos recodificado a VP9 (WebM) tarda aproximadamente **~40 s** en una CPU moderna rápida, ~45 s en Apple Silicon, ~80 s en un móvil de 4 núcleos más antiguo y **~130 s** en un servidor de 4 núcleos más antiguo. Si tu carga de trabajo es intensiva en vídeo, prioriza los núcleos de CPU y la frecuencia de reloj, o eleva el límite de `cpus:` del contenedor; el compose incluido limita la aplicación a 4 núcleos por defecto (8 en el compose de GPU). ### Recomendado (herramientas de IA en CPU) {#recommended-ai-tools-on-cpu} | Recurso | Requisito | |---|---| | CPU | 4 núcleos | | RAM | 4 GB | | Disk | 3 GB (imagen) + aproximadamente 20 GB (todos los paquetes AI opcionales) + espacio de trabajo | | GPU | No requerida (respaldo en CPU) | **La instalación y ejecución de los paquetes de IA más grandes es lo que eleva la recomendación a 4 GB de RAM.** Sin paquetes opcionales instalados, la aplicación ocupa alrededor de 360 ​​MB. Las herramientas Python heredadas comparten un sidecar, mientras que el OCR preciso utiliza un dispatcher dedicado de larga duración anclado a la generación activa inmutable. Antes de la activación, el instalador ejecuta un smoke test en el candidato. Luego cambia atómicamente al nuevo dispatcher y drena el dispatcher anterior antes de garbage collection. Cada artefacto oficial de OCR preciso debe pasar su release suite del peor de los casos dentro de un cgroup de 4 GiB, mientras que la recomendación de host de 4 GB deja espacio para la aplicación Node.js, Postgres, Redis, colas y trabajo simultáneo. La mayoría de las herramientas de IA son perfectamente utilizables en CPU; un par realmente quieren una GPU. Medido en una CPU moderna de 4 núcleos: | Herramienta de IA | Tiempo en CPU | ¿Utilizable en CPU? | |---|---|---| | Detección de rostros (difuminar rostros, recorte inteligente, ojos rojos), eliminación de ruido | menos de 1 s | Sí | | OCR, transcripción, subtítulos | 1-3 s | Sí | | Colorizar, mejora de rostros | ~10 s | Sí | | Eliminación / reemplazo / difuminado de fondo | ~29 s | Sí (tendrás que esperar) | | Escalado con IA (RealESRGAN) | ~33 s en pequeñas; minutos en imágenes grandes | Marginal, se recomienda encarecidamente GPU | | Restauración de fotos (canalización completa) | varios minutos | No, necesita una GPU o una CPU rápida de muchos núcleos | SnapOtter intencionadamente no integra estas descargas de modelos en la imagen de Docker. Los paquetes de IA se descargan solo cuando un administrador habilita la herramienta relacionada, se almacenan en el volumen persistente `/data/ai` y son compartidos por cada herramienta que depende de la misma pila de modelos. Esto mantiene pequeña la imagen final del contenedor y a la vez permite que una instalación completa de IA alcance las cifras de almacenamiento mayores que aparecen a continuación. Algunas herramientas dependen de más de un paquete compartido. Por ejemplo, Foto de Pasaporte necesita tanto `background-removal` como `face-detection`; si `background-removal` ya está instalado, habilitar Foto de Pasaporte solo descarga el paquete `face-detection` que falta. La misma reutilización se aplica a todas las herramientas de IA. Estimaciones de almacenamiento de paquetes de IA opcionales: | Paquete | Tamaño en disco | |---|---| | Eliminación de fondo | 4-5 GB | | Escalado + Mejora de rostros + Eliminación de ruido | 5-6 GB | | Detección de rostros | 200-300 MB | | Borrador de objetos + Colorizar | 1-2 GB | | Preciso OCR (`balanced`/`best`) | ~208-234 MiB descargar / ~409-488 MiB instalado | | Restauración de fotos | 4-5 GB | | Transcripción | ~600MB | | **Todos los paquetes** | **~20 GB instalados** | Fast OCR está integrado en la imagen a través de Tesseract, agrega alrededor de 25 MiB y no requiere el paquete OCR opcional ni sus 4 GiB de memoria. El paquete exacto está disponible en los contenedores oficiales Linux amd64 y arm64 y ejecuta ONNX Runtime en CPU. Los hosts NVIDIA utilizan el mismo tiempo de ejecución CPU OCR, por lo que OCR no depende de la versión de CUDA ni de la arquitectura de GPU. El tiempo de ejecución preciso requiere al menos 4 GiB de memoria efectiva: el límite cgroup del contenedor configurado; de lo contrario, la memoria del host. SnapOtter rechaza los sistemas por debajo del mínimo de compatibilidad firmado antes de descargar el paquete. La instalación precisa del paquete también se rechaza en bare-metal/archivos prediseñados cuyos libc y Python ABI no se pueden garantizar. Las réplicas que compartan el mismo `DATA_DIR` deben usar la misma arquitectura de CPU; fije los despliegues con varias réplicas a nodos compatibles mediante afinidad de nodos. Las réplicas mixtas amd64/arm64 necesitan volúmenes de datos separados y despliegues independientes de SnapOtter. El tiempo de ejecución preciso mantiene una generación activa y purga su caché de descarga después de la activación. Para esta versión, una primera instalación necesita temporalmente aproximadamente 620-720 MiB para el archivo más la preparación, y una actualización puede alcanzar un máximo cercano a 1.2 GiB mientras la generación anterior permanece activa. El instalador calcula el requisito exacto a partir del índice firmado y las generaciones actuales antes de descargarlo o extraerlo, y falla antes de tiempo si el volumen de datos es demasiado pequeño. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Completo (herramientas de IA en NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | Recurso | Requisito | |---|---| | CPU | 6-8 núcleos (la preparación de vídeo + concurrencia se ejecutan en CPU incluso con IA por GPU) | | RAM | 8 GB | | GPU | NVIDIA con 8+ GB VRAM (12 GB recomendado) | | Disco | ~35 GB en total | Una GPU NVIDIA (CUDA) acelera drásticamente los modelos de IA pesados. Medido en una RTX 4070 frente a una CPU moderna: | Herramienta de IA | Aceleración con GPU | Notas | |---|---|---| | Escalado con IA (RealESRGAN 2×) | **~47×** | La mayor ganancia, menos de un segundo frente a ~33 s (minutos en imágenes grandes) | | Mejora de rostros (CodeFormer) | **~12×** | ~0,9 s frente a ~11 s | | Transcripción (Whisper) | ~4,5× | | | Eliminación / reemplazo / difuminado de fondo | ~4× | ~7 s en GPU frente a ~29 s en CPU | | Colorizar | ~1,8× | | | OCR, detección de rostros, ojos rojos, eliminación de ruido | ~1× | Ya rápidas en CPU, una GPU no ayuda | | Restauración de fotos | ninguna | Dependiente de CPU incluso en una GPU (0 % de uso de GPU); aquí importa más una CPU rápida que una GPU | Las herramientas que merecen una GPU son **escalado, mejora de rostros, transcripción y eliminación de fondo**. La detección de rostros, el OCR y los ojos rojos dependen de la CPU y ya son rápidos, así que una GPU no aporta nada. El uso máximo de VRAM alcanza 7,5 GB durante el escalado con mejora de rostros. Una GPU NVIDIA de 6 GB funciona para la mayoría de las herramientas de IA de forma individual, pero fallará en el escalado. 8-12 GB de VRAM manejan todo. La aceleración por iGPU de Intel/AMD mediante VA-API, Quick Sync u OpenCL no es compatible con la inferencia de IA por ahora. Mapear `/dev/dri` en el contenedor no habilita la aceleración de IA por GPU; SnapOtter ejecutará las herramientas de IA en CPU a menos que NVIDIA CUDA esté disponible. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Usuarios concurrentes {#concurrent-users} Solicitudes de redimensionamiento de imagen en paralelo contra el contenedor de la aplicación limitado a 4 núcleos por defecto: | Solicitudes concurrentes | Tiempo de respuesta medio | Errores | |---|---|---| | 1 | 0,4 s | 0 | | 5 | 1,2 s | 0 | | 10 | 2,1 s | 0 | El tiempo de respuesta se degrada de forma sublineal sin errores a medida que se satura el grupo de trabajadores. Elevar el límite de `cpus:` del contenedor de la aplicación (o usar un host con más núcleos) sube el techo. Ten en cuenta que los trabajos pesados (transcodificación de vídeo, IA en CPU) retienen un trabajador durante toda su duración, así que dimensiona la CPU según tu número esperado de trabajos pesados concurrentes, no solo según el recuento de solicitudes. ### Formatos de imagen admitidos {#supported-image-formats} SnapOtter admite **55+ formatos de entrada** y **14 formatos de salida**, incluidos archivos RAW de más de 20 marcas de cámara, formatos profesionales (PSD, EPS, OpenEXR, HDR), códecs modernos (JPEG XL, AVIF, HEIC, QOI) y formatos científicos/de videojuegos (FITS, DDS). Consulta la [lista completa de formatos](/es/guide/supported-formats) para más detalles sobre cada formato admitido, el decodificador utilizado y los controles de calidad disponibles. ### Limitaciones conocidas {#known-limitations} * **El redimensionamiento con reconocimiento de contenido** se bloquea en imágenes grandes (>5 MP) debido a una limitación en el binario caire. Funciona bien con imágenes más pequeñas. * **La decodificación HEIF** tarda entre 13 y 23 segundos. HEIC (la variante de Apple) es mucho más rápida, entre 0,3 y 0,9 segundos. * **El escalado** agota el tiempo en CPU para cualquier cosa que no sean imágenes pequeñas. Se requiere GPU para un uso práctico. * **La mejora de rostros con CodeFormer** es considerablemente más lenta que GFPGAN (53 s frente a 2 s en GPU). Se recomienda GFPGAN para la mayoría de los casos de uso. ## Volúmenes {#volumes} | Montaje / Volumen | Propósito | ¿Requerido? | |---|---|---| | `/data` (app) | Modelos de IA, venv de Python, archivos de usuario | **Sí**, pérdida de archivos sin él | | `/tmp/workspace` (app) | Archivos temporales de procesamiento (limpiados automáticamente) | Recomendado | | `SnapOtter-pgdata` (postgres) | Directorio de datos de PostgreSQL (usuarios, ajustes, canalizaciones, trabajos) | **Sí**, pérdida de datos sin él | | `SnapOtter-redisdata` (redis) | Archivo de solo anexión de Redis para colas de trabajos duraderas | Recomendado | ### Montajes de enlace frente a volúmenes con nombre {#bind-mounts-vs-named-volumes} **Volúmenes con nombre** (recomendado): Docker gestiona los permisos automáticamente: ```yaml volumes: - SnapOtter-data:/data ``` **Montajes de enlace**: Tú gestionas los permisos. Configura `PUID`/`PGID` para que coincidan con tu usuario del host: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Permisos de almacenamiento {#storage-permissions} SnapOtter escribe en dos ubicaciones en tiempo de ejecución: `/data` (archivos de usuario, registros, modelos de IA y el venv de Python) y `/tmp/workspace` (espacio temporal de procesamiento). Ambas deben ser escribibles por el usuario con el que se ejecuta el contenedor. Si alguna no lo es, el contenedor **falla rápido en el arranque** con un mensaje que nombra el directorio, el UID/GID en ejecución y cómo solucionarlo, en lugar de arrancar "sano" y luego fallar en la primera subida con un error críptico. Cómo se gestionan los permisos depende de cómo se lance el contenedor: **Por defecto (arranca como root, cae a `snapotter`)**: el punto de entrada arranca como root, corrige la propiedad de los volúmenes montados y luego cae al usuario sin privilegios `snapotter` mediante `gosu`. Los volúmenes con nombre funcionan sin configuración. Para los montajes de enlace, configura `PUID`/`PGID` con tu usuario del host (arriba) para que los archivos que escribe sean de tu propiedad. **Kubernetes / OpenShift (sin root mediante `runAsUser`)**: lanzado directamente como un usuario sin root, el contenedor no puede hacer chown de los volúmenes por sí mismo, así que el orquestador debe hacerlos escribibles. Configura `fsGroup`: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` Los directorios escribibles de la imagen tienen como grupo propietario el GID 0 y son escribibles por el grupo, así que un pod que se ejecute con un **UID arbitrario** más el grupo suplementario root (el valor predeterminado de OpenShift) puede escribir sin `chown`. **TrueNAS Scale (y otras configuraciones de "UID ajeno")**: TrueNAS ejecuta las apps como un usuario sin root (a menudo `568:568`) y monta conjuntos de datos del host propiedad de un usuario diferente, así que ni el punto de entrada ni `fsGroup` los hacen escribibles por sí solos. Elige una opción: * **Ejecuta la app como root** (recomendado): deja el usuario de la app sin definir o configúralo como `0`, y deja que el punto de entrada por defecto corrija los permisos y caiga a `snapotter`. * **Ejecuta como UID `999`**: configura el usuario/grupo de la app como `999:999` (el usuario integrado `snapotter` de SnapOtter) para que coincida con la propiedad de la imagen. * **`chown` el conjunto de datos del host** al UID con el que se ejecuta el contenedor, desde el shell de TrueNAS: ```bash # Usa el UID del error de arranque (o ejecuta `id` dentro del contenedor) chown -R 568:568 /mnt// ``` El error de arranque nombra el UID exacto que hay que usar, así que la vía más rápida es arrancar la app una vez, leer el mensaje y luego `chown` (o ajustar el usuario) en consecuencia. ## Variables de entorno {#environment-variables} | Variable | Predeterminado | Descripción | |---|---|---| | `AUTH_ENABLED` | `true` | Habilita/deshabilita el requisito de inicio de sesión | | `DEFAULT_USERNAME` | `admin` | Nombre de usuario inicial del administrador | | `DEFAULT_PASSWORD` | `admin` | Contraseña inicial del administrador (cambio forzado en el primer inicio de sesión) | | `MAX_UPLOAD_SIZE_MB` | `0` (ilimitado) | Límite de subida por archivo en MB. La imagen viene con `0`; una compilación desde el código fuente arranca en 100 | | `MAX_BATCH_SIZE` | `0` (ilimitado) | Máximo de archivos por solicitud de lote. La imagen viene con `0`; una compilación desde el código fuente arranca en 100 | | `RATE_LIMIT_PER_MIN` | `1000` | Solicitudes de API por minuto por IP (configura 0 para deshabilitar) | | `MAX_USERS` | `0` (ilimitado) | Máximo de cuentas de usuario | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Qué pares pueden establecer la IP del cliente mediante `X-Forwarded-For`. Solo redes privadas de forma predeterminada | | `PUID` | `999` | Ejecutar como este UID (para permisos de montajes de enlace) | | `PGID` | `999` | Ejecutar como este GID (para permisos de montajes de enlace) | | `LOG_LEVEL` | `info` | Verbosidad del registro: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (auto) | Máximo de trabajos de procesamiento de IA en paralelo | | `SESSION_DURATION_HOURS` | `168` | Duración de la sesión de inicio de sesión (7 días) | | `CORS_ORIGIN` | (vacío) | Orígenes permitidos separados por comas, o vacío para el mismo origen | ### Proxy saliente y CA privada {#outbound-proxy-and-private-ca} El contenedor oficial habilita el soporte de proxy de entorno de Node. Si SnapOtter debe llegar al repositorio de tiempo de ejecución de OCR u otros servicios HTTPS a través de un proxy corporativo, configure `HTTPS_PROXY` (y `HTTP_PROXY` cuando sea necesario). Configure `NO_PROXY` en una lista de hosts separados por comas a los que se debe acceder directamente, como Postgres, Redis y almacenamiento de objetos internos. Si el proxy o un servicio interno está firmado por una autoridad de certificación privada, monte el certificado de CA de solo lectura y apunte `NODE_EXTRA_CA_CERTS` hacia él. El archivo debe existir cuando se inicia el proceso del Nodo: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Mantenga las credenciales del proxy fuera del archivo Compose (por ejemplo, en un archivo `.env` protegido o secreto). No deshabilite la verificación TLS: el índice OCR firmado autentica los metadatos de la versión, mientras que la validación TLS normal aún protege el transporte y cualquier otra solicitud saliente. ## Comprobación de estado {#health-check} El contenedor incluye una comprobación de estado integrada: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Proxy inverso {#reverse-proxy} `TRUST_PROXY` vale `loopback,linklocal,uniquelocal` de forma predeterminada, así que SnapOtter solo cree la cabecera `X-Forwarded-For` de un par que esté en una red privada. Un proxy inverso en el mismo host, en una red de Docker o en tu LAN es de confianza desde el primer momento, de modo que la limitación de tasa, el limitador de fuerza bruta del inicio de sesión, el registro de auditoría y la lista de IP permitidas de la edición enterprise ven la IP real del cliente sin configurar nada. Pon `TRUST_PROXY=true` solo cuando el proxy que tienes delante llegue a SnapOtter desde una dirección **pública**, por ejemplo un balanceador de carga en la nube situado en otra red. En una instancia expuesta directamente, ese valor deja `request.ip` en manos del atacante, porque quien va rotando la cabecera consigue un contador de límite de tasa nuevo en cada solicitud. Dos cosas conviene saber antes de ponerse a medir IP de cliente. Docker Desktop en macOS y Windows sirve un puerto publicado a través de un proxy en espacio de usuario que reescribe todas las direcciones de origen a la puerta de enlace de la VM `192.168.65.1`, así que ahí ningún valor de `TRUST_PROXY` recupera al cliente real; despliega en Linux cualquier cosa expuesta a internet. Y en cualquier plataforma, llegar a un puerto publicado por `localhost` se observa como la puerta de enlace del puente y no como tu cliente, de manera que una prueba en localhost no dice nada sobre cómo se atribuye un cliente real. La tabla completa de valores de `TRUST_PROXY` y la advertencia sobre Docker Desktop están en [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy). Dos cosas importan para cada proxy a continuación: permitir cuerpos de solicitud (cargas) de gran tamaño y no almacenar en búfer las respuestas. Un proxy de almacenamiento en búfer de respuesta interrumpe el progreso de SSE y, de manera más visible, hace que la descarga de un archivo grande "comience pero nunca termine", porque el proxy retiene el archivo completo antes de pasarlo. SnapOtter envía `X-Accel-Buffering: no` en las descargas para que nginx las transmita incluso si el almacenamiento en búfer se deja activado en otro lugar, pero los servidores proxy distintos de nginx necesitan que el búfer de respuesta esté deshabilitado explícitamente (se muestra en cada configuración a continuación). Si una descarga se detiene parcialmente, lo primero que debe verificar es un proxy de almacenamiento en búfer al frente. ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Transmita respuestas en lugar de almacenar en búfer: necesario para el progreso de SSE (lotes, IA, instalaciones de funciones) y para descargas de archivos grandes. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Añade un nuevo Proxy Host 2. Establece el Domain Name a tu dominio 3. Establece el Scheme a `http`, el Forward Hostname a `SnapOtter` (o la IP de tu contenedor), y el Forward Port a `1349` 4. Habilita el soporte de WebSocket 5. En Advanced, añade: `client_max_body_size 500M;` y `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` deshabilita el almacenamiento en búfer de respuesta, que es necesario para los eventos de progreso de SSE (procesamiento por lotes, herramientas de inteligencia artificial, instalaciones de funciones) y para que las descargas de archivos grandes se transmitan en lugar de detenerse. Los tiempos de espera extendidos permiten que se completen las cargas de archivos grandes sin que Caddy cierre la conexión antes de tiempo. ### Túneles de Cloudflare {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Nota: Cloudflare tiene un límite de subida de 100 MB en los planes gratuitos. Configura `MAX_UPLOAD_SIZE_MB=100` para que coincida. ## CI/CD {#ci-cd} El repositorio de GitHub tiene tres flujos de trabajo: * **ci.yml**: se ejecuta automáticamente en cada push y PR. Analiza el código, comprueba tipos, prueba, compila y valida la imagen de Docker (sin publicarla). * **release.yml**: se activa manualmente mediante `workflow_dispatch`. Ejecuta semantic-release para crear una etiqueta de versión y una versión de GitHub, luego compila una imagen de Docker multiarquitectura (amd64 + arm64) y la publica en Docker Hub (`snapotter/snapotter`) y GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`). * **deploy-docs.yml**: compila este sitio de documentación y lo despliega en Cloudflare Pages al hacer push a `main`. Para crear una versión, ve a **Actions > Release > Run workflow** en la interfaz de GitHub, o ejecuta: ```bash gh workflow run release.yml ``` Semantic-release determina la versión a partir del historial de commits. La etiqueta de Docker `latest` siempre apunta a la versión más reciente. ## Analítica {#analytics} SnapOtter incluye analítica de producto anónima (patrones de uso de herramientas, informes de errores) para ayudar a detectar fallos y mejorar funciones. Está activada por defecto. Tus archivos, nombres de archivo y datos personales nunca forman parte de esto. SnapOtter funciona con normalidad con la analítica deshabilitada. ### Deshabilitar la analítica {#disabling-analytics} La exclusión en tiempo de ejecución es un interruptor de administrador de un solo clic. Abre Ajustes > Sistema > Privacidad y desactiva Analítica Anónima de Producto. Se detiene de inmediato para toda la instancia, sin necesidad de recompilar. Para una imagen que nunca pueda emitir analítica, establece la desactivación total en tiempo de compilación clonando el repositorio y recompilando: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` O añade el argumento de compilación a tu `docker-compose.yml` existente: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/tr/guide/supported-formats.md description: >- Tüm modaliteler genelinde desteklenen dosya formatları - 55+ görüntü giriş formatı, video, ses, PDF ve dosya formatları. --- # Desteklenen Formatlar {#supported-formats} SnapOtter dosyaları beş modalitede işler: görüntü, video, ses, PDF ve dosyalar. Bu sayfa desteklenen tüm formatları listeler. ## Görüntü Formatları {#image-formats} SnapOtter giriş için 55+ görüntü formatını, çıkış için 17 formatı destekler. ## Giriş Formatları {#input-formats} ### Web Standartları (9) {#web-standards-9} | Format | Uzantılar | Çözücü | Notlar | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (yerel) | | | PNG | .png | Sharp (yerel) | APNG ilk kare çıkarılır | | WebP | .webp | Sharp (yerel) | | | GIF | .gif | Sharp (yerel) | Animasyonlu desteklenir | | AVIF | .avif | Sharp (yerel) | | | SVG | .svg | Sharp (librsvg) | XXE/SSRF için temizlenir | | SVGZ | .svgz | gunzip + Sharp | Gzip bomb koruması | | APNG | .apng | Sharp (yerel) | Yalnızca ilk kare | | JPEG XL | .jxl | djxl / ImageMagick | İki katmanlı geri dönüş | ### Profesyonel (7) {#professional-7} | Format | Uzantılar | Çözücü | Notlar | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (yerel) | Çok sayfalı desteklenir | | PSD | .psd | ImageMagick | Düzleştirilmiş kompozit | | EPS | .eps, .epsf | ImageMagick + Ghostscript | 300dpi rasterleştirme, güvenlik sağlamlaştırılmış | | OpenEXR | .exr | ImageMagick | Doğrusaldan sRGB'ye dönüşüm | | Radiance HDR | .hdr | ImageMagick | Doğrusaldan sRGB'ye dönüşüm | | DPX | .dpx | ImageMagick | Log'dan sRGB'ye dönüşüm | | Cineon | .cin | ImageMagick | Film/VFX formatı | ### Kamera RAW (23) {#camera-raw-23} | Format | Uzantılar | Kamera Markası | Çözücü | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (evrensel) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (2018 öncesi) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (eski) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (kompakt) | exiftool / ImageMagick + LibRaw | ### Modern Formatlar (3) {#modern-formats-3} | Format | Uzantılar | Çözücü | Notlar | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Dijital sinema, tıbbi görüntüleme | | QOI | .qoi | Satır içi TypeScript codec | Oyun geliştirme, gömülü sistemler | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | iPhone fotoğrafları | ### Eski/Sistem (4) {#legacy-system-4} | Format | Uzantılar | Çözücü | Notlar | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | En büyük katman çıkarılır | | CUR | .cur | ImageMagick | Windows imleci (ICO varyantı) | | TGA | .tga | ImageMagick | Yalnızca uzantı algılama | ### Bilimsel ve Oyun (2) {#scientific-and-gaming-2} | Format | Uzantılar | Çözücü | Notlar | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Astronomi (NASA standardı) | | DDS | .dds | ImageMagick | Oyun dokuları (DirectX) | ### Değiş Tokuş (6) {#interchange-6} | Format | Uzantılar | Çözücü | Notlar | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (yerel) | Renkli pixmap | | PGM | .pgm | Sharp (yerel) | Gri tonlamalı | | PBM | .pbm | Sharp (yerel) | 1-bit bitmap | | PNM | .pnm | Sharp (yerel) | Şemsiye format | | PAM | .pam | Sharp (yerel) | Keyfi map | | PFM | .pfm | Sharp (yerel) | Float map | ## Çıkış Formatları (17) {#output-formats-13} | Format | Kodlayıcı | Kalite Kontrolü | Kullanılabildiği Yer | |--------|---------|----------------|-------------| | JPEG | Sharp yerel | 1-100 | Tüm araçlar | | PNG | Sharp yerel | Sıkıştırma 0-9 | Tüm araçlar | | WebP | Sharp yerel | 1-100 | Tüm araçlar | | AVIF | Sharp yerel | 1-100 | Tüm araçlar | | TIFF | Sharp yerel | 1-100 | Tam dönüştürme araçları | | GIF | Sharp yerel | 1-100 | Tam dönüştürme araçları | | JXL | Sharp yerel | 1-100 | Tüm araçlar | | HEIC | heif-enc CLI | 1-100 | Tam dönüştürme araçları | | HEIF | heif-enc CLI | 1-100 | Tam dönüştürme araçları | | BMP | ImageMagick CLI | Kayıpsız | Dönüştürme aracı | | ICO | ImageMagick CLI | Kayıpsız | Dönüştürme aracı | | JP2 | opj\_compress CLI | Sıkıştırma oranı | Dönüştürme aracı | | QOI | Satır içi codec | Kayıpsız | Dönüştürme aracı | | PSD | ImageMagick CLI | Kayıpsız | Dönüştürme aracı | | PPM | ImageMagick CLI | Kayıpsız | Dönüştürme aracı | | EPS | ImageMagick CLI | Kayıpsız | Dönüştürme aracı | | TGA | ImageMagick CLI | Kayıpsız | Dönüştürme aracı | ## Video Formatları {#video-formats} Video çözme ve kodlama FFmpeg (statik derleme) tarafından yapılır, bu yüzden yaygın her container ve codec girişte desteklenir. ### Giriş Container'ları (15) {#input-containers-15} | Format | Uzantılar | Tipik codec'ler | Notlar | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | En yaygın kullanılan container | | QuickTime | .mov | H.264, ProRes | Apple yakalama/düzenleme | | WebM | .webm | VP8, VP9, AV1 | Telifsiz web formatı | | Matroska | .mkv | Herhangi | Esnek açık container | | AVI | .avi | Çeşitli | Eski Microsoft container | | M4V | .m4v | H.264 | Apple MP4 varyantı | | AVCHD | .mts | H.264 | Kamera kayıtları | | BDAV | .m2ts | H.264 | Blu-ray / AVCHD taşıma akışı | | 3GP | .3gp | H.264, MPEG-4 | Mobil yakalama | | Flash Video | .flv | H.264, VP6 | Eski akış | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | DVD dönemi video | | MPEG-TS | .ts | MPEG-2, H.264 | Yayın taşıma akışı | | Ogg | .ogv | Theora | Açık Ogg video | ### Çıkış Formatları {#output-formats} | Format | Uzantı | Video codec | Üreten | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Dönüştürme, sıkıştırma ve çoğu video aracı | | QuickTime | .mov | H.264 | Video Dönüştür | | WebM | .webm | VP9 | Video Dönüştür | | GIF | .gif | - | Video'dan GIF'e | | WebP | .webp | - | Video'dan WebP'ye (animasyonlu) | ### Altyazılar {#subtitles} | Format | Uzantı | İşlemler | |--------|-----------|-----------| | SubRip | .srt | Gömme, yakma, çıkarma, otomatik oluşturma | | WebVTT | .vtt | Gömme, yakma, çıkarma, otomatik oluşturma | | ASS / SSA | .ass | Gömme, yakma (stil desteği) | ## Ses Formatları {#audio-formats} Ses de FFmpeg tarafından işlenir. ### Giriş Formatları (11) {#input-formats-11} | Format | Uzantılar | Sıkıştırma | Notlar | |--------|-----------|-------------|-------| | MP3 | .mp3 | Kayıplı | Evrensel uyumluluk | | WAV | .wav | Sıkıştırılmamış (PCM) | Stüdyo / düzenleme | | FLAC | .flac | Kayıpsız | Açık kayıpsız codec | | AAC | .aac | Kayıplı | Ham AAC akışı | | M4A | .m4a | Kayıplı (AAC) / Kayıpsız (ALAC) | MPEG-4 ses | | Ogg Vorbis | .ogg | Kayıplı | Açık format | | Opus | .opus | Kayıplı | Modern, düşük gecikmeli | | WMA | .wma | Kayıplı | Windows Media Audio | | AIFF | .aiff | Sıkıştırılmamış (PCM) | Apple sıkıştırılmamış | | AMR | .amr | Kayıplı | Konuşma / mobil | | AC-3 | .ac3 | Kayıplı | Dolby Digital | ### Çıkış Formatları {#output-formats-1} | Format | Uzantı | Codec | Üreten | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Ses Dönüştür, Ses Çıkar | | WAV | .wav | PCM | Ses Dönüştür, Ses Çıkar | | FLAC | .flac | FLAC (kayıpsız) | Ses Dönüştür | | Ogg | .ogg | Vorbis | Ses Dönüştür | | M4A | .m4a | AAC | Ses Dönüştür, Ses Çıkar | ## Belge Formatları {#document-formats} Belge işleme qpdf, LibreOffice, Ghostscript, Pandoc ve WeasyPrint kullanır. ### Giriş Formatları (15) {#input-formats-15} | Format | Uzantılar | Motor | Notlar | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Temel belge formatı | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Metin, sayfa, sunum | | Rich Text | .rtf | LibreOffice | Uygulamalar arası zengin metin | | Düz Metin | .txt | LibreOffice, Pandoc | UTF-8 metin | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | PDF'ye render edilir | | EPUB | .epub | Pandoc, LibreOffice | E-kitap formatı | ### Çıkış Formatları {#output-formats-2} | Format | Uzantılar | Üreten | |--------|-----------|-------------| | PDF | .pdf | Word/Excel/PowerPoint'ten PDF'e, Markdown'dan PDF'e, HTML'den PDF'e | | PDF/A | .pdf | PDF/A Dönüştür (arşivleme) | | Word | .docx, .odt, .rtf, .txt | Belge Dönüştür, PDF'den Word'e, Markdown'dan Word'e | | Sunum | .pptx, .odp | Sunum Dönüştür | | Elektronik tablo | .xlsx, .ods, .csv | Elektronik Tablo Dönüştür | | HTML | .html | Markdown'dan HTML'ye | | EPUB | .epub | EPUB'a Dönüştür | | Görüntüler | .png, .jpg | PDF'den Görüntüye | ## Dosya Formatları {#file-formats} Veri ve arşiv araçları, yapılandırılmış formatlar arasında dönüştürme yapar ve dosyaları paketler. | Format | Uzantılar | Dönüşümler | |--------|-----------|-------------| | CSV | .csv | JSON ve Excel'e/'den; böl ve birleştir; XML'den | | JSON | .json | CSV, XML ve YAML'a/'dan | | XML | .xml | JSON'a/'dan; CSV'ye | | YAML | .yaml, .yml | JSON'a/'dan | | Excel | .xlsx | CSV'ye/'den | | ZIP | .zip | Arşiv oluştur, içerik çıkar | --- --- url: https://docs.snapotter.com/fr/tools/pdf/unlock-pdf.md description: Supprimer la protection par mot de passe d'un PDF. --- # Déverrouiller un PDF {#unlock-pdf} Supprimez la protection par mot de passe d'un PDF chiffré en fournissant le mot de passe correct. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/unlock-pdf` Accepte des données de formulaire multipart avec un fichier PDF et un champ `settings` au format JSON. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | password | string | Oui | - | Mot de passe pour déchiffrer le PDF (1-256 caractères) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/unlock-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"password": "s3cret"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2500000, "processedSize": 2450000 } ``` ## Remarques {#notes} * Le mot de passe correct doit être fourni ; un mot de passe incorrect renvoie une erreur 400. * Le mot de passe utilisateur ou le mot de passe propriétaire fonctionnera pour le déchiffrement. * Les mots de passe sont masqués dans les journaux d'audit. --- --- url: https://docs.snapotter.com/vi/tools/audio/pitch-shift.md description: Nâng hoặc hạ cao độ âm thanh theo semitone mà không thay đổi tốc độ. --- # Dịch cao độ {#pitch-shift} Nâng hoặc hạ cao độ của một tệp âm thanh theo một số semitone mà không thay đổi tốc độ phát lại của nó. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/pitch-shift` Chấp nhận dữ liệu form multipart với một tệp âm thanh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | semitones | integer | Không | `3` | Số semitone để dịch (-12 đến 12). Phải khác không. | ## Yêu cầu ví dụ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/pitch-shift \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"semitones": -5}' ``` ## Phản hồi ví dụ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Ghi chú {#notes} * Giá trị dương nâng cao độ; giá trị âm hạ cao độ. * Dịch 12 semitone bằng một quãng tám lên; -12 bằng một quãng tám xuống. * Thời lượng phát lại vẫn giữ nguyên bất kể lượng dịch. * Đầu ra thường giữ container đầu vào. Đầu vào AAC được ghi thành M4A, và các đầu vào chỉ giải mã không được hỗ trợ sẽ chuyển về MP3. --- --- url: https://docs.snapotter.com/vi/tools/audio/volume-adjust.md description: Tăng hoặc giảm âm lượng bằng một mức khuếch đại cố định tính bằng decibel. --- # Điều chỉnh âm lượng {#volume-adjust} Tăng hoặc giảm âm lượng của một tệp âm thanh bằng cách áp dụng một mức khuếch đại cố định tính bằng decibel. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/volume-adjust` Nhận dữ liệu multipart form với một tệp âm thanh và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | gainDb | number | No | `3` | Điều chỉnh âm lượng tính bằng decibel (-30 đến 30) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/volume-adjust \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"gainDb": 6}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Giá trị dương làm tăng âm lượng; giá trị âm làm giảm âm lượng. * Mức khuếch đại dương lớn có thể gây méo tiếng (clipping). Dùng normalize-audio để cân bằng độ lớn an toàn. * Đầu ra thường giữ nguyên container của tệp đầu vào. Đầu vào AAC được ghi thành M4A, còn các đầu vào chỉ giải mã được nhưng không hỗ trợ sẽ chuyển về MP3. --- --- url: https://docs.snapotter.com/it/tools/audio/fade-audio.md description: Aggiungi effetti di dissolvenza in entrata e in uscita all'audio. --- # Dissolvenza audio {#fade-audio} Aggiungi effetti di dissolvenza in entrata e in uscita all'inizio e alla fine di un file audio. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Accetta dati di form multipart con un file audio e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | fadeInS | number | No | `1` | Durata della dissolvenza in entrata in secondi (da 0 a 30) | | fadeOutS | number | No | `1` | Durata della dissolvenza in uscita in secondi (da 0 a 30) | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Note {#notes} * Imposta uno dei due valori a `0` per saltare quella direzione della dissolvenza. Almeno uno deve essere maggiore di 0. * La durata della dissolvenza viene limitata alla lunghezza dell'audio se la supera. * L'output di solito mantiene il container di input. L'input AAC viene scritto come M4A, e gli input decodificabili solo in lettura non supportati ricadono su MP3. --- --- url: https://docs.snapotter.com/sv/guide/deployment.md description: >- Distribuera SnapOtter till produktion med Docker. Hårdvarukrav, GPU-konfiguration och konfigurationer för omvänd proxy för Nginx, Traefik och Cloudflare. --- # Distribution {#deployment} SnapOtter distribueras som en Docker Compose-stack med 3 containrar: SnapOtter-appavbildningen, PostgreSQL 17 och Redis 8. Appavbildningen stöder **linux/amd64** (med NVIDIA CUDA för AI-acceleration) och **linux/arm64** (CPU), så den körs nativt på Intel/AMD-servrar, Mac-datorer med Apple Silicon och ARM-enheter som Raspberry Pi 4/5. Intel/AMD iGPU-acceleration via VA-API, Quick Sync eller OpenCL stöds inte för AI-inferens i dagsläget. Se [Docker-avbildning](./docker-tags) för GPU-konfiguration, Docker Compose-exempel och versionslåsning. ::: info Kompatibilitet för koreansk OCR Snabb OCR stöder `auto`, `en`, `de`, `es`, `fr`, `zh` och `ja`, men inte koreanska (`ko`). Koreanska kräver det exakta OCR-paketet och `balanced` eller `best`. Paketet fungerar i officiella Linux amd64- och arm64-containrar, även på NVIDIA-värdar där OCR fortsätter köras på CPU. System som inte stöds får ett uttryckligt kompatibilitetsfel och faller aldrig tyst tillbaka till `fast`. Koreanska med `fast` eller det äldre aliaset `tesseract` avvisas före köläggning med `FEATURE_INCOMPATIBLE` och `fast-korean-unsupported`. ::: ## Snabbstart (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` Appen är sedan tillgänglig på `http://localhost:1349`. > **Begränsningar för Docker Hub-hastighet?** Ersätt `snapotter/snapotter:latest` med `ghcr.io/snapotter-hq/snapotter:latest` för att hämta från GitHub Container Registry i stället. Båda registren får samma avbildning vid varje utgåva. ## Snabbstart (NVIDIA CUDA) {#quick-start-nvidia-cuda} För NVIDIA CUDA acceleration på AI-verktyg som stöds (bakgrundsborttagning, uppskalning, ansiktsförbättring): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Ändra detta för icke-lokala distributioner POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### Verifiera GPU-acceleration {#verify-gpu-acceleration} Kontrollera CUDA-detektering i loggarna: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` Om AI-verktyg körs på CPU trots att `--gpus all` och NVIDIA Container Toolkit är korrekt konfigurerade, installera om det berörda paketet (till exempel bakgrundsborttagning) från **Inställningar → AI-funktioner**. Installationsprogrammet återställer GPU-bygget av ONNX Runtime, vilket enbart CPU-bygge som dras in av ett annat paket (som transkription) annars kan skugga i den delade AI-miljön. Om ominstallation från användargränssnittet inte återställer GPU på en äldre bild, se den manuella reparationen i [utgåva #490](https://github.com/snapotter-hq/SnapOtter/issues/490). ## Hårdvarukrav {#hardware-requirements} Dessa siffror kommer från benchmarktester över en rad system, från en modern amd64-arbetsstation med en NVIDIA RTX 4070 ner till en Raspberry Pi, där hela verktygskatalogen kördes på var och en och Docker-resursgränserna svepte över värdena för att hitta det verkliga golvet. Kör du i den nedre änden av dessa nivåer (en Pi, en gammal bärbar dator, en VPS med 2 GB)? [Resurssnåla installationer](/sv/guide/low-resource) omvandlar dessa siffror till en konkret genomgång med anpassade tak. ### Snabbreferens {#quick-reference} | Nivå | Användningsfall | CPU | RAM | GPU | Lagring | |------|----------|-----|-----|-----|---------| | Minimum | Bild-, fil- och lätta PDF-verktyg; en enda användare; små batchar | 2 kärnor | 2 GB | Ingen | ~7 GB | | Rekommenderad | Alla fem modaliteter inkl. video, PDF och AI på CPU; batchar; ett fåtal användare | 4 kärnor | 4 GB | Ingen | ~25 GB | | Full | Allt med hög hastighet inkl. GPU-AI; stora batchar; många användare | 6-8 kärnor | 8 GB | NVIDIA 8 GB+ VRAM (12 GB bekvämt) | ~35 GB | **Arkitektur: endast 64-bitars** (`linux/amd64` eller `linux/arm64`). SnapOtter körs nativt på Intel/AMD-servrar, Mac-datorer med Apple Silicon och 64-bitars ARM-kort inklusive **Raspberry Pi 4 och 5** (4-8 GB). Den körs **inte** på 32-bitars ARM (`armv7`/`armhf`) — ingen avbildning byggs för den — och inte heller på kort i 512 MB-klassen som Pi Zero, vilka ligger under minnesgolvet (se nedan). ### Minimum (bild-, fil- och lätta PDF-verktyg; ingen AI) {#minimum-image-files-and-light-pdf-tools-no-ai} | Resurs | Krav | |---|---| | CPU | 2 kärnor | | RAM | 2 GB | | Disk | ~5,5 GB (avbildning) + datavolym | | GPU | Krävs inte | Alla 222 icke-AI-katalogverktyg - bild (ändra storlek, beskär, konvertera, komprimera, justera, vattenmärke), video (klipp, tysta, remuxa), ljud (konvertera, normalisera, klipp), PDF (slå samman, dela, komprimera, rotera, skydda), filkonverteringar och dedikerade konverteringsförinställningar - körs på blygsam hårdvara. De flesta operationer slutförs på långt under en sekund även på en stor fil: en bild på 2,7 MB ändrar storlek på ~0,05 s och kodas om till WebP på ~2 s. Minnesgolvet är verkligt, enligt en svepning av Docker-resursgränser: **512 MB kan inte starta stacken** (till och med en enda bildstorleksändring dödas), **1 GB** klarar operationer på enstaka filer men en batch med flera filer får slut på minne, och **2 GB / 2 kärnor** är den minsta konfiguration som klarar batchar bekvämt. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **Det enda CPU-tunga undantaget är omkodning av video.** Stream-copy-operationer (klipp, tysta, containerremux) är omedelbara, men transkodning till en annan codec är CPU-bunden. Ett klipp på 1080p / 45 sekunder som kodas om till VP9 (WebM) tar ungefär **~40 s** på en snabb modern CPU, ~45 s på Apple Silicon, ~80 s på en äldre mobil 4-kärna och **~130 s** på en äldre 4-kärnig server. Om din arbetsbelastning är videotung, prioritera CPU-kärnor och klockfrekvens, eller höj containerns `cpus:`-gräns — den levererade compose-filen begränsar appen till 4 kärnor som standard (8 på GPU-compose). ### Rekommenderad (AI-verktyg på CPU) {#recommended-ai-tools-on-cpu} | Resurs | Krav | |---|---| | CPU | 4 kärnor | | RAM | 4 GB | | Disk | 3 GB (bild) + cirka 20 GB (alla valfria AI-paket) + arbetsyta | | GPU | Krävs inte (CPU-reserv) | **Att installera och köra de större AI-paketen är det som driver rekommendationen till 4 GB RAM.** Utan några tillvalspaket installerade är appen inaktiv på cirka 360 MB. Äldre Python-verktyg delar en sidecar, medan exakt OCR använder en dedikerad långlivad dispatcher som är fäst vid den aktiva oföränderliga generationen. Före aktivering kör installatören en smoke test på kandidaten. Den växlar sedan atomärt till den nya dispatcher och dränerar den tidigare dispatcher före garbage collection. Varje officiell exakt OCR-artefakt måste passera sin värsta release suite inuti en 4 GiB cgroup, medan värdrekommendationen på 4 GB lämnar utrymme för Node.js-applikationen, Postgres, Redis, köer, och samtidigt arbete. De flesta AI-verktyg är fullt användbara på CPU; ett par vill verkligen ha en GPU. Uppmätt på en modern 4-kärnig CPU: | AI-verktyg | CPU-tid | Användbart på CPU? | |---|---|---| | Ansiktsigenkänning (blur-faces, smart-crop, red-eye), brusborttagning | under 1 s | Ja | | OCR, transkribering, undertexter | 1-3 s | Ja | | Färgläggning, ansiktsförbättring | ~10 s | Ja | | Bakgrundsborttagning / -ersättning / -oskärpa | ~29 s | Ja (du får vänta) | | AI-uppskalning (RealESRGAN) | ~33 s liten; minuter på stora bilder | Marginellt — GPU rekommenderas starkt | | Fotorestaurering (fullständig pipeline) | flera minuter | Nej — behöver en GPU eller en snabb CPU med många kärnor | SnapOtter bakar avsiktligt inte in dessa modellnedladdningar i Docker-avbildningen. AI-buntar hämtas endast när en administratör aktiverar det relaterade verktyget, lagras i den beständiga `/data/ai`-volymen och delas av varje verktyg som är beroende av samma modellstack. Detta håller den slutliga containeravbildningen liten samtidigt som en fullständig AI-installation kan nå de större lagringstalen nedan. Vissa verktyg är beroende av mer än en delad bunt. Passfoto behöver till exempel både `background-removal` och `face-detection`; om `background-removal` redan är installerad laddar aktiveringen av Passfoto bara ner den saknade `face-detection`-bunten. Samma återanvändning gäller för alla AI-verktyg. Valfria AI-paketlagringsuppskattningar: | Bunt | Diskstorlek | |---|---| | Bakgrundsborttagning | 4-5 GB | | Uppskalning + ansiktsförbättring + brusborttagning | 5-6 GB | | Ansiktsigenkänning | 200-300 MB | | Objektradering + färgläggning | 1-2 GB | | Exakt OCR (`balanced`/`best`) | ~208-234 MiB nedladdning / ~409-488 MiB installerad | | Fotorestaurering | 4-5 GB | | Transkription | ~600 MB | | **Alla paket** | **~20 GB installerat** | Snabb OCR är inbyggd i bilden genom Tesseract, lägger till cirka 25 MiB och kräver inte det valfria OCR-paketet eller dess 4 GiB minneskrav. Den exakta förpackningen är tillgänglig i de officiella Linux amd64- och arm64-behållarna och kör ONNX Runtime på CPU. NVIDIA-värdar använder samma CPU OCR körtid, så OCR är inte beroende av CUDA-versionen eller GPU-arkitekturen. Den exakta körtiden kräver minst 4 GiB effektivt minne: den konfigurerade behållarens cgroup-gräns, annars värdminne. SnapOtter avvisar system under det signerade kompatibilitetsminimum innan paketet laddas ner. Exakt paketinstallation avvisas också på bare-metal/förbyggda arkiv vars libc och Python ABI inte kan garanteras. Repliker som delar samma `DATA_DIR` måste använda samma CPU-arkitektur. Lås driftsättningar med flera repliker till kompatibla noder med hjälp av nodaffinitet. Blandade amd64/arm64-repliker behöver separata datavolymer och oberoende SnapOtter-driftsättningar. Den exakta körtiden håller en aktiv generation och rensar nedladdningscachen efter aktivering. För den här utgåvan behöver en första installation tillfälligt ungefär 620-720 MiB för arkivet plus staging, och en uppgradering kan nå en topp nära 1,2 GiB medan den gamla generationen förblir aktiv. Installationsprogrammet beräknar det exakta kravet från det signerade indexet och nuvarande generationer innan nedladdning eller extrahering, och misslyckas tidigt om datavolymen är för liten. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Full (AI-verktyg på NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | Resurs | Krav | |---|---| | CPU | 6-8 kärnor (videoförberedelse + samtidighet körs på CPU även med GPU-AI) | | RAM | 8 GB | | GPU | NVIDIA med 8+ GB VRAM (12 GB rekommenderas) | | Disk | ~35 GB totalt | En NVIDIA-GPU (CUDA) snabbar dramatiskt upp de tunga AI-modellerna. Uppmätt på en RTX 4070 mot en modern CPU: | AI-verktyg | Hastighetsökning med GPU | Anteckningar | |---|---|---| | AI-uppskalning (RealESRGAN 2×) | **~47×** | Den största vinsten — under en sekund mot ~33 s (minuter på stora bilder) | | Ansiktsförbättring (CodeFormer) | **~12×** | ~0,9 s mot ~11 s | | Transkribering (Whisper) | ~4,5× | | | Bakgrundsborttagning / -ersättning / -oskärpa | ~4× | ~7 s på GPU mot ~29 s på CPU | | Färgläggning | ~1,8× | | | OCR, ansiktsigenkänning, red-eye, brusborttagning | ~1× | Redan snabbt på CPU — en GPU hjälper inte | | Fotorestaurering | ingen | CPU-bunden även på en GPU (0 % GPU-utnyttjande); en snabb CPU spelar större roll än en GPU här | De verktyg som är värda en GPU är **uppskalning, ansiktsförbättring, transkribering och bakgrundsborttagning**. Ansiktsigenkänning, OCR och red-eye är CPU-bundna och redan snabba, så en GPU tillför ingenting. Högsta VRAM-användning når 7,5 GB under uppskalning med ansiktsförbättring. En NVIDIA-GPU med 6 GB fungerar för de flesta AI-verktyg var för sig men misslyckas med uppskalning. 8-12 GB VRAM klarar allt. Intel/AMD iGPU-acceleration via VA-API, Quick Sync eller OpenCL stöds inte för AI-inferens i dagsläget. Att mappa `/dev/dri` in i containern aktiverar inte GPU-acceleration för AI; SnapOtter kör AI-verktyg på CPU om inte NVIDIA CUDA är tillgängligt. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Samtidiga användare {#concurrent-users} Parallella bildstorleksändringsförfrågningar mot den standardmässiga appcontainern begränsad till 4 kärnor: | Samtidiga förfrågningar | Genomsnittlig svarstid | Fel | |---|---|---| | 1 | 0,4 s | 0 | | 5 | 1,2 s | 0 | | 10 | 2,1 s | 0 | Svarstiden försämras underlinjärt utan fel när arbetarpoolen mättas. Att höja appcontainerns `cpus:`-gräns (eller använda en värd med fler kärnor) höjer taket. Observera att tunga jobb (videotranskodning, CPU-AI) håller en arbetare under hela sin varaktighet, så dimensionera CPU:n efter ditt förväntade antal samtidiga tunga jobb, inte bara antalet förfrågningar. ### Bildformat som stöds {#supported-image-formats} SnapOtter stöder **55+ indataformat** och **14 utdataformat**, inklusive RAW-filer från 20+ kameramärken, professionella format (PSD, EPS, OpenEXR, HDR), moderna codec-format (JPEG XL, AVIF, HEIC, QOI) och vetenskapliga/spelformat (FITS, DDS). Se den [fullständiga formatlistan](/sv/guide/supported-formats) för detaljer om varje format som stöds, dekoder som används och tillgängliga kvalitetskontroller. ### Kända begränsningar {#known-limitations} * **Innehållsmedveten storleksändring** kraschar på stora bilder (>5 MP) på grund av en begränsning i caire-binären. Fungerar utmärkt med mindre bilder. * **HEIF-avkodning** tar 13-23 sekunder. HEIC (Apples variant) är mycket snabbare på 0,3-0,9 sekunder. * **Uppskalning** får timeout på CPU för allt utöver små bilder. GPU krävs för praktisk användning. * **CodeFormer**-ansiktsförbättring är betydligt långsammare än GFPGAN (53 s mot 2 s på GPU). GFPGAN rekommenderas för de flesta användningsfall. ## Volymer {#volumes} | Montering / volym | Syfte | Krävs? | |---|---|---| | `/data` (app) | AI-modeller, Python-venv, användarfiler | **Ja** - filförlust utan den | | `/tmp/workspace` (app) | Tillfälliga bearbetningsfiler (rensas automatiskt) | Rekommenderas | | `SnapOtter-pgdata` (postgres) | PostgreSQL-datakatalog (användare, inställningar, pipelines, jobb) | **Ja** - dataförlust utan den | | `SnapOtter-redisdata` (redis) | Redis append-only-fil för hållbara jobbköer | Rekommenderas | ### Bind-monteringar vs. namngivna volymer {#bind-mounts-vs-named-volumes} **Namngivna volymer** (rekommenderas) — Docker hanterar behörigheter automatiskt: ```yaml volumes: - SnapOtter-data:/data ``` **Bind-monteringar** — Du hanterar behörigheter. Ange `PUID`/`PGID` så att de matchar din värdanvändare: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Lagringsbehörigheter {#storage-permissions} SnapOtter skriver till två platser vid körning: `/data` (användarfiler, loggar, AI-modeller och Python-venv) och `/tmp/workspace` (tillfällig bearbetningsscratch). Båda måste vara skrivbara av den användare som containern körs som. Om någon av dem inte är det **misslyckas containern snabbt vid start** med ett meddelande som namnger katalogen, det körande UID/GID och hur du åtgärdar det — i stället för att starta "hälsosamt" och sedan misslyckas vid den första uppladdningen med ett kryptiskt fel. Hur behörigheter hanteras beror på hur containern startas: **Standard (startar som root, släpper till `snapotter`)** — startpunkten startar som root, korrigerar ägarskapet för de monterade volymerna och släpper sedan till den icke-privilegierade `snapotter`-användaren via `gosu`. Namngivna volymer fungerar utan konfiguration. För bind-monteringar, ange `PUID`/`PGID` till din värdanvändare (ovan) så att de filer den skriver ägs av dig. **Kubernetes / OpenShift (icke-root via `runAsUser`)** — när containern startas direkt som en icke-root-användare kan den inte köra chown på volymerna själv, så orkestreraren måste göra dem skrivbara. Ange `fsGroup`: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` Avbildningens skrivbara kataloger är gruppägda av GID 0 och gruppskrivbara, så en pod som körs med ett **godtyckligt UID** plus root-tilläggsgruppen (OpenShift-standarden) kan skriva utan `chown`. **TrueNAS Scale (och andra "främmande UID"-uppsättningar)** — TrueNAS kör appar som en icke-root-användare (ofta `568:568`) och monterar värddataset som ägs av en annan användare, så varken startpunkten eller `fsGroup` gör dem skrivbara på egen hand. Välj ett av följande: * **Kör appen som root** (rekommenderas) — lämna appens användare oinställd eller ange den till `0`, och låt standardstartpunkten korrigera behörigheter och släppa till `snapotter`. * **Kör som UID `999`** — ange appens användare/grupp till `999:999` (SnapOtters inbyggda `snapotter`-användare) så att den matchar avbildningens ägarskap. * **`chown` värddatasetet** till det UID som containern körs som, från TrueNAS-skalet: ```bash # Använd UID:t från startfelet (eller kör `id` inuti containern) chown -R 568:568 /mnt// ``` Startfelet namnger det exakta UID:t som ska användas, så den snabbaste vägen är att starta appen en gång, läsa meddelandet och sedan köra `chown` (eller justera användaren) i enlighet med det. ## Miljövariabler {#environment-variables} | Variabel | Standard | Beskrivning | |---|---|---| | `AUTH_ENABLED` | `true` | Aktivera/inaktivera inloggningskrav | | `DEFAULT_USERNAME` | `admin` | Ursprungligt administratörsanvändarnamn | | `DEFAULT_PASSWORD` | `admin` | Ursprungligt administratörslösenord (tvingad ändring vid första inloggningen) | | `MAX_UPLOAD_SIZE_MB` | `0` (obegränsat) | Uppladdningsgräns per fil i MB. Avbilden levereras med `0`; ett bygge från källkoden börjar på 100 | | `MAX_BATCH_SIZE` | `0` (obegränsat) | Max antal filer per batchförfrågan. Avbilden levereras med `0`; ett bygge från källkoden börjar på 100 | | `RATE_LIMIT_PER_MIN` | `1000` | API-förfrågningar per minut per IP (ange 0 för att inaktivera) | | `MAX_USERS` | `0` (obegränsat) | Maximalt antal användarkonton | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Vilka motparter som får sätta klientens IP via `X-Forwarded-For`. Endast privata nät som standard | | `PUID` | `999` | Kör som detta UID (för bind-monteringsbehörigheter) | | `PGID` | `999` | Kör som detta GID (för bind-monteringsbehörigheter) | | `LOG_LEVEL` | `info` | Loggutförlighet: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (auto) | Max parallella AI-bearbetningsjobb | | `SESSION_DURATION_HOURS` | `168` | Livslängd för inloggningssession (7 dagar) | | `CORS_ORIGIN` | (tom) | Kommaseparerade tillåtna ursprung, eller tom för samma ursprung | ### Utgående proxy och privat CA {#outbound-proxy-and-private-ca} Den officiella behållaren möjliggör Nodes miljö-proxy-stöd. Om SnapOtter måste nå OCR runtime repository eller andra HTTPS-tjänster via en företagsproxy, ställ in `HTTPS_PROXY` (och `HTTP_PROXY` vid behov). Ställ in `NO_PROXY` på en kommaseparerad lista över värdar som måste nås direkt, såsom Postgres, Redis och intern objektlagring. Om proxyn eller en intern tjänst är signerad av en privat certifikatutfärdare, montera CA-certifikatet skrivskyddat och peka `NODE_EXTRA_CA_CERTS` till det. Filen måste finnas när nodprocessen startar: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Behåll proxyuppgifterna utanför Compose-filen (till exempel i en skyddad `.env`-fil eller hemlig). Inaktivera inte TLS-verifiering: det signerade OCR-indexet autentiserar releasemetadata, medan normal TLS-validering fortfarande skyddar transport och alla andra utgående begäranden. ## Hälsokontroll {#health-check} Containern innehåller en inbyggd hälsokontroll: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Omvänd proxy {#reverse-proxy} `TRUST_PROXY` är som standard `loopback,linklocal,uniquelocal`, så SnapOtter tror på `X-Forwarded-For` bara från en motpart i ett privat nät. En omvänd proxy på samma värd, på ett Docker-nätverk eller i ditt LAN är betrodd direkt, vilket gör att hastighetsbegränsningen, brute force-spärren vid inloggning, granskningsloggen och enterprise-utgåvans IP-tillåtlista alla ser den verkliga klient-IP:n utan någon konfiguration. Sätt `TRUST_PROXY=true` bara när proxyn framför når SnapOtter från en **publik** adress, till exempel en molnlastbalanserare i ett annat nät. På en direkt exponerad instans gör det värdet `request.ip` styrbart av en angripare, eftersom den som roterar huvudet får en ny hink för hastighetsbegränsning vid varje förfrågan. Två saker är värda att veta innan du börjar mäta klient-IP:n. Docker Desktop på macOS och Windows betjänar en publicerad port via en proxy i användarrymden som skriver om varje källadress till VM-gatewayen `192.168.65.1`, så där återfår inget värde på `TRUST_PROXY` den verkliga klienten; kör allt som vetter mot internet på Linux. Och på alla plattformar ses en publicerad port som nås över `localhost` som bryggans gateway i stället för som din klient, så ett test mot localhost säger ingenting om hur en verklig klient tillskrivs. Hela tabellen över `TRUST_PROXY`-värden och förbehållet om Docker Desktop finns i [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy). Två saker spelar roll för varje proxy nedan: tillåt stora begäranden (uppladdningar) och buffra inte svar. En svarsbuffrande proxy bryter SSE-förloppet och, mer synligt, gör att en stor filnedladdning "startar men slutar aldrig", eftersom proxyn håller hela filen innan den skickas vidare. SnapOtter skickar `X-Accel-Buffering: no` vid nedladdningar så nginx streamar dem även om buffring lämnas på någon annanstans, men andra proxyservrar än nginx behöver explicit inaktivera svarsbuffring (visas i varje konfiguration nedan). Om en nedladdning stannar halvvägs är en buffrande proxy framför det första att kontrollera. ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Strömma svar istället för buffring: behövs för SSE-förlopp (batch, AI, funktionsinstallationer) och för stora filnedladdningar. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Lägg till en ny Proxy Host 2. Ange Domain Name till din domän 3. Ange Scheme till `http`, Forward Hostname till `SnapOtter` (eller din container-IP), Forward Port till `1349` 4. Aktivera WebSocket-stöd 5. Under Advanced, lägg till: `client_max_body_size 500M;` och `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` inaktiverar svarsbuffring, vilket krävs för SSE-förloppshändelser (batchbearbetning, AI-verktyg, funktionsinstallationer) och för att ladda ner stora filer att strömma igenom istället för att stanna. De utökade tidsgränserna gör att uppladdningar av stora filer kan slutföras utan att Caddy stänger anslutningen i förtid. ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Obs: Cloudflare har en uppladdningsgräns på 100 MB på gratisplaner. Ange `MAX_UPLOAD_SIZE_MB=100` så att den matchar. ## CI/CD {#ci-cd} GitHub-arkivet har tre arbetsflöden: * **ci.yml** - Körs automatiskt vid varje push och PR. Kör lint, typkontroll, tester, bygge och validerar Docker-avbildningen (utan att pusha). * **release.yml** - Utlöses manuellt via `workflow_dispatch`. Kör semantic-release för att skapa en versionstagg och GitHub-utgåva, bygger sedan en Docker-avbildning för flera arkitekturer (amd64 + arm64) och pushar till Docker Hub (`snapotter/snapotter`) och GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`). * **deploy-docs.yml** - Bygger denna dokumentationssida och distribuerar den till Cloudflare Pages vid push till `main`. För att skapa en utgåva, gå till **Actions > Release > Run workflow** i GitHub-gränssnittet, eller kör: ```bash gh workflow run release.yml ``` Semantic-release avgör versionen utifrån commit-historiken. Docker-taggen `latest` pekar alltid på den senaste utgåvan. ## Analys {#analytics} SnapOtter innehåller anonym produktanalys (mönster för verktygsanvändning, felrapporter) för att hjälpa till att fånga buggar och förbättra funktioner. Den är på som standard. Dina filer, filnamn och personuppgifter är aldrig en del av detta. SnapOtter fungerar normalt med analys inaktiverad. ### Inaktivera analys {#disabling-analytics} Bortval vid körning är en administratörsväxel med ett klick. Öppna Settings > System > Privacy och stäng av Anonymous Product Analytics. Den stoppas omedelbart för hela instansen, ingen ombyggnad krävs. För en avbildning som aldrig kan sända analys, ange den hårda avstängningen vid byggtid genom att klona arkivet och bygga om: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` Eller lägg till byggargumentet i din befintliga `docker-compose.yml`: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/it/guide/deployment.md description: >- Distribuisci SnapOtter in produzione con Docker. Requisiti hardware, configurazione GPU e configurazioni di reverse proxy per Nginx, Traefik e Cloudflare. --- # Distribuzione {#deployment} SnapOtter si distribuisce come stack Docker Compose a 3 container: l'immagine dell'app SnapOtter, PostgreSQL 17 e Redis 8. L'immagine dell'app supporta **linux/amd64** (con NVIDIA CUDA per l'accelerazione AI) e **linux/arm64** (CPU), quindi gira in modo nativo su server Intel/AMD, Mac con Apple Silicon e dispositivi ARM come il Raspberry Pi 4/5. L'accelerazione tramite iGPU Intel/AMD attraverso VA-API, Quick Sync o OpenCL non è supportata per l'inferenza AI al momento. Vedi [Immagine Docker](./docker-tags) per la configurazione GPU, esempi di Docker Compose e il pinning delle versioni. ::: info Compatibilità OCR per il coreano OCR veloce supporta `auto`, `en`, `de`, `es`, `fr`, `zh` e `ja`, ma non il coreano (`ko`). Il coreano richiede il pacchetto OCR accurato e `balanced` o `best`. Il pacchetto funziona nei container Linux amd64 e arm64 ufficiali, inclusi gli host NVIDIA, dove l’OCR resta sulla CPU. I sistemi non supportati ricevono un errore di compatibilità esplicito e non passano mai silenziosamente a `fast`. Il coreano con `fast` o con l’alias legacy `tesseract` viene rifiutato prima dell’accodamento con `FEATURE_INCOMPATIBLE` e `fast-korean-unsupported`. ::: ## Avvio rapido (CPU) {#quick-start-cpu} ```yaml # docker-compose.yml - Copy this file and run: docker compose up -d services: SnapOtter: image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest container_name: SnapOtter ports: - "1349:1349" # Web UI + API volumes: - SnapOtter-data:/data # AI models, user files (PERSISTENT) - SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs) environment: # --- Authentication --- - AUTH_ENABLED=true # Set to false to disable login entirely - DEFAULT_USERNAME=admin # First-run admin username - DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it) # --- Database + Queue --- - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 # --- Limits (set 0 for unlimited) --- # - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB # - MAX_BATCH_SIZE=100 # Max files per batch request # - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled) # - MAX_USERS=0 # Max user accounts # --- Networking --- # - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown) # --- Bind mount permissions --- # - PUID=1000 # Match your host user's UID (run: id -u) # - PGID=1000 # Match your host user's GID (run: id -g) depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Needed for Python ML shared memory logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Change this for non-local deployments POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: # Named volume - Docker manages permissions automatically SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose up -d ``` L'app è quindi disponibile all'indirizzo `http://localhost:1349`. > **Limiti di velocità di Docker Hub?** Sostituisci `snapotter/snapotter:latest` con `ghcr.io/snapotter-hq/snapotter:latest` per effettuare il pull da GitHub Container Registry. Entrambi i registry ricevono la stessa immagine a ogni rilascio. ## Avvio rapido (NVIDIA CUDA) {#quick-start-nvidia-cuda} Per l'accelerazione NVIDIA CUDA sugli strumenti AI supportati (rimozione dello sfondo, upscaling, miglioramento del volto): ```yaml # docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit # Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html services: SnapOtter: image: snapotter/snapotter:latest container_name: SnapOtter ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD=admin - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 shm_size: "2gb" # Required for PyTorch CUDA shared memory deploy: resources: reservations: devices: - driver: nvidia count: all # Or set to 1 for a specific GPU capabilities: [gpu] logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine container_name: SnapOtter-postgres environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Modificarlo per distribuzioni non locali POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 start_period: 15s redis: image: redis:8-alpine container_name: SnapOtter-redis command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 start_period: 10s volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` ```bash docker compose -f docker-compose-gpu.yml up -d ``` ### Verifica l'accelerazione GPU {#verify-gpu-acceleration} Controlla il rilevamento CUDA nei log: ```bash docker logs SnapOtter 2>&1 | head -20 # Look for: [gpu] CUDA available via torch ``` Se gli strumenti AI vengono eseguiti sulla CPU anche se `--gpus all` e NVIDIA Container Toolkit sono configurati correttamente, reinstallare il pacchetto interessato (ad esempio Rimozione sfondo) da **Impostazioni → Funzionalità AI**. Il programma di installazione ripristina la build GPU di ONNX Runtime, che una build solo CPU inserita da un altro bundle (come la trascrizione) potrebbe altrimenti oscurare nell'ambiente AI condiviso. Se la reinstallazione dall'interfaccia utente non ripristina la GPU su un'immagine precedente, consulta la riparazione manuale nel [problema n. 490](https://github.com/snapotter-hq/SnapOtter/issues/490). ## Requisiti hardware {#hardware-requirements} Questi valori provengono da benchmark eseguiti su una gamma di sistemi, da una moderna workstation amd64 con una NVIDIA RTX 4070 fino a un Raspberry Pi, eseguendo l'intero catalogo di strumenti su ciascuno e variando i limiti di risorse Docker per trovare il vero limite minimo. Ti trovi all'estremità bassa di questi livelli (un Pi, un vecchio laptop, un VPS da 2 GB)? [Configurazioni a basse risorse](/it/guide/low-resource) trasforma questi numeri in una guida concreta con tetti già calibrati. ### Riferimento rapido {#quick-reference} | Livello | Caso d'uso | CPU | RAM | GPU | Archiviazione | |------|----------|-----|-----|-----|---------| | Minimo | Strumenti per immagini, file e PDF leggeri; utente singolo; batch piccoli | 2 core | 2 GB | Nessuna | ~7 GB | | Consigliato | Tutte e cinque le modalità incl. video, PDF e AI su CPU; batch; alcuni utenti | 4 core | 4 GB | Nessuna | ~25 GB | | Completo | Tutto a piena velocità incl. AI su GPU; batch grandi; molti utenti | 6-8 core | 8 GB | NVIDIA 8 GB+ VRAM (12 GB comodo) | ~35 GB | **Architettura: solo a 64 bit** (`linux/amd64` o `linux/arm64`). SnapOtter gira in modo nativo su server Intel/AMD, Mac con Apple Silicon e schede ARM a 64 bit, tra cui il **Raspberry Pi 4 e 5** (4-8 GB). **Non** gira su ARM a 32 bit (`armv7`/`armhf`), poiché non viene creata alcuna immagine per esso, né su schede della classe 512 MB come il Pi Zero, che sono al di sotto della soglia minima di memoria (vedi sotto). ### Minimo (strumenti per immagini, file e PDF leggeri; senza AI) {#minimum-image-files-and-light-pdf-tools-no-ai} | Risorsa | Requisito | |---|---| | CPU | 2 core | | RAM | 2 GB | | Disco | ~5,5 GB (immagine) + volume dati | | GPU | Non richiesta | Tutti i 222 strumenti del catalogo non-AI, immagine (ridimensiona, ritaglia, converti, comprimi, regola, filigrana), video (taglia, silenzia, remux), audio (converti, normalizza, taglia), PDF (unisci, dividi, comprimi, ruota, proteggi), conversioni di file e preset di conversione dedicati, girano su hardware modesto. La maggior parte delle operazioni si completa in molto meno di un secondo anche su un file di grandi dimensioni: un'immagine da 2,7 MB viene ridimensionata in ~0,05 s e ricodificata in WebP in ~2 s. La soglia minima di memoria è reale, da una variazione dei limiti di risorse Docker: **512 MB non riescono ad avviare lo stack** (anche un singolo ridimensionamento di immagine viene terminato), **1 GB** gestisce operazioni su file singoli ma un batch multi-file esaurisce la memoria, e **2 GB / 2 core** è la configurazione più piccola che gestisce i batch comodamente. ```yaml deploy: resources: limits: cpus: '2' memory: 2G ``` **L'unica eccezione che richiede molta CPU è la ricodifica video.** Le operazioni di stream-copy (taglio, silenziamento, remux del container) sono istantanee, ma la transcodifica in un codec diverso è vincolata alla CPU. Una clip 1080p / 45 secondi ricodificata in VP9 (WebM) richiede all'incirca **~40 s** su una CPU moderna veloce, ~45 s su Apple Silicon, ~80 s su una CPU mobile a 4 core più vecchia e **~130 s** su un server a 4 core più vecchio. Se il tuo carico di lavoro è ricco di video, dai priorità ai core della CPU e alla frequenza di clock, oppure aumenta il limite `cpus:` del container: il compose fornito limita l'app a 4 core per impostazione predefinita (8 sul compose GPU). ### Consigliato (strumenti AI su CPU) {#recommended-ai-tools-on-cpu} | Risorsa | Requisito | |---|---| | CPU | 4 core | | RAM | 4 GB | | Disk | 3 GB (immagine) + circa 20 GB (tutti i pacchetti AI opzionali) + spazio di lavoro | | GPU | Non richiesta (fallback su CPU) | **L'installazione e l'esecuzione dei bundle AI più grandi è ciò che spinge la raccomandazione a 4 GB di RAM.** Senza pacchetti opzionali installati, l'app rimane inattiva a circa 360 MB. Gli strumenti Python legacy condividono uno sidecar, mentre lo OCR accurato utilizza uno dispatcher dedicato di lunga durata fissato alla generazione immutabile attiva. Prima dell'attivazione, l'installatore esegue un smoke test sul candidato. Quindi passa atomicamente al nuovo dispatcher e drena il precedente dispatcher prima di garbage collection. Ogni artefatto OCR accurato ufficiale deve superare il suo caso peggiore release suite all'interno di un GiB cgroup da 4, mentre la raccomandazione host da 4 GB lascia spazio per l'applicazione Node.js, Postgres, Redis, code e lavoro simultaneo. La maggior parte degli strumenti AI è perfettamente utilizzabile su CPU; un paio vogliono davvero una GPU. Misurato su una moderna CPU a 4 core: | Strumento AI | Tempo su CPU | Utilizzabile su CPU? | |---|---|---| | Rilevamento volti (blur-faces, smart-crop, red-eye), rimozione del rumore | meno di 1 s | Sì | | OCR, trascrizione, sottotitoli | 1-3 s | Sì | | Colorizzazione, miglioramento dei volti | ~10 s | Sì | | Rimozione / sostituzione / sfocatura dello sfondo | ~29 s | Sì (dovrai aspettare) | | Upscaling AI (RealESRGAN) | ~33 s piccole; minuti su immagini grandi | Marginale, GPU fortemente consigliata | | Restauro foto (pipeline completa) | diversi minuti | No, richiede una GPU o una CPU veloce con molti core | SnapOtter volutamente non integra questi download di modelli nell'immagine Docker. I bundle AI vengono scaricati solo quando un amministratore abilita lo strumento correlato, memorizzati nel volume persistente `/data/ai` e condivisi da ogni strumento che dipende dallo stesso stack di modelli. Questo mantiene piccola l'immagine finale del container pur consentendo a un'installazione AI completa di raggiungere i valori di archiviazione più elevati indicati sotto. Alcuni strumenti dipendono da più di un bundle condiviso. Ad esempio, Foto Tessera necessita sia di `background-removal` sia di `face-detection`; se `background-removal` è già installato, abilitare Foto Tessera scarica solo il bundle `face-detection` mancante. Lo stesso riutilizzo si applica a tutti gli strumenti AI. Stime facoltative di stoccaggio dei pacchetti AI: | Bundle | Dimensione su disco | |---|---| | Rimozione dello sfondo | 4-5 GB | | Upscaling + Miglioramento volti + Rimozione rumore | 5-6 GB | | Rilevamento volti | 200-300 MB | | Gomma per oggetti + Colorizzazione | 1-2 GB | | OCR preciso (`balanced`/`best`) | ~208-234 MiB scaricato / ~409-488 MiB installato | | Restauro foto | 4-5 GB | | Trascrizione | ~600 MB | | **Tutti i pacchetti** | **~20 GB installati** | OCR veloce è integrato nell'immagine tramite Tesseract, aggiunge circa 25 MiB e non richiede il pacchetto OCR opzionale o i suoi 4 requisiti di memoria GiB. Il pacchetto accurato è disponibile nei contenitori ufficiali Linux amd64 e arm64 ed esegue ONNX Runtime su CPU. Gli host NVIDIA utilizzano lo stesso runtime CPU OCR, quindi OCR non dipende dalla versione CUDA o dall'architettura GPU. Il runtime accurato richiede almeno 4 GiB di memoria effettiva: il limite cgroup del contenitore configurato, altrimenti memoria host. SnapOtter rifiuta i sistemi al di sotto del minimo di compatibilità firmato prima di scaricare il pacchetto. L'installazione accurata del pacchetto viene rifiutata anche su bare-metal/archivi precostruiti i cui libc e Python ABI non possono essere garantiti. Le repliche che condividono lo stesso `DATA_DIR` devono usare la stessa architettura CPU; vincola i deployment con più repliche a nodi compatibili tramite la node affinity. Le repliche miste amd64/arm64 richiedono volumi di dati separati e deployment SnapOtter indipendenti. Il runtime accurato mantiene una generazione attiva e svuota la cache di download dopo l'attivazione. Per questa versione, una prima installazione richiede temporaneamente circa 620-720 MiB per l'archivio più lo staging, e un aggiornamento può raggiungere un picco vicino a 1.2 GiB mentre la vecchia generazione rimane attiva. Il programma di installazione calcola i requisiti esatti dall'indice firmato e dalle generazioni attuali prima del download o dell'estrazione e fallisce anticipatamente se il volume dei dati è troppo piccolo. ```yaml deploy: resources: limits: cpus: '4' memory: 4G ``` ### Completo (strumenti AI su NVIDIA CUDA) {#full-ai-tools-on-nvidia-cuda} | Risorsa | Requisito | |---|---| | CPU | 6-8 core (la preparazione video + la concorrenza girano su CPU anche con AI su GPU) | | RAM | 8 GB | | GPU | NVIDIA con 8+ GB di VRAM (12 GB consigliati) | | Disco | ~35 GB totali | Una GPU NVIDIA (CUDA) velocizza drasticamente i modelli AI pesanti. Misurato su una RTX 4070 rispetto a una CPU moderna: | Strumento AI | Accelerazione con GPU | Note | |---|---|---| | Upscaling AI (RealESRGAN 2×) | **~47×** | Il guadagno maggiore, meno di un secondo contro ~33 s (minuti su immagini grandi) | | Miglioramento dei volti (CodeFormer) | **~12×** | ~0,9 s contro ~11 s | | Trascrizione (Whisper) | ~4,5× | | | Rimozione / sostituzione / sfocatura dello sfondo | ~4× | ~7 s su GPU contro ~29 s su CPU | | Colorizzazione | ~1,8× | | | OCR, rilevamento volti, occhi rossi, rimozione rumore | ~1× | Già veloce su CPU, una GPU non aiuta | | Restauro foto | nessuna | Vincolato alla CPU anche su una GPU (0% di utilizzo GPU); qui conta più una CPU veloce che una GPU | Gli strumenti per cui vale la pena una GPU sono **upscaling, miglioramento dei volti, trascrizione e rimozione dello sfondo**. Rilevamento volti, OCR e occhi rossi sono vincolati alla CPU e già veloci, quindi una GPU non aggiunge nulla. L'utilizzo di picco della VRAM raggiunge 7,5 GB durante l'upscaling con miglioramento dei volti. Una GPU NVIDIA da 6 GB funziona per la maggior parte degli strumenti AI presi singolarmente, ma fallirà con l'upscaling. Con 8-12 GB di VRAM si gestisce tutto. L'accelerazione tramite iGPU Intel/AMD attraverso VA-API, Quick Sync o OpenCL non è supportata per l'inferenza AI al momento. Mappare `/dev/dri` nel container non abilita l'accelerazione GPU dell'AI; SnapOtter eseguirà gli strumenti AI su CPU a meno che non sia disponibile NVIDIA CUDA. ```yaml deploy: resources: limits: cpus: '4' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] ``` ### Utenti concorrenti {#concurrent-users} Richieste di ridimensionamento immagine in parallelo contro il container app limitato a 4 core per impostazione predefinita: | Richieste concorrenti | Tempo medio di risposta | Errori | |---|---|---| | 1 | 0,4s | 0 | | 5 | 1,2s | 0 | | 10 | 2,1s | 0 | Il tempo di risposta degrada in modo sub-lineare senza errori man mano che il pool di worker si satura. Aumentare il limite `cpus:` del container app (o usare un host con più core) alza il tetto massimo. Nota che i job pesanti (transcodifica video, AI su CPU) occupano un worker per l'intera durata, quindi dimensiona la CPU in base al numero previsto di job pesanti concorrenti, non solo al numero di richieste. ### Formati immagine supportati {#supported-image-formats} SnapOtter supporta **55+ formati di input** e **14 formati di output**, inclusi file RAW da 20+ marchi di fotocamere, formati professionali (PSD, EPS, OpenEXR, HDR), codec moderni (JPEG XL, AVIF, HEIC, QOI) e formati scientifici/di gioco (FITS, DDS). Vedi l'[elenco completo dei formati](/it/guide/supported-formats) per i dettagli su ogni formato supportato, il decoder usato e i controlli di qualità disponibili. ### Limitazioni note {#known-limitations} * **Il ridimensionamento content-aware** si blocca su immagini grandi (>5 MP) a causa di una limitazione nel binario caire. Funziona bene con immagini più piccole. * **La decodifica HEIF** richiede 13-23 secondi. HEIC (la variante di Apple) è molto più veloce, tra 0,3 e 0,9 secondi. * **L'upscaling** va in timeout su CPU per qualsiasi cosa oltre le immagini piccole. GPU richiesta per un uso pratico. * **Il miglioramento dei volti CodeFormer** è significativamente più lento di GFPGAN (53s contro 2s su GPU). GFPGAN è consigliato per la maggior parte dei casi d'uso. ## Volumi {#volumes} | Mount / Volume | Scopo | Richiesto? | |---|---|---| | `/data` (app) | Modelli AI, venv Python, file utente | **Sì**, perdita di file senza | | `/tmp/workspace` (app) | File di elaborazione temporanei (puliti automaticamente) | Consigliato | | `SnapOtter-pgdata` (postgres) | Directory dei dati di PostgreSQL (utenti, impostazioni, pipeline, job) | **Sì**, perdita di dati senza | | `SnapOtter-redisdata` (redis) | File append-only di Redis per code di job durevoli | Consigliato | ### Bind mount contro volumi con nome {#bind-mounts-vs-named-volumes} **Volumi con nome** (consigliati), Docker gestisce automaticamente i permessi: ```yaml volumes: - SnapOtter-data:/data ``` **Bind mount**, gestisci tu i permessi. Imposta `PUID`/`PGID` per corrispondere all'utente del tuo host: ```yaml volumes: - ./SnapOtter-data:/data environment: - PUID=1000 # Your host UID (run: id -u) - PGID=1000 # Your host GID (run: id -g) ``` ### Permessi di archiviazione {#storage-permissions} SnapOtter scrive in due posizioni durante l'esecuzione: `/data` (file utente, log, modelli AI e il venv Python) e `/tmp/workspace` (area temporanea di elaborazione). Entrambe devono essere scrivibili dall'utente con cui gira il container. Se una delle due non lo è, il container **fallisce subito all'avvio** con un messaggio che indica la directory, l'UID/GID in esecuzione e come risolvere, invece di avviarsi "integro" e poi fallire al primo upload con un errore criptico. Il modo in cui vengono gestiti i permessi dipende da come viene avviato il container: **Predefinito (parte come root, scende a `snapotter`)**, l'entrypoint parte come root, corregge la proprietà dei volumi montati, poi scende all'utente non privilegiato `snapotter` tramite `gosu`. I volumi con nome funzionano senza alcuna configurazione. Per i bind mount, imposta `PUID`/`PGID` sul tuo utente host (sopra) in modo che i file che scrive siano di tua proprietà. **Kubernetes / OpenShift (non-root tramite `runAsUser`)**, avviato direttamente come utente non-root, il container non può fare il chown dei volumi da solo, quindi l'orchestratore deve renderli scrivibili. Imposta `fsGroup`: ```yaml securityContext: runAsUser: 999 runAsGroup: 999 fsGroup: 999 # makes mounted volumes writable by the pod ``` Le directory scrivibili dell'immagine sono di proprietà del gruppo GID 0 e scrivibili dal gruppo, quindi un pod in esecuzione con un **UID arbitrario** più il gruppo supplementare root (l'impostazione predefinita di OpenShift) può scrivere senza alcun `chown`. **TrueNAS Scale (e altre configurazioni con "UID estraneo")**, TrueNAS esegue le app come utente non-root (spesso `568:568`) e monta dataset host di proprietà di un utente diverso, quindi né l'entrypoint né `fsGroup` li rendono scrivibili da soli. Scegli una delle opzioni: * **Esegui l'app come root** (consigliato), lascia l'utente dell'app non impostato oppure impostalo su `0`, e lascia che l'entrypoint predefinito corregga i permessi e scenda a `snapotter`. * **Esegui come UID `999`**, imposta l'utente/gruppo dell'app su `999:999` (l'utente `snapotter` integrato in SnapOtter) in modo che corrisponda alla proprietà dell'immagine. * **`chown` il dataset host** sull'UID con cui gira il container, dalla shell di TrueNAS: ```bash # Usa l'UID dall'errore di avvio (oppure esegui `id` dentro il container) chown -R 568:568 /mnt// ``` L'errore di avvio indica l'UID esatto da usare, quindi il percorso più rapido è avviare l'app una volta, leggere il messaggio, poi `chown` (o modificare l'utente) di conseguenza. ## Variabili d'ambiente {#environment-variables} | Variabile | Predefinito | Descrizione | |---|---|---| | `AUTH_ENABLED` | `true` | Abilita/disabilita il requisito di login | | `DEFAULT_USERNAME` | `admin` | Nome utente admin iniziale | | `DEFAULT_PASSWORD` | `admin` | Password admin iniziale (cambio forzato al primo login) | | `MAX_UPLOAD_SIZE_MB` | `0` (illimitato) | Limite di upload per file in MB. L'immagine viene fornita con `0`; una build dai sorgenti parte da 100 | | `MAX_BATCH_SIZE` | `0` (illimitato) | Numero massimo di file per richiesta batch. L'immagine viene fornita con `0`; una build dai sorgenti parte da 100 | | `RATE_LIMIT_PER_MIN` | `1000` | Richieste API al minuto per IP (imposta 0 per disabilitare) | | `MAX_USERS` | `0` (illimitato) | Numero massimo di account utente | | `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Quali peer possono impostare l'IP del client tramite `X-Forwarded-For`. Solo reti private per impostazione predefinita | | `PUID` | `999` | Esegui con questo UID (per i permessi dei bind mount) | | `PGID` | `999` | Esegui con questo GID (per i permessi dei bind mount) | | `LOG_LEVEL` | `info` | Verbosità dei log: fatal, error, warn, info, debug, trace | | `CONCURRENT_JOBS` | `0` (auto) | Numero massimo di job di elaborazione AI in parallelo | | `SESSION_DURATION_HOURS` | `168` | Durata della sessione di login (7 giorni) | | `CORS_ORIGIN` | (vuoto) | Origini consentite separate da virgola, oppure vuoto per la stessa origine | ### Proxy in uscita e CA privata {#outbound-proxy-and-private-ca} Il contenitore ufficiale abilita il supporto proxy dell'ambiente di Node. Se SnapOtter deve raggiungere il repository di runtime OCR o altri servizi HTTPS tramite un proxy aziendale, impostare `HTTPS_PROXY` (e `HTTP_PROXY` quando necessario). Imposta `NO_PROXY` su un elenco separato da virgole di host che devono essere raggiunti direttamente, come Postgres, Redis e archiviazione di oggetti interni. Se il proxy o un servizio interno è firmato da un'autorità di certificazione privata, montare il certificato CA in sola lettura e puntarvi `NODE_EXTRA_CA_CERTS`. Il file deve esistere all'avvio del processo Node: ```yaml services: app: environment: HTTPS_PROXY: http://proxy.example.internal:3128 HTTP_PROXY: http://proxy.example.internal:3128 NO_PROXY: postgres,redis,minio,localhost,127.0.0.1 NODE_EXTRA_CA_CERTS: /etc/snapotter/custom-ca.pem volumes: - ./company-ca.pem:/etc/snapotter/custom-ca.pem:ro ``` Conserva le credenziali proxy all'esterno del file Compose (ad esempio in un file `.env` protetto o segreto). Non disabilitare la verifica TLS: l'indice OCR firmato autentica i metadati della release, mentre la normale validazione TLS protegge comunque il trasporto e ogni altra richiesta in uscita. ## Controllo di integrità {#health-check} Il container include un controllo di integrità integrato: ```bash # Check container health status docker inspect --format='{{.State.Health.Status}}' SnapOtter # Manual health check curl http://localhost:1349/api/v1/health # {"status":"healthy","version":"x.y.z"} ``` ## Reverse Proxy {#reverse-proxy} `TRUST_PROXY` vale `loopback,linklocal,uniquelocal` per impostazione predefinita, quindi SnapOtter crede all'intestazione `X-Forwarded-For` solo se arriva da un peer su una rete privata. Un reverse proxy sullo stesso host, su una rete Docker o sulla tua LAN è attendibile fin da subito, il che significa che il rate limiting, il limitatore anti forza bruta del login, il log di audit e la allowlist di IP dell'edizione enterprise vedono tutti l'IP reale del client senza alcuna configurazione. Imposta `TRUST_PROXY=true` solo quando il proxy davanti raggiunge SnapOtter da un indirizzo **pubblico**, per esempio un bilanciatore di carico cloud su un'altra rete. Su un'istanza esposta direttamente quel valore rende `request.ip` controllabile da un attaccante, perché chi ruota l'intestazione ottiene un contatore di rate limit nuovo a ogni richiesta. Due cose da sapere prima di metterti a misurare gli IP dei client. Docker Desktop su macOS e Windows serve una porta pubblicata attraverso un proxy in spazio utente che riscrive ogni indirizzo di origine sul gateway della VM `192.168.65.1`, quindi lì nessun valore di `TRUST_PROXY` recupera il client reale; per tutto ciò che è esposto a internet usa Linux. E su qualsiasi piattaforma, raggiungere una porta pubblicata tramite `localhost` viene osservato come il gateway del bridge e non come il tuo client, perciò una prova in locale non dice nulla su come venga attribuito un client reale. La tabella completa dei valori di `TRUST_PROXY` e l'avvertenza su Docker Desktop sono in [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy). Due cose contano per ogni proxy riportato di seguito: consentire corpi di richieste di grandi dimensioni (caricamenti) e non bufferizzare le risposte. Un proxy con buffer di risposta interrompe l'avanzamento di SSE e, in modo più visibile, fa sì che il download di un file di grandi dimensioni "avvii ma non finisca mai", perché il proxy trattiene l'intero file prima di trasmetterlo. SnapOtter invia `X-Accel-Buffering: no` sui download in modo che nginx li trasmetta in streaming anche se il buffering è lasciato attivo altrove, ma i proxy diversi da nginx necessitano che il buffering della risposta sia disabilitato esplicitamente (mostrato in ciascuna configurazione di seguito). Se un download si blocca parzialmente, la prima cosa da controllare è un proxy di buffering di fronte. ### Nginx {#nginx} ```nginx server { listen 80; server_name images.example.com; # Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited) client_max_body_size 500M; location / { proxy_pass http://localhost:1349; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Risposte in streaming anziché buffering: necessarie per l'avanzamento di SSE (batch, AI, installazioni di funzionalità) e per download di file di grandi dimensioni. proxy_buffering off; proxy_read_timeout 300s; } } ``` ### Nginx Proxy Manager {#nginx-proxy-manager} 1. Aggiungi un nuovo Proxy Host 2. Imposta Domain Name sul tuo dominio 3. Imposta Scheme su `http`, Forward Hostname su `SnapOtter` (o l'IP del tuo container), Forward Port su `1349` 4. Abilita il supporto WebSocket 5. In Advanced, aggiungi: `client_max_body_size 500M;` e `proxy_buffering off;` ### Traefik {#traefik} ```yaml # Add these labels to the SnapOtter service in docker-compose.yml labels: - "traefik.enable=true" - "traefik.http.routers.snapotter.rule=Host(`images.example.com`)" - "traefik.http.routers.snapotter.entrypoints=websecure" - "traefik.http.routers.snapotter.tls.certresolver=letsencrypt" - "traefik.http.services.snapotter.loadbalancer.server.port=1349" # Increase upload limit (default 2MB is too low) - "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000" - "traefik.http.routers.snapotter.middlewares=snapotter-body" ``` ### Caddy {#caddy} ```txt images.example.com { reverse_proxy localhost:1349 { flush_interval -1 transport http { read_timeout 300s write_timeout 300s } } } ``` `flush_interval -1` disabilita il buffering della risposta, necessario per gli eventi di avanzamento di SSE (elaborazione batch, strumenti AI, installazioni di funzionalità) e per lo streaming di download di file di grandi dimensioni anziché in stallo. I timeout estesi consentono il completamento dei caricamenti di file di grandi dimensioni senza che Caddy chiuda anticipatamente la connessione. ### Cloudflare Tunnels {#cloudflare-tunnels} ```bash cloudflared tunnel --url http://localhost:1349 ``` Nota: Cloudflare ha un limite di upload di 100 MB sui piani gratuiti. Imposta `MAX_UPLOAD_SIZE_MB=100` per corrispondere. ## CI/CD {#ci-cd} Il repository GitHub ha tre workflow: * **ci.yml**, viene eseguito automaticamente a ogni push e PR. Esegue lint, typecheck, test, build e valida l'immagine Docker (senza fare il push). * **release.yml**, attivato manualmente tramite `workflow_dispatch`. Esegue semantic-release per creare un tag di versione e una release GitHub, poi costruisce un'immagine Docker multi-arch (amd64 + arm64) e fa il push su Docker Hub (`snapotter/snapotter`) e GitHub Container Registry (`ghcr.io/snapotter-hq/snapotter`). * **deploy-docs.yml**, costruisce questo sito di documentazione e lo distribuisce su Cloudflare Pages al push su `main`. Per creare una release, vai su **Actions > Release > Run workflow** nell'interfaccia GitHub, oppure esegui: ```bash gh workflow run release.yml ``` Semantic-release determina la versione dalla cronologia dei commit. Il tag Docker `latest` punta sempre alla release più recente. ## Analytics {#analytics} SnapOtter include analytics di prodotto anonime (schemi di utilizzo degli strumenti, segnalazioni di errore) per aiutare a individuare i bug e migliorare le funzionalità. È attivo per impostazione predefinita. I tuoi file, i nomi dei file e i dati personali non ne fanno mai parte. SnapOtter funziona normalmente con le analytics disabilitate. ### Disabilitare le analytics {#disabling-analytics} La disattivazione a runtime è un interruttore admin con un solo clic. Apri Impostazioni > Sistema > Privacy e disattiva Anonymous Product Analytics. Si ferma immediatamente per l'intera istanza, senza bisogno di ricostruzione. Per un'immagine che non può mai emettere analytics, imposta la disattivazione definitiva al momento della build clonando il repository e ricostruendo: ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off docker compose -f docker/docker-compose.yml up -d ``` Oppure aggiungi il build arg al tuo `docker-compose.yml` esistente: ```yaml services: snapotter: build: context: . dockerfile: docker/Dockerfile args: SNAPOTTER_ANALYTICS: "off" ``` --- --- url: https://docs.snapotter.com/it/tools/files/split-csv.md description: Divide un CSV in file più piccoli in base al numero di righe. --- # Dividi CSV {#split-csv} Divide un file CSV o TSV di grandi dimensioni in file più piccoli in base al numero di righe. Restituisce un archivio ZIP contenente le parti. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/files/split-csv` Accetta dati di form multipart con un file CSV e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | rowsPerFile | integer | No | `1000` | Numero di righe di dati per file di output (1-1.000.000) | | keepHeader | boolean | No | `true` | Ripete la riga di intestazione in ogni file di output | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Note {#notes} * L'output è sempre un archivio ZIP contenente le parti CSV divise, denominate in sequenza (ad es. `part-1.csv`, `part-2.csv`). * Quando `keepHeader` è `true`, ogni parte include la riga di intestazione originale così che ogni file possa essere usato in modo indipendente. * Sono accettati come input sia file CSV che TSV. * Il conteggio delle righe si riferisce solo alle righe di dati; la riga di intestazione non viene conteggiata. --- --- url: https://docs.snapotter.com/it/tools/image/split.md description: >- Divide un'immagine in tessere a griglia per righe e colonne o per dimensione in pixel, restituite come archivio ZIP. --- # Dividi immagine {#image-splitting} Divide una singola immagine in tessere a griglia per numero di colonne/righe o per dimensioni specifiche in pixel. Restituisce un archivio ZIP contenente tutte le tessere. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/split` ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | columns | integer | No | 3 | Numero di colonne in cui dividere (da 1 a 100) | | rows | integer | No | 3 | Numero di righe in cui dividere (da 1 a 100) | | tileWidth | integer | No | - | Larghezza della tessera in pixel (min 10). Sovrascrive `columns` quando sono impostati sia `tileWidth` sia `tileHeight`. | | tileHeight | integer | No | - | Altezza della tessera in pixel (min 10). Sovrascrive `rows` quando sono impostati sia `tileWidth` sia `tileHeight`. | | outputFormat | string | No | `"original"` | Formato di output per le tessere: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Qualità dell'output per i formati con perdita (da 1 a 100) | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Esempio di risposta {#example-response} La risposta viene trasmessa direttamente come file ZIP con `Content-Type: application/zip`. Il nome del file segue lo schema `split-.zip`. Ogni tessera all'interno dello ZIP è denominata `_r_c.` (ad esempio `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Note {#notes} * Accetta un singolo file immagine. * Supporta i formati di input HEIC, RAW, PSD e SVG (decodificati automaticamente). * Quando vengono forniti sia `tileWidth` sia `tileHeight`, hanno la priorità su `columns`/`rows`. Le dimensioni della griglia vengono calcolate come `ceil(imageWidth / tileWidth)` e `ceil(imageHeight / tileHeight)`. * Le tessere di bordo (colonna più a destra, riga inferiore) possono essere più piccole della dimensione specificata se le dimensioni dell'immagine non sono divisibili in modo uniforme. * La dimensione massima della griglia è limitata a 100x100 (10.000 tessere). * La risposta trasmette lo ZIP direttamente, quindi non c'è un corpo di risposta JSON. Usa `--output` con curl per salvare il file. --- --- url: https://docs.snapotter.com/it/tools/pdf/split-pdf.md description: Estrai pagine o dividi un PDF in parti. --- # Dividi PDF {#split-pdf} Estrai un intervallo di pagine in un nuovo PDF, oppure dividi un documento in blocchi di N pagine. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/split-pdf` Accetta dati di form multipart con un file PDF e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"range"` | Modalità di divisione: `range` o `every` | | range | string | Quando mode è `range` | - | Intervallo di pagine nella sintassi qpdf, es. `"1-5,8,10-z"` | | everyN | integer | Quando mode è `every` | - | Dividi in blocchi di N pagine (1-500) | ## Example Request {#example-request} Estrai pagine specifiche: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "range", "range": "1-5,8"}' ``` Dividi in blocchi di 10 pagine: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "every", "everyN": 10}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 980000 } ``` ## Notes {#notes} * In modalità `range`, viene restituito un singolo PDF contenente le pagine selezionate. * In modalità `every`, il risultato è un archivio ZIP contenente le singole parti. * Gli intervalli di pagine usano la sintassi qpdf: `1-5` per le pagine da 1 a 5, `z` per l'ultima pagina, e le virgole per combinare gli intervalli (es. `1-3,7,10-z`). --- --- url: https://docs.snapotter.com/es/tools/audio/split-audio.md description: >- Divide el audio por intervalos de tiempo, partes iguales o detección de silencios. --- # Dividir audio {#split-audio} Divide un archivo de audio en segmentos por intervalos de tiempo fijos, partes iguales o detección automática de silencios. Devuelve un archivo ZIP con los segmentos. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/split-audio` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | mode | string | No | `"time"` | Estrategia de división: `time`, `parts`, `silence` | | segmentS | number | No | `60` | Longitud del segmento en segundos, 1 a 3600 (se usa cuando mode es `time`) | | parts | integer | No | `2` | Número de partes iguales, 2 a 20 (se usa cuando mode es `parts`) | | thresholdDb | number | No | `-40` | Umbral de silencio en dB, -80 a -20 (se usa cuando mode es `silence`) | | minSilenceS | number | No | `0.3` | Intervalo mínimo de silencio en segundos, 0.1 a 10 (se usa cuando mode es `silence`) | ## Ejemplo de solicitud {#example-request} Dividir en segmentos de 30 segundos: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "time", "segmentS": 30}' ``` Dividir por detección de silencios: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "silence", "thresholdDb": -35, "minSilenceS": 0.5}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio_parts.zip", "originalSize": 4500000, "processedSize": 4600000 } ``` ## Notas {#notes} * El `downloadUrl` apunta a un archivo ZIP que contiene todos los segmentos. * Solo se usan los parámetros relevantes para el `mode` elegido; los demás se ignoran. * Los nombres de archivo de los segmentos están numerados secuencialmente (p. ej. `part-000.mp3`, `part-001.mp3`). * El formato de salida coincide con el formato de entrada. --- --- url: https://docs.snapotter.com/pt-BR/tools/audio/split-audio.md description: Divida o áudio por intervalos de tempo, partes iguais ou detecção de silêncio. --- # Dividir Áudio {#split-audio} Divida um arquivo de áudio em segmentos por intervalos de tempo fixos, partes iguais ou detecção automática de silêncio. Retorna um arquivo ZIP com os segmentos. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/audio/split-audio` Aceita dados de formulário multipart com um arquivo de áudio e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | mode | string | Não | `"time"` | Estratégia de divisão: `time`, `parts`, `silence` | | segmentS | number | Não | `60` | Duração do segmento em segundos, 1 a 3600 (usado quando mode é `time`) | | parts | integer | Não | `2` | Número de partes iguais, 2 a 20 (usado quando mode é `parts`) | | thresholdDb | number | Não | `-40` | Limiar de silêncio em dB, -80 a -20 (usado quando mode é `silence`) | | minSilenceS | number | Não | `0.3` | Intervalo mínimo de silêncio em segundos, 0,1 a 10 (usado quando mode é `silence`) | ## Exemplo de Requisição {#example-request} Dividir em segmentos de 30 segundos: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "time", "segmentS": 30}' ``` Dividir por detecção de silêncio: ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/split-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"mode": "silence", "thresholdDb": -35, "minSilenceS": 0.5}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio_parts.zip", "originalSize": 4500000, "processedSize": 4600000 } ``` ## Notas {#notes} * O `downloadUrl` aponta para um arquivo ZIP contendo todos os segmentos. * Apenas os parâmetros relevantes para o `mode` escolhido são usados; os demais são ignorados. * Os nomes dos arquivos de segmento são numerados em sequência (ex.: `part-000.mp3`, `part-001.mp3`). * O formato de saída corresponde ao formato de entrada. --- --- url: https://docs.snapotter.com/es/tools/files/split-csv.md description: Divide un CSV en archivos más pequeños según el número de filas. --- # Dividir CSV {#split-csv} Divide un archivo CSV o TSV grande en archivos más pequeños según el número de filas. Devuelve un archivo ZIP que contiene las partes. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/split-csv` Acepta datos de formulario multipart con un archivo CSV y un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | rowsPerFile | integer | No | `1000` | Número de filas de datos por archivo de salida (1-1.000.000) | | keepHeader | boolean | No | `true` | Repetir la fila de encabezado en cada archivo de salida | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Notes {#notes} * La salida siempre es un archivo ZIP que contiene las partes del CSV dividido, nombradas secuencialmente (por ejemplo, `part-1.csv`, `part-2.csv`). * Cuando `keepHeader` es `true`, cada parte incluye la fila de encabezado original para que cada archivo pueda usarse de forma independiente. * Se aceptan tanto archivos CSV como TSV de entrada. * El número de filas se refiere solo a las filas de datos; la fila de encabezado no se cuenta. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/split-csv.md description: Divida um CSV em arquivos menores por contagem de linhas. --- # Dividir CSV {#split-csv} Divida um arquivo CSV ou TSV grande em arquivos menores por contagem de linhas. Retorna um arquivo ZIP contendo as partes. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/split-csv` Aceita dados de formulário multipart com um arquivo CSV e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | rowsPerFile | integer | Não | `1000` | Número de linhas de dados por arquivo de saída (1-1.000.000) | | keepHeader | boolean | Não | `true` | Repetir a linha de cabeçalho em cada arquivo de saída | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/split-csv \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@large-dataset.csv" \ -F 'settings={"rowsPerFile": 500, "keepHeader": true}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset_parts.zip", "originalSize": 1048576, "processedSize": 1050000 } ``` ## Observações {#notes} * A saída é sempre um arquivo ZIP contendo as partes CSV divididas, nomeadas sequencialmente (por exemplo, `part-1.csv`, `part-2.csv`). * Quando `keepHeader` é `true`, cada parte inclui a linha de cabeçalho original, para que cada arquivo possa ser usado de forma independente. * Arquivos CSV e TSV são aceitos como entrada. * A contagem de linhas refere-se apenas às linhas de dados; a linha de cabeçalho não é contada. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/split.md description: >- Divide uma imagem em blocos de grade por linhas e colunas ou por tamanho em pixels, retornados como um arquivo ZIP. --- # Dividir Imagem {#image-splitting} Divide uma única imagem em blocos de grade por contagem de colunas/linhas ou por dimensões específicas em pixels. Retorna um arquivo ZIP contendo todos os blocos. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/split` ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | columns | integer | Não | 3 | Número de colunas para dividir (1 a 100) | | rows | integer | Não | 3 | Número de linhas para dividir (1 a 100) | | tileWidth | integer | Não | - | Largura do bloco em pixels (mín. 10). Sobrepõe `columns` quando `tileWidth` e `tileHeight` estão definidos. | | tileHeight | integer | Não | - | Altura do bloco em pixels (mín. 10). Sobrepõe `rows` quando `tileWidth` e `tileHeight` estão definidos. | | outputFormat | string | Não | `"original"` | Formato de saída para os blocos: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | Não | 90 | Qualidade de saída para formatos com perdas (1 a 100) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Exemplo de Resposta {#example-response} A resposta é transmitida diretamente como um arquivo ZIP com `Content-Type: application/zip`. O nome do arquivo segue o padrão `split-.zip`. Cada bloco dentro do ZIP é nomeado `_r_c.` (por exemplo, `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Notas {#notes} * Aceita um único arquivo de imagem. * Suporta os formatos de entrada HEIC, RAW, PSD e SVG (decodificados automaticamente). * Quando `tileWidth` e `tileHeight` são fornecidos, eles têm prioridade sobre `columns`/`rows`. As dimensões da grade são calculadas como `ceil(imageWidth / tileWidth)` e `ceil(imageHeight / tileHeight)`. * Os blocos de borda (coluna mais à direita, linha inferior) podem ser menores que o tamanho de bloco especificado se as dimensões da imagem não forem divisíveis de forma exata. * O tamanho máximo da grade é limitado a 100x100 (10.000 blocos). * A resposta transmite o ZIP diretamente, portanto não há corpo de resposta JSON. Use `--output` com curl para salvar o arquivo. --- --- url: https://docs.snapotter.com/es/tools/image/split.md description: >- Divide una imagen en teselas de cuadrícula por filas y columnas o por tamaño en píxeles, devueltas como archivo ZIP. --- # Dividir imagen {#image-splitting} Divide una sola imagen en teselas de cuadrícula por número de columnas/filas o por dimensiones específicas en píxeles. Devuelve un archivo ZIP con todas las teselas. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/split` ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | columns | integer | No | 3 | Número de columnas en las que dividir (1 a 100) | | rows | integer | No | 3 | Número de filas en las que dividir (1 a 100) | | tileWidth | integer | No | - | Ancho de tesela en píxeles (mín. 10). Anula `columns` cuando se establecen tanto `tileWidth` como `tileHeight`. | | tileHeight | integer | No | - | Alto de tesela en píxeles (mín. 10). Anula `rows` cuando se establecen tanto `tileWidth` como `tileHeight`. | | outputFormat | string | No | `"original"` | Formato de salida de las teselas: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Calidad de salida para formatos con pérdida (1 a 100) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Ejemplo de respuesta {#example-response} La respuesta se transmite directamente como un archivo ZIP con `Content-Type: application/zip`. El nombre del archivo sigue el patrón `split-.zip`. Cada tesela dentro del ZIP se nombra `_r_c.` (por ejemplo, `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Notas {#notes} * Acepta un solo archivo de imagen. * Admite los formatos de entrada HEIC, RAW, PSD y SVG (decodificados automáticamente). * Cuando se proporcionan tanto `tileWidth` como `tileHeight`, tienen prioridad sobre `columns`/`rows`. Las dimensiones de la cuadrícula se calculan como `ceil(imageWidth / tileWidth)` y `ceil(imageHeight / tileHeight)`. * Las teselas de los bordes (columna más a la derecha, fila inferior) pueden ser más pequeñas que el tamaño de tesela especificado si las dimensiones de la imagen no son divisibles de forma exacta. * El tamaño máximo de la cuadrícula está limitado a 100x100 (10.000 teselas). * La respuesta transmite el ZIP directamente, por lo que no hay cuerpo de respuesta en JSON. Usa `--output` con curl para guardar el archivo. --- --- url: https://docs.snapotter.com/es/tools/pdf/split-pdf.md description: Extrae páginas o divide un PDF en partes. --- # Dividir PDF {#split-pdf} Extrae un rango de páginas a un nuevo PDF, o divide un documento en fragmentos de N páginas. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/split-pdf` Acepta datos de formulario multipart con un archivo PDF y un campo JSON `settings`. ## Parameters {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | mode | string | No | `"range"` | Modo de división: `range` o `every` | | range | string | Cuando el modo es `range` | - | Rango de páginas en sintaxis qpdf, p. ej. `"1-5,8,10-z"` | | everyN | integer | Cuando el modo es `every` | - | Dividir en fragmentos de N páginas (1-500) | ## Example Request {#example-request} Extraer páginas específicas: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "range", "range": "1-5,8"}' ``` Dividir en fragmentos de 10 páginas: ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "every", "everyN": 10}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 980000 } ``` ## Notes {#notes} * En el modo `range`, se devuelve un único PDF que contiene las páginas seleccionadas. * En el modo `every`, el resultado es un archivo ZIP que contiene las partes individuales. * Los rangos de páginas usan la sintaxis de qpdf: `1-5` para las páginas 1 a 5, `z` para la última página y comas para combinar rangos (p. ej. `1-3,7,10-z`). --- --- url: https://docs.snapotter.com/fr/tools/pdf/split-pdf.md description: Extraire des pages ou diviser un PDF en plusieurs parties. --- # Diviser un PDF {#split-pdf} Extrayez une plage de pages vers un nouveau PDF, ou divisez un document en blocs de N pages. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/split-pdf` Accepte des données de formulaire multipart avec un fichier PDF et un champ `settings` au format JSON. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | mode | string | Non | `"range"` | Mode de division : `range` ou `every` | | range | string | Lorsque le mode est `range` | - | Plage de pages en syntaxe qpdf, par exemple `"1-5,8,10-z"` | | everyN | integer | Lorsque le mode est `every` | - | Diviser en blocs de N pages (1-500) | ## Exemple de requête {#example-request} Extraire des pages spécifiques : ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "range", "range": "1-5,8"}' ``` Diviser en blocs de 10 pages : ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/split-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"mode": "every", "everyN": 10}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 980000 } ``` ## Remarques {#notes} * En mode `range`, un seul PDF contenant les pages sélectionnées est renvoyé. * En mode `every`, le résultat est une archive ZIP contenant les parties individuelles. * Les plages de pages utilisent la syntaxe qpdf : `1-5` pour les pages 1 à 5, `z` pour la dernière page, et des virgules pour combiner des plages (par exemple `1-3,7,10-z`). --- --- url: https://docs.snapotter.com/hi/guide/docker-tags.md description: >- SnapOtter Docker image टैग, GPU बेंचमार्क, वर्शन पिनिंग, और AMD64 तथा ARM64 के लिए मल्टी-प्लेटफ़ॉर्म समर्थन। --- # Docker Image {#docker-image} SnapOtter एक single Docker image के रूप में उपलब्ध है। इसे अकेले चलाएँ तो यह loopback interface पर एक embedded PostgreSQL 17 और Redis शुरू कर देता है (embedded mode); production के लिए, इसे Compose के साथ अलग PostgreSQL 17 और Redis 8 containers के साथ चलाएँ। app image सभी platforms पर काम करता है। ## Quick start {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` कोई `DATABASE_URL` सेट न होने पर, यह embedded mode में चलता है: PostgreSQL और Redis container के भीतर loopback पर शुरू होते हैं, और सारा data `SnapOtter-data` volume के अंतर्गत रहता है। बाहरी services का उपयोग करने के लिए `DATABASE_URL` और `REDIS_URL` सेट करें (जैसा [Compose](#docker-compose) stack करता है)। देखें [Configuration](/hi/guide/configuration#embedded-mode)। ## NVIDIA CUDA acceleration {#nvidia-cuda-acceleration} image में amd64 पर NVIDIA CUDA समर्थन शामिल है। यदि आपके पास [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) स्थापित के साथ एक NVIDIA GPU है, तो `--gpus all` जोड़ें: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` image runtime पर CUDA का स्वतः पता लगा लेता है। `--gpus all` के बिना, या जब CUDA अनुपलब्ध हो, AI tools CPU पर चलते हैं। दोनों ही स्थिति में वही image। VA-API, Quick Sync, या OpenCL के माध्यम से Intel/AMD iGPU acceleration फ़िलहाल SnapOtter AI inference के लिए समर्थित नहीं है। `/dev/dri` को container में map करने से render device उजागर हो सकता है, लेकिन जब तक CUDA उपलब्ध न हो, AI runtime फिर भी CPU का ही उपयोग करेगा। ### Benchmarks {#benchmarks} एक NVIDIA RTX 4070 (12 GB VRAM) पर 572x1024 JPEG portrait के साथ परीक्षित। #### Warm performance {#warm-performance} | Tool | CPU | GPU | Speedup | |------|-----|-----|---------| | Background removal (u2net) | 2,415ms | 879ms | 2.7x | | Background removal (isnet) | 2,457ms | 1,137ms | 2.2x | | Upscale 2x | 350ms | 309ms | 1.1x | | Upscale 4x | 910ms | 310ms | 2.9x | | Face blur | 139ms | 122ms | 1.1x | #### Cold start (container start के बाद पहला अनुरोध) {#cold-start-first-request-after-container-start} | Tool | CPU | GPU | Speedup | |------|-----|-----|---------| | Background removal | 22,286ms | 4,792ms | 4.7x | | Upscale 2x | 3,957ms | 2,318ms | 1.7x | OCR, CUDA तुलना में शामिल नहीं है। अंतर्निहित Tesseract टियर और वैकल्पिक RapidOCR/ONNX टियर दोनों CPU का उपयोग करते हैं, जिसमें कंटेनर में NVIDIA GPU एक्सेस शामिल है। ### CUDA health check {#cuda-health-check} पहले AI अनुरोध के बाद, admin health endpoint CUDA GPU status की रिपोर्ट देता है: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} पूर्ण Compose stack में app, PostgreSQL 17, और Redis 8 शामिल हैं। पूरे `docker-compose.yml` के लिए [Deployment](/hi/guide/deployment) देखें। एक न्यूनतम उदाहरण: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # गैर-स्थानीय तैनाती के लिए इसे बदलें POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Docker Compose के माध्यम से NVIDIA CUDA acceleration के लिए, SnapOtter service में deploy section जोड़ें: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Version pinning {#version-pinning} | Tag | Description | |-----|------------| | `latest` | नवीनतम release | | `2.2.0` | सटीक version | | `2.2` | 2.2.x में नवीनतम patch | | `2` | 2.x में नवीनतम minor | ## Platforms {#platforms} | Architecture | GPU support | Notes | |---|---|---| | linux/amd64 | NVIDIA CUDA | AI tools के लिए पूर्ण CUDA acceleration | | linux/arm64 | केवल CPU | Raspberry Pi 4/5, Docker Desktop के माध्यम से Apple Silicon | ## पिछले टैग से migration {#migration-from-previous-tags} यदि आप `:cuda` tag का उपयोग कर रहे थे, तो `:latest` पर स्विच करें और `--gpus all` रखें। वही GPU support, एकीकृत image। आपका data और settings volumes में संरक्षित रहते हैं। --- --- url: https://docs.snapotter.com/ko/guide/docker-tags.md description: SnapOtter Docker 이미지 태그, GPU 벤치마크, 버전 고정, AMD64 및 ARM64 멀티 플랫폼 지원. --- # Docker Image {#docker-image} SnapOtter는 단일 Docker 이미지로 제공됩니다. 자체적으로 실행하면 루프백 인터페이스에서 임베디드 PostgreSQL 17과 Redis를 시작합니다(임베디드 모드). 프로덕션 환경에서는 Compose로 별도의 PostgreSQL 17 및 Redis 8 컨테이너와 함께 실행하세요. 앱 이미지는 모든 플랫폼에서 동작합니다. ## Quick start {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` `DATABASE_URL`를 설정하지 않으면 임베디드 모드로 실행됩니다. PostgreSQL과 Redis가 컨테이너 내부의 루프백에서 시작되며, 모든 데이터는 `SnapOtter-data` 볼륨 아래에 저장됩니다. 외부 서비스를 대신 사용하려면 [Compose](#docker-compose) 스택이 하는 것처럼 `DATABASE_URL`과 `REDIS_URL`을 설정하세요. [Configuration](/ko/guide/configuration#embedded-mode)을 참고하세요. ## NVIDIA CUDA acceleration {#nvidia-cuda-acceleration} 이 이미지는 amd64에서 NVIDIA CUDA를 지원합니다. [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)이 설치된 NVIDIA GPU가 있다면 `--gpus all`를 추가하세요: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` 이 이미지는 런타임에 CUDA를 자동으로 감지합니다. `--gpus all`가 없거나 CUDA를 사용할 수 없는 경우, AI 도구는 CPU에서 실행됩니다. 어느 쪽이든 동일한 이미지입니다. VA-API, Quick Sync 또는 OpenCL을 통한 Intel/AMD iGPU 가속은 현재 SnapOtter AI 추론에서 지원되지 않습니다. `/dev/dri`을 컨테이너에 매핑하면 렌더 장치를 노출할 수 있지만, CUDA를 사용할 수 없는 한 AI 런타임은 여전히 CPU를 사용합니다. ### Benchmarks {#benchmarks} 572x1024 JPEG 인물 사진으로 NVIDIA RTX 4070(12 GB VRAM)에서 테스트했습니다. #### Warm performance {#warm-performance} | Tool | CPU | GPU | Speedup | |------|-----|-----|---------| | Background removal (u2net) | 2,415ms | 879ms | 2.7x | | Background removal (isnet) | 2,457ms | 1,137ms | 2.2x | | Upscale 2x | 350ms | 309ms | 1.1x | | Upscale 4x | 910ms | 310ms | 2.9x | | Face blur | 139ms | 122ms | 1.1x | #### Cold start (first request after container start) {#cold-start-first-request-after-container-start} | Tool | CPU | GPU | Speedup | |------|-----|-----|---------| | Background removal | 22,286ms | 4,792ms | 4.7x | | Upscale 2x | 3,957ms | 2,318ms | 1.7x | OCR 에 포함되지 않습니다 CUDA 비교. 둘 다 내장 Tesseract 계층 및 선택 사항 RapidOCR/ONNX 계층 사용 CPU, 컨테이너에 NVIDIA GPU 액세스 권한이 있는 경우도 포함됩니다. ### CUDA health check {#cuda-health-check} 첫 번째 AI 요청 이후, 관리자 상태 확인 엔드포인트가 CUDA GPU 상태를 보고합니다: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} 전체 Compose 스택에는 앱, PostgreSQL 17, Redis 8이 포함됩니다. 전체 `docker-compose.yml`는 [Deployment](/ko/guide/deployment)를 참고하세요. 최소 예시는 다음과 같습니다: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # 로컬이 아닌 배포의 경우 이를 변경합니다. POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Docker Compose를 통한 NVIDIA CUDA 가속을 위해서는 SnapOtter 서비스에 deploy 섹션을 추가하세요: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Version pinning {#version-pinning} | Tag | Description | |-----|------------| | `latest` | 최신 릴리스 | | `2.2.0` | 정확한 버전 | | `2.2` | 2.2.x의 최신 패치 | | `2` | 2.x의 최신 마이너 | ## Platforms {#platforms} | Architecture | GPU support | Notes | |---|---|---| | linux/amd64 | NVIDIA CUDA | AI 도구에 대한 완전한 CUDA 가속 | | linux/arm64 | CPU only | Raspberry Pi 4/5, Docker Desktop을 통한 Apple Silicon | ## Migration from previous tags {#migration-from-previous-tags} `:cuda` 태그를 사용하고 있었다면, `:latest`로 전환하고 `--gpus all`를 유지하세요. GPU 지원은 동일하며, 통합된 이미지입니다. 데이터와 설정은 볼륨에 보존됩니다. --- --- url: https://docs.snapotter.com/th/guide/docker-tags.md description: >- แท็กของ Docker image สำหรับ SnapOtter, การเปรียบเทียบประสิทธิภาพ GPU, การล็อกเวอร์ชัน และการรองรับหลายแพลตฟอร์มสำหรับ AMD64 และ ARM64 --- # Docker Image {#docker-image} SnapOtter เผยแพร่เป็น Docker image เพียงตัวเดียว รันมันเดี่ยว ๆ แล้วมันจะเริ่ม PostgreSQL 17 และ Redis แบบฝังตัวบนอินเทอร์เฟซ loopback (โหมดฝังตัว) สำหรับการใช้งานจริง ให้รันควบคู่ไปกับคอนเทนเนอร์ PostgreSQL 17 และ Redis 8 แยกต่างหากด้วย Compose แอป image นี้ทำงานได้บนทุกแพลตฟอร์ม ## เริ่มต้นอย่างรวดเร็ว {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` เมื่อไม่ได้ตั้งค่า `DATABASE_URL` ตัวนี้จะรันในโหมดฝังตัว: PostgreSQL และ Redis จะเริ่มทำงานภายในคอนเทนเนอร์บน loopback โดยเก็บข้อมูลทั้งหมดไว้ใต้ volume `SnapOtter-data` ตั้งค่า `DATABASE_URL` และ `REDIS_URL` (อย่างที่สแตก [Compose](#docker-compose) ทำ) เพื่อใช้บริการภายนอกแทน ดู [การกำหนดค่า](/th/guide/configuration#embedded-mode) ## การเร่งความเร็วด้วย NVIDIA CUDA {#nvidia-cuda-acceleration} image นี้มีการรองรับ NVIDIA CUDA บน amd64 หากคุณมี NVIDIA GPU พร้อมติดตั้ง [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) แล้ว ให้เพิ่ม `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` image จะตรวจจับ CUDA โดยอัตโนมัติในขณะรัน หากไม่มี `--gpus all` หรือเมื่อ CUDA ไม่พร้อมใช้งาน เครื่องมือ AI จะรันบน CPU ใช้ image เดียวกันได้ทั้งสองแบบ การเร่งความเร็วด้วย iGPU ของ Intel/AMD ผ่าน VA-API, Quick Sync หรือ OpenCL ยังไม่รองรับสำหรับการอนุมาน AI ของ SnapOtter ในปัจจุบัน การแมป `/dev/dri` เข้าไปในคอนเทนเนอร์อาจเปิดเผยอุปกรณ์ render ได้ แต่รันไทม์ AI จะยังคงใช้ CPU เว้นแต่จะมี CUDA พร้อมใช้งาน ### การเปรียบเทียบประสิทธิภาพ {#benchmarks} ทดสอบบน NVIDIA RTX 4070 (VRAM 12 GB) ด้วยภาพบุคคล JPEG ขนาด 572x1024 #### ประสิทธิภาพแบบ warm {#warm-performance} | เครื่องมือ | CPU | GPU | เร็วขึ้น | |------|-----|-----|---------| | การลบพื้นหลัง (u2net) | 2,415ms | 879ms | 2.7x | | การลบพื้นหลัง (isnet) | 2,457ms | 1,137ms | 2.2x | | ขยายภาพ 2x | 350ms | 309ms | 1.1x | | ขยายภาพ 4x | 910ms | 310ms | 2.9x | | เบลอใบหน้า | 139ms | 122ms | 1.1x | #### Cold start (คำขอแรกหลังเริ่มคอนเทนเนอร์) {#cold-start-first-request-after-container-start} | เครื่องมือ | CPU | GPU | เร็วขึ้น | |------|-----|-----|---------| | การลบพื้นหลัง | 22,286ms | 4,792ms | 4.7x | | ขยายภาพ 2x | 3,957ms | 2,318ms | 1.7x | OCR ไม่รวมอยู่ในการเปรียบเทียบ CUDA ทั้งเทียร์ Tesseract ในตัวและเทียร์ RapidOCR/ONNX เสริมใช้ CPU รวมถึงเมื่อคอนเทนเนอร์มีสิทธิ์เข้าถึง NVIDIA GPU ### การตรวจสอบสถานะ CUDA {#cuda-health-check} หลังจากคำขอ AI ครั้งแรก endpoint สำหรับตรวจสอบสถานะของผู้ดูแลระบบจะรายงานสถานะ CUDA GPU: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} สแตก Compose แบบเต็มประกอบด้วยแอป, PostgreSQL 17 และ Redis 8 ดู [การนำไปใช้งาน](/th/guide/deployment) สำหรับ `docker-compose.yml` ฉบับสมบูรณ์ ตัวอย่างขั้นต่ำ: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # เปลี่ยนสิ่งนี้สำหรับการปรับใช้ที่ไม่ใช่ภายในเครื่อง POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` สำหรับการเร่งความเร็วด้วย NVIDIA CUDA ผ่าน Docker Compose ให้เพิ่มส่วน deploy เข้าไปในบริการ SnapOtter: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## การล็อกเวอร์ชัน {#version-pinning} | แท็ก | คำอธิบาย | |-----|------------| | `latest` | รุ่นล่าสุด | | `2.2.0` | เวอร์ชันที่ระบุแน่นอน | | `2.2` | patch ล่าสุดใน 2.2.x | | `2` | minor ล่าสุดใน 2.x | ## แพลตฟอร์ม {#platforms} | สถาปัตยกรรม | การรองรับ GPU | หมายเหตุ | |---|---|---| | linux/amd64 | NVIDIA CUDA | การเร่งความเร็ว CUDA เต็มรูปแบบสำหรับเครื่องมือ AI | | linux/arm64 | CPU เท่านั้น | Raspberry Pi 4/5, Apple Silicon ผ่าน Docker Desktop | ## การย้ายจากแท็กก่อนหน้า {#migration-from-previous-tags} หากคุณเคยใช้แท็ก `:cuda` ให้เปลี่ยนไปใช้ `:latest` และคง `--gpus all` ไว้ การรองรับ GPU เหมือนเดิม เป็น image ที่รวมเป็นหนึ่งเดียว ข้อมูลและการตั้งค่าของคุณจะถูกเก็บรักษาไว้ใน volume --- --- url: https://docs.snapotter.com/vi/guide/docker-tags.md description: >- Các thẻ image Docker của SnapOtter, benchmark GPU, ghim phiên bản và hỗ trợ đa nền tảng cho AMD64 và ARM64. --- # Docker Image {#docker-image} SnapOtter được phân phối dưới dạng một image Docker duy nhất. Chạy image này một mình thì nó sẽ khởi động một PostgreSQL 17 và Redis nhúng trên giao diện loopback (chế độ nhúng); với môi trường production, hãy chạy nó cùng với các container PostgreSQL 17 và Redis 8 riêng biệt qua Compose. Image ứng dụng hoạt động trên mọi nền tảng. ## Bắt đầu nhanh {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Khi không đặt `DATABASE_URL`, image chạy ở chế độ nhúng: PostgreSQL và Redis khởi động bên trong container trên loopback, với toàn bộ dữ liệu nằm dưới volume `SnapOtter-data`. Đặt `DATABASE_URL` và `REDIS_URL` (như stack [Compose](#docker-compose) làm) để dùng các dịch vụ bên ngoài thay thế. Xem [Cấu hình](/vi/guide/configuration#embedded-mode). ## Tăng tốc NVIDIA CUDA {#nvidia-cuda-acceleration} Image bao gồm hỗ trợ NVIDIA CUDA trên amd64. Nếu bạn có GPU NVIDIA đã cài [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html), hãy thêm `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Image tự động phát hiện CUDA khi chạy. Nếu không có `--gpus all`, hoặc khi CUDA không khả dụng, các công cụ AI chạy trên CPU. Vẫn cùng một image trong cả hai trường hợp. Tăng tốc iGPU của Intel/AMD thông qua VA-API, Quick Sync hoặc OpenCL hiện không được hỗ trợ cho suy luận AI của SnapOtter. Việc ánh xạ `/dev/dri` vào container có thể lộ thiết bị render, nhưng runtime AI vẫn sẽ dùng CPU trừ khi có CUDA. ### Benchmark {#benchmarks} Được kiểm thử trên NVIDIA RTX 4070 (12 GB VRAM) với một ảnh chân dung JPEG 572x1024. #### Hiệu năng khi đã khởi động {#warm-performance} | Công cụ | CPU | GPU | Tăng tốc | |------|-----|-----|---------| | Xóa nền (u2net) | 2,415ms | 879ms | 2.7x | | Xóa nền (isnet) | 2,457ms | 1,137ms | 2.2x | | Phóng đại 2x | 350ms | 309ms | 1.1x | | Phóng đại 4x | 910ms | 310ms | 2.9x | | Làm mờ khuôn mặt | 139ms | 122ms | 1.1x | #### Khởi động nguội (yêu cầu đầu tiên sau khi container khởi động) {#cold-start-first-request-after-container-start} | Công cụ | CPU | GPU | Tăng tốc | |------|-----|-----|---------| | Xóa nền | 22,286ms | 4,792ms | 4.7x | | Phóng đại 2x | 3,957ms | 2,318ms | 1.7x | OCR không được đưa vào so sánh CUDA. Cả tầng Tesseract tích hợp và tầng RapidOCR/ONNX tùy chọn đều sử dụng CPU, kể cả khi vùng chứa có quyền truy cập NVIDIA GPU. ### Kiểm tra tình trạng CUDA {#cuda-health-check} Sau yêu cầu AI đầu tiên, endpoint kiểm tra tình trạng của admin sẽ báo cáo trạng thái GPU CUDA: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} Stack Compose đầy đủ bao gồm ứng dụng, PostgreSQL 17 và Redis 8. Xem [Triển khai](/vi/guide/deployment) để có `docker-compose.yml` hoàn chỉnh. Một ví dụ tối giản: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Thay đổi điều này cho việc triển khai không cục bộ POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Để tăng tốc NVIDIA CUDA qua Docker Compose, hãy thêm phần deploy vào dịch vụ SnapOtter: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Ghim phiên bản {#version-pinning} | Thẻ | Mô tả | |-----|------------| | `latest` | Bản phát hành mới nhất | | `2.2.0` | Phiên bản chính xác | | `2.2` | Bản vá mới nhất trong 2.2.x | | `2` | Bản minor mới nhất trong 2.x | ## Nền tảng {#platforms} | Kiến trúc | Hỗ trợ GPU | Ghi chú | |---|---|---| | linux/amd64 | NVIDIA CUDA | Tăng tốc CUDA đầy đủ cho các công cụ AI | | linux/arm64 | Chỉ CPU | Raspberry Pi 4/5, Apple Silicon qua Docker Desktop | ## Chuyển đổi từ các thẻ trước đó {#migration-from-previous-tags} Nếu bạn đang dùng thẻ `:cuda`, hãy chuyển sang `:latest` và giữ `--gpus all`. Cùng hỗ trợ GPU, image hợp nhất. Dữ liệu và cài đặt của bạn được bảo toàn trong các volume. --- --- url: https://docs.snapotter.com/tr/guide/docker-tags.md description: >- SnapOtter Docker imaj etiketleri, GPU karşılaştırmaları, sürüm sabitleme ve AMD64 ile ARM64 için çoklu platform desteği. --- # Docker İmajı {#docker-image} SnapOtter tek bir Docker imajı olarak dağıtılır. Tek başına çalıştırdığınızda, loopback arayüzünde gömülü bir PostgreSQL 17 ve Redis başlatır (gömülü mod); üretim için, Compose ile ayrı PostgreSQL 17 ve Redis 8 konteynerlerinin yanında çalıştırın. Uygulama imajı tüm platformlarda çalışır. ## Hızlı başlangıç {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Hiçbir `DATABASE_URL` ayarlanmadığında bu, gömülü modda çalışır: PostgreSQL ve Redis konteyner içinde loopback üzerinde başlar ve tüm veriler `SnapOtter-data` birimi altında tutulur. Bunun yerine harici hizmetleri kullanmak için `DATABASE_URL` ve `REDIS_URL` ayarlayın ([Compose](#docker-compose) yığınının yaptığı gibi). Bkz. [Yapılandırma](/tr/guide/configuration#embedded-mode). ## NVIDIA CUDA hızlandırması {#nvidia-cuda-acceleration} İmaj, amd64 üzerinde NVIDIA CUDA desteği içerir. [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) kurulu bir NVIDIA GPU'nuz varsa `--gpus all` ekleyin: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` İmaj, CUDA'yı çalışma zamanında otomatik olarak algılar. `--gpus all` olmadan veya CUDA kullanılamadığında, AI araçları CPU üzerinde çalışır. Her iki durumda da aynı imaj. Intel/AMD iGPU hızlandırması, VA-API, Quick Sync veya OpenCL aracılığıyla, bugün SnapOtter AI çıkarımı için desteklenmemektedir. `/dev/dri` öğesini konteyner içine eşlemek render aygıtını açığa çıkarabilir, ancak CUDA kullanılabilir olmadıkça AI çalışma zamanı yine de CPU kullanır. ### Karşılaştırmalar {#benchmarks} 572x1024 boyutunda bir JPEG portresiyle bir NVIDIA RTX 4070 (12 GB VRAM) üzerinde test edildi. #### Sıcak performans {#warm-performance} | Araç | CPU | GPU | Hızlanma | |------|-----|-----|---------| | Arka plan kaldırma (u2net) | 2.415ms | 879ms | 2,7x | | Arka plan kaldırma (isnet) | 2.457ms | 1.137ms | 2,2x | | 2x büyütme | 350ms | 309ms | 1,1x | | 4x büyütme | 910ms | 310ms | 2,9x | | Yüz bulanıklaştırma | 139ms | 122ms | 1,1x | #### Soğuk başlangıç (konteyner başlangıcından sonraki ilk istek) {#cold-start-first-request-after-container-start} | Araç | CPU | GPU | Hızlanma | |------|-----|-----|---------| | Arka plan kaldırma | 22.286ms | 4.792ms | 4,7x | | 2x büyütme | 3.957ms | 2.318ms | 1,7x | OCR, CUDA karşılaştırmasına dahil değildir. Hem yerleşik Tesseract katmanı hem de isteğe bağlı RapidOCR/ONNX katmanları, konteynerin NVIDIA GPU erişimine sahip olduğu durumlar da dahil olmak üzere CPU kullanır. ### CUDA sağlık kontrolü {#cuda-health-check} İlk AI isteğinden sonra, yönetici sağlık uç noktası CUDA GPU durumunu raporlar: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} Tam Compose yığını uygulamayı, PostgreSQL 17'yi ve Redis 8'i içerir. Eksiksiz `docker-compose.yml` için bkz. [Dağıtım](/tr/guide/deployment). Minimal bir örnek: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Yerel olmayan dağıtımlar için bunu değiştirin POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Docker Compose aracılığıyla NVIDIA CUDA hızlandırması için, SnapOtter hizmetine deploy bölümünü ekleyin: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Sürüm sabitleme {#version-pinning} | Etiket | Açıklama | |-----|------------| | `latest` | En son sürüm | | `2.2.0` | Tam sürüm | | `2.2` | 2.2.x içindeki en son yama | | `2` | 2.x içindeki en son ara sürüm | ## Platformlar {#platforms} | Mimari | GPU desteği | Notlar | |---|---|---| | linux/amd64 | NVIDIA CUDA | AI araçları için tam CUDA hızlandırması | | linux/arm64 | Yalnızca CPU | Raspberry Pi 4/5, Docker Desktop aracılığıyla Apple Silicon | ## Önceki etiketlerden geçiş {#migration-from-previous-tags} `:cuda` etiketini kullanıyorduysanız, `:latest` öğesine geçin ve `--gpus all` öğesini koruyun. Aynı GPU desteği, birleşik imaj. Verileriniz ve ayarlarınız birimlerde korunur. --- --- url: https://docs.snapotter.com/ja/guide/docker-tags.md description: SnapOtter の Docker イメージタグ、GPU ベンチマーク、バージョン固定、および AMD64 と ARM64 のマルチプラットフォーム対応。 --- # Docker イメージ {#docker-image} SnapOtter は単一の Docker イメージとして提供されます。単独で実行すると、ループバックインターフェイス上で組み込みの PostgreSQL 17 と Redis を起動します(組み込みモード)。本番環境では、Compose を使って別々の PostgreSQL 17 と Redis 8 のコンテナと並行して実行してください。アプリケーションイメージはすべてのプラットフォームで動作します。 ## クイックスタート {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` `DATABASE_URL` を設定していない場合、これは組み込みモードで実行されます。PostgreSQL と Redis がコンテナ内のループバック上で起動し、すべてのデータは `SnapOtter-data` ボリューム配下に保存されます。外部サービスを使う場合は、([Compose](#docker-compose) スタックが行っているように)`DATABASE_URL` と `REDIS_URL` を設定してください。[設定](/ja/guide/configuration#embedded-mode) を参照してください。 ## NVIDIA CUDA アクセラレーション {#nvidia-cuda-acceleration} イメージには amd64 上での NVIDIA CUDA サポートが含まれています。[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) をインストールした NVIDIA GPU を使用している場合は、`--gpus all` を追加してください: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` イメージは実行時に CUDA を自動検出します。`--gpus all` を指定しない場合、または CUDA が利用できない場合、AI ツールは CPU 上で実行されます。どちらの場合も同じイメージです。 VA-API、Quick Sync、または OpenCL を通じた Intel/AMD の iGPU アクセラレーションは、現時点では SnapOtter の AI 推論には対応していません。`/dev/dri` をコンテナにマッピングすればレンダーデバイスを公開できますが、CUDA が利用可能でない限り、AI ランタイムは引き続き CPU を使用します。 ### ベンチマーク {#benchmarks} 572x1024 の JPEG ポートレートを使い、NVIDIA RTX 4070(12 GB VRAM)でテストしました。 #### ウォーム時の性能 {#warm-performance} | ツール | CPU | GPU | 高速化 | |------|-----|-----|---------| | 背景除去 (u2net) | 2,415ms | 879ms | 2.7x | | 背景除去 (isnet) | 2,457ms | 1,137ms | 2.2x | | 2x アップスケール | 350ms | 309ms | 1.1x | | 4x アップスケール | 910ms | 310ms | 2.9x | | 顔ぼかし | 139ms | 122ms | 1.1x | #### コールドスタート(コンテナ起動後の最初のリクエスト) {#cold-start-first-request-after-container-start} | ツール | CPU | GPU | 高速化 | |------|-----|-----|---------| | 背景除去 | 22,286ms | 4,792ms | 4.7x | | 2x アップスケール | 3,957ms | 2,318ms | 1.7x | OCR は、CUDA の比較には含まれません。組み込みの Tesseract 層とオプションの RapidOCR/ONNX 層は両方とも、コンテナーに NVIDIA GPU アクセス権がある場合を含め、CPU を使用します。 ### CUDA ヘルスチェック {#cuda-health-check} 最初の AI リクエストの後、管理者向けヘルスエンドポイントが CUDA GPU のステータスを報告します: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} 完全な Compose スタックには、アプリ、PostgreSQL 17、Redis 8 が含まれます。完全な `docker-compose.yml` については [デプロイ](/ja/guide/deployment) を参照してください。最小限の例: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # 非ローカル展開の場合はこれを変更します POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Docker Compose 経由の NVIDIA CUDA アクセラレーションには、SnapOtter サービスに deploy セクションを追加してください: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## バージョン固定 {#version-pinning} | タグ | 説明 | |-----|------------| | `latest` | 最新リリース | | `2.2.0` | 正確なバージョン | | `2.2` | 2.2.x の最新パッチ | | `2` | 2.x の最新マイナー | ## プラットフォーム {#platforms} | アーキテクチャ | GPU サポート | 備考 | |---|---|---| | linux/amd64 | NVIDIA CUDA | AI ツールの完全な CUDA アクセラレーション | | linux/arm64 | CPU のみ | Raspberry Pi 4/5、Docker Desktop 経由の Apple Silicon | ## 以前のタグからの移行 {#migration-from-previous-tags} `:cuda` タグを使用していた場合は、`:latest` に切り替えて `--gpus all` をそのまま使用してください。GPU サポートは同じで、統合されたイメージです。 データと設定はボリューム内に保持されます。 --- --- url: https://docs.snapotter.com/zh-TW/guide/docker-tags.md description: SnapOtter Docker 映像標籤、GPU 效能基準、版本鎖定,以及 AMD64 與 ARM64 的多平台支援。 --- # Docker 映像 {#docker-image} SnapOtter 以單一 Docker 映像的形式發佈。單獨執行時,它會在 loopback 介面上啟動內嵌的 PostgreSQL 17 與 Redis(內嵌模式);若用於正式環境,請透過 Compose 讓它與獨立的 PostgreSQL 17 和 Redis 8 容器一同執行。此應用映像可在所有平台上運作。 ## 快速開始 {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` 若未設定 `DATABASE_URL`,這會以內嵌模式執行:PostgreSQL 與 Redis 會在容器內的 loopback 上啟動,所有資料都存放在 `SnapOtter-data` 磁碟區下。設定 `DATABASE_URL` 與 `REDIS_URL`(就像 [Compose](#docker-compose) 堆疊那樣)即可改用外部服務。請參閱 [設定](/zh-TW/guide/configuration#embedded-mode)。 ## NVIDIA CUDA 加速 {#nvidia-cuda-acceleration} 此映像在 amd64 上內含 NVIDIA CUDA 支援。如果你有 NVIDIA GPU 並已安裝 [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html),請加上 `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` 此映像會在執行階段自動偵測 CUDA。若沒有 `--gpus all`,或當 CUDA 無法使用時,AI 工具會在 CPU 上執行。兩種情況都是同一個映像。 目前 SnapOtter 的 AI 推論尚不支援透過 VA-API、Quick Sync 或 OpenCL 進行 Intel/AMD iGPU 加速。將 `/dev/dri` 對應進容器可以公開繪圖裝置,但除非 CUDA 可用,否則 AI 執行環境仍會使用 CPU。 ### 效能基準 {#benchmarks} 在 NVIDIA RTX 4070(12 GB VRAM)上使用一張 572x1024 的 JPEG 人像測試。 #### 暖啟動效能 {#warm-performance} | 工具 | CPU | GPU | 加速倍率 | |------|-----|-----|---------| | 背景移除(u2net) | 2,415ms | 879ms | 2.7x | | 背景移除(isnet) | 2,457ms | 1,137ms | 2.2x | | 放大 2x | 350ms | 309ms | 1.1x | | 放大 4x | 910ms | 310ms | 2.9x | | 臉部模糊 | 139ms | 122ms | 1.1x | #### 冷啟動(容器啟動後的第一次請求) {#cold-start-first-request-after-container-start} | 工具 | CPU | GPU | 加速倍率 | |------|-----|-----|---------| | 背景移除 | 22,286ms | 4,792ms | 4.7x | | 放大 2x | 3,957ms | 2,318ms | 1.7x | OCR 不包含在 CUDA 比較中。內建 Tesseract 圖層和選購的 RapidOCR/ONNX 層都使用 CPU,包括當容器具有 NVIDIA GPU 存取權時。 ### CUDA 健康檢查 {#cuda-health-check} 在第一次 AI 請求之後,管理員健康檢查端點會回報 CUDA GPU 狀態: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} 完整的 Compose 堆疊包含應用程式、PostgreSQL 17 與 Redis 8。完整的 `docker-compose.yml` 請參閱 [部署](/zh-TW/guide/deployment)。一個最精簡的範例: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # 針對非本地部署更改此設置 POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` 若要透過 Docker Compose 進行 NVIDIA CUDA 加速,請將 deploy 區段加入 SnapOtter 服務: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## 版本鎖定 {#version-pinning} | 標籤 | 說明 | |-----|------------| | `latest` | 最新版本 | | `2.2.0` | 明確版本 | | `2.2` | 2.2.x 中的最新修補版 | | `2` | 2.x 中的最新次要版 | ## 平台 {#platforms} | 架構 | GPU 支援 | 備註 | |---|---|---| | linux/amd64 | NVIDIA CUDA | AI 工具的完整 CUDA 加速 | | linux/arm64 | 僅 CPU | Raspberry Pi 4/5、透過 Docker Desktop 的 Apple Silicon | ## 從舊標籤遷移 {#migration-from-previous-tags} 如果你之前使用 `:cuda` 標籤,請改用 `:latest` 並保留 `--gpus all`。相同的 GPU 支援,統一的映像。 你的資料與設定會保留在磁碟區中。 --- --- url: https://docs.snapotter.com/zh-CN/guide/docker-tags.md description: SnapOtter Docker 镜像标签、GPU 基准测试、版本锁定,以及对 AMD64 和 ARM64 的多平台支持。 --- # Docker 镜像 {#docker-image} SnapOtter 以单个 Docker 镜像发布。单独运行它时,会在回环接口上启动内嵌的 PostgreSQL 17 和 Redis(内嵌模式);用于生产环境时,请通过 Compose 让它与独立的 PostgreSQL 17 和 Redis 8 容器一起运行。该应用镜像可在所有平台上运行。 ## 快速开始 {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` 未设置 `DATABASE_URL` 时,它会以内嵌模式运行:PostgreSQL 和 Redis 在容器内部的回环接口上启动,所有数据都保存在 `SnapOtter-data` 卷下。设置 `DATABASE_URL` 和 `REDIS_URL`(就像 [Compose](#docker-compose) 栈那样)即可改用外部服务。请参阅[配置](/zh-CN/guide/configuration#embedded-mode)。 ## NVIDIA CUDA 加速 {#nvidia-cuda-acceleration} 该镜像在 amd64 上包含 NVIDIA CUDA 支持。如果你有一块 NVIDIA GPU 并已安装 [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html),请添加 `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` 该镜像会在运行时自动检测 CUDA。没有 `--gpus all` 或 CUDA 不可用时,AI 工具会在 CPU 上运行。两种情况使用同一个镜像。 目前不支持通过 VA-API、Quick Sync 或 OpenCL 使用 Intel/AMD 核显加速 SnapOtter 的 AI 推理。将 `/dev/dri` 映射到容器中可以暴露渲染设备,但除非 CUDA 可用,否则 AI 运行时仍会使用 CPU。 ### 基准测试 {#benchmarks} 在一块 NVIDIA RTX 4070(12 GB 显存)上,使用一张 572x1024 的 JPEG 人像进行了测试。 #### 热态性能 {#warm-performance} | 工具 | CPU | GPU | 加速比 | |------|-----|-----|---------| | 背景去除(u2net) | 2,415ms | 879ms | 2.7x | | 背景去除(isnet) | 2,457ms | 1,137ms | 2.2x | | 放大 2x | 350ms | 309ms | 1.1x | | 放大 4x | 910ms | 310ms | 2.9x | | 人脸模糊 | 139ms | 122ms | 1.1x | #### 冷启动(容器启动后的首次请求) {#cold-start-first-request-after-container-start} | 工具 | CPU | GPU | 加速比 | |------|-----|-----|---------| | 背景去除 | 22,286ms | 4,792ms | 4.7x | | 放大 2x | 3,957ms | 2,318ms | 1.7x | OCR 不包含在 CUDA 比较中。内置 Tesseract 层和可选的 RapidOCR/ONNX 层都使用 CPU,包括当容器具有 NVIDIA GPU 访问权限时。 ### CUDA 健康检查 {#cuda-health-check} 在首次 AI 请求之后,管理员健康端点会报告 CUDA GPU 状态: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} 完整的 Compose 栈包括应用、PostgreSQL 17 和 Redis 8。完整的 `docker-compose.yml` 请参阅[部署](/zh-CN/guide/deployment)。一个最小示例: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # 针对非本地部署更改此设置 POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` 若要通过 Docker Compose 使用 NVIDIA CUDA 加速,请在 SnapOtter 服务中添加 deploy 部分: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## 版本锁定 {#version-pinning} | 标签 | 说明 | |-----|------------| | `latest` | 最新发布版 | | `2.2.0` | 精确版本 | | `2.2` | 2.2.x 中的最新补丁版 | | `2` | 2.x 中的最新次版本 | ## 平台 {#platforms} | 架构 | GPU 支持 | 备注 | |---|---|---| | linux/amd64 | NVIDIA CUDA | AI 工具的完整 CUDA 加速 | | linux/arm64 | 仅 CPU | Raspberry Pi 4/5、通过 Docker Desktop 运行的 Apple Silicon | ## 从旧标签迁移 {#migration-from-previous-tags} 如果你之前使用的是 `:cuda` 标签,请切换到 `:latest` 并保留 `--gpus all`。GPU 支持相同,镜像已统一。 你的数据和设置会保留在卷中。 --- --- url: https://docs.snapotter.com/sv/guide/docker-tags.md description: >- SnapOtters Docker-avbildningstaggar, GPU-benchmarks, versionslåsning och stöd för flera plattformar för AMD64 och ARM64. --- # Docker-avbildning {#docker-image} SnapOtter levereras som en enda Docker-avbildning. Kör den fristående så startar den en inbäddad PostgreSQL 17 och Redis på loopback-gränssnittet (inbäddat läge); i produktion kör du den tillsammans med separata containrar för PostgreSQL 17 och Redis 8 med Compose. App-avbildningen fungerar på alla plattformar. ## Snabbstart {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Utan att `DATABASE_URL` är satt körs detta i inbäddat läge: PostgreSQL och Redis startar inuti containern på loopback, med all data under volymen `SnapOtter-data`. Sätt `DATABASE_URL` och `REDIS_URL` (som [Compose](#docker-compose)-stacken gör) för att använda externa tjänster i stället. Se [Konfiguration](/sv/guide/configuration#embedded-mode). ## NVIDIA CUDA-acceleration {#nvidia-cuda-acceleration} Avbildningen inkluderar stöd för NVIDIA CUDA på amd64. Om du har en NVIDIA-GPU med [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) installerat lägger du till `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Avbildningen upptäcker CUDA automatiskt vid körning. Utan `--gpus all`, eller när CUDA inte är tillgängligt, körs AI-verktygen på CPU. Samma avbildning oavsett. Acceleration med Intel/AMD iGPU via VA-API, Quick Sync eller OpenCL stöds inte för SnapOtters AI-inferens i dag. Att mappa in `/dev/dri` i containern kan exponera renderingsenheten, men AI-körtiden använder fortfarande CPU om inte CUDA finns tillgängligt. ### Benchmarks {#benchmarks} Testat på en NVIDIA RTX 4070 (12 GB VRAM) med ett 572x1024 JPEG-porträtt. #### Varm prestanda {#warm-performance} | Verktyg | CPU | GPU | Snabbhetsökning | |------|-----|-----|---------| | Bakgrundsborttagning (u2net) | 2 415 ms | 879 ms | 2,7x | | Bakgrundsborttagning (isnet) | 2 457 ms | 1 137 ms | 2,2x | | Uppskalning 2x | 350 ms | 309 ms | 1,1x | | Uppskalning 4x | 910 ms | 310 ms | 2,9x | | Ansiktsoskärpa | 139 ms | 122 ms | 1,1x | #### Kallstart (första begäran efter containerstart) {#cold-start-first-request-after-container-start} | Verktyg | CPU | GPU | Snabbhetsökning | |------|-----|-----|---------| | Bakgrundsborttagning | 22 286 ms | 4 792 ms | 4,7x | | Uppskalning 2x | 3 957 ms | 2 318 ms | 1,7x | OCR ingår inte i CUDA-jämförelsen. Både den inbyggda Tesseract-nivån och de valfria RapidOCR/ONNX-nivåerna använder CPU, inklusive när behållaren har NVIDIA GPU-åtkomst. ### CUDA-hälsokontroll {#cuda-health-check} Efter den första AI-begäran rapporterar administratörens hälsoslutpunkt CUDA-GPU-status: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} Hela Compose-stacken inkluderar appen, PostgreSQL 17 och Redis 8. Se [Distribution](/sv/guide/deployment) för den kompletta `docker-compose.yml`. Ett minimalt exempel: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Ändra detta för icke-lokala distributioner POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` För NVIDIA CUDA-acceleration via Docker Compose lägger du till deploy-avsnittet till SnapOtter-tjänsten: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Versionslåsning {#version-pinning} | Tagg | Beskrivning | |-----|------------| | `latest` | Senaste utgåvan | | `2.2.0` | Exakt version | | `2.2` | Senaste patch i 2.2.x | | `2` | Senaste minor i 2.x | ## Plattformar {#platforms} | Arkitektur | GPU-stöd | Anteckningar | |---|---|---| | linux/amd64 | NVIDIA CUDA | Full CUDA-acceleration för AI-verktyg | | linux/arm64 | Endast CPU | Raspberry Pi 4/5, Apple Silicon via Docker Desktop | ## Migrering från tidigare taggar {#migration-from-previous-tags} Om du använde taggen `:cuda` byter du till `:latest` och behåller `--gpus all`. Samma GPU-stöd, en enhetlig avbildning. Dina data och inställningar bevaras i volymerna. --- --- url: https://docs.snapotter.com/nl/guide/docker-tags.md description: >- SnapOtter Docker-image-tags, GPU-benchmarks, versievastzetting en multiplatformondersteuning voor AMD64 en ARM64. --- # Docker-image {#docker-image} SnapOtter wordt geleverd als één enkele Docker-image. Draai deze op zichzelf en er wordt een ingebedde PostgreSQL 17 en Redis op de loopback-interface gestart (ingebedde modus); voor productie draai je deze naast aparte PostgreSQL 17- en Redis 8-containers met Compose. De app-image werkt op alle platforms. ## Snelstart {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Zonder ingestelde `DATABASE_URL` draait dit in ingebedde modus: PostgreSQL en Redis starten binnen de container op loopback, met alle gegevens onder het `SnapOtter-data`-volume. Stel `DATABASE_URL` en `REDIS_URL` in (zoals de [Compose](#docker-compose)-stack doet) om in plaats daarvan externe services te gebruiken. Zie [Configuratie](/nl/guide/configuration#embedded-mode). ## NVIDIA CUDA-versnelling {#nvidia-cuda-acceleration} De image bevat NVIDIA CUDA-ondersteuning op amd64. Als je een NVIDIA-GPU met de [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) geïnstalleerd hebt, voeg dan `--gpus all` toe: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` De image detecteert CUDA automatisch tijdens runtime. Zonder `--gpus all`, of wanneer CUDA niet beschikbaar is, draaien AI-tools op de CPU. Hoe dan ook dezelfde image. Intel/AMD-iGPU-versnelling via VA-API, Quick Sync of OpenCL wordt momenteel niet ondersteund voor SnapOtter AI-inferentie. Het toewijzen van `/dev/dri` aan de container kan het render-apparaat blootstellen, maar de AI-runtime blijft de CPU gebruiken tenzij CUDA beschikbaar is. ### Benchmarks {#benchmarks} Getest op een NVIDIA RTX 4070 (12 GB VRAM) met een 572x1024 JPEG-portret. #### Warme prestaties {#warm-performance} | Tool | CPU | GPU | Versnelling | |------|-----|-----|---------| | Achtergrond verwijderen (u2net) | 2.415ms | 879ms | 2,7x | | Achtergrond verwijderen (isnet) | 2.457ms | 1.137ms | 2,2x | | Upscalen 2x | 350ms | 309ms | 1,1x | | Upscalen 4x | 910ms | 310ms | 2,9x | | Gezicht vervagen | 139ms | 122ms | 1,1x | #### Koude start (eerste verzoek na containerstart) {#cold-start-first-request-after-container-start} | Tool | CPU | GPU | Versnelling | |------|-----|-----|---------| | Achtergrond verwijderen | 22.286ms | 4.792ms | 4,7x | | Upscalen 2x | 3.957ms | 2.318ms | 1,7x | OCR is niet opgenomen in de CUDA-vergelijking. Zowel de ingebouwde Tesseract-laag als de optionele RapidOCR/ONNX-lagen gebruiken CPU, ook wanneer de container NVIDIA GPU-toegang heeft. ### CUDA-gezondheidscontrole {#cuda-health-check} Na het eerste AI-verzoek rapporteert het admin-gezondheidseindpunt de CUDA GPU-status: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} De volledige Compose-stack bevat de app, PostgreSQL 17 en Redis 8. Zie [Implementatie](/nl/guide/deployment) voor de volledige `docker-compose.yml`. Een minimaal voorbeeld: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Wijzig dit voor niet-lokale implementaties POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Voeg voor NVIDIA CUDA-versnelling via Docker Compose de deploy-sectie toe aan de SnapOtter-service: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Versievastzetting {#version-pinning} | Tag | Beschrijving | |-----|------------| | `latest` | Nieuwste release | | `2.2.0` | Exacte versie | | `2.2` | Nieuwste patch in 2.2.x | | `2` | Nieuwste minor in 2.x | ## Platforms {#platforms} | Architectuur | GPU-ondersteuning | Opmerkingen | |---|---|---| | linux/amd64 | NVIDIA CUDA | Volledige CUDA-versnelling voor AI-tools | | linux/arm64 | Alleen CPU | Raspberry Pi 4/5, Apple Silicon via Docker Desktop | ## Migratie van vorige tags {#migration-from-previous-tags} Gebruikte je de `:cuda`-tag, schakel dan over naar `:latest` en houd `--gpus all` aan. Dezelfde GPU-ondersteuning, verenigde image. Je gegevens en instellingen blijven behouden in de volumes. --- --- url: https://docs.snapotter.com/de/guide/docker-tags.md description: >- SnapOtter Docker-Image-Tags, GPU-Benchmarks, Versionsfixierung und Multi-Plattform-Unterstützung für AMD64 und ARM64. --- # Docker-Image {#docker-image} SnapOtter wird als einzelnes Docker-Image ausgeliefert. Wenn Sie es allein ausführen, startet es ein eingebettetes PostgreSQL 17 und Redis auf der Loopback-Schnittstelle (eingebetteter Modus); für den Produktivbetrieb führen Sie es zusammen mit separaten PostgreSQL-17- und Redis-8-Containern per Compose aus. Das App-Image funktioniert auf allen Plattformen. ## Schnellstart {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Ohne gesetztes `DATABASE_URL` läuft dies im eingebetteten Modus: PostgreSQL und Redis starten innerhalb des Containers auf dem Loopback, wobei alle Daten unter dem Volume `SnapOtter-data` liegen. Setzen Sie `DATABASE_URL` und `REDIS_URL` (wie es der [Compose](#docker-compose)-Stack tut), um stattdessen externe Dienste zu verwenden. Siehe [Konfiguration](/de/guide/configuration#embedded-mode). ## NVIDIA-CUDA-Beschleunigung {#nvidia-cuda-acceleration} Das Image enthält NVIDIA-CUDA-Unterstützung auf amd64. Wenn Sie über eine NVIDIA-GPU mit installiertem [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) verfügen, fügen Sie `--gpus all` hinzu: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Das Image erkennt CUDA zur Laufzeit automatisch. Ohne `--gpus all` oder wenn CUDA nicht verfügbar ist, laufen die KI-Werkzeuge auf der CPU. In beiden Fällen dasselbe Image. Intel/AMD-iGPU-Beschleunigung über VA-API, Quick Sync oder OpenCL wird für die KI-Inferenz von SnapOtter derzeit nicht unterstützt. Das Einbinden von `/dev/dri` in den Container kann das Rendergerät verfügbar machen, aber die KI-Laufzeit nutzt weiterhin die CPU, sofern CUDA nicht verfügbar ist. ### Benchmarks {#benchmarks} Getestet auf einer NVIDIA RTX 4070 (12 GB VRAM) mit einem 572x1024-JPEG-Porträt. #### Warme Leistung {#warm-performance} | Werkzeug | CPU | GPU | Beschleunigung | |------|-----|-----|---------| | Hintergrundentfernung (u2net) | 2.415 ms | 879 ms | 2,7x | | Hintergrundentfernung (isnet) | 2.457 ms | 1.137 ms | 2,2x | | Hochskalierung 2x | 350 ms | 309 ms | 1,1x | | Hochskalierung 4x | 910 ms | 310 ms | 2,9x | | Gesichtsunschärfe | 139 ms | 122 ms | 1,1x | #### Kaltstart (erste Anfrage nach Containerstart) {#cold-start-first-request-after-container-start} | Werkzeug | CPU | GPU | Beschleunigung | |------|-----|-----|---------| | Hintergrundentfernung | 22.286 ms | 4.792 ms | 4,7x | | Hochskalierung 2x | 3.957 ms | 2.318 ms | 1,7x | OCR ist nicht im CUDA-Vergleich enthalten. Sowohl die integrierte Tesseract-Ebene als auch die optionalen RapidOCR/ONNX-Ebenen verwenden CPU. Dies gilt auch dann, wenn der Container Zugriff auf NVIDIA GPU hat. ### CUDA-Statusprüfung {#cuda-health-check} Nach der ersten KI-Anfrage meldet der Admin-Health-Endpunkt den Status der CUDA-GPU: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} Der vollständige Compose-Stack umfasst die App, PostgreSQL 17 und Redis 8. Siehe [Bereitstellung](/de/guide/deployment) für die vollständige `docker-compose.yml`. Ein minimales Beispiel: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Ändern Sie dies für nicht lokale Bereitstellungen POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Für NVIDIA-CUDA-Beschleunigung über Docker Compose fügen Sie den deploy-Abschnitt zum SnapOtter-Dienst hinzu: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Versionsfixierung {#version-pinning} | Tag | Beschreibung | |-----|------------| | `latest` | Neueste Version | | `2.2.0` | Exakte Version | | `2.2` | Neuester Patch in 2.2.x | | `2` | Neueste Minor-Version in 2.x | ## Plattformen {#platforms} | Architektur | GPU-Unterstützung | Hinweise | |---|---|---| | linux/amd64 | NVIDIA CUDA | Volle CUDA-Beschleunigung für KI-Werkzeuge | | linux/arm64 | nur CPU | Raspberry Pi 4/5, Apple Silicon über Docker Desktop | ## Migration von früheren Tags {#migration-from-previous-tags} Wenn Sie den Tag `:cuda` verwendet haben, wechseln Sie zu `:latest` und behalten Sie `--gpus all`. Gleiche GPU-Unterstützung, vereinheitlichtes Image. Ihre Daten und Einstellungen bleiben in den Volumes erhalten. --- --- url: https://docs.snapotter.com/ru/guide/docker-tags.md description: >- Теги Docker-образа SnapOtter, тесты производительности GPU, закрепление версий и поддержка нескольких платформ для AMD64 и ARM64. --- # Docker-образ {#docker-image} SnapOtter поставляется в виде единого Docker-образа. Запустите его самостоятельно, и он запустит встроенные PostgreSQL 17 и Redis на интерфейсе loopback (встроенный режим); для продакшена запускайте его рядом с отдельными контейнерами PostgreSQL 17 и Redis 8 через Compose. Образ приложения работает на всех платформах. ## Быстрый старт {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Без заданного `DATABASE_URL` он работает во встроенном режиме: PostgreSQL и Redis запускаются внутри контейнера на loopback, а все данные хранятся в томе `SnapOtter-data`. Задайте `DATABASE_URL` и `REDIS_URL` (как это делает стек [Compose](#docker-compose)), чтобы вместо этого использовать внешние сервисы. См. [Конфигурация](/ru/guide/configuration#embedded-mode). ## Ускорение NVIDIA CUDA {#nvidia-cuda-acceleration} Образ включает поддержку NVIDIA CUDA на amd64. Если у вас есть GPU NVIDIA с установленным [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html), добавьте `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Образ автоматически обнаруживает CUDA во время выполнения. Без `--gpus all` или когда CUDA недоступна, инструменты ИИ работают на CPU. В обоих случаях образ один и тот же. Ускорение через интегрированные GPU Intel/AMD посредством VA-API, Quick Sync или OpenCL сегодня не поддерживается для инференса ИИ в SnapOtter. Проброс `/dev/dri` в контейнер может открыть render-устройство, но среда выполнения ИИ всё равно будет использовать CPU, если CUDA недоступна. ### Тесты производительности {#benchmarks} Протестировано на NVIDIA RTX 4070 (12 ГБ VRAM) с портретным JPEG 572x1024. #### Производительность в прогретом состоянии {#warm-performance} | Инструмент | CPU | GPU | Ускорение | |------|-----|-----|---------| | Удаление фона (u2net) | 2 415 мс | 879 мс | 2.7x | | Удаление фона (isnet) | 2 457 мс | 1 137 мс | 2.2x | | Увеличение 2x | 350 мс | 309 мс | 1.1x | | Увеличение 4x | 910 мс | 310 мс | 2.9x | | Размытие лиц | 139 мс | 122 мс | 1.1x | #### Холодный старт (первый запрос после запуска контейнера) {#cold-start-first-request-after-container-start} | Инструмент | CPU | GPU | Ускорение | |------|-----|-----|---------| | Удаление фона | 22 286 мс | 4 792 мс | 4.7x | | Увеличение 2x | 3 957 мс | 2 318 мс | 1.7x | OCR не включен в сравнение CUDA. Как встроенный уровень Tesseract, так и дополнительные уровни RapidOCR/ONNX используют CPU, в том числе, когда контейнер имеет доступ NVIDIA GPU. ### Проверка состояния CUDA {#cuda-health-check} После первого запроса к ИИ административная конечная точка health сообщает о статусе GPU CUDA: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} Полный стек Compose включает приложение, PostgreSQL 17 и Redis 8. См. [Развёртывание](/ru/guide/deployment) для полного `docker-compose.yml`. Минимальный пример: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Измените это для нелокальных развертываний. POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Для ускорения NVIDIA CUDA через Docker Compose добавьте секцию deploy к сервису SnapOtter: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Закрепление версии {#version-pinning} | Тег | Описание | |-----|------------| | `latest` | Последний релиз | | `2.2.0` | Точная версия | | `2.2` | Последний патч в 2.2.x | | `2` | Последний минорный в 2.x | ## Платформы {#platforms} | Архитектура | Поддержка GPU | Примечания | |---|---|---| | linux/amd64 | NVIDIA CUDA | Полное ускорение CUDA для инструментов ИИ | | linux/arm64 | Только CPU | Raspberry Pi 4/5, Apple Silicon через Docker Desktop | ## Миграция с предыдущих тегов {#migration-from-previous-tags} Если вы использовали тег `:cuda`, переключитесь на `:latest` и сохраните `--gpus all`. Та же поддержка GPU, единый образ. Ваши данные и настройки сохраняются в томах. --- --- url: https://docs.snapotter.com/uk/guide/docker-tags.md description: >- Теги Docker-образу SnapOtter, тести продуктивності GPU, закріплення версій і мультиплатформна підтримка для AMD64 та ARM64. --- # Docker-образ {#docker-image} SnapOtter постачається як єдиний Docker-образ. Запустіть його окремо, і він запустить вбудовані PostgreSQL 17 та Redis на інтерфейсі loopback (вбудований режим); для промислового використання запускайте його поряд з окремими контейнерами PostgreSQL 17 та Redis 8 за допомогою Compose. Образ застосунку працює на всіх платформах. ## Швидкий старт {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Без встановленого `DATABASE_URL` це запускається у вбудованому режимі: PostgreSQL та Redis стартують усередині контейнера на loopback, а всі дані зберігаються в томі `SnapOtter-data`. Встановіть `DATABASE_URL` та `REDIS_URL` (як це робить стек [Compose](#docker-compose)), щоб натомість використовувати зовнішні сервіси. Див. [Налаштування](/uk/guide/configuration#embedded-mode). ## Прискорення NVIDIA CUDA {#nvidia-cuda-acceleration} Образ включає підтримку NVIDIA CUDA на amd64. Якщо у вас є GPU NVIDIA зі встановленим [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html), додайте `--gpus all`: ```bash docker run -d --name SnapOtter --gpus all -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Образ автоматично виявляє CUDA під час виконання. Без `--gpus all` або коли CUDA недоступна, інструменти AI працюють на CPU. Образ той самий в обох випадках. Прискорення iGPU Intel/AMD через VA-API, Quick Sync чи OpenCL наразі не підтримується для AI-інференсу SnapOtter. Прокидання `/dev/dri` у контейнер може відкрити доступ до render-пристрою, але AI-середовище виконання все одно використовуватиме CPU, доки CUDA недоступна. ### Тести продуктивності {#benchmarks} Протестовано на NVIDIA RTX 4070 (12 ГБ VRAM) з портретним JPEG 572x1024. #### Продуктивність у прогрітому стані {#warm-performance} | Інструмент | CPU | GPU | Прискорення | |------|-----|-----|---------| | Видалення фону (u2net) | 2415 мс | 879 мс | 2.7x | | Видалення фону (isnet) | 2457 мс | 1137 мс | 2.2x | | Збільшення 2x | 350 мс | 309 мс | 1.1x | | Збільшення 4x | 910 мс | 310 мс | 2.9x | | Розмиття облич | 139 мс | 122 мс | 1.1x | #### Холодний старт (перший запит після запуску контейнера) {#cold-start-first-request-after-container-start} | Інструмент | CPU | GPU | Прискорення | |------|-----|-----|---------| | Видалення фону | 22286 мс | 4792 мс | 4.7x | | Збільшення 2x | 3957 мс | 2318 мс | 1.7x | OCR не входить до порівняння CUDA. Як вбудований рівень Tesseract, так і додаткові рівні RapidOCR/ONNX використовують CPU, у тому числі коли контейнер має доступ NVIDIA GPU. ### Перевірка стану CUDA {#cuda-health-check} Після першого AI-запиту адміністративний ендпоінт стану звітує про статус GPU CUDA: ``` GET /api/v1/admin/health {"ai": {"gpu": true}} ``` ## Docker Compose {#docker-compose} Повний стек Compose включає застосунок, PostgreSQL 17 та Redis 8. Див. [Розгортання](/uk/guide/deployment) для повного `docker-compose.yml`. Мінімальний приклад: ```yaml services: SnapOtter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - SnapOtter-data:/data - SnapOtter-workspace:/tmp/workspace environment: - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter - REDIS_URL=redis://redis:6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" postgres: image: postgres:17-alpine environment: POSTGRES_USER: snapotter POSTGRES_PASSWORD: snapotter # Змініть це для нелокальних розгортань POSTGRES_DB: snapotter volumes: - SnapOtter-pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"] interval: 10s timeout: 5s retries: 12 redis: image: redis:8-alpine command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"] volumes: - SnapOtter-redisdata:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 12 volumes: SnapOtter-data: SnapOtter-workspace: SnapOtter-pgdata: SnapOtter-redisdata: ``` Для прискорення NVIDIA CUDA через Docker Compose додайте секцію deploy до сервісу SnapOtter: ```yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## Закріплення версій {#version-pinning} | Тег | Опис | |-----|------------| | `latest` | Останній випуск | | `2.2.0` | Точна версія | | `2.2` | Останній патч у 2.2.x | | `2` | Останній мінорний у 2.x | ## Платформи {#platforms} | Архітектура | Підтримка GPU | Примітки | |---|---|---| | linux/amd64 | NVIDIA CUDA | Повне прискорення CUDA для AI-інструментів | | linux/arm64 | Лише CPU | Raspberry Pi 4/5, Apple Silicon через Docker Desktop | ## Міграція з попередніх тегів {#migration-from-previous-tags} Якщо ви використовували тег `:cuda`, перейдіть на `:latest` і залиште `--gpus all`. Та сама підтримка GPU, уніфікований образ. Ваші дані та налаштування зберігаються в томах. --- --- url: https://docs.snapotter.com/pt-BR.md description: >- Infraestrutura de processamento de arquivos open-source e self-hosted. Converta, comprima, faça OCR, transcreva e rode IA local em imagem, vídeo, áudio, PDF e documentos, via interface, API REST e pipelines. Faça self-host com um único comando Docker. Seus arquivos nunca saem do seu servidor. --- --- --- url: https://docs.snapotter.com/es.md description: >- Infraestructura de procesamiento de archivos de código abierto y autoalojada. Convierte, comprime, aplica OCR, transcribe y ejecuta IA local en imágenes, vídeo, audio, PDF y documentos, mediante la interfaz, la API REST y las canalizaciones. Autoalójala con un solo comando de Docker. Tus archivos nunca salen de tu servidor. --- --- --- url: https://docs.snapotter.com/pl/api/rest.md description: >- Kompletna dokumentacja API REST. Punkty końcowe narzędzi, przetwarzanie wsadowe, potoki, biblioteka plików, uwierzytelnianie, zespoły i operacje administracyjne. --- # Dokumentacja API REST {#rest-api-reference} Interaktywna dokumentacja API z przykładami żądań i odpowiedzi jest dostępna pod adresem . Specyfikacje odczytywalne maszynowo: * `/api/v1/openapi.yaml` - specyfikacja OpenAPI 3.1 * `/llms.txt` - podsumowanie przyjazne dla LLM * `/llms-full.txt` - kompletna dokumentacja przyjazna dla LLM ## Uwierzytelnianie {#authentication} Wszystkie punkty końcowe wymagają uwierzytelnienia, chyba że `AUTH_ENABLED=false`. ### Token sesji {#session-token} ```bash # Login curl -X POST http://localhost:1349/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin"}' # Returns: {"token":""} # Use token (tool routes are POST multipart) curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer " \ -F "file=@photo.jpg" \ -F 'settings={"width":800}' ``` Sesje wygasają po 7 dniach (konfigurowalne za pomocą `SESSION_DURATION_HOURS`). ### Klucze API {#api-keys} ```bash # Create a key (returns key once - store it) curl -X POST http://localhost:1349/api/v1/api-keys \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"name":"my-script"}' # Returns: {"key":"si_<96 hex chars>","id":"...","name":"my-script"} # Use the key curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800}' ``` Klucze są poprzedzone przedrostkiem `si_` i przechowywane jako skróty scrypt - surowy klucz jest pokazywany raz i nigdy więcej nie można go odzyskać. ### Punkty końcowe uwierzytelniania {#auth-endpoints} | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `POST` | `/api/auth/login` | Publiczny | Logowanie, uzyskanie tokena sesji | | `POST` | `/api/auth/logout` | Uwierzytelniony | Zniszczenie bieżącej sesji | | `GET` | `/api/auth/session` | Uwierzytelniony | Weryfikacja bieżącej sesji | | `POST` | `/api/auth/change-password` | Uwierzytelniony | Zmiana własnego hasła (unieważnia wszystkie inne sesje + klucze API) | | `GET` | `/api/auth/users` | Administrator | Lista wszystkich użytkowników | | `POST` | `/api/auth/register` | Administrator | Utworzenie nowego użytkownika | | `PUT` | `/api/auth/users/:id` | Administrator | Aktualizacja roli lub zespołu użytkownika | | `POST` | `/api/auth/users/:id/reset-password` | Administrator | Zresetowanie hasła użytkownika | | `DELETE` | `/api/auth/users/:id` | Administrator | Usunięcie użytkownika | | `GET` | `/api/v1/config/auth` | Publiczny | Sprawdzenie, czy uwierzytelnianie jest włączone (`{ authEnabled: bool }`) | | `POST` | `/api/auth/mfa/enroll` | Uwierzytelniony | Rozpoczęcie rejestracji TOTP MFA. Wymaga funkcji enterprise `mfa` | | `POST` | `/api/auth/mfa/verify` | Uwierzytelniony | Potwierdzenie rejestracji MFA kodem TOTP | | `POST` | `/api/auth/mfa/complete` | Publiczny | Zakończenie oczekującego wyzwania logowania MFA | | `POST` | `/api/auth/mfa/disable` | Uwierzytelniony | Wyłączenie MFA dla bieżącego użytkownika | | `POST` | `/api/auth/users/:id/mfa/reset` | Administrator (`users:manage`) | Zresetowanie MFA dla użytkownika | | `GET` | `/api/auth/oidc/login` | Publiczny | Rozpoczęcie logowania OIDC, gdy OIDC jest włączony | | `GET` | `/api/auth/oidc/callback` | Publiczny | Wywołanie zwrotne autoryzacji OIDC | | `GET` | `/api/auth/saml/metadata` | Publiczny | Metadane XML SAML SP, gdy SAML jest włączony | | `GET` | `/api/auth/saml/login` | Publiczny | Rozpoczęcie logowania SAML | | `POST` | `/api/auth/saml/callback` | Publiczny | Usługa konsumenta asercji SAML | Gdy MFA jest włączone dla użytkownika, `POST /api/auth/login` zwraca `{"requiresMfa":true,"mfaToken":"...","mfaRequired":true|false}` zamiast tokena sesji. Wyślij ten `mfaToken` wraz z kodem TOTP lub kodem odzyskiwania do `/api/auth/mfa/complete`. ### Uprawnienia {#permissions} | Uprawnienie | Administrator | Użytkownik | |-----------|:-----:|:----:| | Korzystanie z narzędzi | ✓ | ✓ | | Własne pliki/potoki/klucze API | ✓ | ✓ | | Podgląd plików/potoków/kluczy wszystkich użytkowników | ✓ | - | | Zapis ustawień | ✓ | - | | Zarządzanie użytkownikami i zespołami | ✓ | - | | Zarządzanie marką | ✓ | - | ## Kontrola stanu {#health-check} | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/health` | Publiczny | Podstawowa kontrola stanu. Zwraca `{"status":"healthy","version":"..."}` z kodem 200 lub `{"status":"unhealthy"}` z kodem 503, jeśli baza danych jest nieosiągalna. | | `GET` | `/api/v1/readyz` | Publiczny | Sonda gotowości. Sprawdza PostgreSQL, Redis, miejsce na dysku oraz S3, gdy jest skonfigurowane. Zwraca 503, gdy instancja nie powinna odbierać ruchu. | | `GET` | `/api/v1/admin/health` | Administrator (`system:health`) | Szczegółowa diagnostyka obejmująca czas działania, tryb przechowywania, stan bazy danych, stan kolejki i dostępność GPU. | ## Korzystanie z narzędzi {#using-tools} Każde narzędzie działa według tego samego wzorca: ```bash # Single file curl -X POST http://localhost:1349/api/v1/tools/
/ \ -H "Authorization: Bearer " \ -F "file=@input.jpg" \ -F 'settings={"width":800,"height":600}' # Batch (returns ZIP) curl -X POST http://localhost:1349/api/v1/tools/
//batch \ -H "Authorization: Bearer " \ -F "files=@a.jpg" \ -F "files=@b.jpg" \ -F 'settings={...}' ``` `
` jest jednym z `image`, `video`, `audio`, `pdf` lub `files`. * Przesyłany plik ma pole `multipart/form-data`. * `settings` to ciąg JSON z opcjami specyficznymi dla narzędzia. * `clientJobId` to opcjonalne pole formularza służące do korelacji postępu dostarczanej przez wywołującego. * `fileId` to opcjonalne pole formularza odwołujące się do istniejącego elementu biblioteki plików. Gdy jest obecne, przetworzony wynik jest zapisywany jako nowa wersja, a odpowiedź zawiera `savedFileId`. * **Szybkie narzędzia** zwykle zwracają JSON z kodem 200: `{"jobId":"...","downloadUrl":"/api/v1/download//","originalSize":1234,"processedSize":567}`. Pobierz przetworzony plik z `downloadUrl`. * **Każde narzędzie w kolejce** może zwrócić JSON z kodem 202, jeśli działa długo lub przekracza okno synchronicznego oczekiwania: `{"jobId":"...","async":true}`. Połącz się z SSE, aby śledzić postęp, a następnie pobierz plik po zakończeniu (zobacz [Śledzenie postępu](#progress-tracking)). * **Trasy wsadowe** zwracają archiwum ZIP przesyłane bezpośrednio strumieniowo (z nagłówkiem `X-Job-Id`) dla narzędzi zarejestrowanych w ogólnym rejestrze wsadowym. ## Dokumentacja narzędzi {#tools-reference} ### Ustawienia wstępne konwersji {#conversion-presets} Wspólny katalog zawiera 83 dedykowane punkty końcowe ustawień wstępnych konwersji, takie jak `jpg-to-png`, `mov-to-mp4`, `m4a-to-mp3`, `pdf-to-jpg` i `excel-to-csv`. Ustawienia wstępne to pełnoprawne trasy narzędzi: `POST /api/v1/tools/
/` Każde ustawienie wstępne blokuje format wyjściowy i deleguje do narzędzia bazowego, takiego jak `convert`, `convert-video`, `extract-audio`, `convert-audio`, `image-to-pdf`, `pdf-to-image`, `svg-to-raster` lub `convert-spreadsheet`. Zobacz [Ustawienia wstępne konwersji](/pl/tools/conversion-presets), aby uzyskać kompletną tabelę tras i opcjonalne ustawienia. ### Podstawy {#essentials} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `resize` | Zmiana rozmiaru | `width`, `height`, `fit` (cover/contain/fill/inside/outside), `percentage`, `withoutEnlargement`, plus 23 ustawienia wstępne mediów społecznościowych | | `crop` | Kadrowanie | `left`, `top`, `width`, `height`, `unit` (px/percent) | | `rotate` | Obrót i odbicie | `angle`, `horizontal` (bool), `vertical` (bool) | | `convert` | Konwersja | `format` (jpg/png/webp/avif/tiff/gif/heic/heif), `quality` | | `compress` | Kompresja | `mode` (quality/targetSize), `quality` (1–100), `targetSizeKb` | ### Optymalizacja {#optimization} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `optimize-for-web` | Optymalizacja pod kątem internetu | `format` (webp/jpeg/avif/png), `quality`, `maxWidth`, `maxHeight`, `progressive`, `stripMetadata` | | `strip-metadata` | Usuwanie metadanych | - | | `edit-metadata` | Edycja metadanych | `title`, `description`, `author`, `copyright`, `keywords`, `gps` (lat/lon), `dateTime` | | `bulk-rename` | Zmiana nazw zbiorczo | `pattern` (obsługuje `{n}`, `{date}`, `{original}`), `startIndex`, `padding` | | `image-to-pdf` | Obraz do PDF | `pageSize` (A4/Letter/...), `orientation`, `margin`, `targetSize` ({value, unit}) | | `favicon` | Generator favicon | `padding`, `backgroundColor`, `borderRadius` - generuje wszystkie standardowe rozmiary | ### Korekty {#adjustments} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `adjust-colors` | Korekta kolorów | `brightness`, `contrast`, `exposure`, `saturation`, `temperature`, `tint`, `hue`, `sharpness`, `red`, `green`, `blue`, `effect` (none/grayscale/sepia/invert) | | `sharpening` | Wyostrzanie | `method` (adaptive/unsharp-mask/high-pass), `sigma`, `m1`, `m2`, `x1`, `y2`, `y3`, `amount`, `radius`, `threshold`, `strength`, `kernelSize` (3/5), `denoise` (off/light/medium/strong) | | `replace-color` | Zamiana koloru | `sourceColor`, `targetColor` (zamiennik), `makeTransparent`, `tolerance` | | `color-blindness` | Symulacja daltonizmu | `simulationType` (protanopia/deuteranopia/tritanopia/protanomaly/deuteranomaly/tritanomaly/achromatopsia/blueConeMonochromacy, domyślnie "deuteranomaly") | | `duotone` | Duotone | `shadow` (hex), `highlight` (hex), `intensity` (0-100) | | `pixelate` | Pikselizacja | `blockSize` (2-128), `region` ({left, top, width, height} dla częściowej pikselizacji) | | `vignette` | Winieta | `strength` (0.1-1), `color` (hex), `radius`, `softness`, `roundness`, `centerX`, `centerY` | ### Narzędzia AI {#ai-tools} Wszystkie narzędzia AI działają na Twoim sprzęcie: domyślnie na CPU lub na NVIDIA CUDA, gdy dostępny jest obsługiwany procesor graficzny NVIDIA. Akceleracja iGPU firm Intel/AMD przez VA-API, Quick Sync lub OpenCL nie jest obecnie obsługiwana dla wnioskowania AI. Nie wymaga połączenia z internetem. | ID narzędzia | Nazwa | Model AI | Kluczowe ustawienia | |---------|------|---------|-------------| | `remove-background` | Usuwanie tła | rembg (BiRefNet / U2-Net) | `model`, `backgroundType` (transparent/color/gradient/blur/image), `backgroundColor`, `gradientColor1`, `gradientColor2`, `gradientAngle`, `blurEnabled`, `blurIntensity`, `shadowEnabled`, `shadowOpacity` | | `upscale` | Powiększanie obrazu | RealESRGAN | `scale` (2/4), `model`, `faceEnhance`, `denoise`, `format`, `quality` | | `erase-object` | Wymazywanie obiektów | LaMa (ONNX) | Maska wysyłana jako druga część pliku (nazwa pola `mask`), `format`, `quality` | | `ocr` | OCR / Ekstrakcja tekstu | Tesseract (szybki); RapidOCR + PP-OCR ONNX (zrównoważony/najlepszy) | `quality` (szybki/zrównoważony/najlepszy), `language`, `enhance` | | `blur-faces` | Rozmycie twarzy / PII | MediaPipe | `blurRadius`, `sensitivity` | | `smart-crop` | Inteligentne kadrowanie | MediaPipe + Sharp | `mode` (subject/face/trim), `strategy` (attention/entropy), `width`, `height`, `padding`, `facePreset` (closeup/head-shoulders/upper-body/half-body), `sensitivity`, `threshold`, `padToSquare`, `padColor`, `targetSize`, `quality` | | `image-enhancement` | Poprawa obrazu | Oparte na analizie | `mode` (auto/exposure/contrast/color/sharpness), `strength` | | `enhance-faces` | Poprawa twarzy | GFPGAN / CodeFormer | `model` (gfpgan/codeformer), `strength`, `sensitivity`, `centerFace` | | `colorize` | Koloryzacja AI | DDColor | `intensity`, `model` | | `noise-removal` | Usuwanie szumów | Wielopoziomowe odszumianie | `tier` (quick/balanced/quality/maximum), `strength`, `detailPreservation`, `colorNoise`, `format`, `quality` | | `red-eye-removal` | Usuwanie efektu czerwonych oczu | Punkty charakterystyczne twarzy + analiza kolorów | `sensitivity`, `strength` | | `restore-photo` | Rekonstrukcja zdjęć | Wieloetapowy potok | `mode` (auto/light/heavy), `scratchRemoval`, `faceEnhancement`, `fidelity`, `denoise`, `denoiseStrength`, `colorize` | | `passport-photo` | Zdjęcie paszportowe | Punkty charakterystyczne MediaPipe | Dwufazowy przepływ. Analiza używa multipart `file`; generowanie używa JSON z `countryCode`, `bgColor`, `printLayout` (none/4x6/a4), punktami charakterystycznymi, wymiarami obrazu | | `content-aware-resize` | Zmiana rozmiaru z zachowaniem treści | Wycinanie szwów (caire) | `width`, `height`, `protectFaces`, `blurRadius`, `sobelThreshold`, `square` | | `transparency-fixer` | Naprawa przezroczystości PNG | BiRefNet HR-matting | `defringe` (0-100), `outputFormat` (png/webp) | | `background-replace` | Zamiana tła | rembg (BiRefNet) | `backgroundType` (color/gradient), `color` (hex), `gradientColor1`, `gradientColor2`, `gradientAngle`, `feather` (0-20), `format` (png/webp) | | `blur-background` | Rozmycie tła | rembg (BiRefNet) | `intensity` (1-100), `feather` (0-20), `format` (png/webp) | | `ai-canvas-expand` | Rozszerzanie płótna AI | LaMa (outpainting) | `extendTop`, `extendRight`, `extendBottom`, `extendLeft` (px), `tier` (fast/balanced/high), `format`, `quality` | ### Znak wodny i nakładka {#watermark-overlay} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `watermark-text` | Tekstowy znak wodny | `text`, `font`, `fontSize`, `color`, `opacity`, `position`, `rotation`, `tile` | | `watermark-image` | Graficzny znak wodny | `opacity`, `position`, `scale` - drugi plik jest znakiem wodnym | | `text-overlay` | Nakładka tekstowa | `text`, `font`, `fontSize`, `color`, `x`, `y`, `background`, `padding`, `borderRadius` | | `compose` | Kompozycja obrazu | `x`, `y`, `opacity`, `blend` - drugi plik jest nakładany na wierzch | | `meme-generator` | Generator memów | `templateId`, `textLayout` (top-bottom/top-only/bottom-only/center/side-by-side), `textBoxes` (\[{id, text}]), `fontFamily` (anton/arial-black/comic-sans/montserrat/bebas-neue/permanent-marker/roboto), `fontSize`, `textColor`, `strokeColor`, `textAlign`, `allCaps`. Obsługuje tryb szablonu (treść JSON z `templateId`) lub tryb obrazu niestandardowego (multipart z plikiem). | ### Narzędzia pomocnicze {#utilities} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `info` | Informacje o obrazie | - (zwraca szerokość, wysokość, format, rozmiar, kanały, hasAlpha, DPI, EXIF) | | `compare` | Porównanie obrazów | `mode` (side-by-side/overlay/diff), `diffThreshold` - drugi plik jest celem porównania | | `find-duplicates` | Wyszukiwanie duplikatów | `threshold` (odległość skrótu percepcyjnego, domyślnie 8) - wieloplikowe | | `color-palette` | Paleta kolorów | `count` (liczba dominujących kolorów), `format` (hex/rgb) | | `qr-generate` | Generator kodów QR | `data`, `size`, `margin`, `colorDark`, `colorLight`, `errorCorrectionLevel`, `dotStyle`, `cornerStyle`, `logo` (opcjonalny plik) | | `barcode-read` | Czytnik kodów kreskowych | - (automatyczne wykrywanie QR, EAN, Code128, DataMatrix itd.) | | `image-to-base64` | Obraz do Base64 | `format` (data-uri/plain), `mimeType` | | `html-to-image` | HTML do obrazu | `url`, `format` (png/jpg/webp), `quality`, `fullPage`, `devicePreset` (desktop/tablet/mobile/custom), `viewportWidth`, `viewportHeight` | | `histogram` | Histogram | `scale` (linear/log) - zwraca wykres histogramu RGB + statystyki dla poszczególnych kanałów | | `lqip-placeholder` | Symbol zastępczy LQIP | `width` (4-64), `blur`, `strategy` (blur/pixelate/solid), `format` (webp/png/jpeg), `quality` | | `barcode-generate` | Generator kodów kreskowych | `text`, `type` (code128/ean13/upca/code39/itf14/datamatrix), `scale` (1-8), `includeText` (bool). Treść JSON, bez przesyłania pliku. | ### Układ i kompozycja {#layout-composition} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `collage` | Kolaż / Siatka | `template` (25+ układów), `gap`, `backgroundColor`, `borderRadius` - wieloplikowe | | `stitch` | Zszywanie / Łączenie | `direction` (horizontal/vertical/grid), `gap`, `backgroundColor`, `alignment` - wieloplikowe | | `split` | Dzielenie obrazu | `mode` (grid/rows/cols), `rows`, `cols`, `tileWidth`, `tileHeight` | | `border` | Obramowanie i ramka | `width`, `color`, `style` (solid/gradient/pattern), `borderRadius`, `padding`, `shadow` | | `beautify` | Upiększanie zrzutu ekranu | `backgroundType` (solid/linear-gradient/radial-gradient/image/transparent), `gradientStops`, `padding`, `borderRadius`, `shadowPreset`, `frame` (none/macos-light/macos-dark/windows-light/windows-dark/browser-light/browser-dark/iphone/macbook/ipad/...), `socialPreset` (none/twitter/linkedin/instagram-square/instagram-story/facebook/producthunt), `watermarkText`, `outputFormat` | | `circle-crop` | Kadrowanie okrągłe | `zoom` (1-5), `offsetX`, `offsetY`, `borderWidth`, `borderColor`, `background` (transparent/hex), `outputSize` | | `image-pad` | Dopełnianie obrazu | `target` (16:9/9:16/1:1/4:3/3:4/custom), `ratioW`, `ratioH`, `background` (color/transparent/blur), `color` (hex), `padding` (0-50%) | | `sprite-sheet` | Arkusz duszków | `columns` (1-16), `padding`, `background` (hex), `format` (png/webp/jpeg), `quality` - wieloplikowe (2-64 obrazy) | ### Format i konwersja {#format-conversion} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `svg-to-raster` | SVG do rastra | `format` (png/jpeg/webp/avif/tiff/gif/heif), `width`, `height`, `scale`, `dpi`, `background` | | `vectorize` | Obraz do SVG | `colorMode` (bw/color), `threshold`, `colorPrecision`, `filterSpeckle`, `pathMode` (none/polygon/spline) | | `gif-tools` | Narzędzia GIF | `action` (resize/optimize/reverse/speed/extract-frames/rotate/add-text), parametry specyficzne dla akcji | | `gif-webp` | Konwerter GIF/WebP | `quality` (1-100), `lossless` (bool), `resizePercent` (10-100) | ### Narzędzia wideo {#video-tools} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `convert-video` | Konwersja wideo | `format` (mp4/mov/webm/avi/mkv), `quality` (high/balanced/small) | | `compress-video` | Kompresja wideo | `quality` (light/balanced/strong), `resolution` (original/1080p/720p/480p) | | `trim-video` | Przycinanie wideo | `startS`, `endS`, `precise` (bool, cięcie z dokładnością do klatki) | | `mute-video` | Wyciszanie wideo | - | | `video-to-gif` | Wideo do GIF | `fps` (1-30), `width`, `startS`, `durationS` (maks. 60 s) | | `resize-video` | Zmiana rozmiaru wideo | `width`, `height`, `preset` (custom/2160p/1440p/1080p/720p/480p/360p) | | `crop-video` | Kadrowanie wideo | `width`, `height`, `x`, `y` | | `rotate-video` | Obrót wideo | `transform` (cw90/ccw90/180/hflip/vflip) | | `change-fps` | Zmiana FPS | `fps` (1-120) | | `video-color` | Kolor wideo | `brightness`, `contrast`, `saturation`, `gamma` | | `video-speed` | Prędkość wideo | `factor` (0.25-4), `keepPitch` (bool) | | `reverse-video` | Odwracanie wideo | - (maks. 5 minut) | | `video-loudnorm` | Normalizacja dźwięku | - (EBU R128) | | `aspect-pad` | Dopełnianie proporcji | `target` (16:9/9:16/1:1/4:3/3:4), `color` (hex) | | `blur-pad` | Dopełnianie rozmyciem | `target` (16:9/9:16/1:1/4:3/3:4), `blur` (2-50) | | `watermark-video` | Znak wodny na wideo | `text`, `position`, `fontSize`, `opacity`, `color` | | `stabilize-video` | Stabilizacja wideo | `smoothing` (5-60, w klatkach) | | `gif-to-video` | GIF do wideo | `format` (mp4/webm/mov) | | `video-to-webp` | Wideo do WebP | `fps`, `width`, `quality`, `loop` (bool) | | `video-to-frames` | Wideo do klatek | `mode` (all/nth/timestamps), `n`, `timestamps`, `format` (png/jpg) | | `merge-videos` | Łączenie wideo | - (wieloplikowe, znormalizowane do rozdzielczości pierwszego wideo) | | `replace-audio` | Zamiana dźwięku | - (plik wideo + audio, dwa pliki) | | `burn-subtitles` | Wypalanie napisów | `fontSize` (8-72) - plik wideo + napisy | | `embed-subtitles` | Osadzanie napisów | `language` (kod ISO 639-2/B) - plik wideo + napisy | | `extract-subtitles` | Wyodrębnianie napisów | - (na wyjściu SRT) | | `images-to-video` | Obrazy do wideo | `secondsPerImage` (0.5-10), `resolution` (1080p/720p/square), `fps` - wieloplikowe | | `video-metadata` | Czyszczenie metadanych wideo | - | | `auto-subtitles` | Automatyczne napisy (AI) | `language` (auto/en/de/fr/es/zh/ja/ko/id/th/vi), `format` (srt/vtt) | | `extract-audio` | Wyodrębnianie dźwięku | `format` (mp3/wav/m4a/ogg) | ### Narzędzia audio {#audio-tools} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `convert-audio` | Konwersja dźwięku | `format` (mp3/wav/ogg/flac/m4a), `bitrateKbps` (32-320) | | `trim-audio` | Przycinanie dźwięku | `startS`, `endS` | | `volume-adjust` | Regulacja głośności | `gainDb` (-30 do 30) | | `normalize-audio` | Normalizacja dźwięku | - (EBU R128, -16 LUFS) | | `fade-audio` | Wyciszanie/wzmacnianie dźwięku | `fadeInS` (0-30), `fadeOutS` (0-30) | | `reverse-audio` | Odwracanie dźwięku | - | | `audio-speed` | Prędkość dźwięku | `factor` (0.25-4) | | `pitch-shift` | Przesunięcie tonacji | `semitones` (-12 do 12) | | `audio-channels` | Kanały dźwięku | `mode` (stereo-to-mono/mono-to-stereo/swap) | | `silence-removal` | Usuwanie ciszy | `thresholdDb` (-80 do -20), `minSilenceS` (0.1-5) | | `noise-reduction` | Redukcja szumów | `strength` (light/medium/strong) | | `merge-audio` | Łączenie dźwięku | `format` (mp3/wav/flac/m4a) - wieloplikowe | | `split-audio` | Dzielenie dźwięku | `mode` (time/parts/silence), `segmentS`, `parts`, `thresholdDb`, `minSilenceS` | | `ringtone-maker` | Twórca dzwonków | `startS`, `durationS` (1-30) | | `waveform-image` | Obraz przebiegu | `width`, `height`, `color` (hex) | | `audio-metadata` | Metadane dźwięku | `strip` (bool), `title`, `artist`, `album` | | `transcribe-audio` | Transkrypcja dźwięku (AI) | `language` (auto/en/de/fr/es/zh/ja/ko/id/th/vi), `outputFormat` (txt/srt/vtt) | ### Narzędzia do dokumentów {#document-tools} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `merge-pdf` | Łączenie plików PDF | - (wieloplikowe, do 20 plików PDF) | | `split-pdf` | Dzielenie PDF | `mode` (range/every), `range`, `everyN` (1-500) | | `compress-pdf` | Kompresja PDF | `mode` (quality/targetSize), `quality` (1-100), `targetSizeKb` | | `rotate-pdf` | Obrót PDF | `angle` (90/180/270), `range` (zakres stron) | | `extract-pages` | Wyodrębnianie stron | `range` (składnia qpdf, np. "1-5,8,10-z") | | `remove-pages` | Usuwanie stron | `pages` (zakres qpdf do usunięcia) | | `organize-pdf` | Organizacja PDF | `order` (kolejność stron qpdf, np. "3,1,2,5-z") | | `protect-pdf` | Ochrona PDF | `userPassword`, `ownerPassword` (AES-256) | | `unlock-pdf` | Odblokowanie PDF | `password` | | `repair-pdf` | Naprawa PDF | - | | `linearize-pdf` | Optymalizacja PDF pod kątem internetu | - (linearyzacja dla szybkiego przeglądania w sieci) | | `grayscale-pdf` | PDF w skali szarości | - | | `pdfa-convert` | Konwersja do PDF/A | - (archiwalny PDF/A-2) | | `crop-pdf` | Kadrowanie PDF | `margin` (0-2000 punktów) | | `nup-pdf` | N-up PDF | `perSheet` (2/3/4/8/9/12/16) | | `booklet-pdf` | Broszura PDF | `perSheet` (2/4/6/8) | | `watermark-pdf` | Znak wodny PDF | `text`, `position`, `fontSize`, `opacity`, `rotation` | | `pdf-page-numbers` | Numery stron PDF | `position` (bl/bc/br/tl/tc/tr), `fontSize` | | `flatten-pdf` | Spłaszczanie PDF | - (utrwala formularze i adnotacje) | | `redact-pdf` | Redakcja PDF | `terms` (string\[]), `caseSensitive` (bool) | | `sign-pdf` | Podpisywanie PDF | Niestandardowa trasa multipart z plikiem PDF `file`, plikami podpisu `sig0`, `sig1` oraz tablicą JSON `placements` | | `pdf-to-text` | PDF do tekstu | - | | `pdf-to-word` | PDF do Word | - | | `pdf-metadata` | Metadane PDF | `title`, `author`, `subject`, `keywords` | | `convert-document` | Konwersja dokumentu | `format` (docx/odt/rtf/txt) | | `convert-presentation` | Konwersja prezentacji | `format` (pptx/odp) | | `convert-spreadsheet` | Konwersja arkusza kalkulacyjnego | `format` (xlsx/ods/csv) | | `excel-to-pdf` | Excel do PDF | - | | `word-to-pdf` | Word do PDF | - | | `powerpoint-to-pdf` | PowerPoint do PDF | - | | `html-to-pdf` | HTML do PDF | - (zdalne zasoby wyłączone) | | `markdown-to-docx` | Markdown do Word | - | | `markdown-to-html` | Markdown do HTML | - | | `markdown-to-pdf` | Markdown do PDF | - (zdalne zasoby wyłączone) | | `epub-convert` | Konwersja EPUB | `format` (pdf/docx/html/md) | | `to-epub` | Konwersja do EPUB | - (akceptuje .docx, .md, .html, .txt) | | `ocr-pdf` | OCR PDF (AI) | `quality` (fast/balanced/best), `language` (auto/en/de/fr/es/zh/ja/ko), `pages` | | `pdf-to-image` | PDF do obrazu | `pages` (all/range), `format`, `dpi`, `quality` | | `pdf-to-jpg` | PDF do JPG | `pages`, `dpi`, `quality`, `colorMode` | | `pdf-to-png` | PDF do PNG | `pages`, `dpi`, `quality`, `colorMode` | | `pdf-to-tiff` | PDF do TIFF | `pages`, `dpi`, `quality`, `colorMode` | ### Narzędzia do plików {#file-tools} | ID narzędzia | Nazwa | Kluczowe ustawienia | |---------|------|-------------| | `chart-maker` | Twórca wykresów | `kind` (bar/line/pie), `title`, `width`, `height` | | `csv-excel` | CSV do Excel | `sheet` (numer arkusza dla wejścia XLSX) - dwukierunkowe | | `csv-json` | CSV do JSON | `pretty` (bool) - dwukierunkowe | | `json-xml` | JSON do XML | `pretty` (bool) - dwukierunkowe | | `split-csv` | Dzielenie CSV | `rowsPerFile` (1-1000000), `keepHeader` (bool) | | `merge-csvs` | Łączenie plików CSV | - (wieloplikowe, pasujące kolumny) | | `yaml-json` | YAML / JSON | - (dwukierunkowe) | | `xml-to-csv` | XML do CSV | - (automatyczne wyszukiwanie powtarzających się elementów) | | `excel-to-csv` | Excel do CSV | dedykowane ustawienie wstępne konwersji oparte na `convert-spreadsheet` | | `create-zip` | Utwórz ZIP | - (wieloplikowe, 2-50 plików) | | `extract-zip` | Wypakuj ZIP | - (ochrona przed bombą) | ### HTML do obrazu {#html-to-image} Przechwyć stronę internetową jako obraz. W przeciwieństwie do innych narzędzi ten punkt końcowy przyjmuje `application/json` zamiast danych formularza multipart (bez potrzeby przesyłania pliku). **Punkt końcowy:** `POST /api/v1/tools/image/html-to-image` **Content-Type:** `application/json` | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `url` | string | (wymagane) | URL do przechwycenia (tylko http/https) | | `format` | string | `"png"` | Format wyjściowy: `jpg`, `png`, `webp` | | `quality` | number | `90` | Jakość 1-100 (tylko JPG/WebP) | | `fullPage` | boolean | `false` | Przechwyć całą przewijaną stronę | | `devicePreset` | string | `"desktop"` | `desktop`, `tablet`, `mobile`, `custom` | | `viewportWidth` | number | `1280` | Niestandardowa szerokość okna widoku 320-3840 | | `viewportHeight` | number | `720` | Niestandardowa wysokość okna widoku 320-2160 | **Przykład:** ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"url": "https://snapotter.com", "format": "png", "devicePreset": "desktop"}' ``` **Odpowiedź:** ```json { "jobId": "uuid", "downloadUrl": "/api/v1/download/{jobId}/screenshot.png", "originalSize": 0, "processedSize": 54321 } ``` ### Podtrasy narzędzi {#tool-sub-routes} Niektóre narzędzia udostępniają dodatkowe punkty końcowe poza standardowym `POST /api/v1/tools/
/`: | Metoda | Ścieżka | Opis | |--------|------|-------------| | `GET` | `/api/v1/tools/popular` | Zwraca popularne identyfikatory narzędzi, wracając do wyselekcjonowanej listy domyślnej, gdy dane o użyciu są skąpe | | `POST` | `/api/v1/tools/image/remove-background/effects` | Zastosuj efekty tła (color/gradient/blur/shadow) bez ponownego uruchamiania AI. Używa maski z pamięci podręcznej z początkowego usunięcia. | | `POST` | `/api/v1/tools/image/edit-metadata/inspect` | Odczytaj istniejące metadane EXIF/IPTC/XMP z obrazu | | `POST` | `/api/v1/tools/image/strip-metadata/inspect` | Sprawdź pola metadanych przed usunięciem | | `POST` | `/api/v1/tools/image/passport-photo/analyze` | Faza 1: Wykrywanie twarzy AI + usuwanie tła. Zwraca punkty charakterystyczne twarzy i dane z pamięci podręcznej. | | `POST` | `/api/v1/tools/image/passport-photo/generate` | Faza 2: Kadrowanie, zmiana rozmiaru i kafelkowanie przy użyciu analizy z pamięci podręcznej. Bez ponownego uruchamiania AI. | | `POST` | `/api/v1/tools/image/gif-tools/info` | Pobierz metadane GIF (liczba klatek, wymiary, czas trwania) | | `POST` | `/api/v1/tools/pdf/pdf-to-image/info` | Pobierz metadane PDF (liczba stron, wymiary) | | `POST` | `/api/v1/tools/pdf/pdf-to-image/preview` | Wygeneruj podgląd konkretnej strony PDF | | `POST` | `/api/v1/tools/pdf/pdf-to-jpg/info` | Pobierz metadane PDF dla dedykowanego ustawienia wstępnego JPG | | `POST` | `/api/v1/tools/pdf/pdf-to-jpg/preview` | Wygeneruj podgląd strony PDF z ustawieniem wstępnym JPG | | `POST` | `/api/v1/tools/pdf/pdf-to-png/info` | Pobierz metadane PDF dla dedykowanego ustawienia wstępnego PNG | | `POST` | `/api/v1/tools/pdf/pdf-to-png/preview` | Wygeneruj podgląd strony PDF z ustawieniem wstępnym PNG | | `POST` | `/api/v1/tools/pdf/pdf-to-tiff/info` | Pobierz metadane PDF dla dedykowanego ustawienia wstępnego TIFF | | `POST` | `/api/v1/tools/pdf/pdf-to-tiff/preview` | Wygeneruj podgląd strony PDF z ustawieniem wstępnym TIFF | | `POST` | `/api/v1/tools/image/svg-to-raster/batch` | Konwertuj wsadowo wiele plików SVG do rastra | | `POST` | `/api/v1/tools/image/image-enhancement/analyze` | Przeanalizuj jakość obrazu i zwróć rekomendacje poprawy | | `POST` | `/api/v1/tools/image/optimize-for-web/preview` | Lekki podgląd do dostrajania parametrów na żywo. Zwraca zoptymalizowany obraz z nagłówkami rozmiaru. | ## Przetwarzanie wsadowe {#batch-processing} Zastosuj ogólne narzędzie obsługujące tryb wsadowy do wielu plików jednocześnie. Zwraca archiwum ZIP. Niestandardowe trasy wieloplikowe lub wieloetapowe, takie jak podpisywanie PDF oraz trasy ustawień wstępnych PDF-do-obrazu, używają własnego kontraktu punktu końcowego zamiast ogólnej trasy `/batch`. Narzędzie `ocr-pdf` obsługuje tę ogólną trasę `/batch`. ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress/batch \ -H "Authorization: Bearer " \ -F "files=@a.jpg" \ -F "files=@b.jpg" \ -F "files=@c.jpg" \ -F 'settings={"quality":80}' ``` Współbieżnością steruje `CONCURRENT_JOBS` (domyślnie: automatycznie wykrywana na podstawie rdzeni CPU). `MAX_BATCH_SIZE` ogranicza liczbę plików w partii (domyślnie: 100; ustaw 0 dla braku limitu). ## Potoki {#pipelines} ### Wykonaj potok {#execute-a-pipeline} ```bash # Single file curl -X POST http://localhost:1349/api/v1/pipeline/execute \ -H "Authorization: Bearer " \ -F "file=@input.jpg" \ -F 'pipeline={"steps":[ {"toolId":"resize","settings":{"width":1200}}, {"toolId":"compress","settings":{"quality":80}}, {"toolId":"watermark-text","settings":{"text":"© 2025"}} ]}' # Batch (multiple files → ZIP) curl -X POST http://localhost:1349/api/v1/pipeline/batch \ -H "Authorization: Bearer " \ -F "files=@a.jpg" \ -F "files=@b.jpg" \ -F 'pipeline={"steps":[{"toolId":"resize","settings":{"width":800}}]}' ``` Wyjście każdego kroku jest wejściem następnego kroku. Potoki domyślnie dopuszczają 20 kroków, co jest konfigurowalne za pomocą `MAX_PIPELINE_STEPS`. Ustaw `MAX_PIPELINE_STEPS=0`, aby usunąć limit. ### Zapisywanie potoków i zarządzanie nimi {#save-and-manage-pipelines} | Metoda | Ścieżka | Opis | |--------|------|-------------| | `POST` | `/api/v1/pipeline/save` | Zapisz nazwany potok (`name`, `description`, `steps[]`) | | `GET` | `/api/v1/pipeline/list` | Lista zapisanych potoków (administratorzy widzą wszystkie; użytkownicy widzą własne) | | `DELETE` | `/api/v1/pipeline/:id` | Usuń (właściciel lub administrator) | | `GET` | `/api/v1/pipeline/tools` | Lista identyfikatorów narzędzi ważnych dla kroków potoku | ## Śledzenie postępu {#progress-tracking} Długotrwałe zadania, narzędzia w kolejce, zadania wsadowe i potoki emitują postęp w czasie rzeczywistym za pomocą Server-Sent Events. Strumień postępu jest publiczny i identyfikowany przez identyfikator zadania, więc klienci nie muszą wysyłać nagłówka Authorization, aby go odczytać. ```bash # Connect to the SSE stream (jobId is in the JSON response body from the tool endpoint) curl -N http://localhost:1349/api/v1/jobs//progress ``` Format zdarzenia: ``` data: {"jobId":"...","type":"single","phase":"processing","stage":"Upscaling","percent":42} data: {"jobId":"...","type":"single","phase":"complete","percent":100,"result":{"downloadUrl":"/api/v1/download/..."}} data: {"jobId":"...","type":"batch","status":"processing","completedFiles":2,"totalFiles":5,"failedFiles":0,"errors":[]} ``` Możesz zażądać anulowania zadania w kolejce lub uruchomionego za pomocą `POST /api/v1/jobs/:jobId/cancel`. Odpowiedzią jest `{"canceled":true|false}`. ## Biblioteka plików {#file-library} Trwałe przechowywanie plików z historią wersji. | Metoda | Ścieżka | Opis | |--------|------|-------------| | `POST` | `/api/v1/upload` | Prześlij pliki do obszaru roboczego (tymczasowe przetwarzanie) | | `POST` | `/api/v1/files/upload` | Prześlij pliki do trwałej biblioteki plików | | `POST` | `/api/v1/files/save-result` | Zapisz wynik przetwarzania narzędzia jako nową wersję pliku | | `GET` | `/api/v1/files` | Lista zapisanych plików (stronicowana, z wyszukiwaniem) | | `GET` | `/api/v1/files/:id` | Pobierz metadane pliku + łańcuch wersji | | `GET` | `/api/v1/files/:id/download` | Pobierz plik | | `GET` | `/api/v1/files/:id/thumbnail` | Pobierz miniaturę JPEG 300px | | `DELETE` | `/api/v1/files` | Zbiorczo usuń pliki i ich łańcuchy wersji (treść: `{ ids: [...] }`) | | `POST` | `/api/v1/fetch-urls` | Pobierz zdalne adresy URL do obszaru roboczego dla importów opartych na URL | | `POST` | `/api/v1/preview` | Wygeneruj podgląd WebP zgodny z przeglądarką (dla formatów HEIC/HEIF/RAW) | | `GET` | `/api/v1/files/:id/preview` | Przesyłaj strumieniowo podgląd zgodny z przeglądarką z pamięci podręcznej lub wygenerowany dla zapisanego pliku PDF, dokumentu biurowego, wideo lub audio | | `POST` | `/api/v1/preview/generate` | Wygeneruj na żądanie podgląd MP4 lub MP3 dla przesłanego pliku multimedialnego bez uprzedniego zapisywania go | | `GET` | `/api/v1/download/:jobId/:filename` | Pobierz przetworzony plik z obszaru roboczego | Aby automatycznie zapisać wynik narzędzia w bibliotece, dołącz `fileId` jako pole formularza multipart odwołujące się do istniejącego pliku w bibliotece. Przetworzony wynik zostanie zapisany jako nowa wersja. ## Zarządzanie kluczami API {#api-key-management} | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `POST` | `/api/v1/api-keys` | Uwierzytelniony | Wygeneruj nowy klucz - pokazywany raz | | `GET` | `/api/v1/api-keys` | Uwierzytelniony | Lista kluczy (nazwa, id, lastUsedAt - bez surowego klucza) | | `DELETE` | `/api/v1/api-keys/:id` | Uwierzytelniony | Usuń klucz | ## Zespoły {#teams} | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/teams` | Administrator (`teams:manage`) | Lista zespołów | | `POST` | `/api/v1/teams` | Administrator (`teams:manage`) | Utwórz zespół | | `PUT` | `/api/v1/teams/:id` | Administrator (`teams:manage`) | Zmień nazwę zespołu | | `DELETE` | `/api/v1/teams/:id` | Administrator (`teams:manage`) | Usuń zespół (nie można usunąć domyślnego zespołu ani zespołów z członkami) | ## Ustawienia {#settings} Konfiguracja środowiska uruchomieniowego używa zamkniętego zbioru rozpoznawanych kluczy. Odczyt wymaga uprawnienia `settings:read`, a zapis — `settings:write`; klucze zabezpieczeń i zgodności dodatkowo wymagają uprawnienia `security:manage` lub `compliance:manage`. Ustawienia tajne wymagają uprawnień pełnego administratora, natomiast poświadczenia i stan zarządzane przez dedykowane punkty końcowe są tutaj tylko do odczytu. Aktualizacje zbiorcze są weryfikowane przed zapisaniem jakiejkolwiek wartości. | Metoda | Ścieżka | Opis | |--------|------|-------------| | `GET` | `/api/v1/settings` | Pobierz wszystkie ustawienia | | `PUT` | `/api/v1/settings` | Zbiorczo zaktualizuj ustawienia (treść JSON z parami klucz-wartość) | | `GET` | `/api/v1/settings/:key` | Pobierz konkretne ustawienie według klucza | Przykładowe klucze: `disabledTools` (tablica JSON identyfikatorów narzędzi), `enableExperimentalTools` (wartość logiczna), `loginAttemptLimit` (zasady zabezpieczeń) oraz `auditRetentionDays` (zasady zgodności). Nieznane klucze są odrzucane. ## Preferencje {#preferences} Preferencje poszczególnych użytkowników są oddzielone od ustawień instancji. Każdy uwierzytelniony użytkownik może odczytać i zaktualizować własną mapę preferencji. | Metoda | Ścieżka | Opis | |--------|------|-------------| | `GET` | `/api/v1/preferences` | Pobierz preferencje bieżącego użytkownika jako `{ "preferences": { ... } }` | | `PUT` | `/api/v1/preferences` | Zapisz lub zaktualizuj jeden lub więcej kluczy preferencji dla bieżącego użytkownika | ## Role {#roles} Zarządzanie niestandardowymi rolami z granularnymi uprawnieniami. | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/roles` | Administrator (`audit:read`) | Lista wszystkich ról z liczbą użytkowników | | `POST` | `/api/v1/roles` | Administrator (`security:manage`) | Utwórz niestandardową rolę (`name`, `description`, `permissions`) | | `PUT` | `/api/v1/roles/:id` | Administrator (`security:manage`) | Zaktualizuj niestandardową rolę (nie można modyfikować wbudowanych ról) | | `DELETE` | `/api/v1/roles/:id` | Administrator (`security:manage`) | Usuń niestandardową rolę (nie można usuwać wbudowanych ról; dotknięci użytkownicy wracają do roli `user`) | Dostępne uprawnienia (17): `tools:use`, `files:own`, `files:all`, `apikeys:own`, `apikeys:all`, `pipelines:own`, `pipelines:all`, `settings:read`, `settings:write`, `users:manage`, `teams:manage`, `features:manage`, `system:health`, `audit:read`, `compliance:manage`, `webhooks:manage`, `security:manage`. ## Dziennik audytu {#audit-log} Punkt końcowy tylko dla administratora do przeglądania działań istotnych z punktu widzenia bezpieczeństwa. | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/audit-log` | Administrator (`audit:read`) | Stronicowany dziennik audytu z opcjonalnymi filtrami | Parametry zapytania: | Parametr | Opis | |-----------|-------------| | `page` | Numer strony (domyślnie: 1) | | `limit` | Wpisy na stronę (domyślnie: 50, maks.: 100) | | `action` | Filtruj według typu akcji (np. `ROLE_CREATED`, `ROLE_DELETED`) | | `ip` | Filtruj według źródłowego adresu IP | | `from` | Filtruj wpisy po tej dacie ISO 8601 | | `to` | Filtruj wpisy przed tą datą ISO 8601 | ## Analityka {#analytics} | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/config/analytics` | Publiczny | Pobierz efektywną konfigurację analityki (klucz PostHog, DSN Sentry, częstotliwość próbkowania). Klucze, DSN i identyfikator instancji są puste, gdy analityka jest wyłączona, zarówno z powodu ustawienia w czasie kompilacji, jak i ustawienia instancji `analyticsEnabled`. | | `POST` | `/api/v1/feedback` | Uwierzytelniony | Prześlij wyraźną opinię użytkownika do skonfigurowanego projektu PostHog jako `feedback_submitted`. Trasa respektuje bramkę analityki, ogranicza liczbę zgłoszeń, usuwa pola kontaktowe, chyba że `contactOk` ma wartość true, i nigdy nie akceptuje zawartości plików, nazw plików, ścieżek przesyłania ani surowego, prywatnego tekstu błędu. Gdy analityka jest wyłączona, zwraca `{ "ok": true, "accepted": false }`. | | `PUT` | `/api/v1/settings` | Administrator (`settings:write`) | Ustaw rezygnację obejmującą całą instancję. Wyślij treść JSON `{ "analyticsEnabled": "false" }`, aby wyłączyć analitykę dla wszystkich, lub `"true"`, aby ją ponownie włączyć. | ## Funkcje / Pakiety AI {#features-ai-bundles} Zarządzaj pakietami funkcji AI (instaluj/odinstalowuj pakiety modeli AI w środowisku Docker). Preferuj punkt końcowy instalacji na poziomie narzędzia podczas włączania narzędzia z niestandardowej automatyzacji: niektóre narzędzia AI potrzebują więcej niż jednego współdzielonego pakietu, a ten punkt końcowy pomija już zainstalowane pakiety, kolejkując tylko brakujące. OCR jest opcjonalnym ulepszeniem, a nie stałą zależnością. Poziom `fast` Tesseract działa bez pakietu; `POST /api/v1/admin/features/ocr/install` instaluje podpisany pakiet RapidOCR dla `balanced` i `best` na Linux amd64 lub arm64. Dokładne środowisko wykonawcze OCR wykorzystuje CPU na hostach wyposażonych wyłącznie w procesor i NVIDIA i wymaga co najmniej 4 GiB efektywnej pamięci (skonfigurowany limit kontenera cgroup, w przeciwnym razie pamięć hosta). SnapOtter zgłasza `requiredMemoryBytes`, `effectiveMemoryBytes` i przyczynę kompatybilności `insufficient-memory` i odrzuca niezgodną instalację przed pobraniem. To wymaganie dotyczące pamięci nie dotyczy `fast`. Pakiet zawiera około 208-234 MiB do pobrania i 409-488 MiB do zainstalowania, w zależności od celu; podpisany indeks wiąże dokładne rozmiary wymuszone podczas instalacji. | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/features` | Uwierzytelniony | Lista wszystkich pakietów funkcji i ich status instalacji | | `POST` | `/api/v1/admin/features/:bundleId/install` | Administrator (`features:manage`) | Zainstaluj pakiet funkcji (asynchronicznie, zwraca `jobId` do śledzenia postępu) | | `POST` | `/api/v1/admin/tools/:toolId/features/install` | Administrator (`features:manage`) | Zainstaluj każdy pakiet wymagany przez narzędzie; zwraca status queued/skipped dla poszczególnych pakietów | | `POST` | `/api/v1/admin/features/:bundleId/uninstall` | Administrator (`features:manage`) | Odinstaluj pakiet funkcji i usuń pliki modeli | | `GET` | `/api/v1/admin/features/disk-usage` | Administrator (`features:manage`) | Pobierz całkowite zużycie dysku przez modele AI | | `POST` | `/api/v1/admin/features/import` | Administrator (`features:manage`) | Zaimportuj starszy pakiet AI (`file`) lub podpisaną wersję offline OCR (`index` plus `archive`) | Import OCR z przerwami powietrznymi musi zawierać podpisany plik `ocr-runtime-index.json` wydania i pasujące archiwum platformy. SnapOtter stosuje tę samą sygnaturę Ed25519, hash artefaktów, kompatybilność, ekstrakcję i kontrole testów dymu, które są używane podczas instalacji online: ```bash curl -X POST http://localhost:1349/api/v1/admin/features/import \ -H "Authorization: Bearer " \ -F "index=@ocr-runtime-index.json" \ -F "archive=@ocr-linux-amd64-cpu-py312.tar.gz" ``` Użyj archiwum `linux-arm64-cpu-py311` na arm64. Podpisany artefakt innego celu jest odrzucany, a nie instalowany. ## Operacje administracyjne {#admin-operations} Operacyjne punkty końcowe do obserwowalności, wsparcia, raportowania użycia i statusu kopii zapasowej. | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/admin/log-level` | Administrator (`settings:write`) | Odczytaj bieżący poziom logowania w czasie działania | | `POST` | `/api/v1/admin/log-level` | Administrator (`settings:write`) | Zmień poziom logowania w czasie działania (`fatal`, `error`, `warn`, `info`, `debug`, `trace` lub `silent`) | | `GET` | `/api/v1/metrics` | Administrator (`system:health`) | Metryki Prometheus w formacie tekstowym | | `GET` | `/api/v1/admin/support-bundle` | Administrator (`system:health`) | Pobierz zredagowany pakiet diagnostyczny wsparcia ZIP | | `GET` | `/api/v1/admin/usage` | Administrator (`audit:read`) | Dane pulpitu użycia, z opcjonalnym parametrem zapytania `days` | | `GET` | `/api/v1/admin/backup-status` | Administrator (`system:health`) | Odczytaj metadane ostatniej kopii zapasowej i status aktualności | | `POST` | `/api/v1/admin/backup-status` | Administrator (`system:health`) | Zarejestruj ukończoną kopię zapasową (`type`, opcjonalnie `sizeBytes`, opcjonalnie `notes`) | ## API Enterprise {#enterprise-apis} Te trasy są bramkowane licencją przez powiązaną z nimi funkcję enterprise. Nadal wymagają wymienionego uprawnienia SnapOtter. **Wbudowany administrator z pełnymi uprawnieniami** oznacza uwierzytelnionego użytkownika z rolą `admin` i pełnym zestawem efektywnych uprawnień administratora. Klucz API, któremu brakuje choć jednego uprawnienia administratora, nie spełnia tego wymagania. | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/enterprise/audit/export` | Administrator (`audit:read`) | Eksportuj wpisy audytu jako JSON lub CSV z filtrami | | `GET` | `/api/v1/enterprise/config/export` | Wbudowany administrator z pełnymi uprawnieniami | Eksportuj zredagowaną konfigurację instancji, niestandardowe role i zespoły | | `POST` | `/api/v1/enterprise/config/import` | Wbudowany administrator z pełnymi uprawnieniami | Zaimportuj konfigurację, z opcjonalnym przebiegiem próbnym | | `GET` | `/api/v1/enterprise/ip-allowlist` | Administrator (`security:manage`) | Odczytaj skonfigurowaną listę dozwolonych CIDR | | `PUT` | `/api/v1/enterprise/ip-allowlist` | Administrator (`security:manage`) | Zaktualizuj listę dozwolonych CIDR z ochroną przed zablokowaniem samego siebie | | `GET` | `/api/v1/enterprise/legal-hold` | Administrator (`compliance:manage`) | Lista blokad prawnych użytkowników i zespołów | | `PUT` | `/api/v1/enterprise/legal-hold` | Administrator (`compliance:manage`) | Zastosuj lub zwolnij blokadę prawną dla użytkownika lub zespołu | | `POST` | `/api/v1/enterprise/scim/token` | Administrator (`users:manage`) | Wygeneruj token bearer SCIM, zwracany raz | | `DELETE` | `/api/v1/enterprise/scim/token` | Administrator (`users:manage`) | Unieważnij bieżący token bearer SCIM | | `GET` | `/api/v1/enterprise/siem/config` | Administrator (`webhooks:manage`) | Odczytaj konfigurację przekazywania SIEM | | `PUT` | `/api/v1/enterprise/siem/config` | Administrator (`webhooks:manage`) | Zaktualizuj konfigurację przekazywania SIEM | | `GET` | `/api/v1/enterprise/webhooks` | Administrator (`webhooks:manage`) | Lista miejsc docelowych webhooków | | `POST` | `/api/v1/enterprise/webhooks` | Administrator (`webhooks:manage`) | Utwórz miejsce docelowe webhooka | | `PUT` | `/api/v1/enterprise/webhooks/:index` | Administrator (`webhooks:manage`) | Zaktualizuj miejsce docelowe webhooka | | `DELETE` | `/api/v1/enterprise/webhooks/:index` | Administrator (`webhooks:manage`) | Usuń miejsce docelowe webhooka | | `POST` | `/api/v1/enterprise/webhooks/:index/test` | Administrator (`webhooks:manage`) | Wyślij testowy ładunek webhooka | | `POST` | `/api/v1/enterprise/users/:id/export` | Administrator (`compliance:manage`) | Rozpocznij zadanie eksportu użytkownika RODO | | `GET` | `/api/v1/enterprise/users/:id/export/:jobId` | Administrator (`compliance:manage`) | Odczytaj status eksportu RODO i adres URL pobierania | | `DELETE` | `/api/v1/enterprise/users/:id/purge` | Administrator (`compliance:manage`) | Trwale usuń dane użytkownika po potwierdzeniu | | `DELETE` | `/api/v1/enterprise/teams/:id/purge` | Administrator (`compliance:manage`) | Trwale usuń dane zespołu po potwierdzeniu | | `GET` | `/api/v1/admin/version` | Administrator (`system:health`) | Odczytaj metadane wersji aplikacji, kompilacji, Node i schematu | | `GET` | `/api/v1/admin/migrations/pending` | Administrator (`system:health`) | Porównaj spakowane migracje z zastosowanymi migracjami | | `GET` | `/api/v1/admin/upgrade-check` | Administrator (`system:health`) | Uruchom kontrole gotowości do aktualizacji | ### SCIM 2.0 {#scim-2-0} Punkty końcowe wykrywania SCIM są publiczne. Punkty końcowe użytkowników i grup wymagają tokena bearer SCIM wygenerowanego powyżej. | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/scim/v2/ServiceProviderConfig` | Publiczny | Możliwości serwera SCIM | | `GET` | `/api/v1/scim/v2/Schemas` | Publiczny | Wykrywanie schematu SCIM | | `GET` | `/api/v1/scim/v2/ResourceTypes` | Publiczny | Wykrywanie typu zasobu SCIM | | `GET` | `/api/v1/scim/v2/Users` | Token SCIM | Lista użytkowników, z opcjonalnym filtrem SCIM | | `POST` | `/api/v1/scim/v2/Users` | Token SCIM | Utwórz użytkownika | | `GET` | `/api/v1/scim/v2/Users/:id` | Token SCIM | Pobierz użytkownika | | `PUT` | `/api/v1/scim/v2/Users/:id` | Token SCIM | Zastąp użytkownika | | `DELETE` | `/api/v1/scim/v2/Users/:id` | Token SCIM | Miękka dezaktywacja użytkownika | | `GET` | `/api/v1/scim/v2/Groups` | Token SCIM | Lista zespołów jako grup SCIM | | `POST` | `/api/v1/scim/v2/Groups` | Token SCIM | Utwórz zespół | | `GET` | `/api/v1/scim/v2/Groups/:id` | Token SCIM | Pobierz zespół | | `PUT` | `/api/v1/scim/v2/Groups/:id` | Token SCIM | Zastąp zespół i członkostwo w grupie | | `DELETE` | `/api/v1/scim/v2/Groups/:id` | Token SCIM | Usuń zespół | ## Szablony memów {#meme-templates} Wspierające API dla narzędzia generatora memów. | Metoda | Ścieżka | Dostęp | Opis | |--------|------|--------|-------------| | `GET` | `/api/v1/meme-templates` | Uwierzytelniony | Lista wszystkich dostępnych szablonów memów z pozycjami pól tekstowych | | `GET` | `/api/v1/meme-templates/full/:filename` | Uwierzytelniony | Udostępnij obraz szablonu w pełnym rozmiarze | | `GET` | `/api/v1/meme-templates/thumbs/:filename` | Uwierzytelniony | Udostępnij miniaturę szablonu | | `GET` | `/api/v1/meme-templates/fonts/:filename` | Uwierzytelniony | Udostępnij plik czcionki używany do renderowania tekstu memu | ## Odpowiedzi z błędami {#error-responses} Wszystkie błędy zwracają JSON: ```json { "error": "Human-readable message", "code": "MACHINE_READABLE_CODE" } ``` | Status | Znaczenie | |--------|---------| | 400 | Nieprawidłowe żądanie / walidacja nie powiodła się | | 401 | Brak uwierzytelnienia | | 403 | Niewystarczające uprawnienia | | 404 | Nie znaleziono zasobu | | 413 | Plik zbyt duży (zobacz `MAX_UPLOAD_SIZE_MB`) | | 422 | Przetwarzanie nie powiodło się po walidacji | | 429 | Ograniczenie liczby żądań (zobacz `RATE_LIMIT_PER_MIN`) | | 501 | Wymagany pakiet funkcji AI nie jest zainstalowany (`FEATURE_NOT_INSTALLED`) | | 500 | Wewnętrzny błąd serwera | --- --- url: https://docs.snapotter.com/pl/api/ai.md description: >- Dokumentacja silnika AI ze wszystkimi lokalnymi narzędziami ML. Usuwanie tła, powiększanie, OCR, wykrywanie twarzy, renowacja zdjęć i więcej. --- # Dokumentacja silnika AI {#ai-engine-reference} Pakiet `@snapotter/ai` koordynuje natywne narzędzia i środowiska wykonawcze Python dla lokalnych operacji ML. Większość narzędzi ML wykorzystuje trwały Python sidecar do szybkiego ciepłego startu. OCR jest celowo oddzielny: `fast` wywołuje natywny plik binarny Tesseract, podczas gdy `balanced` i `best` używają dedykowanego trwałego JSONL dispatcher przypiętego do aktywnej, niezmiennej generacji RapidOCR w ramach `/data/ai/v3`. Każde żądanie zawiera generation lease. Podczas aktualizacji SnapOtter uruchamia smoke test na kandydacie przed aktywacją, atomowo przełącza się na nowy dispatcher, a następnie opróżnia starą generację przed garbage collection. NVIDIA CUDA jest automatycznie wykrywany i używany przez środowiska wykonawcze, które go obsługują. OCR używa CPU na każdym hoście, w tym na systemach z procesorami graficznymi NVIDIA, unikając łączenia CUDA i sterowników dla tego narzędzia. Przyspieszenie iGPU Intel/AMD za pośrednictwem VA-API, Quick Sync lub OpenCL nie jest obecnie obsługiwane dla wnioskowania AI. Mapowanie `/dev/dri` do kontenera nie przyspiesza tych narzędzi procesu pomocniczego Pythona, chyba że dostępny jest GPU NVIDIA obsługujący CUDA. 19 narzędzi AI procesu pomocniczego Pythona w czterech modalnościach (obraz, dźwięk, wideo, dokument), plus 2 narzędzia z opcjonalnymi funkcjami AI. Wszystkie modele działają lokalnie - po początkowym pobraniu modeli internet nie jest wymagany. ::: info Zgodność OCR dla języka koreańskiego Szybki OCR obsługuje `auto`, `en`, `de`, `es`, `fr`, `zh` i `ja`, ale nie język koreański (`ko`). Koreański wymaga dokładnego pakietu OCR i `balanced` lub `best`. Pakiet działa w oficjalnych kontenerach Linux amd64 i arm64, także na hostach NVIDIA, gdzie OCR nadal używa CPU. Nieobsługiwany system otrzymuje jawny błąd zgodności i nigdy po cichu nie przechodzi na `fast`. Koreański z `fast` lub starszym aliasem `tesseract` jest odrzucany przed zakolejkowaniem z `FEATURE_INCOMPATIBLE` i `fast-korean-unsupported`. ::: ## Architektura {#architecture} ``` Node.js Tool Route | v @snapotter/ai bridge.ts | (stdin/stdout JSON + stderr progress events) v +-- Native Tesseract + Ghostscript (fast image/PDF OCR) | +-- Isolated OCR runtime (persistent JSONL dispatcher) | `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models | `-- Python dispatcher (persistent process, "ai" profile) | |-- remove_bg.py (rembg / BiRefNet) |-- upscale.py (RealESRGAN) |-- inpaint.py (LaMa ONNX) |-- outpaint.py (LaMa canvas expansion) |-- detect_faces.py (MediaPipe) |-- face_landmarks.py (MediaPipe landmarks) |-- enhance_faces.py (GFPGAN / CodeFormer) |-- colorize.py (DDColor) |-- noise_removal.py (SCUNet / tiered denoising) |-- red_eye_removal.py (landmark + color analysis) |-- restore.py (scratch repair + enhancement + denoising) |-- transcribe.py (faster-whisper speech-to-text) +-- install_feature.py (on-demand bundle installer) ``` Oddzielny profil dyspozytora "docs" zastępuje listę dozwolonych AI skryptami do przetwarzania dokumentów (`doc_pagecount`, `doc_health`, `doc_flatten`, `doc_redact`, `doc_text`, `doc_to_word`, `doc_metadata`, `doc_html_pdf`) i pomija ciężkie importy ML. **Limity czasu:** 300 s domyślnie; OCR i usuwanie tła BiRefNet otrzymują 600 s. ## Pakiety funkcji {#feature-bundles} Modele AI są pakowane według współdzielonego stosu zależności, a nie jako jedno archiwum na narzędzie. Pakiet funkcji może włączyć kilka narzędzi, gdy używają tej samej rodziny modeli, tych samych pakietów wheel Pythona lub natywnych bibliotek. Utrzymuje to mniejszy rozmiar wydania obrazu Docker i pozwala uniknąć przechowywania zduplikowanych kopii tych samych modeli mattingu tła, wykrywania twarzy, OCR, renowacji i mowy. Obraz Docker dostarcza aplikację oraz wspólne środowisko uruchomieniowe. Duże archiwa modeli są pobierane na żądanie do trwałego woluminu `/data/ai`, a następnie ponownie wykorzystywane przez każde narzędzie, które ich potrzebuje. Jeśli pakiet jest już zainstalowany, ponieważ inne narzędzie go potrzebowało, włączenie nowego zależnego narzędzia nie powoduje ponownego pobrania tego pakietu. Większość narzędzi AI wymaga jednego lub więcej pakietów funkcji, zanim będą mogły zostać uruchomione. Interfejs administratora instaluje je za pomocą narzędzia `POST /api/v1/admin/tools/:toolId/features/install`, które rozpoznaje pełną listę pakietów, pomija już zainstalowane pakiety i umieszcza w kolejce tylko brakujące pliki do pobrania. Na przykład włączenie zdjęcia paszportowego w kolejkach świeżych instancji `background-removal` i `face-detection`; włączenie go po usunięciu tła jest już zainstalowanych kolejek tylko `face-detection`. OCR jest wyjątkiem, ponieważ `fast` nie wymaga pakietu; zainstaluj opcjonalne dokładne środowisko wykonawcze za pośrednictwem interfejsu użytkownika lub `POST /api/v1/admin/features/ocr/install`. | Pakiet | Rozmiar | Współdzielona grupa zależności | Narzędzia, które go używają | |--------|------|-------------------------|-------------------| | `background-removal` | 4-5 GB | matting tła rembg / BiRefNet | remove-background, passport-photo, transparency-fixer, background-replace, blur-background | | `face-detection` | 200-300 MB | wykrywanie twarzy i punktów charakterystycznych MediaPipe | blur-faces, red-eye-removal, smart-crop | | `object-eraser-colorize` | 1-2 GB | inpainting/outpainting LaMa oraz DDColor | erase-object, colorize, ai-canvas-expand | | `upscale-enhance` | 5-6 GB | RealESRGAN, GFPGAN / CodeFormer, odszumianie | upscale, enhance-faces, noise-removal | | `photo-restoration` | 4-5 GB | naprawa rys i potok renowacji | restore-photo | | `ocr` | ~208-234 MiB pobierz / ~409-488 MiB zainstalowany | Opcjonalne modele RapidOCR 3.9.1, ONNX Runtime 1.20.1 i przypinane PP-OCR | ocr, ocr-pdf (tylko `balanced` i `best`) | | `transcription` | ~600 MB | modele mowy na tekst faster-whisper | transcribe-audio, auto-subtitles | Narzędzia z zależnościami międzypakietowymi: | Narzędzie | Wymagane pakiety | Dlaczego | |------|------------------|-----| | `passport-photo` | `background-removal`, `face-detection` | Usuwa tło, a następnie używa punktów charakterystycznych twarzy do wykadrowania zgodnie z zasadami zdjęć paszportowych i dowodowych. | | `enhance-faces` | `upscale-enhance`, `face-detection` | Wykrywa twarze przed uruchomieniem ulepszenia GFPGAN lub CodeFormer na wybranych obszarach twarzy. | Narzędzie jest dostępne tylko wtedy, gdy zainstalowane są wszystkie wymagane pakiety, z wyjątkiem OCR: jego wbudowana warstwa `fast` pozostaje dostępna bez opcjonalnego pakietu OCR. Instalacje częściowe są ważne i obsługiwane przyrostowo: zainstalowane pakiety są ponownie wykorzystywane, brakujące pakiety są wyświetlane jako pliki do pobrania, a instalacje w kolejce są uruchamiane pojedynczo, więc współdzielone środowisko Python nie jest modyfikowane jednocześnie. ### Dokładna instalacja środowiska wykonawczego OCR {#accurate-ocr-runtime-installation} Dokładny pakiet OCR to specyficzne dla platformy środowisko uruchomieniowe dla oficjalnego kontenera Linux amd64 lub Linux arm64. Kompilacja amd64 wykorzystuje Python 3.12; kompilacja arm64 wykorzystuje Python 3.11. Obie kompilacje działają od RapidOCR do ONNX Runtime `CPUExecutionProvider`, więc ten sam pakiet działa na hostach wyposażonych tylko w procesor i NVIDIA Docker. Dokładny czas działania wymaga co najmniej 4 GiB efektywnej pamięci: skonfigurowany limit kontenera cgroup, w przeciwnym razie pamięć hosta. System poniżej podpisanego minimum zgodności jest odrzucany przed pobraniem. Wymaganie to nie dotyczy wbudowanego Fast OCR. Kompilacje Bare-metal są odrzucane, ponieważ nie można bezpiecznie wywnioskować ich libc i Python ABI; Szybki OCR pozostaje dostępny, gdy host udostępnia Tesseract i Ghostscript. Opcjonalny artefakt to około 208-234 skompresowany MiB i wyodrębniony 409-488 MiB, w zależności od architektury. Podpisany indeks wiąże dokładną liczbę skompresowanych i wyodrębnionych bajtów wymuszonych przez instalatora. Wbudowany Tesseract dodaje około 25 MiB do oficjalnego obrazu i nie wymaga żadnych plików w `/data/ai`. Instalacja online pobiera podpisany indeks wersji i dokładny artefakt adresowany do treści dla bieżącej platformy. SnapOtter weryfikuje sygnaturę indeksu Ed25519, rozmiar artefaktu, podsumowanie SHA-256, podsumowania modelu, ścieżki, tryby plików i etapową smoke test przed atomową aktywacją nowej generacji. Nieudana instalacja pozostawia aktywną poprzednią, zdrową generację. W przypadku instalacji z przerwą powietrzną prześlij zarówno wersję `ocr-runtime-index.json`, jak i pasujące archiwum wykonawcze OCR do `POST /api/v1/admin/features/import`, używając wieloczęściowych pól o nazwach `index` i `archive`. Import offline stosuje te same kontrole podpisu, skrótu, ekstrakcji, zgodności i testu dymu, co podczas instalacji online; archiwum bez zaufanego podpisanego indeksu jest odrzucane. *** ## Usuwanie tła {#background-removal} **Trasa narzędzia:** `remove-background`\ **Model:** rembg z BiRefNet (domyślnie) lub warianty U2-Net | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `model` | string | - | Wariant modelu (opcjonalne nadpisanie) | | `backgroundType` | string | `"transparent"` | Jeden z: `transparent`, `color`, `gradient`, `blur`, `image` | | `backgroundColor` | string | - | Kolor hex dla jednolitego tła | | `gradientColor1` | string | - | Pierwszy kolor gradientu | | `gradientColor2` | string | - | Drugi kolor gradientu | | `gradientAngle` | number | - | Kąt gradientu w stopniach | | `blurEnabled` | boolean | - | Włącz efekt rozmycia tła | | `blurIntensity` | number (0-100) | - | Intensywność rozmycia | | `shadowEnabled` | boolean | - | Włącz cień pod obiektem | | `shadowOpacity` | number (0-100) | - | Krycie cienia | | `outputFormat` | string | - | Format wyjściowy: `png`, `webp` lub `avif` | | `edgeRefine` | integer (0-3) | - | Poziom wygładzania krawędzi | | `decontaminate` | boolean | - | Usuń przenikanie koloru z krawędzi | ## Zamiana tła {#background-replace} **Trasa narzędzia:** `background-replace`\ **Model:** rembg / BiRefNet (współdzielony z remove-background) Usuwa tło i zastępuje je jednolitym kolorem lub gradientem. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `backgroundType` | `"color"` | `"gradient"` | `"color"` | Tryb tła | | `color` | string | `"#ffffff"` | Kolor hex tła (gdy `backgroundType` to `color`) | | `gradientColor1` | string | - | Pierwszy kolor hex gradientu | | `gradientColor2` | string | - | Drugi kolor hex gradientu | | `gradientAngle` | integer (0-360) | `180` | Kąt gradientu w stopniach | | `feather` | integer (0-20) | `0` | Promień wtapiania krawędzi | | `format` | `"png"` | `"webp"` | `"png"` | Format wyjściowy | ## Rozmycie tła {#blur-background} **Trasa narzędzia:** `blur-background`\ **Model:** rembg / BiRefNet (współdzielony z remove-background) Rozmywa tło, zachowując ostrość obiektu. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `intensity` | integer (1-100) | `50` | Intensywność rozmycia | | `feather` | integer (0-20) | `0` | Promień wtapiania krawędzi | | `format` | `"png"` | `"webp"` | `"png"` | Format wyjściowy | ## Powiększanie obrazu {#image-upscaling} **Trasa narzędzia:** `upscale`\ **Model:** RealESRGAN (z rezerwowym Lanczos, gdy niedostępny) | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `scale` | number | `2` | Współczynnik powiększenia | | `model` | string | `"auto"` | Wariant modelu | | `faceEnhance` | boolean | `false` | Zastosuj przebieg ulepszania twarzy GFPGAN | | `denoise` | number | `0` | Siła odszumiania | | `format` | string | `"auto"` | Nadpisanie formatu wyjściowego | | `quality` | number | `95` | Jakość wyjściowa (1-100) | ## OCR / Wyodrębnianie tekstu {#ocr-text-extraction} **Trasa narzędzia:** `ocr`\ **Modele:** Tesseract (`fast`); RapidOCR z małymi modelami PP-OCRv6 (`balanced`); PP-OCRv6 średnie modele z kalibrowaną punktacją wariantów (`best`) | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dynamiczny | Gdy pominięto `quality` i `engine`, SnapOtter wybiera najlepszy dostępny poziom w kolejności `best`, `balanced`, `fast`. Dla języka koreańskiego nigdy nie wybiera `fast`; używa `best`, następnie `balanced`, albo zwraca błąd instalacji lub zgodności dokładnego środowiska. | | `language` | string | `"auto"` | Język: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `enhance` | wartość logiczna | Zależne od poziomu | Popraw lokalny kontrast. Fast stosuje go bezpośrednio; dokładne poziomy utrzymują wariant tylko wtedy, gdy skalibrowana punktacja poprawia OCR. Domyślnie włączone dla Najlepsze | | `engine` | smyczkowy | - | Przestarzały alias zgodności. Mapuje `tesseract` na `fast` i starszą wartość `paddleocr` na `balanced`; nie ładuje PaddlePaddle | Zwraca wyodrębniony tekst oraz metadane pochodzenia: silnik, żądaną i rzeczywistą jakość, urządzenie, dostawcę, stan degradacji, ostrzeżenia i dokładne wersje środowiska wykonawczego/modelu, jeśli ma to zastosowanie. Wyraźne żądania jakości nigdy nie przechodzą na inny poziom. Jeżeli `balanced` lub `best` jest niedostępne, API zwraca `FEATURE_NOT_INSTALLED` lub `FEATURE_INCOMPATIBLE` zamiast cichego działania `fast`. ## OCR PDF {#pdf-ocr} **Trasa narzędzia:** `ocr-pdf`\ **Modele:** Ten sam system poziomów co OCR obrazu Wyodrębnia tekst ze skanowanych dokumentów PDF przy użyciu OCR wspieranego przez AI, strona po stronie. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `quality` | `"fast"` | `"balanced"` | `"best"` | Dynamiczny | Gdy pominięto `quality` i `engine`, SnapOtter wybiera najlepszy dostępny poziom w kolejności `best`, `balanced`, `fast`. Dla języka koreańskiego nigdy nie wybiera `fast`; używa `best`, następnie `balanced`, albo zwraca błąd instalacji lub zgodności dokładnego środowiska. | | `language` | string | `"auto"` | Język: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | | `pages` | string | `"all"` | Wybór stron: `"all"`, `"1-3"`, `"1,3,5"` | | `enhance` | wartość logiczna | Zależne od poziomu | Popraw lokalny kontrast. Fast stosuje go bezpośrednio; dokładne poziomy utrzymują wariant tylko wtedy, gdy skalibrowana punktacja poprawia OCR. Domyślnie włączone dla Najlepsze | | `engine` | smyczkowy | - | Przestarzały alias zgodności. Mapuje `tesseract` na `fast` i starszą wartość `paddleocr` na `balanced`; nie ładuje PaddlePaddle | Ta sama zasada zakazu zmiany wersji ma zastosowanie do PDF OCR. Strony PDF są rasteryzowane przed rozpoznaniem, a jedno żądanie może wybrać maksymalnie 50 stron. ## Rozmycie twarzy / danych osobowych {#face-pii-blur} **Trasa narzędzia:** `blur-faces`\ **Model:** wykrywanie twarzy MediaPipe | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `blurRadius` | number (1-100) | `30` | Promień rozmycia gaussowskiego | | `sensitivity` | number (0-1) | `0.5` | Próg pewności wykrywania | ## Ulepszanie twarzy {#face-enhancement} **Trasa narzędzia:** `enhance-faces`\ **Modele:** GFPGAN, CodeFormer | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `model` | `"auto"` | `"gfpgan"` | `"codeformer"` | `"auto"` | Model ulepszania | | `strength` | number (0-1) | `0.8` | Siła ulepszania | | `sensitivity` | number (0-1) | `0.5` | Próg wykrywania twarzy | | `onlyCenterFace` | boolean | `false` | Ulepsz tylko najbardziej centralną twarz | ## Koloryzacja AI {#ai-colorization} **Trasa narzędzia:** `colorize`\ **Model:** DDColor (z rezerwowym OpenCV DNN) Przekształca zdjęcia czarno-białe lub w skali szarości na pełny kolor. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `intensity` | number (0-1) | `1.0` | Siła nasycenia kolorów | | `model` | `"auto"` | `"ddcolor"` | `"opencv"` | `"auto"` | Wariant modelu | ## Usuwanie szumu {#noise-removal} **Trasa narzędzia:** `noise-removal`\ **Model:** SCUNet (wielopoziomowy potok odszumiania) | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `tier` | `"quick"` | `"balanced"` | `"quality"` | `"maximum"` | `"balanced"` | Poziom przetwarzania | | `strength` | number (0-100) | `50` | Siła odszumiania | | `detailPreservation` | number (0-100) | `50` | Ile detali zachować; wyższa wartość zachowuje więcej tekstury | | `colorNoise` | number (0-100) | `30` | Siła redukcji szumu kolorów | | `format` | string | `"original"` | Format wyjściowy: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | `quality` | number (1-100) | `90` | Jakość kodowania wyjścia | ## Usuwanie czerwonych oczu {#red-eye-removal} **Trasa narzędzia:** `red-eye-removal` Wykrywa punkty charakterystyczne twarzy, lokalizuje obszary oczu i koryguje nadmierne nasycenie kanału czerwonego. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `sensitivity` | number (0-100) | `50` | Próg wykrywania czerwonych pikseli | | `strength` | number (0-100) | `70` | Siła korekcji | | `format` | string | - | Nadpisanie formatu wyjściowego (opcjonalne) | | `quality` | number (1-100) | `90` | Jakość wyjściowa | ## Renowacja zdjęć {#photo-restoration} **Trasa narzędzia:** `restore-photo` Wieloetapowy potok dla starych lub uszkodzonych zdjęć: wykrywanie i naprawa rys/rozdarć, ulepszanie twarzy, odszumianie oraz opcjonalna koloryzacja. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `scratchRemoval` | boolean | `true` | Wykryj i napraw rysy, rozdarcia | | `faceEnhancement` | boolean | `true` | Zastosuj przebieg ulepszania twarzy | | `fidelity` | number (0-1) | `0.7` | Siła ulepszania twarzy (wyższa = bardziej zachowawcza) | | `denoise` | boolean | `true` | Zastosuj przebieg odszumiania | | `denoiseStrength` | number (0-100) | `25` | Siła odszumiania | | `colorize` | boolean | `false` | Koloryzuj po renowacji | | `colorizeStrength` | number (0-100) | `85` | Intensywność koloryzacji | ## Zdjęcie paszportowe {#passport-photo} **Trasa narzędzia:** `passport-photo`\ **Modele:** punkty charakterystyczne twarzy MediaPipe + usuwanie tła BiRefNet Dwufazowy przepływ pracy: analiza (wykryj twarz + usuń tło), a następnie generowanie (kadrowanie, zmiana rozmiaru, kafelkowanie). Obsługuje ponad 37 krajów w 6 regionach. ### Faza 1: Analiza {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` Przyjmuje plik obrazu (multipart). Zwraca dane punktów charakterystycznych twarzy, podgląd base64 oraz wymiary obrazu. ### Faza 2: Generowanie {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` Przyjmuje treść JSON z wynikami Fazy 1 oraz ustawieniami generowania: | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `jobId` | string | (wymagane) | Identyfikator zadania z Fazy 1 | | `filename` | string | (wymagane) | Oryginalna nazwa pliku z Fazy 1 | | `countryCode` | string | (wymagane) | Kod kraju ISO (np. `US`, `GB`, `IN`) | | `documentType` | string | `"passport"` | Typ dokumentu | | `bgColor` | string | `"#FFFFFF"` | Kolor tła hex | | `printLayout` | string | `"none"` | Układ wydruku: `none`, `4x6`, `a4`, `letter` | | `maxFileSizeKb` | number | `0` | Maksymalny rozmiar pliku w KB (0 = brak limitu) | | `dpi` | number (72-1200) | `300` | DPI wyjścia | | `customWidthMm` | number | - | Niestandardowa szerokość w mm (nadpisuje specyfikację kraju) | | `customHeightMm` | number | - | Niestandardowa wysokość w mm (nadpisuje specyfikację kraju) | | `zoom` | number (0.5-3) | `1` | Współczynnik przybliżenia | | `adjustX` | number | `0` | Korekta położenia w poziomie | | `adjustY` | number | `0` | Korekta położenia w pionie | | `landmarks` | object | (wymagane) | Punkty charakterystyczne z Fazy 1 | | `imageWidth` | number | (wymagane) | Szerokość obrazu z Fazy 1 | | `imageHeight` | number | (wymagane) | Wysokość obrazu z Fazy 1 | ## Usuwanie obiektów (Inpainting) {#object-erasing-inpainting} **Trasa narzędzia:** `erase-object`\ **Model:** LaMa przez ONNX Runtime Maska jest wysyłana jako **druga część pliku** (nazwa pola `mask`), a nie jako base64. Białe piksele w masce wskazują obszary do usunięcia. Ustawienia `format` i `quality` są wysyłane jako pola formularza najwyższego poziomu. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `file` | file | (wymagane) | Obraz źródłowy (multipart) | | `mask` | file | (wymagane) | Obraz maski (multipart, nazwa pola `mask`, biały = usuń) | | `format` | string | `"auto"` | Format wyjściowy: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Jakość wyjściowa | Przyspieszane przez CUDA, gdy dostępny jest GPU NVIDIA. ## Rozszerzanie kadru AI {#ai-canvas-expand} **Trasa narzędzia:** `ai-canvas-expand`\ **Model:** outpainting oparty na LaMa Rozszerza kadr obrazu w dowolnym kierunku i wypełnia nowe obszary treścią wygenerowaną przez AI, która pasuje do istniejącego obrazu. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `extendTop` | integer | `0` | Piksele do rozszerzenia u góry | | `extendRight` | integer | `0` | Piksele do rozszerzenia po prawej | | `extendBottom` | integer | `0` | Piksele do rozszerzenia u dołu | | `extendLeft` | integer | `0` | Piksele do rozszerzenia po lewej | | `tier` | `"fast"` | `"balanced"` | `"high"` | `"balanced"` | Poziom jakości | | `format` | string | `"auto"` | Format wyjściowy: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | `quality` | integer (1-100) | `95` | Jakość wyjściowa | Co najmniej jeden kierunek rozszerzenia musi być większy niż 0. ## Inteligentne kadrowanie {#smart-crop} **Trasa narzędzia:** `smart-crop`\ **Model:** wykrywanie twarzy MediaPipe (tylko tryb twarzy) | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `mode` | string | `"subject"` | Strategia kadrowania: `subject`, `face`, `trim` | | `strategy` | `"attention"` | `"entropy"` | `"attention"` | Strategia dla trybu obiektu | | `width` | integer | - | Szerokość wyjścia | | `height` | integer | - | Wysokość wyjścia | | `padding` | integer (0-50) | `0` | Procent marginesu wokół obiektu | | `facePreset` | string | `"head-shoulders"` | Predefiniowane kadrowanie, gdy `mode=face` | | `sensitivity` | number (0-1) | `0.5` | Próg wykrywania twarzy | | `threshold` | integer (0-255) | `30` | Próg wykrywania tła (tryb przycinania) | | `padToSquare` | boolean | `false` | Dopełnij przycięty wynik do kwadratu | | `padColor` | string | `"#ffffff"` | Kolor tła dla dopełnienia kwadratowego | | `targetSize` | integer | - | Docelowy rozmiar dla dopełnionego wyjścia (piksele) | | `quality` | integer (1-100) | - | Jakość wyjściowa | Starsze wartości `mode` `attention` i `content` są akceptowane i mapowane odpowiednio na `subject` i `trim`. **Predefiniowane ustawienia twarzy:** | Predefiniowane | Najlepsze do | |--------|---------| | `closeup` | Zdjęcia portretowe | | `head-shoulders` | Zdjęcia profilowe | | `upper-body` | LinkedIn / formalne | | `half-body` | Pełna górna część ciała | ## Transkrypcja dźwięku {#transcribe-audio} **Trasa narzędzia:** `transcribe-audio`\ **Model:** faster-whisper Przekształca mowę na tekst. Obsługuje formaty wyjściowe zwykły tekst, SRT i VTT. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Język: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `outputFormat` | `"txt"` | `"srt"` | `"vtt"` | `"txt"` | Format wyjściowy | ## Automatyczne napisy {#auto-subtitles} **Trasa narzędzia:** `auto-subtitles`\ **Model:** faster-whisper (wyodrębnia dźwięk z wideo, a następnie transkrybuje) Generuje pliki napisów ze ścieżki dźwiękowej wideo. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `language` | string | `"auto"` | Język: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | | `format` | `"srt"` | `"vtt"` | `"srt"` | Format wyjściowy napisów | ## Naprawa przezroczystości PNG {#png-transparency-fixer} **Trasa narzędzia:** `transparency-fixer`\ **Model:** BiRefNet HR-matting (rozdzielczość 2048x2048) Naprawia "fałszywie przezroczyste" pliki PNG, w których tło zostało usunięte, ale pozostawiło obwódki, aureole lub półprzezroczyste artefakty. Używa modelu mattingu wysokiej rozdzielczości BiRefNet, aby uzyskać czysty kanał alfa, a następnie stosuje konfigurowalne przetwarzanie usuwające przebarwienia w celu usunięcia zanieczyszczenia kolorem wzdłuż krawędzi. **Łańcuch rezerwowy OOM:** Jeśli BiRefNet HR-matting przekroczy dostępną pamięć, narzędzie automatycznie przechodzi na `birefnet-general`, a następnie na `u2net`. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `defringe` | number (0-100) | `30` | Siła usuwania obwódek krawędzi w celu usunięcia zanieczyszczenia kolorem | | `outputFormat` | `"png"` | `"webp"` | `"png"` | Format obrazu wyjściowego | | `removeWatermark` | boolean | `false` | Zastosuj wstępne przetwarzanie usuwania znaku wodnego (filtr medianowy) | ```bash curl -X POST http://localhost:1349/api/v1/tools/image/transparency-fixer \ -H "Authorization: Bearer " \ -F "file=@fake-transparent.png" \ -F 'settings={"defringe":30,"outputFormat":"png"}' ``` *** ## Narzędzia z opcjonalnymi funkcjami AI {#tools-with-optional-ai-capabilities} Poniższe narzędzia nie są narzędziami procesu pomocniczego Pythona, ale używają funkcji AI, gdy włączone są określone opcje. ### Ulepszanie obrazu {#image-enhancement} **Trasa narzędzia:** `image-enhancement`\ **Silnik:** oparty na analizie (histogram i statystyki Sharp) Analizuje obraz i stosuje automatyczne korekcje ekspozycji, kontrastu, balansu bieli, nasycenia, ostrości i szumu. Obsługuje tryby dostosowane do sceny. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `mode` | `"auto"` | `"portrait"` | `"landscape"` | `"low-light"` | `"food"` | `"document"` | `"auto"` | Tryb sceny do dostrajania korekcji | | `intensity` | number (0-100) | `50` | Ogólna siła korekcji | | `corrections.exposure` | boolean | `true` | Zastosuj korekcję ekspozycji | | `corrections.contrast` | boolean | `true` | Zastosuj korekcję kontrastu | | `corrections.whiteBalance` | boolean | `true` | Zastosuj korekcję balansu bieli | | `corrections.saturation` | boolean | `true` | Zastosuj korekcję nasycenia | | `corrections.sharpness` | boolean | `true` | Zastosuj korekcję ostrości | | `corrections.denoise` | boolean | `true` | Zastosuj odszumianie | | `deepEnhance` | boolean | `false` | Włącz usuwanie szumu AI przez SCUNet (wymaga pakietu `upscale-enhance`) | Dodatkowy punkt końcowy analizy jest dostępny pod `POST /api/v1/tools/image/image-enhancement/analyze`, który zwraca wykryte korekcje bez ich stosowania. ### Zmiana rozmiaru z uwzględnieniem treści (Seam Carving) {#content-aware-resize-seam-carving} **Trasa narzędzia:** `content-aware-resize`\ **Silnik:** binarka Go `caire` (nie Python - brak korzyści z GPU) Inteligentnie zmienia rozmiar obrazów, usuwając szwy o niskiej energii i zachowując ważną treść. | Parametr | Typ | Domyślnie | Opis | |-----------|------|---------|-------------| | `width` | number | - | Docelowa szerokość | | `height` | number | - | Docelowa wysokość | | `protectFaces` | boolean | `false` | Chroń wykryte obszary twarzy (wymaga pakietu `face-detection`) | | `blurRadius` | number (0-20) | `4` | Wstępne rozmycie do obliczania energii | | `sobelThreshold` | number (1-20) | `2` | Próg czułości krawędzi | | `square` | boolean | `false` | Wymuś kwadratowe wyjście | --- --- url: https://docs.snapotter.com/pl.md description: >- Otwartoźródłowa, samodzielnie hostowana infrastruktura do przetwarzania plików. Konwertuj, kompresuj, rozpoznawaj tekst (OCR), transkrybuj i uruchamiaj lokalne AI dla obrazów, wideo, audio, PDF i dokumentów, przez interfejs, REST API i potoki. Hostuj samodzielnie jednym poleceniem Docker. Twoje pliki nigdy nie opuszczają twojego serwera. --- --- --- url: https://docs.snapotter.com/vi/guide/contributing.md description: >- Cách đóng góp cho SnapOtter. Báo cáo lỗi, yêu cầu tính năng, pull request và các yêu cầu về CLA. --- # Đóng góp {#contributing} Cảm ơn bạn đã quan tâm đến việc đóng góp. Hướng dẫn này trình bày cách tham gia, những gì chúng tôi chấp nhận, và cách bắt đầu. ## Các cách đóng góp {#ways-to-contribute} ### Issue (không cần thiết lập gì) {#issues-no-setup-required} * **Báo cáo lỗi** - Có thứ gì đó bị hỏng? Hãy mở một [báo cáo lỗi](https://github.com/snapotter-hq/snapotter/issues/new?template=bug_report.yml) kèm các bước tái hiện. * **Yêu cầu tính năng** - Bạn có ý tưởng? Hãy bắt đầu một [thảo luận](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) để cộng đồng cân nhắc và bình chọn cho nó. * **Vấn đề về bản dịch** - Phát hiện một bản dịch sai hoặc thiếu? Hãy mở một [issue về bản dịch](https://github.com/snapotter-hq/snapotter/issues/new?template=translation.yml). * **Vấn đề về tài liệu** - Có gì đó không ổn trong tài liệu? Hãy mở một [issue về tài liệu](https://github.com/snapotter-hq/snapotter/issues/new?template=documentation.yml). ### Mã nguồn (yêu cầu CLA) {#code-requires-cla} Chúng tôi chấp nhận pull request cho: | Loại | Quy trình | |------|---------| | Sửa lỗi | Mở PR trực tiếp (liên kết tới issue nếu có) | | Bản dịch mới | Mở PR trực tiếp (xem [Hướng dẫn dịch](/vi/guide/translations)) | | Cải thiện tài liệu | Mở PR trực tiếp | | Cải thiện độ bao phủ kiểm thử | Mở PR trực tiếp | | Công cụ hoặc tính năng mới | Bắt đầu một [thảo luận](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) trước; một maintainer sẽ chuyển các ý tưởng đã được phê duyệt thành issue được theo dõi trước khi bạn viết mã | | Refactor hoặc thay đổi kiến trúc | Bắt đầu một [thảo luận](https://github.com/snapotter-hq/snapotter/discussions/new?category=ideas) trước và chờ maintainer chấp thuận trước khi viết mã | ### Những gì chúng tôi sẽ không chấp nhận {#what-we-will-not-accept} * Thay đổi đối với các workflow CI/CD, cấu hình phát hành, hoặc cấu hình linter/compiler * PR mà không có [Thỏa thuận Giấy phép Người đóng góp](#contributor-license-agreement) đã ký * PR thay đổi hơn 400 dòng (hãy chia công việc lớn thành các PR nhỏ hơn) * Tính năng chưa được thảo luận và phê duyệt trước * Thay đổi đối với `packages/ai/` mà không thảo luận trước ## Thỏa thuận Giấy phép Người đóng góp {#contributor-license-agreement} Trước khi chúng tôi có thể hợp nhất PR đầu tiên của bạn, bạn phải ký [CLA cá nhân](https://github.com/snapotter-hq/snapotter/blob/main/CLA.md) của chúng tôi. Đây là yêu cầu chỉ một lần. **Tại sao:** SnapOtter cấp phép kép (AGPLv3 + thương mại). CLA trao cho chúng tôi quyền phân phối các đóng góp của bạn theo cả hai giấy phép. Bạn giữ toàn bộ quyền sở hữu bản quyền đối với công việc của mình. **Bằng cách nào:** Khi bạn mở PR đầu tiên, bot CLA Assistant sẽ để lại bình luận kèm một liên kết. Nhấp vào đó, xem lại thỏa thuận, và ký bằng tài khoản GitHub của bạn. Chỉ mất 30 giây. Nếu bạn đóng góp thay mặt cho nhà tuyển dụng của mình và nhà tuyển dụng giữ quyền sở hữu trí tuệ đối với công việc của bạn, hãy liên hệ contact@snapotter.com để thu xếp một CLA doanh nghiệp trước khi gửi. ## Bắt đầu {#getting-started} ### Điều kiện tiên quyết {#prerequisites} * Node.js 22.22+ * pnpm 9+ * Python 3.11+ (chỉ dành cho các công cụ AI) * Docker (tùy chọn, để kiểm thử tích hợp đầy đủ) ### Thiết lập {#setup} ```bash # Fork and clone git clone https://github.com//snapotter.git cd snapotter # Start Postgres + Redis for local dev docker compose -f docker-compose.dev.yml up -d # Install dependencies pnpm install # Start dev servers (web on :1351, API on :13490) pnpm dev ``` ### Chạy kiểm tra {#running-checks} Trước khi gửi PR, hãy đảm bảo tất cả các kiểm tra đều vượt qua ở máy cục bộ: ```bash pnpm lint # Biome lint + format check pnpm typecheck # TypeScript across monorepo pnpm test # Vitest unit + integration tests ``` ## Quy trình pull request {#pull-request-process} 1. Fork repo và tạo một nhánh từ `main` (`feat/my-feature` hoặc `fix/issue-123`) 2. Thực hiện các thay đổi trong những commit tập trung, dễ xem xét bằng [conventional commits](https://www.conventionalcommits.org/) 3. Thêm hoặc cập nhật kiểm thử cho các thay đổi của bạn 4. Chạy `pnpm lint && pnpm typecheck && pnpm test` ở máy cục bộ 5. Mở PR nhắm vào `main` và điền vào mẫu 6. Ký CLA nếu được nhắc 7. Chờ CI vượt qua và một maintainer xem xét ### Kỳ vọng về việc xem xét {#review-expectations} * Chúng tôi cố gắng phản hồi PR trong vòng 7 ngày * PR nhỏ, tập trung sẽ được xem xét nhanh hơn * Nếu bạn không nhận được phản hồi trong 7 ngày, hãy để lại bình luận nhắc trong luồng * Chúng tôi có thể yêu cầu thay đổi, đề xuất một cách tiếp cận khác, hoặc đóng PR nếu nó không phù hợp với định hướng dự án ### Sau khi PR của bạn được hợp nhất {#after-your-pr-is-merged} Đóng góp của bạn sẽ được đưa vào bản phát hành tiếp theo và được ghi công trong changelog. ## Good first issues {#good-first-issues} Đang tìm việc gì đó để làm? Hãy xem [good first issues](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) của chúng tôi để tìm các nhiệm vụ thân thiện với người mới, hoặc [help wanted](https://github.com/snapotter-hq/snapotter/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) cho những hạng mục lớn hơn nơi chúng tôi rất mong nhận được sự trợ giúp của cộng đồng. ## Phong cách mã {#code-style} * Biome xử lý định dạng và linting (dấu nháy kép, dấu chấm phẩy, thụt lề 2 khoảng trắng) * Hook trước khi commit tự động chạy `biome check --write` trên các tệp đã được staged * Nếu linter phàn nàn, hãy sửa mã (đừng chỉnh sửa cấu hình Biome) * ES module ở khắp mọi nơi (`import`/`export`) * Conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` Để biết đầy đủ chi tiết kiến trúc, hãy xem [Hướng dẫn dành cho nhà phát triển](/vi/guide/developer). ## Bảo mật {#security} **Đừng mở PR hoặc issue công khai cho các lỗ hổng bảo mật.** Hãy báo cáo chúng một cách riêng tư qua [GitHub Security Advisories](https://github.com/snapotter-hq/snapotter/security/advisories/new) hoặc email contact@snapotter.com. Xem [SECURITY.md](https://github.com/snapotter-hq/snapotter/blob/main/SECURITY.md) để biết đầy đủ chi tiết. ## Câu hỏi? {#questions} * [Tài liệu](https://docs.snapotter.com/) * [Discord](https://discord.gg/hr3s7HPUsr) * [GitHub Discussions](https://github.com/snapotter-hq/snapotter/discussions) --- --- url: https://docs.snapotter.com/pl/tools/image/image-pad.md description: >- Dopełnij obraz do docelowych proporcji jednolitym kolorem, przezroczystym lub rozmytym tłem. --- # Dopełnianie obrazu {#image-pad} Dopełnij obraz do docelowych proporcji, dodając wokół niego jednolity kolor, przezroczyste lub rozmyte tło. Przydatne do dopasowywania obrazów do stałych proporcji dla mediów społecznościowych lub druku bez przycinania. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/image-pad` Przyjmuje dane formularza multipart z plikiem obrazu oraz polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | target | string | Nie | `"1:1"` | Docelowe proporcje: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` lub `custom` | | ratioW | integer | Nie | `1` | Niestandardowa szerokość proporcji (1-100, używana gdy target to `custom`) | | ratioH | integer | Nie | `1` | Niestandardowa wysokość proporcji (1-100, używana gdy target to `custom`) | | background | string | Nie | `"color"` | Tryb tła: `color`, `transparent` lub `blur` | | color | string | Nie | `"#ffffff"` | Kolor tła w formacie hex (gdy background to `color`) | | padding | integer | Nie | `0` | Dodatkowy odstęp jako procent kanwy (0-50) | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 3100000 } ``` ## Uwagi {#notes} * Tryb tła `blur` tworzy rozmytą kopię oryginalnego obrazu jako wypełnienie dopełnienia, dając wizualnie spójny rezultat. * Podczas używania tła `transparent` wynik jest konwertowany na PNG w celu zachowania kanału alfa. * Format wyjściowy odpowiada formatowi wejściowemu, chyba że w grę wchodzi przezroczystość. Wejścia HEIC, RAW, PSD i SVG są automatycznie dekodowane przed przetwarzaniem. * Ustaw `target` na `custom` i podaj `ratioW` oraz `ratioH` dla dowolnych proporcji (np. `ratioW: 3, ratioH: 2` dla 3:2). --- --- url: https://docs.snapotter.com/pl/tools/image/adjust-colors.md description: >- Dostosuj jasność, kontrast, nasycenie, temperaturę, odcień, kanały i zastosuj efekty kolorystyczne. --- # Dostosuj kolory {#adjust-colors} Kompleksowe narzędzie do dostosowywania kolorów, łączące jasność, kontrast, ekspozycję, nasycenie, temperaturę, tinting, obrót odcienia, poziomy poszczególnych kanałów oraz efekty jednym kliknięciem (skala szarości, sepia, inwersja) w jednym punkcie końcowym. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` Przyjmuje dane formularza multipart z plikiem obrazu oraz polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | brightness | number | Nie | `0` | Regulacja jasności (-100 do 100) | | contrast | number | Nie | `0` | Regulacja kontrastu (-100 do 100) | | exposure | number | Nie | `0` | Ekspozycja / gamma tonów średnich (-100 do 100) | | saturation | number | Nie | `0` | Nasycenie koloru (-100 do 100) | | temperature | number | Nie | `0` | Balans bieli: chłodny/niebieski do ciepłego/pomarańczowego (-100 do 100) | | tint | number | Nie | `0` | Przesunięcie odcienia: zielony do magenty (-100 do 100) | | hue | number | Nie | `0` | Obrót odcienia w stopniach (-180 do 180) | | sharpness | number | Nie | `0` | Siła wyostrzania (0 do 100) | | red | number | Nie | `100` | Poziom kanału czerwonego (0 do 200, 100 = bez zmian) | | green | number | Nie | `100` | Poziom kanału zielonego (0 do 200, 100 = bez zmian) | | blue | number | Nie | `100` | Poziom kanału niebieskiego (0 do 200, 100 = bez zmian) | | effect | string | Nie | `"none"` | Efekt kolorystyczny: `none`, `grayscale`, `sepia`, `invert` | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` Zastosuj ciepły, vintage'owy wygląd: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Uwagi {#notes} * Wszystkie parametry mają domyślnie wartości neutralne, więc możesz regulować tylko to, czego potrzebujesz. * Regulacje są stosowane w tej kolejności: jasność, kontrast, ekspozycja, nasycenie/odcień, temperatura/tint, wyostrzanie, kanały, efekty. * Temperatura używa macierzy rekombinacji kolorów 3x3 na osiach niebiesko-pomarańczowej i zielono-magentowej. * Ekspozycja mapuje się na funkcję gamma Sharpa (wartości dodatnie rozjaśniają tony średnie, ujemne je przyciemniają). * Ten punkt końcowy odpowiada również pod starszymi ścieżkami `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels` oraz `/api/v1/tools/image/color-effects`. Wszystkie używają tego samego schematu. * Format wyjściowy odpowiada formatowi wejściowemu. Dane wejściowe HEIC, RAW, PSD i SVG są automatycznie dekodowane przed przetworzeniem. --- --- url: https://docs.snapotter.com/tr/tools/image/duotone.md description: Özel gölge ve vurgu renkleriyle iki renkli düoton efekti uygulayın. --- # Düoton {#duotone} Bir görüntüye iki renkli düoton efekti uygulayın. Görüntü gri tonlamaya dönüştürülür, ardından gölge rengi (koyu tonlar) ile vurgu rengi (parlak tonlar) arasında bir gradyana eşlenir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/duotone` Bir görüntü dosyası ve bir JSON `settings` alanı ile çok parçalı form verilerini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | shadow | string | Hayır | `"#1e3a8a"` | Gölge hex rengi (koyu tonlara uygulanır) | | highlight | string | Hayır | `"#fbbf24"` | Vurgu hex rengi (parlak tonlara uygulanır) | | intensity | integer | Hayır | `100` | Efekt yoğunluğu (0-100); 0 orijinali döndürür, 100 tam düotonu uygular | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notlar {#notes} * Çıktı biçimi giriş biçimiyle eşleşir. HEIC, RAW, PSD ve SVG girişleri işlenmeden önce otomatik olarak çözülür. * 100'den küçük bir `intensity`, düoton sonucunu orijinal görüntüyle harmanlar ve daha ince efektlere olanak tanır. * Popüler düoton kombinasyonları arasında lacivert/altın, deniz mavisi/mercan ve mor/pembe yer alır. --- --- url: https://docs.snapotter.com/ar/tools/image/duotone.md description: تطبيق تأثير ثنائي اللون بلونَي ظل وإبراز مخصّصين. --- # Duotone {#duotone} طبّق تأثيرًا ثنائي اللون على صورة. تُحوَّل الصورة إلى تدرّج رمادي، ثم تُربَط بتدرّج بين لون الظل (الدرجات الداكنة) ولون الإبراز (الدرجات الفاتحة). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` يقبل بيانات نموذج multipart تحتوي على ملف صورة وحقل JSON باسم `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | shadow | string | No | `"#1e3a8a"` | لون الظل hex (يُطبَّق على الدرجات الداكنة) | | highlight | string | No | `"#fbbf24"` | لون الإبراز hex (يُطبَّق على الدرجات الفاتحة) | | intensity | integer | No | `100` | شدة التأثير (0-100)؛ 0 يعيد الأصل، و100 يطبّق التأثير ثنائي اللون بالكامل | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notes {#notes} * صيغة الإخراج تطابق صيغة الإدخال. تُفَكّ شفرة مدخلات HEIC وRAW وPSD وSVG تلقائيًا قبل المعالجة. * قيمة `intensity` أقل من 100 تمزج النتيجة ثنائية اللون مع الصورة الأصلية، مما يتيح تأثيرات أخفت. * تشمل تركيبات duotone الشائعة الكحلي/الذهبي، والفيروزي/المرجاني، والبنفسجي/الوردي. --- --- url: https://docs.snapotter.com/de/tools/image/duotone.md description: >- Wendet einen zweifarbigen Duotone-Effekt mit individuellen Schatten- und Lichterfarben an. --- # Duotone {#duotone} Wendet einen zweifarbigen Duotone-Effekt auf ein Bild an. Das Bild wird in Graustufen umgewandelt und dann auf einen Verlauf zwischen der Schattenfarbe (dunkle Töne) und der Lichterfarbe (helle Töne) abgebildet. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/duotone` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | shadow | string | Nein | `"#1e3a8a"` | Schatten-Hex-Farbe (wird auf dunkle Töne angewendet) | | highlight | string | Nein | `"#fbbf24"` | Lichter-Hex-Farbe (wird auf helle Töne angewendet) | | intensity | integer | Nein | `100` | Effektintensität (0-100); 0 gibt das Original zurück, 100 wendet den vollen Duotone-Effekt an | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Hinweise {#notes} * Das Ausgabeformat entspricht dem Eingabeformat. HEIC-, RAW-, PSD- und SVG-Eingaben werden vor der Verarbeitung automatisch dekodiert. * Ein `intensity` von weniger als 100 mischt das Duotone-Ergebnis mit dem Originalbild und ermöglicht so dezentere Effekte. * Beliebte Duotone-Kombinationen sind Marineblau/Gold, Petrol/Koralle und Violett/Rosa. --- --- url: https://docs.snapotter.com/fr/tools/image/duotone.md description: >- Appliquez un effet duotone à deux couleurs avec des couleurs d'ombre et de haute lumière personnalisées. --- # Duotone {#duotone} Appliquez un effet duotone à deux couleurs à une image. L'image est convertie en niveaux de gris, puis mappée sur un dégradé entre la couleur d'ombre (tons sombres) et la couleur de haute lumière (tons clairs). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` Accepte des données de formulaire multipart avec un fichier image et un champ JSON `settings`. ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | shadow | string | Non | `"#1e3a8a"` | Couleur hexadécimale d'ombre (appliquée aux tons sombres) | | highlight | string | Non | `"#fbbf24"` | Couleur hexadécimale de haute lumière (appliquée aux tons clairs) | | intensity | integer | Non | `100` | Intensité de l'effet (0-100) ; 0 renvoie l'original, 100 applique le duotone complet | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notes {#notes} * Le format de sortie correspond au format d'entrée. Les entrées HEIC, RAW, PSD et SVG sont décodées automatiquement avant le traitement. * Une `intensity` inférieure à 100 mélange le résultat duotone avec l'image d'origine, permettant des effets plus subtils. * Les combinaisons duotone populaires incluent bleu marine/or, sarcelle/corail et violet/rose. --- --- url: https://docs.snapotter.com/hi/tools/image/duotone.md description: कस्टम शैडो और हाइलाइट रंगों के साथ दो-रंग वाला ड्युओटोन प्रभाव लागू करें। --- # Duotone {#duotone} किसी छवि पर दो-रंग वाला ड्युओटोन प्रभाव लागू करें। छवि को ग्रेस्केल में परिवर्तित किया जाता है, फिर शैडो रंग (गहरे टोन) और हाइलाइट रंग (चमकीले टोन) के बीच एक ग्रेडिएंट में मैप किया जाता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` एक छवि फ़ाइल और एक JSON `settings` फ़ील्ड के साथ मल्टीपार्ट फ़ॉर्म डेटा स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | shadow | string | No | `"#1e3a8a"` | शैडो हेक्स रंग (गहरे टोन पर लागू) | | highlight | string | No | `"#fbbf24"` | हाइलाइट हेक्स रंग (चमकीले टोन पर लागू) | | intensity | integer | No | `100` | प्रभाव तीव्रता (0-100); 0 मूल लौटाता है, 100 पूर्ण ड्युओटोन लागू करता है | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notes {#notes} * आउटपुट फ़ॉर्मेट इनपुट फ़ॉर्मेट से मेल खाता है। HEIC, RAW, PSD, और SVG इनपुट प्रोसेसिंग से पहले स्वचालित रूप से डिकोड किए जाते हैं। * 100 से कम की `intensity` ड्युओटोन परिणाम को मूल छवि के साथ मिश्रित करती है, जिससे सूक्ष्म प्रभाव संभव होते हैं। * लोकप्रिय ड्युओटोन संयोजनों में navy/gold, teal/coral, और purple/pink शामिल हैं। --- --- url: https://docs.snapotter.com/id/tools/image/duotone.md description: Terapkan efek duotone dua warna dengan warna bayangan dan sorotan kustom. --- # Duotone {#duotone} Terapkan efek duotone dua warna pada gambar. Gambar diubah menjadi grayscale, lalu dipetakan ke gradien antara warna bayangan (nada gelap) dan warna sorotan (nada terang). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` Menerima data formulir multipart dengan file gambar dan field JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Default | Deskripsi | |-----------|------|----------|---------|-------------| | shadow | string | Tidak | `"#1e3a8a"` | Warna hex bayangan (diterapkan pada nada gelap) | | highlight | string | Tidak | `"#fbbf24"` | Warna hex sorotan (diterapkan pada nada terang) | | intensity | integer | Tidak | `100` | Intensitas efek (0-100); 0 mengembalikan gambar asli, 100 menerapkan duotone penuh | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Catatan {#notes} * Format output sesuai dengan format input. Input HEIC, RAW, PSD, dan SVG didekode otomatis sebelum diproses. * `intensity` kurang dari 100 memadukan hasil duotone dengan gambar asli, memungkinkan efek yang lebih halus. * Kombinasi duotone populer meliputi navy/emas, teal/coral, dan ungu/pink. --- --- url: https://docs.snapotter.com/it/tools/image/duotone.md description: >- Applica un effetto duotone a due colori con colori personalizzati per ombre e luci. --- # Duotone {#duotone} Applica un effetto duotone a due colori a un'immagine. L'immagine viene convertita in scala di grigi, quindi mappata su un gradiente tra il colore delle ombre (toni scuri) e il colore delle luci (toni chiari). ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/duotone` Accetta dati di form multipart con un file immagine e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | shadow | string | No | `"#1e3a8a"` | Colore esadecimale delle ombre (applicato ai toni scuri) | | highlight | string | No | `"#fbbf24"` | Colore esadecimale delle luci (applicato ai toni chiari) | | intensity | integer | No | `100` | Intensità dell'effetto (0-100); 0 restituisce l'originale, 100 applica il duotone completo | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Note {#notes} * Il formato di output corrisponde al formato di input. Gli input HEIC, RAW, PSD e SVG vengono decodificati automaticamente prima dell'elaborazione. * Un valore di `intensity` inferiore a 100 miscela il risultato duotone con l'immagine originale, consentendo effetti più tenui. * Combinazioni duotone popolari includono blu navy/oro, verde acqua/corallo e viola/rosa. --- --- url: https://docs.snapotter.com/nl/tools/image/duotone.md description: >- Pas een tweekleurig duotone-effect toe met aangepaste schaduw- en hooglichtkleuren. --- # Duotone {#duotone} Pas een tweekleurig duotone-effect toe op een afbeelding. De afbeelding wordt omgezet naar grijstinten en vervolgens toegewezen aan een verloop tussen de schaduwkleur (donkere tonen) en de hooglichtkleur (heldere tonen). ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/duotone` Accepteert multipart-formuliergegevens met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | shadow | string | Nee | `"#1e3a8a"` | Hex-kleur voor de schaduw (toegepast op donkere tonen) | | highlight | string | Nee | `"#fbbf24"` | Hex-kleur voor het hooglicht (toegepast op heldere tonen) | | intensity | integer | Nee | `100` | Effectintensiteit (0-100); 0 geeft het origineel terug, 100 past de volledige duotone toe | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Opmerkingen {#notes} * Het uitvoerformaat komt overeen met het invoerformaat. HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór verwerking. * Een `intensity` lager dan 100 mengt het duotone-resultaat met de originele afbeelding, wat subtielere effecten mogelijk maakt. * Populaire duotone-combinaties zijn onder meer marineblauw/goud, teal/koraal en paars/roze. --- --- url: https://docs.snapotter.com/pl/tools/image/duotone.md description: >- Zastosuj dwukolorowy efekt duotone z niestandardowymi kolorami cieni i świateł. --- # Duotone {#duotone} Zastosuj dwukolorowy efekt duotone do obrazu. Obraz jest konwertowany do skali szarości, a następnie mapowany na gradient między kolorem cieni (ciemne tony) a kolorem świateł (jasne tony). ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/duotone` Przyjmuje dane formularza multipart z plikiem obrazu oraz polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | shadow | string | Nie | `"#1e3a8a"` | Szesnastkowy kolor cieni (stosowany do ciemnych tonów) | | highlight | string | Nie | `"#fbbf24"` | Szesnastkowy kolor świateł (stosowany do jasnych tonów) | | intensity | integer | Nie | `100` | Intensywność efektu (0-100); 0 zwraca oryginał, 100 stosuje pełny efekt duotone | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Uwagi {#notes} * Format wyjściowy odpowiada formatowi wejściowemu. Pliki wejściowe HEIC, RAW, PSD i SVG są automatycznie dekodowane przed przetwarzaniem. * Wartość `intensity` mniejsza niż 100 miesza wynik duotone z oryginalnym obrazem, pozwalając na subtelniejsze efekty. * Popularne kombinacje duotone to granat/złoto, morski/koralowy oraz fioletowy/różowy. --- --- url: https://docs.snapotter.com/sv/tools/image/duotone.md description: Applicera en tvåfärgad duotone-effekt med anpassade skugg- och högdagerfärger. --- # Duotone {#duotone} Applicera en tvåfärgad duotone-effekt på en bild. Bilden konverteras till gråskala och mappas sedan till en gradient mellan skuggfärgen (mörka toner) och högdagerfärgen (ljusa toner). ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/duotone` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | shadow | string | Nej | `"#1e3a8a"` | Skugghexfärg (tillämpas på mörka toner) | | highlight | string | Nej | `"#fbbf24"` | Högdagerhexfärg (tillämpas på ljusa toner) | | intensity | integer | Nej | `100` | Effektintensitet (0-100); 0 returnerar originalet, 100 tillämpar hela duotonen | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Anteckningar {#notes} * Utdataformatet matchar indataformatet. Indata i HEIC, RAW, PSD och SVG avkodas automatiskt före bearbetning. * Ett `intensity` under 100 blandar duotone-resultatet med originalbilden, vilket möjliggör subtilare effekter. * Populära duotone-kombinationer inkluderar marinblå/guld, turkos/korall och lila/rosa. --- --- url: https://docs.snapotter.com/th/tools/image/duotone.md description: ใช้เอฟเฟกต์ duotone สองสีด้วยสีเงาและสีไฮไลต์ที่กำหนดเอง --- # Duotone {#duotone} ใช้เอฟเฟกต์ duotone สองสีกับภาพ ภาพจะถูกแปลงเป็นโทนสีเทา แล้วแมปกับการไล่สีระหว่างสีเงา (โทนเข้ม) กับสีไฮไลต์ (โทนสว่าง) ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` รับข้อมูลฟอร์ม multipart พร้อมไฟล์ภาพและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | shadow | string | No | `"#1e3a8a"` | สี hex ของเงา (ใช้กับโทนเข้ม) | | highlight | string | No | `"#fbbf24"` | สี hex ของไฮไลต์ (ใช้กับโทนสว่าง) | | intensity | integer | No | `100` | ความเข้มของเอฟเฟกต์ (0-100); 0 จะคืนภาพต้นฉบับ, 100 จะใช้ duotone เต็มรูปแบบ | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notes {#notes} * รูปแบบเอาต์พุตตรงกับรูปแบบอินพุต อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสอัตโนมัติก่อนประมวลผล * ค่า `intensity` ที่น้อยกว่า 100 จะผสมผลลัพธ์ duotone กับภาพต้นฉบับ ทำให้ได้เอฟเฟกต์ที่นุ่มนวลกว่า * การจับคู่ duotone ที่นิยม ได้แก่ กรมท่า/ทอง, เทาน้ำเงิน/ปะการัง และม่วง/ชมพู --- --- url: https://docs.snapotter.com/uk/tools/image/duotone.md description: >- Застосовуйте двоколірний ефект дуотон із власними кольорами тіней та світлих ділянок. --- # Duotone {#duotone} Застосовуйте двоколірний ефект дуотон до зображення. Зображення перетворюється на відтінки сірого, а потім відображається на градієнт між кольором тіней (темні тони) та кольором світлих ділянок (яскраві тони). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` Приймає дані форми multipart із файлом зображення та полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | shadow | string | No | `"#1e3a8a"` | Hex-колір тіней (застосовується до темних тонів) | | highlight | string | No | `"#fbbf24"` | Hex-колір світлих ділянок (застосовується до яскравих тонів) | | intensity | integer | No | `100` | Інтенсивність ефекту (0-100); 0 повертає оригінал, 100 застосовує повний дуотон | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notes {#notes} * Вихідний формат збігається з вхідним. Вхідні дані HEIC, RAW, PSD та SVG автоматично декодуються перед обробкою. * `intensity` менша за 100 змішує результат дуотону з оригінальним зображенням, дозволяючи створювати м'якші ефекти. * Популярні комбінації дуотону включають синій/золотий, бірюзовий/кораловий та фіолетовий/рожевий. --- --- url: https://docs.snapotter.com/vi/tools/image/duotone.md description: Áp dụng hiệu ứng duotone hai màu với màu vùng tối và vùng sáng tùy chỉnh. --- # Duotone {#duotone} Áp dụng hiệu ứng duotone hai màu cho một ảnh. Ảnh được chuyển sang thang xám, rồi ánh xạ thành một dải chuyển sắc giữa màu vùng tối (tông tối) và màu vùng sáng (tông sáng). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/duotone` Chấp nhận dữ liệu form multipart với một tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | shadow | string | Không | `"#1e3a8a"` | Màu vùng tối dạng hex (áp dụng cho tông tối) | | highlight | string | Không | `"#fbbf24"` | Màu vùng sáng dạng hex (áp dụng cho tông sáng) | | intensity | integer | Không | `100` | Cường độ hiệu ứng (0-100); 0 trả về ảnh gốc, 100 áp dụng duotone đầy đủ | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Ghi chú {#notes} * Định dạng đầu ra khớp với định dạng đầu vào. Đầu vào HEIC, RAW, PSD và SVG được giải mã tự động trước khi xử lý. * Giá trị `intensity` nhỏ hơn 100 pha trộn kết quả duotone với ảnh gốc, cho phép tạo hiệu ứng nhẹ nhàng hơn. * Các kết hợp duotone phổ biến gồm xanh navy/vàng gold, teal/coral, và tím/hồng. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/duotone.md description: >- Aplique um efeito duotônico de duas cores com cores de sombra e realce personalizadas. --- # Duotônico {#duotone} Aplique um efeito duotônico de duas cores a uma imagem. A imagem é convertida para tons de cinza e depois mapeada para um gradiente entre a cor de sombra (tons escuros) e a cor de realce (tons claros). ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/duotone` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | shadow | string | Não | `"#1e3a8a"` | Cor de sombra em hexadecimal (aplicada aos tons escuros) | | highlight | string | Não | `"#fbbf24"` | Cor de realce em hexadecimal (aplicada aos tons claros) | | intensity | integer | Não | `100` | Intensidade do efeito (0-100); 0 retorna o original, 100 aplica o duotônico completo | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notas {#notes} * O formato de saída corresponde ao formato de entrada. Entradas HEIC, RAW, PSD e SVG são decodificadas automaticamente antes do processamento. * Uma `intensity` menor que 100 mescla o resultado duotônico com a imagem original, permitindo efeitos mais sutis. * Combinações duotônicas populares incluem azul-marinho/dourado, verde-azulado/coral e roxo/rosa. --- --- url: https://docs.snapotter.com/es/tools/image/duotone.md description: >- Aplica un efecto duotono de dos colores con colores personalizados de sombra y luz. --- # Duotono {#duotone} Aplica un efecto duotono de dos colores a una imagen. La imagen se convierte a escala de grises y luego se asigna a un gradiente entre el color de sombra (tonos oscuros) y el color de luz (tonos brillantes). ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/duotone` Acepta datos de formulario multipart con un archivo de imagen y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | shadow | string | No | `"#1e3a8a"` | Color hex de sombra (aplicado a los tonos oscuros) | | highlight | string | No | `"#fbbf24"` | Color hex de luz (aplicado a los tonos brillantes) | | intensity | integer | No | `100` | Intensidad del efecto (0-100); 0 devuelve el original, 100 aplica el duotono completo | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/duotone \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1870000 } ``` ## Notas {#notes} * El formato de salida coincide con el formato de entrada. Las entradas HEIC, RAW, PSD y SVG se decodifican automáticamente antes del procesamiento. * Una `intensity` menor que 100 mezcla el resultado duotono con la imagen original, lo que permite efectos más sutiles. * Las combinaciones duotono populares incluyen azul marino/dorado, verde azulado/coral y morado/rosa. --- --- url: https://docs.snapotter.com/nl/tools/image/find-duplicates.md description: Detecteer dubbele en bijna-dubbele afbeeldingen met perceptuele hashing. --- # Duplicaten zoeken {#find-duplicates} Upload meerdere afbeeldingen om duplicaten en bijna-duplicaten te detecteren met perceptuele hashing (dHash). Groepeert vergelijkbare afbeeldingen, identificeert de versie met de beste kwaliteit in elke groep en berekent de potentiële ruimtebesparing. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` Accepteert multipart-formuliergegevens met meerdere afbeeldingsbestanden en een optioneel JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | threshold | number | Nee | `8` | Maximale Hamming-afstand om afbeeldingen als duplicaten te beschouwen (0 tot 20). Lager = strengere matching | ### Bestandsvelden {#file-fields} Upload minstens 2 afbeeldingsbestanden in het multipart-verzoek (allemaal met de veldnaam `file` of een willekeurige veldnaam voor bestandsonderdelen). ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Voorbeeldantwoord {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Antwoordvelden {#response-fields} | Veld | Type | Beschrijving | |-------|------|-------------| | totalImages | number | Aantal succesvol geanalyseerde afbeeldingen | | duplicateGroups | array | Groepen dubbele afbeeldingen | | uniqueImages | number | Aantal afbeeldingen dat geen deel uitmaakt van een duplicaatgroep | | spaceSaveable | number | Totaal aantal bytes dat bespaard kan worden door niet-beste duplicaten te verwijderen | | skippedFiles | array | Bestanden die niet verwerkt konden worden (met bestandsnaam en reden) | ### Duplicaatgroep-object {#duplicate-group-object} | Veld | Type | Beschrijving | |-------|------|-------------| | groupId | number | Groeps-identifier | | files | array | Afbeeldingen in deze duplicaatgroep | ### Bestandsobject (binnen een groep) {#file-object-within-a-group} | Veld | Type | Beschrijving | |-------|------|-------------| | filename | string | Oorspronkelijke bestandsnaam | | similarity | number | Overeenkomstpercentage met de referentieafbeelding (eerste in de groep) | | width | number | Afbeeldingsbreedte in pixels | | height | number | Afbeeldingshoogte in pixels | | fileSize | number | Bestandsgrootte in bytes | | format | string | Afbeeldingsformaat | | isBest | boolean | Of dit de versie met de hoogste kwaliteit is (meeste pixels, grootste bestand) | | thumbnail | string of null | Base64 JPEG-thumbnail (200px breed) voor voorbeeldweergave | ## Opmerkingen {#notes} * Gebruikt een 128-bits dHash (64-bits rij + 64-bits kolom) voor perceptuele overeenkomstdetectie. Dit vangt duplicaten zelfs bij vergrotingen/verkleiningen, hercompressie en kleine bewerkingen. * De drempelwaarde vertegenwoordigt de maximale Hamming-afstand tussen hashes. De standaardwaarde van 8 vangt bijna-duplicaten terwijl valse positieven worden vermeden. Gebruik 0 voor alleen pixel-identieke afbeeldingen, of 15-20 voor zeer losse matching. * De "beste" afbeelding in elke groep is die met de meeste pixels (breedte x hoogte), met de bestandsgrootte als tiebreaker. * Er zijn minstens 2 afbeeldingen vereist. Bestanden die niet slagen voor validatie of decodering worden gerapporteerd in `skippedFiles` in plaats van dat het hele verzoek mislukt. * Thumbnails zijn 200px brede JPEG-voorbeelden gecodeerd als data-URI's. * Alle gangbare formaten worden ondersteund (HEIC, RAW, PSD, SVG worden automatisch gedecodeerd). --- --- url: https://docs.snapotter.com/de/tools/image/find-duplicates.md description: >- Erkennt doppelte und nahezu doppelte Bilder mithilfe von perzeptuellem Hashing. --- # Duplikate finden {#find-duplicates} Laden Sie mehrere Bilder hoch, um Duplikate und nahezu Duplikate mithilfe von perzeptuellem Hashing (dHash) zu erkennen. Gruppiert ähnliche Bilder, identifiziert die beste Qualitätsversion in jeder Gruppe und berechnet mögliche Speichereinsparungen. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` Akzeptiert Multipart-Formulardaten mit mehreren Bilddateien und einem optionalen JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | threshold | number | Nein | `8` | Maximaler Hamming-Abstand, um Bilder als Duplikate zu betrachten (0 bis 20). Niedriger = strengere Übereinstimmung | ### Datei-Felder {#file-fields} Laden Sie mindestens 2 Bilddateien in der Multipart-Anfrage hoch (alle unter dem Feldnamen `file` oder einem beliebigen Feldnamen für Dateibestandteile). ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Beispielantwort {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Antwortfelder {#response-fields} | Feld | Typ | Beschreibung | |-------|------|-------------| | totalImages | number | Anzahl der erfolgreich analysierten Bilder | | duplicateGroups | array | Gruppen doppelter Bilder | | uniqueImages | number | Anzahl der Bilder, die zu keiner Duplikatgruppe gehören | | spaceSaveable | number | Gesamtzahl der Bytes, die durch Entfernen der nicht besten Duplikate eingespart werden könnten | | skippedFiles | array | Dateien, die nicht verarbeitet werden konnten (mit Dateiname und Grund) | ### Objekt „Duplikatgruppe“ {#duplicate-group-object} | Feld | Typ | Beschreibung | |-------|------|-------------| | groupId | number | Gruppenbezeichner | | files | array | Bilder in dieser Duplikatgruppe | ### Datei-Objekt (innerhalb einer Gruppe) {#file-object-within-a-group} | Feld | Typ | Beschreibung | |-------|------|-------------| | filename | string | Ursprünglicher Dateiname | | similarity | number | Ähnlichkeitsprozentsatz zum Referenzbild (das erste in der Gruppe) | | width | number | Bildbreite in Pixeln | | height | number | Bildhöhe in Pixeln | | fileSize | number | Dateigröße in Bytes | | format | string | Bildformat | | isBest | boolean | Ob dies die Version mit der höchsten Qualität ist (die meisten Pixel, größte Datei) | | thumbnail | string oder null | Base64-JPEG-Vorschaubild (200 px breit) für die Vorschau | ## Hinweise {#notes} * Verwendet einen 128-Bit-dHash (64-Bit-Zeile + 64-Bit-Spalte) zur Erkennung perzeptueller Ähnlichkeit. Damit werden Duplikate selbst über Größenänderungen, Neukompression und kleinere Bearbeitungen hinweg erfasst. * Der Schwellenwert steht für den maximalen Hamming-Abstand zwischen Hashes. Der Standardwert 8 erfasst nahezu Duplikate und vermeidet dabei Fehltreffer. Verwenden Sie 0 für ausschließlich pixelidentische Bilder oder 15-20 für eine sehr lockere Übereinstimmung. * Das „beste“ Bild in jeder Gruppe ist dasjenige mit den meisten Pixeln (Breite x Höhe), wobei die Dateigröße als Tiebreaker dient. * Es sind mindestens 2 Bilder erforderlich. Dateien, die die Validierung oder Decodierung nicht bestehen, werden in `skippedFiles` gemeldet, anstatt die gesamte Anfrage scheitern zu lassen. * Vorschaubilder sind 200 px breite JPEG-Vorschauen, die als Data-URIs codiert sind. * Alle gängigen Formate werden unterstützt (HEIC, RAW, PSD, SVG werden automatisch decodiert). --- --- url: https://docs.snapotter.com/tr/guide/low-resource.md --- # Düşük Kaynaklı Kurulumlar {#low-resource-setups} SnapOtter küçük donanımda iyi çalışır: bir Raspberry Pi 4 veya 5, eski bir dizüstü bilgisayar ya da 2 GB'lık bir VPS. Bu sayfa, bu makineler için pratik kılavuzdur: neler beklemeniz gerektiği, makul sınırlarla kopyala-yapıştır bir kurulum ve hangi özelliklerin atlanacağı. Bu sayıların arkasındaki tam kıyaslama verileri [Donanım Gereksinimleri](/tr/guide/deployment#hardware-requirements) bölümündedir. Baştan iki kesin kısıt: * **Yalnızca 64 bit.** İmaj `linux/amd64` ve `linux/arm64` için oluşturulur. 32 bit ARM (`armv7`/`armhf`) desteklenmez; bu yüzden birinci nesil Pi'ler ve Pi Zero ailesi devre dışıdır. * **2 GB bellek alt sınırı.** 512 MB yığını başlatamaz, 1 GB ise çok dosyalı toplu işlerde başarısız olur. Rahat çalışan en küçük yapılandırma 2 çekirdekli 2 GB'dir. ## Küçük donanımda neler iyi çalışır {#what-runs-well} AI olmayan her araç 2 GB / 2 çekirdekli bir makinede çalışır: Görsel ve Dosyalar bölümlerinin tamamı, PDF araçları ve stream copy ile yapılan video ve ses işlemleri (kırpma, sesi kapatma, kapsayıcı değişimi). Çoğu bir saniyenin altında tamamlanır. İki iş yükü istisnadır: * **Videoyu yeniden kodlama** (codec'ler arasında dönüştürme) CPU'ya bağlıdır. Hızlı bir masaüstü CPU'sunda ~40 sn süren bir 1080p klip, Pi sınıfı bir CPU'da birkaç dakika sürebilir. Stream copy işlemleri anlık kalır. * **AI araçları** RAM (4 GB önerilir) ve disk ister (büyük paketlerin her biri 4-5 GB'dir) ve ağır olanlar (ölçek büyütme, fotoğraf restorasyonu, arka plan kaldırma) Pi sınıfı CPU'larda pratik değildir. Yüz algılama ve OCR gibi hafif AI, belleğiniz yetiyorsa kullanılabilir. İkisi de siz kullanmadıkça kurulmaz ve çalışmaz: hiçbir AI paketi kurulu değilken uygulama boşta yaklaşık 360 MB kullanır ve AI paketleri yalnızca bir yönetici etkinleştirdiğinde indirilir. ## Raspberry Pi / eski dizüstü için adım adım kurulum {#walkthrough} Bu, [Başlarken](/tr/guide/getting-started) bölümündeki standart Compose kurulumunun kaynak limitleri ve temkinli sınırlar eklenmiş hâlidir. 64 bit bir işletim sistemi varsayar (bir Pi'de: Raspberry Pi OS 64-bit veya Ubuntu Server arm64). ```yaml services: snapotter: image: snapotter/snapotter:latest ports: - "1349:1349" volumes: - ./snapotter-data:/data environment: - DATABASE_URL=postgres://snapotter:snapotter@db:5432/snapotter - REDIS_URL=redis://redis:6379 # Small-box profile: see the table below for what each cap does. - CONCURRENT_JOBS=1 - MAX_WORKER_THREADS=2 - MAX_BATCH_SIZE=5 - MAX_UPLOAD_SIZE_MB=100 - MAX_MEGAPIXELS=50 - MAX_VIDEO_DURATION_S=300 deploy: resources: limits: cpus: "2" memory: 2G depends_on: - db - redis restart: unless-stopped db: image: postgres:17-alpine environment: - POSTGRES_USER=snapotter - POSTGRES_PASSWORD=snapotter # Yerel olmayan dağıtımlar için bunu değiştirin - POSTGRES_DB=snapotter volumes: - ./postgres-data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:8-alpine command: redis-server --maxmemory 256mb --maxmemory-policy noeviction restart: unless-stopped ``` Pi sınıfı makineler için notlar: * **SD kart yerine bir USB SSD tercih edin**; veri birimi ve Postgres bunun üzerinde dursun. İş çalışma alanları gerçek disk G/Ç'si yapar ve SD kartlar hem yavaştır hem de çabuk aşınır. * **Hepsi bir arada tek konteyner burada da çalışır** (`DATABASE_URL`/`REDIS_URL` ayarlanmadığında gömülü Postgres ve Redis) ve belleği kısıtlı bir ana makinede gömülü Redis sınırını `REDIS_MAXMEMORY` ile düşürmelisiniz (bkz. [Yapılandırma](/tr/guide/configuration)). Compose servis başına daha ince denetim sağlar; bu kılavuzun Compose kullanmasının nedeni de budur. * **2 GB'lık cihazlara swap ekleyin.** Bu, ara sıra oluşan bir sıçramanın (büyük bir PDF, sınırlamayı unuttuğunuz bir toplu iş) bellek yetersizliğinden süreç sonlandırmayla bitmesini önler. zram, SD kart dostu seçenektir. * arm64 imajı yalnızca CPU içindir; ARM kartlarda CUDA yoktur. ## Ayar düğmeleri {#tuning-knobs} Tüm sınırlar ortam değişkenleridir ve [Yapılandırma](/tr/guide/configuration) bölümünde eksiksiz belgelenmiştir. `0` sınırsız veya otomatik anlamına gelir. Küçük donanımda önemli olanlar: | Değişken | Küçük makine önerisi | Neyi korur | |---|---|---| | `CONCURRENT_JOBS` | `1` | Kaç işin paralel çalıştığı. Otomatik algılama CPU çekirdek sayısının bir eksiğini kullanır; bu büyük makinelerde iyidir, bellek baskısı altındaki 2 çekirdekli bir makinede ise fazla isteklidir. | | `MAX_WORKER_THREADS` | `2` | Görüntü işleme iş parçacığı havuzu. | | `MAX_BATCH_SIZE` | `5` | 1-2 GB'lık makinelerin belleği ilk önce toplu işlerde tükenir. | | `MAX_UPLOAD_SIZE_MB` | `100` | Tek bir devasa dosyanın tüm çalışma alanını kaplamasını önler. | | `MAX_MEGAPIXELS` | `50` | 100+ MP bir görseli çözmek, dosya boyutundan bağımsız olarak RAM'e mal olur. | | `MAX_VIDEO_DURATION_S` | `300` | Uzun dönüştürmeler küçük bir CPU'yu dakikalarca, hatta saatlerce meşgul eder. | | `PROCESSING_TIMEOUT_S` | `600` | Kontrolden çıkan bir işin makineyi eninde sonunda serbest bırakması için kesin tavan. | Bu sınırlar sunucunun neyi kabul ettiğini belirler; bu yüzden onları olabildiğince küçük değil, gerçekten kullandığınız şeye göre ayarlayın. Videoya hiç dokunmuyorsanız bir `MAX_VIDEO_DURATION_S` sınırının maliyeti yoktur; her gün belge tarıyorsanız `MAX_PDF_PAGES` değişkenine sınır koymayın. ## Nelerden vazgeçmeli {#what-to-skip} * **Ağır AI paketleri.** Ölçek büyütme, fotoğraf restorasyonu ve arka plan kaldırma bir GPU veya çok çekirdekli hızlı bir CPU ister ve her paket 4-5 GB disk kaplar. Küçük bir makinede bunları kurmamanız yeterlidir; paketi eksik olan araçlar çalışmak yerine bir kurulum istemi gösterir. * **Rutin iş yükü olarak video yeniden kodlama.** Ara sıra dönüştürme sorun değildir (yalnızca yavaştır); sürekli bir dönüştürme kuyruğu CPU çekirdeği ister, Pi değil. * **Genel olarak kullanılmayan araçlar.** Bir yönetici Settings içinden tek tek araçları kapatabilir; bu, onları arayüzden kaldırır ve API rotalarının kaydını durdurur. Bu tek başına bellek kazandırmaz, ancak paylaşılan küçük bir örneğin donanımın kaldıramayacağı o tek iş yükü için kullanılmasını engeller. Örneği daha sonra daha büyük bir donanıma taşırsanız sınırları kaldırın (`0` değerine geri alın); aynı veri birimi olduğu gibi taşınır. --- --- url: https://docs.snapotter.com/pl/changelog.md description: >- Informacje o wydaniach i historia wersji SnapOtter. Zobacz, co nowego, co ulepszono i co naprawiono w każdym wydaniu. --- # Dziennik zmian {#changelog} ## v2.0.0 {#v2-0-0} SnapOtter 2.0 zamienia zestaw narzędzi do obrazów w pełnoprawny pakiet do manipulacji plikami: ponad 200 narzędzi w pięciu modalnościach (Image, Video, Audio, PDF i Files), przebudowany na bazie Postgres 17 i kolejki zadań opartej na Redis, z jednopoleceniowym `docker run`. To duże wydanie; przed aktualizacją z wersji 1.x przeczytaj sekcję Zmiany łamiące zgodność. ### Nowe funkcje {#new-features} * **Cztery nowe modalności narzędzi**: Video, Audio, PDF i Files dołączają do Image, powiększając katalog do ponad 200 narzędzi. * **Trwałe zadania w tle**: Kolejka oparta na Redis (BullMQ) uruchamia każde narzędzie jako śledzone zadanie z podglądem postępu na żywo przez SSE. * **Tryb pojedynczego kontenera all-in-one**: Jedno `docker run` uruchamia kompletną instancję z wbudowanym Postgres i Redis. * **Pakiety AI na żądanie**: Usuwanie tła, OCR, transkrypcja, skalowanie w górę, wykrywanie i poprawianie twarzy, gumka do obiektów, koloryzacja i renowacja zdjęć instalują się z poziomu interfejsu. Akceleracja GPU jest wykrywana osobno dla każdego frameworka. * **Sign PDF**: Narysuj, wpisz lub prześlij podpis i umieść go w pliku PDF w przeglądarce. * **Automate**: Wizualny kreator potoków, który łączy narzędzia w łańcuch, z dziewięcioma gotowymi szablonami. * **83 gotowe do jednego kliknięcia ustawienia konwersji**: Dedykowane konwertery JPG na PNG, MP4 na GIF i podobne, z wyszukiwaniem rozmytym. * **Warstwowy edytor obrazów**: Edytor napędzany przez Konva pod adresem `/editor` z pędzlami, kształtami, korektami, filtrami i krzywymi. * **Biblioteka Files**: Zapisz dowolny wynik i użyj go ponownie jako danych wejściowych do innego narzędzia. * Przypięte narzędzia, powiększanie i przesuwanie w obrębie płótna, 21 języków oraz możliwości dla przedsiębiorstw (OIDC/SSO, SAML, SCIM, magazyn S3, uprawnienia dla poszczególnych narzędzi, eksport dziennika audytu, śledzenie rozproszone). ### Ulepszenia {#improvements} * Anulowanie trwającego procesu. (#137) * Dekodowanie RAW w pełnej rozdzielczości przez LibRaw, w tym DNG. (#289) * Wdrożenia bez uprawnień roota i z obcym UID (TrueNAS, Unraid, OpenShift, PUID/PGID). (#230, #127) * Dokładne wykrywanie instalacji AI i wzmocniony proces instalacji. (#214, #352) * Wzmocnienie prywatności: brak automatycznego ruchu wychodzącego do stron trzecich oraz opcjonalny tryb ścisłego offline. * Zawsze dostępny przycisk opinii, nawet przy wyłączonej analityce. ### Poprawki błędów {#bug-fixes} * `RATE_LIMIT_PER_MIN=0` ponownie wyłącza ograniczanie liczby żądań dla tras narzędzi. (#271) * Naprawiono ścieżki wirtualnego środowiska AI wewnątrz obrazu Docker. (#390) * Zgodność z sharp 0.35.2+. (#362) * Poprawki układu edytora obrazów: linijki, zachowanie wypełnienia, panel boczny i rozmiar płótna. (#258, #259) * Ukończono tłumaczenie na język włoski. (#231, #206, #425) * Normalizacja dźwięku i loudnorm zachowują częstotliwość próbkowania źródła. * Wzmocnienie ochrony przed SSRF: numeryczne dopasowywanie CIDR dla IPv6 i rozszerzone wstępne skanowanie adresów URL. (#287) * Wygenerowane pliki PDF są oznaczane wartością SnapOtter w polu Producer. * mediapipe instaluje się na Pythonie 3.13 i Debianie 13. ### Zmiany łamiące zgodność {#breaking-changes} Wersja 2.0 zastępuje wbudowaną bazę danych SQLite bazą Postgres 17 i dodaje Redis 8 do obsługi kolejki zadań. Twoje dane z wersji 1.x migrują automatycznie przy pierwszym uruchomieniu, ale zmienił się układ kontenerów, więc najpierw wykonaj kopię zapasową całego woluminu `/data` (wersja 1.x uruchamia SQLite w trybie WAL, więc zatwierdzone dane zwykle znajdują się w `snapotter.db-wal`). Następnie wybierz obraz jednego kontenera (wbudowane Postgres i Redis, tylko root) albo stos Compose (aplikacja plus Postgres 17 i Redis 8). Zobacz [przewodnik migracji](https://github.com/snapotter-hq/SnapOtter/blob/main/MIGRATING.md) oraz [przewodnik aktualizacji](/pl/guide/upgrading). ### Aktualizacja {#upgrade} ```bash docker pull snapotter/snapotter:2.0.0 ``` Lub za pomocą Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Pełna różnica na GitHubie](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.2...v2.0.0) *** ## v1.17.2 {#v1-17-2} Nowe narzędzie HTML na Image, dostępność WCAG 2.2 AA, wzmocnienie bezpieczeństwa dzięki testom penetracyjnym oraz 5 krytycznych poprawek dla Dockera. ### Nowe funkcje {#new-features-1} * **HTML na Image**: Przechwytuj zrzuty ekranu adresów URL lub surowego HTML jako PNG/JPEG/WebP. Przechwytywanie całych stron, niestandardowe okna widoku, tryb ciemny. * **Konwencja sekretów Docker \_FILE**: Montuj wrażliwe zmienne środowiskowe jako pliki zamiast tekstu jawnego. (#205) * **Licencjonowanie dla przedsiębiorstw i magazyn S3**: Opcjonalny komercyjny klucz licencyjny oraz magazyn obiektów zgodny z S3. * **Ulepszenia edytora kształtów**: Przezroczystość wypełnienia/obrysu, próbnik kolorów RGBA, style linii kreskowanych. * **Gotowe archiwa wydań**: Pobieraj archiwa tarball z GitHub Releases dla instalacji bez Dockera (Proxmox, bare metal, LXC). (#202) ### Ulepszenia {#improvements-1} * **Dostępność WCAG 2.2 AA**: Pomijanie nawigacji, pułapkowanie fokusu, regiony aria-live, obsługa ograniczonego ruchu, poprawne współczynniki kontrastu. (#209) * **Responsywność na urządzeniach mobilnych**: Responsywne ustawienia, automatyczne ponowne łączenie SSE przy przełączaniu karty na urządzeniu mobilnym. (#203, #204) * **Jakość usuwania tła**: Wygładzanie krawędzi, dekontaminacja kolorów, wybór formatu wyjściowego. * **Tłumaczenie na język włoski**: ~145 nowych ciągów autorstwa @albanobattistella. (#206) * **Dokumentacja API dla poszczególnych narzędzi**: 53 strony dokumentacji z parametrami, przykładami i formatami odpowiedzi. * **Pobieranie modeli AI**: Logika ponawiania z wykładniczym odczekiwaniem dla HuggingFace. (#201) ### Poprawki błędów {#bug-fixes-1} * Świeże kontenery Docker były całkowicie bezużyteczne (ograniczenie liczby żądań blokowało wszystkie żądania). * Narzędzia AI do wykrywania twarzy (blur-faces, red-eye-removal, enhance-faces, passport-photo) zawodziły na wszystkich platformach. * Pliki HEIC uszkodzone na ARM (niezgodność symboli libheif). * Pakiety AI upscale i restore-photo nie instalowały się na ARM. * OCR używał niewłaściwej wersji CUDA w kontenerach z GPU. * Obejście zabezpieczenia przed SSRF przez szesnastkowe adresy IPv6 mapowane na IPv4. (Podziękowania: @tonghuaroot) * Dekodowanie iPhone HEIC z obrazami pomocniczymi. (#183, #199) * Błąd braku pamięci CUDA w Real-ESRGAN na kartach GPU o pojemności 8 GB. (#200) * 6 produkcyjnych błędów Sentry i 7 błędów QA. (#208) ### Bezpieczeństwo {#security} * Rozwiązano 10 ustaleń z testów penetracyjnych (obejście XFF, awarie na zniekształconym JSON, nieograniczone potoki, XSS w dzienniku audytu, metoda TRACE i inne). (#207) * Zablokowano obejście SSRF przez szesnastkowy IPv6. (Podziękowania: @tonghuaroot) * Obrazy bazowe Dockerfile przypięte przez skrót (digest). ### Aktualizacja {#upgrade-1} ```bash docker pull snapotter/snapotter:1.17.2 ``` Lub za pomocą Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Pełna różnica na GitHubie](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2) *** ## v1.17.1 {#v1-17-1} Wersja demonstracyjna na żywo, strony docelowe poszczególnych narzędzi oraz zestaw poprawek dopracowujących. ### Nowe funkcje {#new-features-2} * **Wersja demonstracyjna na żywo** - [demo.snapotter.com](https://demo.snapotter.com) pozwala ludziom wypróbować SnapOtter bez instalowania czegokolwiek. * **Strona z indeksem narzędzi** - Przeglądaj wszystkie ponad 50 narzędzi pod adresem `/tools` z wyszukiwaniem i filtrami kategorii. * **Ponad 50 stron docelowych SEO** - Każde narzędzie ma teraz dedykowaną stronę docelową z sekcją FAQ, przypadkami użycia i tabelami porównawczymi. * **Podgląd tła** - Suwak przed i po pokazuje szachownicę za przezroczystymi obrazami. * **Generator silnych haseł** - Przycisk jednego kliknięcia w formularzu Dodaj członków. ### Poprawki błędów {#bug-fixes-2} * Narzędzie informacji o HEIC/HEIF już nie zawodzi (dodano wstępne dekodowanie). * Instalacja pakietów modeli AI wyświetla lepsze komunikaty o błędach i respektuje limity zasobów. * Miniatury biblioteki ładują się poprawnie (brakowało nagłówków uwierzytelniania). * Menu rozwijane już nie są przycinane w tabelach ustawień People i Teams. * Ukryto procent porównania rozmiaru w narzędziach niezwiązanych z kompresją. * Usunięto zduplikowany odnośnik do polityki prywatności. * Dodano tłumaczenie na język włoski dla ustawień funkcji AI. * Zaktualizowano przemianowane ikony Lucide (Wand2, Columns). ### Infrastruktura {#infrastructure} * Wynik OpenSSF Scorecard wzmocniono z 4,3 do ~7,0. * Testy CI zrównoleglono w 4 fragmenty ze zmniejszonymi zasobami testowymi. * 41 aktualizacji zależności. ### Aktualizacja {#upgrade-2} ```bash docker pull snapotter/snapotter:1.17.1 ``` Lub za pomocą Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Pełna różnica na GitHubie](https://github.com/snapotter-hq/SnapOtter/compare/v1.17.0...v1.17.1) *** ## v1.17.0 {#v1-17-0} Pięć nowych narzędzi, pełny edytor obrazów, logowanie SSO, 20 języków. Prawdopodobnie powinny to być trzy osobne wydania, ale jest jak jest. ### Nowe funkcje {#new-features-3} * **Edytor obrazów** - Warstwy, pędzle, kształty, korekty, filtry, krzywe, skróty klawiaturowe. Działa w przeglądarce, przetwarza na Twoim sprzęcie. * **Uwierzytelnianie OIDC / SSO** - Logowanie za pomocą Google, GitHub, Okta lub dowolnego dostawcy OpenID Connect. Ustaw kilka zmiennych środowiskowych, a Twój zespół korzysta ze swoich istniejących kont. * **Generator memów** - 100 wbudowanych szablonów z renderowaniem tekstu przez opentype.js. Albo prześlij własny obraz. * **Beautify** - Wrzuć zrzut ekranu, otrzymaj dopracowany obraz. Ramki urządzeń (macOS, Windows, przeglądarka), cienie, gradienty, gotowe ustawienia dla mediów społecznościowych. * **Symulacja daltonizmu** - Podejrzyj, jak obrazy wyglądają przy protanopii, deuteranopii, tritanopii i innych zaburzeniach widzenia barw. * **Naprawa przezroczystości PNG** - Wykrywa pliki PNG z fałszywą przezroczystością i naprawia je za pomocą matowania BiRefNet HR. Opcjonalne usuwanie znaku wodnego przez inpainting LaMa. * **Rozszerzanie płótna AI** - Powiększaj granice obrazu z wypełnieniem AI. Trzy poziomy jakości (szybki, zrównoważony, jakościowy) zależnie od tego, ile czasu GPU chcesz poświęcić. * **20 języków** - arabski, chiński (uproszczony/tradycyjny), czeski, niderlandzki, francuski, niemiecki, hindi, indonezyjski, włoski, japoński, koreański, polski, portugalski, rosyjski, hiszpański, tajski, turecki, ukraiński, wietnamski. Układ RTL działa dla arabskiego. * **Import z adresu URL** - Wklejaj adresy URL do strefy upuszczania lub importuj masowo z listy. Pobieranie po stronie serwera z ochroną przed SSRF. * **Gumka dla wielu plików** - Rysuj maski wymazywania na wielu obrazach, przetwarzaj je wszystkie jednym kliknięciem. Pociągnięcia utrzymują się osobno dla każdego obrazu. * **Import/eksport potoków** - Zapisuj łańcuchy narzędzi jako JSON, udostępniaj je innym. * **17 nowych formatów aparatowych RAW** przez exiftool, a także wejście QOI, JP2, EPS, DDS, CUR, DPX, FITS, PPM/PGM/PBM, SVGZ i APNG. Nowe kodeki wyjściowe dla BMP, ICO, JP2, QOI. Odzyskano eksport AVIF, TIFF, GIF, JXL i PSD z wcześniej utraconej gałęzi. ### Ulepszenia {#improvements-2} * **Ulepszanie obrazu** - Zastąpiono stary potok kombinacją CLAHE + normalise + gamma. Nowy przełącznik Deep Enhance używa modelu AI dla bardziej agresywnych rezultatów. * **Renowacja zdjęć** - Wykrywanie zarysowań przepisano z ośmiokątowym filtrowaniem Otsu. Inpainting LaMa działa teraz w natywnej rozdzielczości. * **Egzotyczne formaty wszędzie** - OCR, image-to-PDF, generator faviconów, kompozycja, łączenie i wektoryzacja dekodują teraz HEIC, RAW, PSD. * **Kompresja** - Zaostrzono tolerancję rozmiaru docelowego z 5% do 1%. Rozmiar docelowy jest teraz trybem domyślnym. Dodano przyciski krokowe i selektor jednostek KB/MB. * **Porządki w Sentry** - Odfiltrowano 644 zdarzenia niewymagające działania. Prawdziwe błędy są teraz obsługiwane poprawnie. * **Wykrywanie GPU** - Lepsza diagnostyka dla kontenerów, w których CUDA jest obecne, ale nvidia-smi nie. * **Tryb z wyłączonym uwierzytelnianiem** - Anonimowy użytkownik jest zasiewany w bazie danych z rolą admina. Klucze API, potoki i pliki użytkownika już nie łamią się na ograniczeniach kluczy obcych. * **Ponad 2705 nowych testów** w warstwach jednostkowej, integracyjnej i E2E. ### Poprawki błędów {#bug-fixes-3} * Skalowanie w górę na CPU już nie przekracza limitu czasu na urządzeniach NAS i sprzęcie o małej mocy. * Logo kodu QR już nie powoduje trwałego zniknięcia podglądu. * Naprawiono przepełnienie kadrowania dla wysokich obrazów portretowych. * Pliki TIFF z kanałem alfa poprawnie wymuszają wyjście PNG zamiast powodować uszkodzenie. * Dekodowanie HDR/EXR konwertuje do 8 bitów przed CLAHE, naprawiając błędy dekodowania. * Bufory wejściowe punktów charakterystycznych twarzy są konwertowane do PNG przed sidecarem Pythona, naprawiając awarie. * Znajdowanie duplikatów obsługuje partie o mieszanych formatach i błędy sieciowe. * Podgląd Beautify aktualizuje się w czasie rzeczywistym. * Paski postępu dla łączenia i wektoryzacji. * SVGZ obsługiwane przez SVG-to-raster. * Naprawiono nazwy plików spoza ASCII przez nagłówek X-File-Results z kodowaniem procentowym. ### Aktualizacja {#upgrade-3} ```bash docker pull snapotter/snapotter:1.17.0 ``` Lub za pomocą Docker Compose: ```bash docker compose pull && docker compose up -d ``` [Pełna różnica na GitHubie](https://github.com/snapotter-hq/SnapOtter/compare/v1.16.0...v1.17.0) *** ## v1.14.0 {#v1-14-0} Ujednolicony obraz Docker z automatycznym wykrywaniem GPU. Jeden obraz obsługuje zarówno obciążenia CPU, jak i GPU. Uproszczono compose do pojedynczego pliku z rotacją logów. Wstępne pobieranie modeli obejmuje teraz weryfikację i test dymny. *** ## v1.13.0 {#v1-13-0} Kontrola dostępu oparta na rolach (RBAC). 14 szczegółowych uprawnień, trzy wbudowane role (admin, editor, user), obsługa niestandardowych ról. Sprawdzanie uprawnień na wszystkich trasach API. Karty frontendu filtrowane według uprawnień użytkownika. *** ## v1.12.0 {#v1-12-0} Narzędzie PDF na Image. Konwertuj strony PDF na PNG, JPEG, WebP lub TIFF z niestandardowym DPI. Ujednolicony obraz Docker z automatycznym wykrywaniem GPU. *** ## v1.11.0 {#v1-11-0} Automatycznie generowany plik llms.txt przez vitepress-plugin-llms dla dokumentacji przyjaznej AI. *** ## v1.10.0 {#v1-10-0} Zmiana rozmiaru z uwzględnieniem treści (seam carving) z ochroną twarzy. Zmieniaj rozmiar obrazów, zachowując ważną treść. *** ## v1.9.0 {#v1-9-0} Narzędzie Stitch / Combine. Łącz obrazy obok siebie, jeden nad drugim lub w niestandardowej siatce. *** ## v1.8.0 {#v1-8-0} Narzędzie Edit Metadata. Przeglądaj i edytuj metadane EXIF, IPTC i XMP z szczegółowym interfejsem usuwania/zachowywania. *** ## Starsze wydania {#older-releases} Pełny dziennik zmian na poziomie zatwierdzeń, w tym wydania poprawkowe, znajdziesz w [GitHub Releases](https://github.com/snapotter-hq/snapotter/releases). --- --- url: https://docs.snapotter.com/pt-BR/tools/image/edit-metadata.md description: >- Edite campos de metadados EXIF, IPTC, GPS e XMP em imagens sem recodificar os pixels. --- # Editar Metadados da Imagem {#edit-metadata} Edite campos de metadados de imagem, incluindo EXIF, IPTC, coordenadas GPS, datas e palavras-chave. Usa o ExifTool internamente, então os metadados são gravados no local sem recodificar os pixels, preservando a qualidade total da imagem. ## Endpoints da API {#api-endpoints} ### Editar Metadados {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Grava campos de metadados na imagem e retorna o arquivo modificado. ### Inspecionar Metadados {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Retorna os metadados completos da imagem via ExifTool como JSON. Não modifica a imagem. ## Parâmetros (Editar) {#parameters-edit} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | title | string | Não | - | Título da imagem (XMP/EXIF) | | author | string | Não | - | Nome do autor | | artist | string | Não | - | Nome do artista (tag Artist do EXIF) | | copyright | string | Não | - | Aviso de copyright | | imageDescription | string | Não | - | Descrição da imagem (EXIF) | | software | string | Não | - | Tag de software | | dateTime | string | Não | - | Valor DateTime do EXIF | | dateTimeOriginal | string | Não | - | Valor DateTimeOriginal do EXIF | | setAllDates | string | Não | - | Define todos os campos de data de uma vez | | dateShift | string | Não | - | Desloca todas as datas por um deslocamento (formato: `+HH:MM` ou `-HH:MM`) | | clearGps | boolean | Não | `false` | Remove todos os dados de GPS | | gpsLatitude | number | Não | - | Define a latitude GPS (-90 a 90) | | gpsLongitude | number | Não | - | Define a longitude GPS (-180 a 180) | | gpsAltitude | number | Não | - | Define a altitude GPS em metros | | keywords | string\[] | Não | - | Palavras-chave/tags a adicionar ou definir | | keywordsMode | string | Não | `"add"` | Como tratar as palavras-chave: `add` (anexar) ou `set` (substituir) | | fieldsToRemove | string\[] | Não | `[]` | Lista de nomes de campos de metadados específicos a remover | | iptcTitle | string | Não | - | Nome do Objeto IPTC | | iptcHeadline | string | Não | - | Manchete IPTC | | iptcCity | string | Não | - | Cidade IPTC | | iptcState | string | Não | - | Província/Estado IPTC | | iptcCountry | string | Não | - | País IPTC | ## Exemplo de Requisição {#example-request} Definir autor e copyright: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` Definir coordenadas GPS: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` Remover GPS e adicionar palavras-chave: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Inspecionar metadados: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Exemplo de Resposta (Editar) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Notas {#notes} * Esta ferramenta requer que o ExifTool esteja instalado no servidor. Ele está incluído na imagem Docker. * Os metadados são gravados no local, então nenhuma recodificação de pixels ocorre. A mudança no tamanho do arquivo é mínima (apenas os bytes de metadados). * O parâmetro `dateShift` desloca todos os campos de data pelo deslocamento especificado, útil para corrigir erros de fuso horário (por exemplo, `+02:00` ou `-05:30`). * Se nenhuma alteração for solicitada (todos os parâmetros omitidos ou vazios), o arquivo original é retornado inalterado. * Formatos suportados: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * Para formatos não pré-visualizáveis no navegador (HEIF, TIFF), a resposta inclui um campo `previewUrl` com uma pré-visualização WebP. --- --- url: https://docs.snapotter.com/es/tools/image/edit-metadata.md description: >- Edita campos de metadatos EXIF, IPTC, GPS y XMP en imágenes sin recodificar los píxeles. --- # Editar metadatos de imagen {#edit-metadata} Edita campos de metadatos de imagen, incluidos EXIF, IPTC, coordenadas GPS, fechas y palabras clave. Usa ExifTool internamente, por lo que los metadatos se escriben en el sitio sin recodificar los píxeles, preservando la calidad completa de la imagen. ## Endpoints de la API {#api-endpoints} ### Editar metadatos {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Escribe campos de metadatos en la imagen y devuelve el archivo modificado. ### Inspeccionar metadatos {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Devuelve todos los metadatos de la imagen mediante ExifTool como JSON. No modifica la imagen. ## Parámetros (Editar) {#parameters-edit} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | title | string | No | - | Título de la imagen (XMP/EXIF) | | author | string | No | - | Nombre del autor | | artist | string | No | - | Nombre del artista (etiqueta EXIF Artist) | | copyright | string | No | - | Aviso de derechos de autor | | imageDescription | string | No | - | Descripción de la imagen (EXIF) | | software | string | No | - | Etiqueta de software | | dateTime | string | No | - | Valor EXIF DateTime | | dateTimeOriginal | string | No | - | Valor EXIF DateTimeOriginal | | setAllDates | string | No | - | Establece todos los campos de fecha a la vez | | dateShift | string | No | - | Desplaza todas las fechas por un valor de compensación (formato: `+HH:MM` o `-HH:MM`) | | clearGps | boolean | No | `false` | Elimina todos los datos GPS | | gpsLatitude | number | No | - | Establece la latitud GPS (-90 a 90) | | gpsLongitude | number | No | - | Establece la longitud GPS (-180 a 180) | | gpsAltitude | number | No | - | Establece la altitud GPS en metros | | keywords | string\[] | No | - | Palabras clave/etiquetas que se añaden o establecen | | keywordsMode | string | No | `"add"` | Cómo tratar las palabras clave: `add` (añadir) o `set` (reemplazar) | | fieldsToRemove | string\[] | No | `[]` | Lista de nombres específicos de campos de metadatos que se eliminan | | iptcTitle | string | No | - | IPTC Object Name | | iptcHeadline | string | No | - | IPTC Headline | | iptcCity | string | No | - | IPTC City | | iptcState | string | No | - | IPTC Province/State | | iptcCountry | string | No | - | IPTC Country | ## Ejemplo de solicitud {#example-request} Establecer autor y derechos de autor: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` Establecer coordenadas GPS: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` Eliminar GPS y añadir palabras clave: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Inspeccionar metadatos: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Ejemplo de respuesta (Editar) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Notas {#notes} * Esta herramienta requiere que ExifTool esté instalado en el servidor. Está incluido en la imagen de Docker. * Los metadatos se escriben en el sitio, por lo que no se produce recodificación de píxeles. El cambio en el tamaño del archivo es mínimo (solo los bytes de metadatos). * El parámetro `dateShift` desplaza todos los campos de fecha por la compensación especificada, útil para corregir errores de zona horaria (p. ej. `+02:00` o `-05:30`). * Si no se solicitan cambios (todos los parámetros omitidos o vacíos), el archivo original se devuelve sin cambios. * Formatos admitidos: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * Para los formatos que no se pueden previsualizar en el navegador (HEIF, TIFF), la respuesta incluye un campo `previewUrl` con una vista previa WebP. --- --- url: https://docs.snapotter.com/pl/tools/image/edit-metadata.md description: >- Edytuj pola metadanych EXIF, IPTC, GPS i XMP w obrazach bez ponownego kodowania pikseli. --- # Edycja metadanych obrazu {#edit-metadata} Edytuj pola metadanych obrazu, w tym EXIF, IPTC, współrzędne GPS, daty i słowa kluczowe. Wykorzystuje pod spodem ExifTool, więc metadane są zapisywane w miejscu bez ponownego kodowania pikseli, zachowując pełną jakość obrazu. ## Punkty końcowe API {#api-endpoints} ### Edycja metadanych {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Zapisuje pola metadanych do obrazu i zwraca zmodyfikowany plik. ### Sprawdzanie metadanych {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Zwraca pełne metadane z obrazu za pomocą ExifTool w formacie JSON. Nie modyfikuje obrazu. ## Parametry (Edycja) {#parameters-edit} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | title | string | Nie | - | Tytuł obrazu (XMP/EXIF) | | author | string | Nie | - | Nazwa autora | | artist | string | Nie | - | Nazwa artysty (znacznik EXIF Artist) | | copyright | string | Nie | - | Nota o prawach autorskich | | imageDescription | string | Nie | - | Opis obrazu (EXIF) | | software | string | Nie | - | Znacznik oprogramowania | | dateTime | string | Nie | - | Wartość EXIF DateTime | | dateTimeOriginal | string | Nie | - | Wartość EXIF DateTimeOriginal | | setAllDates | string | Nie | - | Ustaw wszystkie pola dat naraz | | dateShift | string | Nie | - | Przesuń wszystkie daty o wartość (format: `+HH:MM` lub `-HH:MM`) | | clearGps | boolean | Nie | `false` | Usuń wszystkie dane GPS | | gpsLatitude | number | Nie | - | Ustaw szerokość geograficzną GPS (od -90 do 90) | | gpsLongitude | number | Nie | - | Ustaw długość geograficzną GPS (od -180 do 180) | | gpsAltitude | number | Nie | - | Ustaw wysokość GPS w metrach | | keywords | string\[] | Nie | - | Słowa kluczowe/tagi do dodania lub ustawienia | | keywordsMode | string | Nie | `"add"` | Sposób obsługi słów kluczowych: `add` (dołącz) lub `set` (zastąp) | | fieldsToRemove | string\[] | Nie | `[]` | Lista nazw konkretnych pól metadanych do usunięcia | | iptcTitle | string | Nie | - | IPTC Object Name | | iptcHeadline | string | Nie | - | IPTC Headline | | iptcCity | string | Nie | - | IPTC City | | iptcState | string | Nie | - | IPTC Province/State | | iptcCountry | string | Nie | - | IPTC Country | ## Przykładowe żądanie {#example-request} Ustawianie autora i praw autorskich: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` Ustawianie współrzędnych GPS: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` Usuwanie GPS i dodawanie słów kluczowych: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Sprawdzanie metadanych: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Przykładowa odpowiedź (Edycja) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Uwagi {#notes} * To narzędzie wymaga zainstalowanego na serwerze ExifTool. Jest on dołączony do obrazu Docker. * Metadane są zapisywane w miejscu, więc nie następuje ponowne kodowanie pikseli. Zmiana rozmiaru pliku jest minimalna (tylko bajty metadanych). * Parametr `dateShift` przesuwa wszystkie pola dat o określoną wartość, co jest przydatne do korygowania błędów stref czasowych (np. `+02:00` lub `-05:30`). * Jeśli nie zażądano żadnych zmian (wszystkie parametry pominięte lub puste), oryginalny plik jest zwracany bez zmian. * Obsługiwane formaty: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * W przypadku formatów, których nie można podejrzeć w przeglądarce (HEIF, TIFF), odpowiedź zawiera pole `previewUrl` z podglądem WebP. --- --- url: https://docs.snapotter.com/tr/tools/image/beautify.md description: >- Sade ekran görüntülerini gradyan arka planlar, cihaz çerçeveleri, gölgeler ve sosyal medya boyutlarıyla cilalı görsellere dönüştürün. --- # Ekran Görüntüsünü Güzelleştir {#beautify-screenshot} Ekran görüntülerine gradyan arka planlar, cihaz çerçeveleri, gölgeler, filigranlar ve sosyal medya boyutları ekleyin. Ürün pazarlaması, sosyal medya ve dokümantasyon için cilalı görseller oluşturmak için idealdir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | backgroundType | dize | Hayır | `"linear-gradient"` | Arka plan türü: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | dize | Hayır | `"#667eea"` | Düz arka plan rengi (`backgroundType` `solid` olduğunda kullanılır) | | gradientStops | dizi | Hayır | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | Gradyan renk durakları (en az 2). Her durak bir `color` (onaltılık) ve bir `position` (0-100) değerine sahiptir. | | gradientAngle | sayı | Hayır | 135 | Derece cinsinden gradyan açısı (0 ile 360 arası) | | padding | sayı | Hayır | 64 | Görselin çevresindeki piksel cinsinden dolgu (0 ile 256 arası) | | borderRadius | sayı | Hayır | 12 | Ekran görüntüsünün köşe yarıçapı (0 ile 64 arası) | | shadowPreset | dize | Hayır | `"subtle"` | Gölge ön ayarı: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | sayı | Hayır | 20 | Özel gölge bulanıklık yarıçapı (0 ile 100 arası, `shadowPreset` `custom` olduğunda kullanılır) | | shadowOffsetX | sayı | Hayır | 0 | Özel gölge yatay konumu (-50 ile 50 arası) | | shadowOffsetY | sayı | Hayır | 10 | Özel gölge dikey konumu (-50 ile 50 arası) | | shadowColor | dize | Hayır | `"#000000"` | Onaltılık olarak özel gölge rengi | | shadowOpacity | sayı | Hayır | 30 | Özel gölge opaklığı (0 ile 100 arası) | | frame | dize | Hayır | `"none"` | Cihaz veya pencere çerçevesi: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | dize | Hayır | - | Pencere çerçevesi başlık çubuklarında görüntülenen başlık metni | | socialPreset | dize | Hayır | `"none"` | Sosyal medya boyutlarına yeniden boyutlandır: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | dize | Hayır | - | İsteğe bağlı filigran metni yerleşimi | | watermarkPosition | dize | Hayır | `"bottom-right"` | Filigran konumu: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | sayı | Hayır | 50 | Filigran opaklığı (0 ile 100 arası) | | outputFormat | dize | Hayır | `"png"` | Çıktı biçimi: `png`, `jpeg`, `webp` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### Arka Plan Görseliyle {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notlar {#notes} * İki dosya alanı kabul eder: `file` (zorunlu, ana ekran görüntüsü) ve `backgroundImage` (isteğe bağlı, `backgroundType` `image` olduğunda kullanılır). * HEIC, RAW, PSD ve SVG giriş biçimlerini destekler (otomatik olarak çözülür). * Gölge ön ayarları belirli değerlere eşlenir: * `subtle`: bulanıklık 20, offsetY 4, opaklık %20 * `medium`: bulanıklık 40, offsetY 10, opaklık %35 * `dramatic`: bulanıklık 80, offsetY 20, opaklık %50 * Sosyal medya ön ayarları, `contain` modunu kullanarak nihai çıktıyı hedef boyutlara sığacak şekilde yeniden boyutlandırır: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * Cihaz çerçeveleri (`iphone`, `macbook`, `ipad`) görselin çevresine bir donanım çerçevesi uygular ve `borderRadius` ayarını atlar. * Saydamlık gerektiğinde (gölge, köşe yarıçapı, cihaz çerçeveleri veya saydam arka plan), `jpeg` seçilmiş olsa bile çıktı PNG'ye zorlanır. * Görsel arka planlar pipeline/toplu modda desteklenmez. --- --- url: https://docs.snapotter.com/es/tools/image/red-eye-removal.md description: >- Detección y corrección con IA de los ojos rojos causados por el flash de la cámara. --- # Eliminación de ojos rojos {#red-eye-removal} Detección y corrección con IA de los ojos rojos causados por el flash de la cámara. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/red-eye-removal` **Procesamiento:** asíncrono (devuelve 202, consulta `/api/v1/jobs/{jobId}/progress` para conocer el estado vía SSE) **Paquete del modelo:** `face-detection` (200-300 MB) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | sensitivity | number | No | `50` | Sensibilidad de detección de ojos rojos (0-100). Los valores más altos detectan ojos rojos más sutiles | | strength | number | No | `70` | Intensidad de la corrección (0-100). Con cuánta agresividad se neutraliza el rojo | | format | string | No | - | Formato de salida (anulación opcional) | | quality | number | No | `90` | Calidad de salida (1-100) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/red-eye-removal \ -F "file=@flash-photo.jpg" \ -F 'settings={"sensitivity":60,"strength":80}' ``` ## Respuesta {#response} ### Respuesta inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progreso (SSE en `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting red eyes...","percent":40} ``` ### Resultado final (vía SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/flash-photo_redeye_fixed.png", "originalSize": 280000, "processedSize": 290000, "facesDetected": 2, "eyesCorrected": 4 } } ``` ## Notas {#notes} * Requiere que el paquete del modelo `face-detection` esté instalado (200-300 MB). * Primero detecta los rostros, luego localiza las regiones de los ojos dentro de cada rostro y, por último, identifica y corrige los píxeles de ojos rojos. * El recuento `facesDetected` indica cuántos rostros se encontraron; `eyesCorrected` es el número total de ojos individuales a los que se corrigieron los ojos rojos. * La salida es siempre PNG para conservar la máxima calidad. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/es/tools/image/noise-removal.md description: Eliminación de ruido y grano con IA y opciones de calidad de varios niveles. --- # Eliminación de ruido {#noise-removal} Eliminación de ruido y grano con IA y opciones de calidad de varios niveles, mediante el sidecar de Python (modelo SCUNet). ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/noise-removal` **Procesamiento:** asíncrono (devuelve 202, consulta `/api/v1/jobs/{jobId}/progress` para conocer el estado vía SSE) **Paquete del modelo:** `upscale-enhance` (5-6 GB) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | tier | string | No | `"balanced"` | Nivel de calidad: `quick`, `balanced`, `quality`, `maximum` | | strength | number | No | `50` | Intensidad del reductor de ruido (0-100) | | detailPreservation | number | No | `50` | Cuánto detalle conservar (0-100). Valores más altos mantienen más textura | | colorNoise | number | No | `30` | Intensidad de la reducción del ruido de color (0-100) | | format | string | No | `"original"` | Formato de salida: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | No | `90` | Calidad de codificación de salida (1-100) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/noise-removal \ -F "file=@noisy-photo.jpg" \ -F 'settings={"tier":"quality","strength":60,"detailPreservation":70,"colorNoise":40}' ``` ## Respuesta {#response} ### Respuesta inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progreso (SSE en `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Denoising...","percent":65} ``` ### Resultado final (vía SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/noisy-photo_denoised.jpg", "originalSize": 500000, "processedSize": 380000 } } ``` ## Notas {#notes} * Requiere que el paquete del modelo `upscale-enhance` esté instalado (5-6 GB). * Los niveles de calidad intercambian velocidad por calidad: `quick` es el más rápido con reducción de ruido básica, mientras que `maximum` usa el enfoque multipasada más exhaustivo. * El parámetro `detailPreservation` es fundamental para sujetos con textura (tejido, cabello, follaje). Los valores más altos evitan que el reductor de ruido suavice el detalle fino. * Cuando `format` se establece en `"original"`, el formato de salida coincide con el formato del archivo de entrada. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. --- --- url: https://docs.snapotter.com/es/tools/audio/silence-removal.md description: Elimina las secciones silenciosas de un archivo de audio. --- # Eliminación de silencios {#silence-removal} Detecta y elimina las secciones silenciosas de un archivo de audio según un umbral y una duración mínima configurables. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/silence-removal` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | thresholdDb | number | No | `-50` | Umbral de silencio en dB (-80 a -20). El audio por debajo de este nivel se considera silencio. | | minSilenceS | number | No | `0.5` | Duración mínima del silencio en segundos que se debe eliminar (0.1 a 5) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/silence-removal \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"thresholdDb": -45, "minSilenceS": 1}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 3200000 } ``` ## Notas {#notes} * Un umbral más alto (menos negativo) es más agresivo y elimina también los pasajes más silenciosos, además del silencio real. * Aumenta `minSilenceS` para eliminar solo las pausas más largas y conservar las breves pausas naturales. * Útil para limpiar grabaciones de podcasts, conferencias y notas de voz. * La salida suele mantener el contenedor de entrada. La entrada AAC se escribe como M4A, y las entradas de solo decodificación no compatibles recurren a MP3. --- --- url: https://docs.snapotter.com/es/tools/image/remove-background.md description: >- Eliminación de fondo con IA con efectos opcionales (desenfoque, sombra, degradado, fondo personalizado). --- # Eliminar fondo {#remove-background} Eliminación de fondo con IA con efectos opcionales (desenfoque, sombra, degradado, fondo personalizado). ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/remove-background` **Procesamiento:** asíncrono (devuelve 202, consulta `/api/v1/jobs/{jobId}/progress` para conocer el estado vía SSE) **Paquete del modelo:** `background-removal` (4-5 GB) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | model | string | No | - | Variante del modelo de IA que se usará | | backgroundType | string | No | `"transparent"` | Uno de: `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | No | - | Color hexadecimal para fondo sólido | | gradientColor1 | string | No | - | Primer color del degradado | | gradientColor2 | string | No | - | Segundo color del degradado | | gradientAngle | number | No | - | Ángulo del degradado en grados | | blurEnabled | boolean | No | - | Habilitar el efecto de desenfoque de fondo | | blurIntensity | number | No | - | Intensidad del desenfoque (0-100) | | shadowEnabled | boolean | No | - | Habilitar la sombra paralela sobre el sujeto | | shadowOpacity | number | No | - | Opacidad de la sombra (0-100) | | outputFormat | string | No | - | Formato de salida: `png`, `webp` o `avif` | | edgeRefine | integer | No | - | Nivel de refinamiento de bordes (0-3) | | decontaminate | boolean | No | - | Eliminar el sangrado de color de los bordes | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType":"transparent","edgeRefine":2,"outputFormat":"png"}' ``` ## Respuesta {#response} ### Respuesta inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progreso (SSE en `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing background...","percent":50} ``` ### Resultado final (vía SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_mask.png", "maskUrl": "/api/v1/download/{jobId}/photo_mask.png", "originalUrl": "/api/v1/download/{jobId}/photo_original.png", "originalSize": 245000, "processedSize": 180000, "filename": "photo.jpg", "model": "rembg" } } ``` ## Endpoint de efectos (Fase 2) {#effects-endpoint-phase-2} `POST /api/v1/tools/image/remove-background/effects` Vuelve a aplicar los efectos de fondo sin volver a ejecutar el modelo de IA. Usa la máscara y el original en caché de la Fase 1. ### Parámetros {#parameters-1} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | settings | JSON | Sí | - | JSON con los ajustes de los efectos (ver más abajo) | | backgroundImage | file | No | - | Imagen de fondo personalizada (cuando backgroundType es `image`) | #### Campos del JSON de ajustes {#settings-json-fields} | Campo | Tipo | Obligatorio | Descripción | |-------|------|----------|-------------| | jobId | string | Sí | ID de trabajo de la Fase 1 | | filename | string | Sí | Nombre de archivo original de la Fase 1 | | backgroundType | string | No | `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | No | Color hexadecimal para fondo sólido | | gradientColor1 | string | No | Primer color del degradado | | gradientColor2 | string | No | Segundo color del degradado | | gradientAngle | number | No | Ángulo del degradado en grados | | blurEnabled | boolean | No | Habilitar el desenfoque de fondo | | blurIntensity | number | No | Intensidad del desenfoque (0-100) | | shadowEnabled | boolean | No | Habilitar la sombra paralela | | shadowOpacity | number | No | Opacidad de la sombra (0-100) | | outputFormat | string | No | `png`, `webp` o `avif` | ### Ejemplo de solicitud {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background/effects \ -F 'settings={"jobId":"a1b2c3d4-...","filename":"photo.jpg","backgroundType":"color","backgroundColor":"#FF5500","outputFormat":"png"}' ``` ### Respuesta (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_nobg.png", "processedSize": 195000 } ``` ## Notas {#notes} * Requiere que el paquete del modelo `background-removal` esté instalado (4-5 GB). * La Fase 1 almacena en caché la máscara transparente y la imagen original para que la Fase 2 (efectos) pueda volver a aplicar distintos fondos al instante sin volver a ejecutar el modelo de IA. * Admite los formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR y HDR mediante decodificación automática. * La rotación EXIF se corrige automáticamente antes del procesamiento. --- --- url: https://docs.snapotter.com/es/tools/image/strip-metadata.md description: >- Elimina metadatos EXIF, GPS, ICC y XMP de las imágenes para mayor privacidad y menor tamaño de archivo. --- # Eliminar metadatos de imagen {#remove-metadata} Elimina los metadatos EXIF, GPS, perfiles de color ICC y XMP de las imágenes. Útil para la privacidad (eliminar coordenadas GPS, información de la cámara) y para reducir el tamaño del archivo. ## API Endpoints {#api-endpoints} ### Eliminar metadatos {#strip-metadata} `POST /api/v1/tools/image/strip-metadata` Procesa la imagen y devuelve una versión limpia con los metadatos seleccionados eliminados. ### Inspeccionar metadatos {#inspect-metadata} `POST /api/v1/tools/image/strip-metadata/inspect` Devuelve los metadatos analizados como JSON sin modificar la imagen. Útil para previsualizar qué metadatos existen antes de eliminarlos. ## Parámetros (Eliminar) {#parameters-strip} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | stripExif | boolean | No | `false` | Elimina los datos EXIF (ajustes de la cámara, fechas, etc.) | | stripGps | boolean | No | `false` | Elimina solo los datos de GPS/ubicación | | stripIcc | boolean | No | `false` | Elimina el perfil de color ICC | | stripXmp | boolean | No | `false` | Elimina los metadatos XMP (Adobe, IPTC) | | stripAll | boolean | No | `true` | Elimina todos los metadatos de una vez | Cuando `stripAll` es `true`, anula los indicadores individuales y elimina todo. ## Ejemplo de solicitud {#example-request} Eliminar todos los metadatos: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": true}' ``` Eliminar solo los datos de GPS (conservar la información de la cámara y el perfil de color): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": false, "stripGps": true}' ``` Inspeccionar los metadatos sin modificar: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Ejemplo de respuesta (Eliminar) {#example-response-strip} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Ejemplo de respuesta (Inspeccionar) {#example-response-inspect} ```json { "filename": "photo.jpg", "fileSize": 2450000, "exif": { "Make": "Canon", "Model": "EOS R5", "DateTimeOriginal": "2024:03:15 14:30:00", "ExposureTime": "1/250", "FNumber": 2.8, "ISO": 400 }, "gps": { "GPSLatitudeRef": "N", "GPSLatitude": [37, 46, 30], "_latitude": 37.775, "_longitude": -122.4183 }, "icc": { "Profile Size": "3144 bytes", "Color Space": "RGB", "Description": "sRGB IEC61966-2.1" }, "xmp": { "CreatorTool": "Adobe Photoshop 25.0" } } ``` ## Notas {#notes} * La imagen se vuelve a codificar en su formato original después de la eliminación. JPEG usa mozjpeg con calidad 90, PNG usa nivel de compresión 9, WebP usa calidad 85. * Eliminar los perfiles ICC puede provocar cambios sutiles de color si la imagen estaba etiquetada con un perfil no sRGB. Usa `stripIcc: false` si la precisión del color es importante. * El endpoint de inspección analiza las coordenadas GPS en valores decimales de latitud/longitud (con prefijo de guion bajo) para mayor comodidad. * Formatos de entrada admitidos: JPEG, PNG, WebP, AVIF, TIFF, GIF. --- --- url: https://docs.snapotter.com/es/tools/pdf/remove-pages.md description: Elimina páginas específicas de un PDF. --- # Eliminar páginas {#remove-pages} Elimina páginas específicas de un PDF, manteniendo intactas todas las páginas restantes. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/remove-pages` Acepta datos de formulario multipart con un archivo PDF y un campo JSON `settings`. ## Parameters {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | pages | string | Sí | - | Rango de páginas a eliminar en sintaxis qpdf, p. ej. `"3,5-7"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/remove-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"pages": "3,5-7"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 1800000 } ``` ## Notes {#notes} * No puedes eliminar todas las páginas de un documento; debe quedar al menos una página. * Los rangos de páginas usan la sintaxis de qpdf: `3` para una sola página, `5-7` para un rango y comas para combinar (p. ej. `1,3,5-7`). --- --- url: https://docs.snapotter.com/ar/tools/video/embed-subtitles.md description: دمج مسار ترجمة داخل حاوية الفيديو. --- # Embed Subtitles {#embed-subtitles} دمج ملف ترجمة داخل حاوية الفيديو كمسار ترجمة مرن يمكن للمشاهدين تشغيله أو إيقافه. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو وملف ترجمة، بالإضافة إلى حقل JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | رمز لغة ISO 639-2/B (3 أحرف صغيرة، مثل `"eng"` أو `"fra"` أو `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * ارفع ملفين: يجب أن يكون الأول فيديو، ويجب أن يكون الثاني ملف ترجمة (.srt أو .vtt أو .ass). * يمكن للمشاهد تبديل الترجمات المدمجة (المرنة) في مشغل الوسائط الخاص به. للحصول على ترجمات ظاهرة بشكل دائم، استخدم أداة Burn Subtitles بدلاً من ذلك. * يُخزَّن رمز اللغة كبيانات وصفية في الحاوية ويساعد مشغلات الوسائط على تصنيف مسار الترجمة. --- --- url: https://docs.snapotter.com/de/tools/video/embed-subtitles.md description: Eine Untertitelspur in den Videocontainer muxen. --- # Embed Subtitles {#embed-subtitles} Eine Untertiteldatei als weiche Untertitelspur in den Videocontainer muxen, die Betrachter ein- oder ausschalten können. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Nimmt Multipart-Formulardaten mit einer Videodatei und einer Untertiteldatei sowie einem JSON-Feld `settings` entgegen. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B-Sprachcode (3 Kleinbuchstaben, z. B. `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Laden Sie zwei Dateien hoch: Die erste muss ein Video sein, die zweite eine Untertiteldatei (.srt, .vtt oder .ass). * Eingebettete (weiche) Untertitel können vom Betrachter in seinem Media-Player umgeschaltet werden. Für dauerhaft sichtbare Untertitel verwenden Sie stattdessen das Tool Burn Subtitles. * Der Sprachcode wird als Metadaten im Container gespeichert und hilft Media-Playern, die Untertitelspur zu kennzeichnen. --- --- url: https://docs.snapotter.com/es/tools/video/embed-subtitles.md description: Multiplexa una pista de subtítulos en el contenedor del vídeo. --- # Embed Subtitles {#embed-subtitles} Multiplexa un archivo de subtítulos en el contenedor del vídeo como una pista de subtítulos blanda que el espectador puede activar o desactivar. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Acepta datos de formulario multipart con un archivo de vídeo y un archivo de subtítulos, además de un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | Código de idioma ISO 639-2/B (3 letras minúsculas, por ejemplo `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Sube dos archivos: el primero debe ser un vídeo y el segundo un archivo de subtítulos (.srt, .vtt o .ass). * Los subtítulos incrustados (blandos) pueden activarse y desactivarse por el espectador en su reproductor multimedia. Para subtítulos permanentemente visibles, usa la herramienta Burn Subtitles en su lugar. * El código de idioma se almacena como metadato en el contenedor y ayuda a los reproductores multimedia a etiquetar la pista de subtítulos. --- --- url: https://docs.snapotter.com/fr/tools/video/embed-subtitles.md description: Multiplexe une piste de sous-titres dans le conteneur vidéo. --- # Embed Subtitles {#embed-subtitles} Multiplexe un fichier de sous-titres dans le conteneur vidéo sous forme de piste de sous-titres souple que les spectateurs peuvent activer ou désactiver. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Accepte des données de formulaire multipart avec un fichier vidéo et un fichier de sous-titres, plus un champ JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | Code de langue ISO 639-2/B (3 lettres minuscules, par exemple `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Téléversez deux fichiers : le premier doit être une vidéo, le second doit être un fichier de sous-titres (.srt, .vtt ou .ass). * Les sous-titres intégrés (souples) peuvent être activés par le spectateur dans son lecteur multimédia. Pour des sous-titres visibles en permanence, utilisez plutôt l'outil Burn Subtitles. * Le code de langue est stocké sous forme de métadonnées dans le conteneur et aide les lecteurs multimédias à étiqueter la piste de sous-titres. --- --- url: https://docs.snapotter.com/hi/tools/video/embed-subtitles.md description: किसी सबटाइटल ट्रैक को वीडियो कंटेनर में mux करें। --- # Embed Subtitles {#embed-subtitles} एक सबटाइटल फ़ाइल को वीडियो कंटेनर में एक सॉफ़्ट सबटाइटल ट्रैक के रूप में mux करें, जिसे दर्शक चालू या बंद कर सकते हैं। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` एक वीडियो फ़ाइल और एक सबटाइटल फ़ाइल के साथ, तथा एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B भाषा कोड (3 छोटे अक्षर, जैसे `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * दो फ़ाइलें अपलोड करें: पहली एक वीडियो होनी चाहिए, दूसरी एक सबटाइटल फ़ाइल (.srt, .vtt, या .ass) होनी चाहिए। * एम्बेडेड (सॉफ़्ट) सबटाइटल को दर्शक अपने मीडिया प्लेयर में टॉगल कर सकते हैं। स्थायी रूप से दिखने वाले सबटाइटल के लिए, इसके बजाय Burn Subtitles टूल का उपयोग करें। * भाषा कोड कंटेनर में मेटाडेटा के रूप में संग्रहीत होता है और मीडिया प्लेयर को सबटाइटल ट्रैक लेबल करने में मदद करता है। --- --- url: https://docs.snapotter.com/id/tools/video/embed-subtitles.md description: Mux sebuah trek subtitle ke dalam kontainer video. --- # Embed Subtitles {#embed-subtitles} Mux sebuah file subtitle ke dalam kontainer video sebagai trek subtitle lunak yang dapat dinyalakan atau dimatikan oleh penonton. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Menerima multipart form data dengan file video dan file subtitle, ditambah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | Kode bahasa ISO 639-2/B (3 huruf kecil, mis. `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Unggah dua file: yang pertama harus berupa video, yang kedua harus berupa file subtitle (.srt, .vtt, atau .ass). * Subtitle tersemat (lunak) dapat dialihkan oleh penonton di pemutar media mereka. Untuk subtitle yang terlihat permanen, gunakan alat Burn Subtitles sebagai gantinya. * Kode bahasa disimpan sebagai metadata di dalam kontainer dan membantu pemutar media melabeli trek subtitle. --- --- url: https://docs.snapotter.com/it/tools/video/embed-subtitles.md description: Effettua il mux di una traccia di sottotitoli nel contenitore video. --- # Embed Subtitles {#embed-subtitles} Effettua il mux di un file di sottotitoli nel contenitore video come traccia di sottotitoli soft che gli spettatori possono attivare o disattivare. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Accetta dati form multipart con un file video e un file di sottotitoli, più un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | Codice lingua ISO 639-2/B (3 lettere minuscole, ad es. `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Carica due file: il primo deve essere un video, il secondo deve essere un file di sottotitoli (.srt, .vtt o .ass). * I sottotitoli incorporati (soft) possono essere attivati e disattivati dallo spettatore nel proprio lettore multimediale. Per sottotitoli sempre visibili, usa invece lo strumento Burn Subtitles. * Il codice lingua viene memorizzato come metadato nel contenitore e aiuta i lettori multimediali a etichettare la traccia dei sottotitoli. --- --- url: https://docs.snapotter.com/ja/tools/video/embed-subtitles.md description: 字幕トラックを動画コンテナに多重化します。 --- # Embed Subtitles {#embed-subtitles} 字幕ファイルを、視聴者がオン/オフを切り替えられるソフト字幕トラックとして動画コンテナに多重化します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` 動画ファイルと字幕ファイル、および JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B 言語コード(小文字3文字、例: `"eng"`、`"fra"`、`"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * ファイルを2つアップロードします。1つ目は動画、2つ目は字幕ファイル(.srt、.vtt、または .ass)である必要があります。 * 埋め込まれた(ソフト)字幕は、視聴者がメディアプレーヤーで切り替えられます。常時表示される字幕には、代わりに Burn Subtitles ツールを使用してください。 * 言語コードはコンテナ内にメタデータとして保存され、メディアプレーヤーが字幕トラックにラベルを付けるのに役立ちます。 --- --- url: https://docs.snapotter.com/ko/tools/video/embed-subtitles.md description: 자막 트랙을 비디오 컨테이너에 먹싱합니다. --- # Embed Subtitles {#embed-subtitles} 시청자가 켜고 끌 수 있는 소프트 자막 트랙으로 자막 파일을 비디오 컨테이너에 먹싱합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` 비디오 파일과 자막 파일, 그리고 JSON `settings` 필드가 담긴 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B 언어 코드(소문자 3자, 예: `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * 파일 두 개를 업로드하세요. 첫 번째는 비디오여야 하고 두 번째는 자막 파일(.srt, .vtt 또는 .ass)이어야 합니다. * 임베드된(소프트) 자막은 시청자가 미디어 플레이어에서 켜고 끌 수 있습니다. 항상 표시되는 자막을 원한다면 대신 Burn Subtitles 도구를 사용하세요. * 언어 코드는 컨테이너에 메타데이터로 저장되며 미디어 플레이어가 자막 트랙에 레이블을 붙이는 데 도움을 줍니다. --- --- url: https://docs.snapotter.com/nl/tools/video/embed-subtitles.md description: Een ondertitelspoor in de videocontainer muxen. --- # Embed Subtitles {#embed-subtitles} Mux een ondertitelbestand in de videocontainer als een soft ondertitelspoor dat kijkers kunnen in- of uitschakelen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Accepteert multipart form data met een videobestand en een ondertitelbestand, plus een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | language | string | Nee | `"eng"` | ISO 639-2/B-taalcode (3 kleine letters, bijv. `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Upload twee bestanden: het eerste moet een video zijn, het tweede moet een ondertitelbestand zijn (.srt, .vtt of .ass). * Ingebedde (soft) ondertitels kunnen door de kijker in hun mediaspeler worden in- en uitgeschakeld. Gebruik voor permanent zichtbare ondertitels in plaats daarvan de tool Burn Subtitles. * De taalcode wordt als metadata in de container opgeslagen en helpt mediaspelers het ondertitelspoor te labelen. --- --- url: https://docs.snapotter.com/pl/tools/video/embed-subtitles.md description: Dołączenie ścieżki napisów do kontenera wideo. --- # Embed Subtitles {#embed-subtitles} Dołącza plik napisów do kontenera wideo jako miękką ścieżkę napisów, którą widzowie mogą włączać i wyłączać. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Przyjmuje dane formularza multipart z plikiem wideo i plikiem napisów oraz polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | language | string | Nie | `"eng"` | Kod języka ISO 639-2/B (3 małe litery, np. `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Prześlij dwa pliki: pierwszy musi być wideo, drugi musi być plikiem napisów (.srt, .vtt lub .ass). * Osadzone (miękkie) napisy mogą być przełączane przez widza w jego odtwarzaczu multimediów. Aby uzyskać trwale widoczne napisy, użyj zamiast tego narzędzia Burn Subtitles. * Kod języka jest przechowywany jako metadane w kontenerze i pomaga odtwarzaczom multimediów oznaczyć ścieżkę napisów. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/embed-subtitles.md description: Multiplexa uma faixa de legenda no contêiner do vídeo. --- # Embed Subtitles {#embed-subtitles} Multiplexa um arquivo de legenda no contêiner do vídeo como uma faixa de legenda soft que os espectadores podem ativar ou desativar. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Aceita dados de formulário multipart com um arquivo de vídeo e um arquivo de legenda, além de um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | language | string | Não | `"eng"` | Código de idioma ISO 639-2/B (3 letras minúsculas, por exemplo `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Envie dois arquivos: o primeiro deve ser um vídeo, o segundo deve ser um arquivo de legenda (.srt, .vtt ou .ass). * As legendas embutidas (soft) podem ser ativadas e desativadas pelo espectador no seu reprodutor de mídia. Para legendas permanentemente visíveis, use a ferramenta Burn Subtitles. * O código de idioma é armazenado como metadado no contêiner e ajuda os reprodutores de mídia a rotular a faixa de legenda. --- --- url: https://docs.snapotter.com/ru/tools/video/embed-subtitles.md description: Мультиплексирование дорожки субтитров в контейнер видео. --- # Embed Subtitles {#embed-subtitles} Мультиплексирование файла субтитров в контейнер видео как программной дорожки субтитров, которую зрители могут включать или отключать. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Принимает multipart form data с файлом видео и файлом субтитров, а также полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | Код языка ISO 639-2/B (3 строчные буквы, например `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Загрузите два файла: первым должно быть видео, вторым - файл субтитров (.srt, .vtt или .ass). * Встроенные (программные) субтитры зритель может включать и выключать в своём медиаплеере. Для постоянно видимых субтитров используйте вместо этого инструмент Burn Subtitles. * Код языка сохраняется как метаданные в контейнере и помогает медиаплеерам подписывать дорожку субтитров. --- --- url: https://docs.snapotter.com/th/tools/video/embed-subtitles.md description: รวมแทร็กคำบรรยายเข้าไปในคอนเทนเนอร์วิดีโอ --- # Embed Subtitles {#embed-subtitles} รวมไฟล์คำบรรยายเข้าไปในคอนเทนเนอร์วิดีโอเป็นแทร็กคำบรรยายแบบ soft ที่ผู้ชมสามารถเปิดหรือปิดได้ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอและไฟล์คำบรรยาย รวมถึงฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | รหัสภาษา ISO 639-2/B (ตัวพิมพ์เล็ก 3 ตัว เช่น `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * อัปโหลดสองไฟล์: ไฟล์แรกต้องเป็นวิดีโอ ไฟล์ที่สองต้องเป็นไฟล์คำบรรยาย (.srt, .vtt หรือ .ass) * คำบรรยายแบบฝัง (soft) ผู้ชมสามารถเปิด/ปิดได้ในโปรแกรมเล่นสื่อของตน หากต้องการคำบรรยายที่มองเห็นอย่างถาวร ให้ใช้เครื่องมือ Burn Subtitles แทน * รหัสภาษาจะถูกจัดเก็บเป็นเมทาดาทาในคอนเทนเนอร์และช่วยให้โปรแกรมเล่นสื่อระบุป้ายกำกับแทร็กคำบรรยายได้ --- --- url: https://docs.snapotter.com/tr/tools/video/embed-subtitles.md description: Bir altyazı parçasını video konteynerine ekleyin. --- # Embed Subtitles {#embed-subtitles} Bir altyazı dosyasını, izleyicilerin açıp kapatabileceği yumuşak bir altyazı parçası olarak video konteynerine ekleyin. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Bir video dosyası ve bir altyazı dosyası ile birlikte bir JSON `settings` alanı içeren multipart form data kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B dil kodu (3 küçük harf, örneğin `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * İki dosya yükleyin: ilki bir video, ikincisi bir altyazı dosyası (.srt, .vtt veya .ass) olmalıdır. * Gömülü (yumuşak) altyazılar, izleyici tarafından medya oynatıcısında açılıp kapatılabilir. Kalıcı olarak görünür altyazılar için bunun yerine Burn Subtitles aracını kullanın. * Dil kodu konteynerde meta veri olarak saklanır ve medya oynatıcıların altyazı parçasını etiketlemesine yardımcı olur. --- --- url: https://docs.snapotter.com/uk/tools/video/embed-subtitles.md description: Додає доріжку субтитрів у відеоконтейнер. --- # Embed Subtitles {#embed-subtitles} Додає файл субтитрів у відеоконтейнер як програмну доріжку субтитрів, яку глядачі можуть вмикати чи вимикати. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Приймає дані форми multipart із відеофайлом і файлом субтитрів, а також полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | Код мови за ISO 639-2/B (3 малі літери, наприклад `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Завантажте два файли: перший має бути відео, другий має бути файлом субтитрів (.srt, .vtt або .ass). * Вбудовані (програмні) субтитри глядач може перемикати у своєму медіапрогравачі. Для постійно видимих субтитрів використовуйте натомість інструмент Burn Subtitles. * Код мови зберігається як метадані в контейнері й допомагає медіапрогравачам маркувати доріжку субтитрів. --- --- url: https://docs.snapotter.com/vi/tools/video/embed-subtitles.md description: Ghép một track phụ đề vào container video. --- # Embed Subtitles {#embed-subtitles} Ghép một file phụ đề vào container video dưới dạng track phụ đề mềm mà người xem có thể bật hoặc tắt. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` Nhận multipart form data gồm một file video và một file phụ đề, cùng với một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | Mã ngôn ngữ ISO 639-2/B (3 chữ cái thường, ví dụ `"eng"`, `"fra"`, `"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * Tải lên hai file: file đầu tiên phải là video, file thứ hai phải là file phụ đề (.srt, .vtt hoặc .ass). * Phụ đề nhúng (mềm) có thể được người xem bật/tắt trong trình phát media của họ. Để có phụ đề luôn hiển thị vĩnh viễn, hãy dùng công cụ Burn Subtitles. * Mã ngôn ngữ được lưu dưới dạng metadata trong container và giúp các trình phát media gắn nhãn track phụ đề. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/embed-subtitles.md description: 将字幕轨道复用(mux)进视频容器。 --- # Embed Subtitles {#embed-subtitles} 将字幕文件复用(mux)进视频容器,作为观看者可自行开启或关闭的软字幕轨道。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` 接受包含视频文件、字幕文件以及 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B 语言代码(3 个小写字母,例如 `"eng"`、`"fra"`、`"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * 上传两个文件:第一个必须是视频,第二个必须是字幕文件(.srt、.vtt 或 .ass)。 * 内嵌的(软)字幕可由观看者在其媒体播放器中切换。若需要永久可见的字幕,请改用 Burn Subtitles 工具。 * 语言代码以元数据形式存储在容器中,有助于媒体播放器为字幕轨道标注标签。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/embed-subtitles.md description: 將字幕軌混流到影片容器中。 --- # Embed Subtitles {#embed-subtitles} 將字幕檔案混流到影片容器中,作為觀看者可自行開啟或關閉的軟字幕軌。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/embed-subtitles` 接受包含一個影片檔案和一個字幕檔案,以及一個 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | language | string | No | `"eng"` | ISO 639-2/B 語言代碼(3 個小寫字母,例如 `"eng"`、`"fra"`、`"deu"`) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/embed-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@subtitles.srt" \ -F 'settings={"language": "fra"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 12520000 } ``` ## Notes {#notes} * 上傳兩個檔案:第一個必須是影片,第二個必須是字幕檔案(.srt、.vtt 或 .ass)。 * 觀看者可在其媒體播放器中切換嵌入的(軟)字幕。若需要永久可見的字幕,請改用 Burn Subtitles 工具。 * 語言代碼會以中繼資料的形式儲存在容器中,有助於媒體播放器標記字幕軌。 --- --- url: https://docs.snapotter.com/pt-BR/tools/image/beautify.md description: >- Transforme capturas de tela simples em imagens sofisticadas com fundos em gradiente, molduras de dispositivos, sombras e dimensionamento para redes sociais. --- # Embelezar Captura de Tela {#beautify-screenshot} Adicione fundos em gradiente, molduras de dispositivos, sombras, marcas d'água e dimensionamento para redes sociais a capturas de tela. Ideal para criar imagens sofisticadas para marketing de produto, redes sociais e documentação. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | backgroundType | string | Não | `"linear-gradient"` | Tipo de fundo: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | string | Não | `"#667eea"` | Cor de fundo sólida (usada quando `backgroundType` é `solid`) | | gradientStops | array | Não | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | Pontos de cor do gradiente (mín. 2). Cada ponto tem `color` (hex) e `position` (0-100). | | gradientAngle | number | Não | 135 | Ângulo do gradiente em graus (0 a 360) | | padding | number | Não | 64 | Espaçamento ao redor da imagem em pixels (0 a 256) | | borderRadius | number | Não | 12 | Raio dos cantos da captura de tela (0 a 64) | | shadowPreset | string | Não | `"subtle"` | Predefinição de sombra: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | number | Não | 20 | Raio de desfoque da sombra personalizada (0 a 100, usado quando `shadowPreset` é `custom`) | | shadowOffsetX | number | Não | 0 | Deslocamento horizontal da sombra personalizada (-50 a 50) | | shadowOffsetY | number | Não | 10 | Deslocamento vertical da sombra personalizada (-50 a 50) | | shadowColor | string | Não | `"#000000"` | Cor da sombra personalizada em hex | | shadowOpacity | number | Não | 30 | Opacidade da sombra personalizada (0 a 100) | | frame | string | Não | `"none"` | Moldura de dispositivo ou janela: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | string | Não | - | Texto de título exibido nas barras de título das molduras de janela | | socialPreset | string | Não | `"none"` | Redimensiona para dimensões de redes sociais: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | string | Não | - | Texto opcional de marca d'água sobreposto | | watermarkPosition | string | Não | `"bottom-right"` | Posição da marca d'água: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | number | Não | 50 | Opacidade da marca d'água (0 a 100) | | outputFormat | string | Não | `"png"` | Formato de saída: `png`, `jpeg`, `webp` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### Com Imagem de Fundo {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Observações {#notes} * Aceita dois campos de arquivo: `file` (obrigatório, a captura de tela principal) e `backgroundImage` (opcional, usado quando `backgroundType` é `image`). * Suporta os formatos de entrada HEIC, RAW, PSD e SVG (decodificados automaticamente). * As predefinições de sombra correspondem a valores específicos: * `subtle`: desfoque 20, offsetY 4, opacidade 20% * `medium`: desfoque 40, offsetY 10, opacidade 35% * `dramatic`: desfoque 80, offsetY 20, opacidade 50% * As predefinições de redes sociais redimensionam a saída final para caber nas dimensões alvo usando o modo `contain`: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * As molduras de dispositivo (`iphone`, `macbook`, `ipad`) aplicam uma borda física ao redor da imagem e ignoram a configuração `borderRadius`. * Quando a transparência é necessária (sombra, raio das bordas, molduras de dispositivo ou fundo transparente), a saída é forçada para PNG mesmo que `jpeg` esteja selecionado. * Imagens de fundo não são suportadas no modo pipeline/lote. --- --- url: https://docs.snapotter.com/es/tools/image/beautify.md description: >- Convierte capturas de pantalla sencillas en imágenes pulidas con fondos degradados, marcos de dispositivo, sombras y tamaños para redes sociales. --- # Embellecer captura {#beautify-screenshot} Añade fondos degradados, marcos de dispositivo, sombras, marcas de agua y tamaños para redes sociales a las capturas de pantalla. Ideal para crear imágenes pulidas para marketing de productos, redes sociales y documentación. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | backgroundType | string | No | `"linear-gradient"` | Tipo de fondo: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | string | No | `"#667eea"` | Color de fondo sólido (usado cuando `backgroundType` es `solid`) | | gradientStops | array | No | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | Paradas de color del degradado (mín. 2). Cada parada tiene `color` (hex) y `position` (0-100). | | gradientAngle | number | No | 135 | Ángulo del degradado en grados (0 a 360) | | padding | number | No | 64 | Relleno alrededor de la imagen en píxeles (0 a 256) | | borderRadius | number | No | 12 | Radio de las esquinas de la captura (0 a 64) | | shadowPreset | string | No | `"subtle"` | Ajuste preestablecido de sombra: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | number | No | 20 | Radio de desenfoque de sombra personalizado (0 a 100, usado cuando `shadowPreset` es `custom`) | | shadowOffsetX | number | No | 0 | Desplazamiento horizontal de sombra personalizado (-50 a 50) | | shadowOffsetY | number | No | 10 | Desplazamiento vertical de sombra personalizado (-50 a 50) | | shadowColor | string | No | `"#000000"` | Color de sombra personalizado en hex | | shadowOpacity | number | No | 30 | Opacidad de sombra personalizada (0 a 100) | | frame | string | No | `"none"` | Marco de dispositivo o ventana: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | string | No | - | Texto del título mostrado en las barras de título de los marcos de ventana | | socialPreset | string | No | `"none"` | Redimensiona a dimensiones de redes sociales: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | string | No | - | Texto de marca de agua opcional superpuesto | | watermarkPosition | string | No | `"bottom-right"` | Posición de la marca de agua: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | number | No | 50 | Opacidad de la marca de agua (0 a 100) | | outputFormat | string | No | `"png"` | Formato de salida: `png`, `jpeg`, `webp` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### With Background Image {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Notes {#notes} * Acepta dos campos de archivo: `file` (obligatorio, la captura de pantalla principal) y `backgroundImage` (opcional, usado cuando `backgroundType` es `image`). * Admite los formatos de entrada HEIC, RAW, PSD y SVG (se decodifican automáticamente). * Los ajustes preestablecidos de sombra se corresponden con valores específicos: * `subtle`: desenfoque 20, offsetY 4, opacidad 20% * `medium`: desenfoque 40, offsetY 10, opacidad 35% * `dramatic`: desenfoque 80, offsetY 20, opacidad 50% * Los ajustes preestablecidos para redes sociales redimensionan la salida final para adaptarla a las dimensiones de destino usando el modo `contain`: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * Los marcos de dispositivo (`iphone`, `macbook`, `ipad`) aplican un bisel de hardware alrededor de la imagen y omiten el ajuste `borderRadius`. * Cuando se requiere transparencia (sombra, radio de borde, marcos de dispositivo o fondo transparente), la salida se fuerza a PNG aunque se haya seleccionado `jpeg`. * Los fondos de imagen no se admiten en modo pipeline/lote. --- --- url: https://docs.snapotter.com/fr/tools/image/beautify.md description: >- Transforme de simples captures d'écran en images soignées avec arrière-plans en dégradé, cadres d'appareils, ombres et formats pour réseaux sociaux. --- # Embellir une capture d'écran {#beautify-screenshot} Ajoute des arrière-plans en dégradé, des cadres d'appareils, des ombres, des filigranes et des formats pour réseaux sociaux à vos captures d'écran. Idéal pour créer des images soignées destinées au marketing produit, aux réseaux sociaux et à la documentation. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | backgroundType | chaîne | Non | `"linear-gradient"` | Type d'arrière-plan : `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | chaîne | Non | `"#667eea"` | Couleur d'arrière-plan unie (utilisée lorsque `backgroundType` vaut `solid`) | | gradientStops | tableau | Non | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | Points d'arrêt du dégradé (min 2). Chaque point a un `color` (hex) et une `position` (0 à 100). | | gradientAngle | nombre | Non | 135 | Angle du dégradé en degrés (0 à 360) | | padding | nombre | Non | 64 | Marge autour de l'image en pixels (0 à 256) | | borderRadius | nombre | Non | 12 | Rayon des coins de la capture (0 à 64) | | shadowPreset | chaîne | Non | `"subtle"` | Préréglage d'ombre : `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | nombre | Non | 20 | Rayon de flou d'ombre personnalisé (0 à 100, utilisé lorsque `shadowPreset` vaut `custom`) | | shadowOffsetX | nombre | Non | 0 | Décalage horizontal d'ombre personnalisé (-50 à 50) | | shadowOffsetY | nombre | Non | 10 | Décalage vertical d'ombre personnalisé (-50 à 50) | | shadowColor | chaîne | Non | `"#000000"` | Couleur d'ombre personnalisée en hex | | shadowOpacity | nombre | Non | 30 | Opacité d'ombre personnalisée (0 à 100) | | frame | chaîne | Non | `"none"` | Cadre d'appareil ou de fenêtre : `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | chaîne | Non | - | Texte de titre affiché dans les barres de titre des fenêtres | | socialPreset | chaîne | Non | `"none"` | Redimensionne aux dimensions des réseaux sociaux : `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | chaîne | Non | - | Texte de filigrane facultatif à superposer | | watermarkPosition | chaîne | Non | `"bottom-right"` | Position du filigrane : `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | nombre | Non | 50 | Opacité du filigrane (0 à 100) | | outputFormat | chaîne | Non | `"png"` | Format de sortie : `png`, `jpeg`, `webp` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### Avec image d'arrière-plan {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Remarques {#notes} * Accepte deux champs de fichier : `file` (requis, la capture d'écran principale) et `backgroundImage` (facultatif, utilisé lorsque `backgroundType` vaut `image`). * Prend en charge les formats d'entrée HEIC, RAW, PSD et SVG (décodés automatiquement). * Les préréglages d'ombre correspondent à des valeurs précises : * `subtle` : flou 20, offsetY 4, opacité 20 % * `medium` : flou 40, offsetY 10, opacité 35 % * `dramatic` : flou 80, offsetY 20, opacité 50 % * Les préréglages pour réseaux sociaux redimensionnent la sortie finale aux dimensions cibles en mode `contain` : * `twitter` : 1600x900 * `linkedin` : 1200x627 * `instagram-square` : 1080x1080 * `instagram-story` : 1080x1920 * `facebook` : 1200x630 * `producthunt` : 1270x760 * Les cadres d'appareils (`iphone`, `macbook`, `ipad`) appliquent une bordure matérielle autour de l'image et ignorent le réglage `borderRadius`. * Lorsque la transparence est requise (ombre, rayon des coins, cadres d'appareils ou arrière-plan transparent), la sortie est forcée en PNG même si `jpeg` est sélectionné. * Les images d'arrière-plan ne sont pas prises en charge en mode pipeline/batch. --- --- url: https://docs.snapotter.com/tr/tools/video/aspect-pad.md description: Hedef bir en boy oranına sığdırmak için düz renkli çubuklar ekleyin. --- # En Boy Dolgusu {#aspect-pad} Bir videoyu kırpmadan hedef bir en boy oranına sığdırmak için düz renkli letterbox veya pillarbox çubukları ekleyin. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/video/aspect-pad` Bir video dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | target | string | Hayır | `"9:16"` | Hedef en boy oranı: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | | color | string | Hayır | `"#000000"` | Dolgu çubukları için onaltılık renk (örn. siyah için `"#000000"`) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/aspect-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"target": "1:1", "color": "#ffffff"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13200000 } ``` ## Notlar {#notes} * Video zaten hedef en boy oranıyla eşleşiyorsa, dosya değiştirilmeden döndürülür. * Dikey/portre sosyal medya biçimleri (TikTok, Reels, Shorts) için `9:16` kullanın. * Düz renk yerine bulanık dolgu için Bulanık Dolgu aracını kullanın. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/find-duplicates.md description: Detecte imagens duplicadas e quase duplicadas usando hashing perceptual. --- # Encontrar Duplicatas {#find-duplicates} Envie várias imagens para detectar duplicatas e quase duplicatas usando hashing perceptual (dHash). Agrupa imagens semelhantes, identifica a versão de melhor qualidade em cada grupo e calcula a economia potencial de espaço. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` Aceita dados de formulário multipart com vários arquivos de imagem e um campo JSON `settings` opcional. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | threshold | number | Não | `8` | Distância de Hamming máxima para considerar imagens como duplicatas (0 a 20). Menor = correspondência mais rigorosa | ### Campos de Arquivo {#file-fields} Envie pelo menos 2 arquivos de imagem na requisição multipart (todos usando o nome de campo `file` ou qualquer nome de campo para as partes de arquivo). ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Exemplo de Resposta {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Campos da Resposta {#response-fields} | Campo | Tipo | Descrição | |-------|------|-------------| | totalImages | number | Número de imagens analisadas com sucesso | | duplicateGroups | array | Grupos de imagens duplicadas | | uniqueImages | number | Número de imagens que não fazem parte de nenhum grupo de duplicatas | | spaceSaveable | number | Total de bytes que poderiam ser economizados removendo as duplicatas que não são as melhores | | skippedFiles | array | Arquivos que não puderam ser processados (com nome do arquivo e motivo) | ### Objeto de Grupo de Duplicatas {#duplicate-group-object} | Campo | Tipo | Descrição | |-------|------|-------------| | groupId | number | Identificador do grupo | | files | array | Imagens neste grupo de duplicatas | ### Objeto de Arquivo (dentro de um grupo) {#file-object-within-a-group} | Campo | Tipo | Descrição | |-------|------|-------------| | filename | string | Nome original do arquivo | | similarity | number | Percentual de similaridade em relação à imagem de referência (a primeira do grupo) | | width | number | Largura da imagem em pixels | | height | number | Altura da imagem em pixels | | fileSize | number | Tamanho do arquivo em bytes | | format | string | Formato da imagem | | isBest | boolean | Se esta é a versão de maior qualidade (mais pixels, arquivo maior) | | thumbnail | string ou null | Miniatura JPEG em base64 (200px de largura) para pré-visualização | ## Observações {#notes} * Usa um dHash de 128 bits (linha de 64 bits + coluna de 64 bits) para detecção de similaridade perceptual. Isso captura duplicatas mesmo após redimensionamentos, recompressões e pequenas edições. * O limite representa a distância de Hamming máxima entre os hashes. O padrão de 8 captura quase duplicatas evitando falsos positivos. Use 0 para apenas idênticas em pixels, ou 15-20 para correspondência bem flexível. * A imagem "melhor" em cada grupo é aquela com mais pixels (largura x altura), com o tamanho do arquivo como critério de desempate. * São necessárias pelo menos 2 imagens. Arquivos que falham na validação ou na decodificação são reportados em `skippedFiles` em vez de fazer toda a requisição falhar. * As miniaturas são pré-visualizações JPEG de 200px de largura codificadas como data URIs. * Todos os formatos comuns são suportados (HEIC, RAW, PSD, SVG decodificados automaticamente). --- --- url: https://docs.snapotter.com/es/tools/image/sharpening.md description: >- Enfoca imágenes mediante métodos adaptativos, de máscara de enfoque o de paso alto, con reducción de ruido opcional. --- # Enfocar imagen {#sharpening} Herramienta de enfoque avanzada con tres métodos: adaptativo (inteligente y sensible a los bordes), máscara de enfoque (radio/cantidad clásicos) y paso alto (énfasis en la textura). Incluye reducción de ruido integrada para evitar artefactos de enfoque. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/sharpening` Acepta datos de formulario multipart con un archivo de imagen y un campo `settings` en JSON. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | method | string | No | `"adaptive"` | Algoritmo de enfoque: `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | No | `1.0` | Adaptativo: sigma gaussiano (0.5 a 10) | | m1 | number | No | `1.0` | Adaptativo: enfoque de áreas planas (0 a 10) | | m2 | number | No | `3.0` | Adaptativo: enfoque de áreas irregulares (0 a 20) | | x1 | number | No | `2.0` | Adaptativo: umbral plano/irregular (0 a 10) | | y2 | number | No | `12` | Adaptativo: enfoque máximo de áreas planas (0 a 50) | | y3 | number | No | `20` | Adaptativo: enfoque máximo de áreas irregulares (0 a 50) | | amount | number | No | `100` | Máscara de enfoque: cantidad de enfoque (0 a 1000) | | radius | number | No | `1.0` | Máscara de enfoque: radio de desenfoque en píxeles (0.1 a 5) | | threshold | number | No | `0` | Máscara de enfoque: diferencia mínima de brillo para enfocar (0 a 255) | | strength | number | No | `50` | Paso alto: intensidad del filtro (0 a 100) | | kernelSize | number | No | `3` | Paso alto: tamaño del kernel de convolución (3 o 5) | | denoise | string | No | `"off"` | Reducción de ruido previa al enfoque: `off`, `light`, `medium`, `strong` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Máscara de enfoque con umbral para proteger las áreas suaves: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Notas {#notes} * Solo se usan los parámetros pertinentes al método elegido. Por ejemplo, `amount`, `radius` y `threshold` se ignoran cuando `method` es `adaptive`. * El método adaptativo usa el enfoque adaptativo integrado de Sharp con un comportamiento configurable para las regiones planas/irregulares. * La opción `denoise` aplica reducción de ruido antes del enfoque para evitar la amplificación del ruido/grano. * El enfoque de paso alto extrae el detalle fino restando una versión desenfocada del original y luego combinándola de nuevo. * El formato de salida coincide con el formato de entrada. Las entradas HEIC, RAW, PSD y SVG se decodifican automáticamente antes del procesamiento. --- --- url: https://docs.snapotter.com/vi/api/image-engine.md description: >- Tài liệu tham khảo các thao tác của engine hình ảnh. Tất cả thao tác xử lý ảnh dựa trên Sharp và tham số của chúng. --- # Engine hình ảnh {#image-engine} Gói `@snapotter/image-engine` xử lý mọi thao tác ảnh không dùng AI. Nó bao bọc [Sharp](https://sharp.pixelplumbing.com/) và chạy hoàn toàn trong tiến trình mà không có phụ thuộc bên ngoài. ## Thao tác {#operations} ### resize {#resize} Thay đổi tỷ lệ ảnh theo kích thước cụ thể hoặc theo phần trăm. | Tham số | Kiểu | Mô tả | |---|---|---| | `width` | number | Chiều rộng mục tiêu tính bằng điểm ảnh | | `height` | number | Chiều cao mục tiêu tính bằng điểm ảnh | | `fit` | string | `cover`, `contain`, `fill`, `inside`, hoặc `outside` | | `withoutEnlargement` | boolean | Nếu true, sẽ không phóng to các ảnh nhỏ hơn | | `percentage` | number | Thay đổi tỷ lệ theo phần trăm thay vì kích thước tuyệt đối | Bạn có thể đặt `width`, `height`, hoặc cả hai. Nếu chỉ đặt một, giá trị còn lại được tính để giữ tỷ lệ khung hình. ### crop {#crop} Cắt một vùng hình chữ nhật ra khỏi ảnh. | Tham số | Kiểu | Mô tả | |---|---|---| | `left` | number | Độ lệch X từ cạnh trái | | `top` | number | Độ lệch Y từ cạnh trên | | `width` | number | Chiều rộng của vùng cắt | | `height` | number | Chiều cao của vùng cắt | | `unit` | string | `px` (mặc định) hoặc `percent` | ### rotate {#rotate} Xoay ảnh theo một góc cho trước. | Tham số | Kiểu | Mô tả | |---|---|---| | `angle` | number | Góc xoay tính bằng độ (0-360) | | `background` | string | Màu tô cho vùng lộ ra (mặc định: `#000000`). Chỉ áp dụng cho các góc không phải 90 độ. | ### flip {#flip} Lật ảnh theo chiều ngang, chiều dọc, hoặc cả hai. Ít nhất một phải là true. | Tham số | Kiểu | Mô tả | |---|---|---| | `horizontal` | boolean | Lật từ trái sang phải | | `vertical` | boolean | Lật từ trên xuống dưới | ### convert {#convert} Thay đổi định dạng ảnh. | Tham số | Kiểu | Mô tả | |---|---|---| | `format` | string | Định dạng mục tiêu: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `jxl`, `heic`, `heif`, `bmp`, `ico`, `jp2`, `qoi` | | `quality` | number | Chất lượng nén (1-100, áp dụng cho các định dạng có tổn hao) | Bảy định dạng đầu tiên (từ `jpg` đến `jxl`) được Sharp mã hóa trong tiến trình. Các định dạng còn lại dùng bộ mã hóa bên ngoài ở lớp API: `heic`/`heif` qua heif-enc, `bmp`/`ico` qua ImageMagick, `jp2` qua opj\_compress, và `qoi` qua một codec TypeScript nội tuyến. ### compress {#compress} Giảm kích thước tệp trong khi giữ nguyên định dạng. | Tham số | Kiểu | Mô tả | |---|---|---| | `quality` | number | Chất lượng mục tiêu (1-100) | | `targetSizeBytes` | number | Kích thước tệp mục tiêu tùy chọn tính bằng byte | | `format` | string | Ghi đè định dạng tùy chọn | ### strip-metadata {#strip-metadata} Xóa siêu dữ liệu EXIF, IPTC, XMP, và ICC khỏi ảnh. Khi không có tham số nào (hoặc `stripAll: true`), xóa tất cả. Truyền các cờ riêng lẻ để xóa có chọn lọc. | Tham số | Kiểu | Mô tả | |---|---|---| | `stripAll` | boolean | Xóa toàn bộ siêu dữ liệu (mặc định khi không đặt cờ nào) | | `stripExif` | boolean | Xóa dữ liệu EXIF (bao gồm GPS nếu `stripGps` không được đặt riêng) | | `stripGps` | boolean | Xóa dữ liệu vị trí GPS | | `stripIcc` | boolean | Xóa hồ sơ màu ICC | | `stripXmp` | boolean | Xóa siêu dữ liệu XMP | ### Điều chỉnh màu {#color-adjustments} Các thao tác này chỉnh sửa thuộc tính màu của ảnh. Mỗi thao tác nhận một giá trị số duy nhất. | Thao tác | Tham số | Khoảng | Mô tả | |---|---|---|---| | `brightness` | `value` | -100 đến 100 | Điều chỉnh độ sáng | | `contrast` | `value` | -100 đến 100 | Điều chỉnh độ tương phản | | `saturation` | `value` | -100 đến 100 | Điều chỉnh độ bão hòa màu | ### Bộ lọc màu {#color-filters} Các bộ lọc này áp dụng một biến đổi màu cố định. Chúng không nhận tham số. | Thao tác | Mô tả | |---|---| | `grayscale` | Chuyển sang thang xám | | `sepia` | Áp dụng tông màu sepia | | `invert` | Đảo ngược toàn bộ màu | ### Kênh màu {#color-channels} Điều chỉnh từng kênh màu RGB riêng lẻ. Giá trị là hệ số nhân trong đó 100 = không thay đổi. | Tham số | Kiểu | Mô tả | |---|---|---| | `red` | number | Hệ số nhân kênh đỏ (0 đến 200, 100 = không đổi) | | `green` | number | Hệ số nhân kênh xanh lá (0 đến 200, 100 = không đổi) | | `blue` | number | Hệ số nhân kênh xanh dương (0 đến 200, 100 = không đổi) | ### sharpen {#sharpen} Làm sắc nét đơn giản được điều khiển bởi một giá trị duy nhất. | Tham số | Kiểu | Mô tả | |---|---|---| | `value` | number | Cường độ làm sắc nét (0 đến 100). Được ánh xạ sang sigma Gaussian từ 0.5-10. | ### sharpen-advanced {#sharpen-advanced} Làm sắc nét nâng cao với ba phương pháp có thể chọn và một bước tiền xử lý giảm nhiễu tùy chọn. | Tham số | Kiểu | Mô tả | |---|---|---| | `method` | string | `adaptive`, `unsharp-mask`, hoặc `high-pass` | | `sigma` | number | Bán kính làm mờ Gaussian, 0.5-10 (thích ứng) | | `m1` | number | Làm sắc nét vùng phẳng, 0-10 (thích ứng) | | `m2` | number | Làm sắc nét vùng có kết cấu, 0-20 (thích ứng) | | `x1` | number | Ngưỡng phẳng/gồ ghề, 0-10 (thích ứng) | | `y2` | number | Làm sáng tối đa (kẹp quầng sáng), 0-50 (thích ứng) | | `y3` | number | Làm tối tối đa (kẹp quầng sáng), 0-50 (thích ứng) | | `amount` | number | Phần trăm cường độ, 0-500 (unsharp-mask) | | `radius` | number | Bán kính làm mờ, 0.1-5.0 (unsharp-mask) | | `threshold` | number | Độ sáng cạnh tối thiểu, 0-255 (unsharp-mask) | | `strength` | number | Cường độ hòa trộn, 0-100 (high-pass) | | `kernelSize` | number | `3` hoặc `5` cho kernel 3x3 / 5x5 (high-pass) | | `denoise` | string | Bước tiền xử lý giảm nhiễu: `off`, `light`, `medium`, hoặc `strong` | Các tham số là riêng theo phương pháp. Chỉ cung cấp những tham số liên quan đến phương pháp đã chọn. ### color-blindness {#color-blindness} Mô phỏng khiếm khuyết thị giác màu bằng ma trận tái kết hợp màu 3x3. | Tham số | Kiểu | Mô tả | |---|---|---| | `type` | string | Một trong: `protanopia`, `deuteranopia`, `tritanopia`, `protanomaly`, `deuteranomaly`, `tritanomaly`, `achromatopsia`, `blueConeMonochromacy` | ### edit-metadata {#edit-metadata} Ghi hoặc xóa từng trường siêu dữ liệu EXIF/IPTC riêng lẻ mà không xóa toàn bộ khối. | Tham số | Kiểu | Mô tả | |---|---|---| | `artist` | string | Thẻ EXIF Artist | | `copyright` | string | Thẻ EXIF Copyright | | `imageDescription` | string | Thẻ EXIF ImageDescription | | `software` | string | Thẻ EXIF Software | | `dateTime` | string | Thẻ EXIF DateTime | | `dateTimeOriginal` | string | Thẻ EXIF DateTimeOriginal | | `clearGps` | boolean | Xóa tất cả thẻ GPS | | `fieldsToRemove` | string\[] | Danh sách tên trường EXIF cần xóa | Tất cả tham số đều tùy chọn. Các trường được liệt kê trong `fieldsToRemove` bị xóa khỏi khối EXIF hiện có. Các trường được đặt qua tham số có tên sẽ được ghi (hoặc ghi đè). Các khóa nhị phân/không an toàn như MakerNote bị bỏ qua một cách âm thầm. ## Phát hiện định dạng {#format-detection} Engine tự động phát hiện định dạng đầu vào từ phần đầu tệp, không chỉ từ phần mở rộng tệp. Điều này có nghĩa là một tệp `.jpg` thực chất là PNG sẽ được xử lý đúng cách. Việc phát hiện dùng cách tiếp cận nhiều lớp: các byte magic trước, rồi phần mở rộng tệp làm dự phòng. SnapOtter hỗ trợ **hơn 55 định dạng đầu vào** và **13 định dạng đầu ra**, bao gồm 23 định dạng camera RAW từ hơn 20 hãng, các định dạng chuyên nghiệp (PSD, EPS, OpenEXR, HDR), các codec hiện đại (JPEG XL, AVIF, HEIC, QOI, JPEG 2000), và các định dạng khoa học/trò chơi (FITS, DDS). Việc giải mã được Sharp xử lý nguyên bản khi có thể, với dự phòng tự động sang ImageMagick, LibRaw, và các bộ giải mã CLI chuyên dụng. Xem trang [Định dạng được hỗ trợ](/vi/guide/supported-formats) để có danh sách đầy đủ. ## Trích xuất siêu dữ liệu {#metadata-extraction} Công cụ `info` trả về siêu dữ liệu ảnh. Xem [Thông tin ảnh](/vi/tools/image/info) để có tài liệu tham khảo đầy đủ về các trường. ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` --- --- url: https://docs.snapotter.com/de/guide/developer.md description: >- Lokales Entwicklungs-Setup, Befehle, Code-Konventionen und wie man ein neues Tool zu SnapOtter hinzufügt. --- # Entwicklerleitfaden {#developer-guide} Wie man eine lokale Entwicklungsumgebung einrichtet und Code zu SnapOtter beiträgt. ## Voraussetzungen {#prerequisites} * [Node.js](https://nodejs.org/) 22.22+ * [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`) * [Docker](https://www.docker.com/) (erforderlich für lokales Postgres + Redis, Container-Builds und AI-Features) * Git Python 3.11+ wird nur benötigt, wenn du am AI/ML-Sidecar arbeitest (Hintergrundentfernung, Hochskalierung, OCR). ## Setup {#setup} ```bash git clone https://github.com/snapotter-hq/snapotter.git cd snapotter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` Dies startet zwei Dev-Server: | Dienst | URL | Hinweise | |----------|--------------------------|------------------------------------| | Frontend | http://localhost:1351 | Vite-Dev-Server, proxyt /api | | Backend | http://localhost:13490 | Fastify-API (über Proxy erreichbar) | Öffne http://localhost:1351 in deinem Browser. Melde dich mit `admin` / `admin` an. Bei der ersten Anmeldung wirst du aufgefordert, das Passwort zu ändern. ## Projektstruktur {#project-structure} ``` apps/ api/ Fastify backend web/ Vite + React frontend docs/ VitePress documentation (this site) packages/ shared/ Constants, types, i18n strings image-engine/ Sharp-based image operations media-engine/ FFmpeg spawn + progress parsing doc-engine/ qpdf, LibreOffice, ghostscript wrappers ai/ Python sidecar bridge for ML models tests/ unit/ Vitest unit tests integration/ Vitest integration tests (full API) e2e/ Playwright end-to-end specs fixtures/ Small test images ``` ## Befehle {#commands} ```bash pnpm dev # start frontend + backend pnpm build # build all workspaces pnpm typecheck # TypeScript check across monorepo pnpm lint # Biome lint + format check pnpm lint:fix # auto-fix lint + format pnpm test # unit + integration tests pnpm test:unit # unit tests only pnpm test:integration # integration tests only pnpm test:e2e # Playwright e2e tests pnpm test:coverage # tests with coverage report ``` ## Code-Konventionen {#code-conventions} * Doppelte Anführungszeichen, Semikolons, Einrückung mit 2 Leerzeichen (durch Biome erzwungen) * ES-Module in allen Workspaces * [Conventional Commits](https://www.conventionalcommits.org/) für semantic-release * Zod für alle API-Eingabevalidierungen * Keine Änderungen an Biome-, TypeScript- oder Editor-Konfigurationsdateien. Behebe den Code, nicht den Linter. ## Datenbank {#database} PostgreSQL 17 über Drizzle ORM (pg-core). Die lokale Entwicklung erfordert ein laufendes Postgres und Redis - starte sie mit: ```bash docker compose -f docker-compose.dev.yml up -d ``` Dies stellt dir Postgres auf Port 5432 und Redis auf Port 6379 bereit. Generiere und wende dann die Migrationen an: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Das Schema ist in `apps/api/src/db/schema.ts` definiert. Tabellen: users, sessions, settings, jobs, apiKeys, pipelines, teams, userFiles, roles, auditLog. ## Ein neues Tool hinzufügen {#adding-a-new-tool} Jedes Tool folgt demselben Muster. Hier ein minimales Beispiel. ### 1. Backend-Route {#\_1-backend-route} Erstelle `apps/api/src/routes/tools/my-tool.ts`: ```ts import { z } from "zod"; import type { FastifyInstance } from "fastify"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ intensity: z.number().min(0).max(100).default(50), }); export function registerMyTool(app: FastifyInstance) { createToolRoute(app, { toolId: "my-tool", settingsSchema, async process(inputBuffer, settings, filename) { // Use sharp or other libraries to process the image const sharp = (await import("sharp")).default; const result = await sharp(inputBuffer) // ... your processing logic .toBuffer(); return { buffer: result, filename: filename.replace(/\.[^.]+$/, ".png"), contentType: "image/png", }; }, }); } ``` Registriere es dann in `apps/api/src/routes/tools/index.ts`. ### 2. Frontend-Einstellungskomponente {#\_2-frontend-settings-component} Erstelle `apps/web/src/components/tools/my-tool-settings.tsx`: ```tsx import { useState } from "react"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; export function MyToolSettings() { const { files } = useFileStore(); const { processFiles, processing, error, downloadUrl } = useToolProcessor("my-tool"); const [intensity, setIntensity] = useState(50); const handleProcess = () => { processFiles(files, { intensity }); }; return (
{/* your controls here */}
); } ``` Registriere es dann in der Frontend-Tool-Registry unter `apps/web/src/lib/tool-registry.tsx`: ```tsx // Add the lazy import const MyToolSettings = lazy(() => import("@/components/tools/my-tool-settings").then((m) => ({ default: m.MyToolSettings, })), ); // Add to the toolRegistry Map ["my-tool", { displayMode: "before-after", Settings: MyToolSettings }], ``` Anzeigemodi: `"side-by-side"`, `"before-after"`, `"live-preview"`, `"no-comparison"`, `"interactive-crop"`, `"interactive-eraser"`, `"no-dropzone"`. ### 3. i18n-Eintrag {#\_3-i18n-entry} Füge zu `packages/shared/src/i18n/en.ts` hinzu: ```ts "my-tool": { name: "My Tool", description: "Short description of what this tool does", }, ``` ### 4. Tests {#\_4-tests} Füge deinem Aktions-Button ein `data-testid`-Attribut hinzu (wie oben gezeigt), damit e2e-Tests ihn zuverlässig ansteuern können. ## Docker-Builds {#docker-builds} Baue das vollständige Produktions-Image lokal: ```bash docker build -f docker/Dockerfile -t snapotter:latest . ``` Verwende BuildKit-Cache-Mounts für schnellere Rebuilds: ```bash DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest . ``` ## Release-Versionsdomänen {#release-version-domains} SnapOtter verfügt absichtlich über drei Versionsdomänen. Kopieren Sie während einer Veröffentlichung nicht eine Domäne in eine andere: * Die Anwendungsfreigabeversion deckt das Root-Manifest, alle privaten Arbeitsbereichspakete und `APP_VERSION` ab. Semantic-release stellt diesen Wert bereit und `pnpm version:sync ` aktualisiert jeden Arbeitsbereich vor einer Anwendungsfreigabe. * OpenAPI `info.version` ist der stabile öffentliche API-Großvertrag. Alle lokalisierten Spezifikationen bleiben für kompatible Anwendungsversionen auf `.0.0` und ändern sich nur, wenn der API-Vertrag auf eine neue Hauptversion umgestellt wird. * `docker/feature-manifest.json` behält `imageVersion: 2.0.0` als unveränderliche Legacy-Feature-Bundle-Speicherepoche bei. Bei diesen v2-Archivpfaden handelt es sich nicht um Anwendungspaketversionen. Accurate OCR verwendet das Laufzeitformat v3 und zeichnet die Herkunft der Anwendungsversion separat auf. `tests/unit/infra/release-version-policy.test.ts` erzwingt diese Grenzen. Eine neue Versionsdomäne oder Migration muss diesen Vertrag und das relevante Artefaktmigrationsdesign zusammen aktualisieren. Die unabhängigen API- und Legacy-Bundle-Werte befinden sich in `config/release-version-policy.json`; Die Synchronisierung der Anwendungsversion darf diese Richtliniendatei niemals implizit neu schreiben. ## Umgebungsvariablen {#environment-variables} Die vollständige Liste findest du im [Konfigurationsleitfaden](/de/guide/configuration). Wichtige für die Entwicklung: | Variable | Standard | Beschreibung | |-----------------------------|-----------|------------------------------------------------| | `AUTH_ENABLED` | `true` | Authentifizierung aktivieren/deaktivieren | | `DEFAULT_USERNAME` | `admin` | Standard-Admin-Benutzername | | `DEFAULT_PASSWORD` | `admin` | Standard-Admin-Passwort | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Erzwungene Passwortänderung überspringen (nur CI/Dev) | | `RATE_LIMIT_PER_MIN` | `1000` | API-Ratenlimit pro Minute (0 = deaktiviert) | | `MAX_UPLOAD_SIZE_MB` | `100` | Maximale Upload-Größe in MB (0 = unbegrenzt) | --- --- url: https://docs.snapotter.com/hi/tools/files/epub-convert.md description: एक EPUB को PDF, DOCX, HTML, या Markdown में कन्वर्ट करें। --- # EPUB से कन्वर्ट {#convert-epub} एक EPUB e-book को PDF, Word (DOCX), HTML, या Markdown में कन्वर्ट करें। पुस्तक के अंदर के रिमोट संसाधन नहीं लाए जाते। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` एक EPUB फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | आउटपुट फ़ॉर्मेट: `pdf`, `docx`, `html`, `md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} `202 Accepted` लौटाता है। `/api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति को ट्रैक करें। ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * स्वीकृत इनपुट फ़ॉर्मेट: `.epub`। * सुरक्षा के लिए EPUB में एम्बेड किए गए रिमोट संसाधन (बाहरी इमेज, फ़ॉन्ट) नहीं लाए जाते। * कन्वर्ट किए गए आउटपुट में इमेज की विश्वसनीयता EPUB संरचना के आधार पर भिन्न हो सकती है। * कन्वर्ज़न सर्वर पर Pandoc द्वारा नियंत्रित किया जाता है। --- --- url: https://docs.snapotter.com/ja/tools/files/epub-convert.md description: EPUB を PDF、DOCX、HTML、または Markdown に変換します。 --- # EPUB から変換 {#convert-epub} EPUB 電子書籍を PDF、Word(DOCX)、HTML、または Markdown に変換します。書籍内のリモートリソースは取得されません。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` EPUB ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | 出力形式: `pdf`、`docx`、`html`、`md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} `202 Accepted` を返します。`/api/v1/jobs/{jobId}/progress` の SSE で進捗を追跡します。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 受け付ける入力形式: `.epub`。 * EPUB に埋め込まれたリモートリソース(外部の画像、フォント)は、セキュリティのため取得されません。 * 変換後の出力における画像の忠実度は、EPUB の構造によって異なる場合があります。 * 変換はサーバー上の Pandoc によって処理されます。 --- --- url: https://docs.snapotter.com/tr/tools/files/to-epub.md description: Word, Markdown, HTML veya düz metin dosyalarını EPUB'a dönüştürün. --- # EPUB'a Dönüştür {#convert-to-epub} Word belgelerini, Markdown, HTML veya düz metin dosyalarını EPUB e-kitap biçimine dönüştürün. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/files/to-epub` Bir Word/Markdown/HTML/TXT dosyası içeren multipart form verisi kabul eder. ## Parametreler {#parameters} Bu aracın yapılandırılabilir parametresi yoktur. Bir belge yükleyin, EPUB'a dönüştürülecektir. ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/to-epub \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@manuscript.docx" ``` ## Örnek Yanıt {#example-response} `202 Accepted` döndürür. İlerlemeyi SSE üzerinden `/api/v1/jobs/{jobId}/progress` adresinden takip edin. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notlar {#notes} * Kabul edilen giriş biçimleri: `.docx`, `.md`, `.html`, `.txt`. * EPUB çıktısı EPUB 3 belirtimini izler. * Kaynak belgedeki başlıklar içindekiler tablosunu oluşturmak için kullanılır. * Dönüştürme, sunucuda Pandoc tarafından gerçekleştirilir. --- --- url: https://docs.snapotter.com/tr/tools/files/epub-convert.md description: Bir EPUB'ı PDF, DOCX, HTML veya Markdown'a dönüştürün. --- # EPUB'dan Dönüştür {#convert-epub} Bir EPUB e-kitabını PDF, Word (DOCX), HTML veya Markdown'a dönüştürün. Kitabın içindeki uzak kaynaklar getirilmez. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/epub-convert` Bir EPUB dosyası ve JSON `settings` alanı içeren multipart form verisi kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | Yes | - | Çıktı formatı: `pdf`, `docx`, `html`, `md` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## Example Response {#example-response} `202 Accepted` döndürür. İlerlemeyi `/api/v1/jobs/{jobId}/progress` adresinde SSE üzerinden izleyin. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Kabul edilen giriş formatı: `.epub`. * EPUB'a gömülü uzak kaynaklar (harici görüntüler, yazı tipleri) güvenlik nedeniyle getirilmez. * Dönüştürülen çıktıdaki görüntü kalitesi EPUB yapısına bağlı olarak değişebilir. * Dönüştürme, sunucuda Pandoc tarafından gerçekleştirilir. --- --- url: https://docs.snapotter.com/ko/tools/files/epub-convert.md description: EPUB를 PDF, DOCX, HTML, 또는 Markdown으로 변환합니다. --- # EPUB에서 변환 {#convert-epub} EPUB 전자책을 PDF, Word(DOCX), HTML, 또는 Markdown으로 변환합니다. 책 내부의 원격 리소스는 가져오지 않습니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/files/epub-convert` EPUB 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} | 매개변수 | 유형 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | format | string | 예 | - | 출력 형식: `pdf`, `docx`, `html`, `md` | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/epub-convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@book.epub" \ -F 'settings={"format": "pdf"}' ``` ## 응답 예시 {#example-response} `202 Accepted`을 반환합니다. `/api/v1/jobs/{jobId}/progress`에서 SSE를 통해 진행 상황을 추적하세요. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## 참고 사항 {#notes} * 허용 입력 형식: `.epub`. * EPUB에 임베디드된 원격 리소스(외부 이미지, 폰트)는 보안을 위해 가져오지 않습니다. * 변환된 출력의 이미지 충실도는 EPUB 구조에 따라 달라질 수 있습니다. * 변환은 서버의 Pandoc이 처리합니다. --- --- url: https://docs.snapotter.com/sv/tools/image/background-replace.md description: Ersätt en bilds bakgrund med en enfärgad färg eller gradient med hjälp av AI. --- # Ersätt bakgrund {#background-replace} Ersätt bakgrunden i en bild med en enfärgad färg eller gradient. AI-modellen identifierar motivet, tar bort den ursprungliga bakgrunden och komponerar motivet på den bakgrund du valt. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/background-replace` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | backgroundType | sträng | Nej | `"color"` | Bakgrundsläge: `color` eller `gradient` | | color | sträng | Nej | `"#ffffff"` | Bakgrundsfärg i hex (när backgroundType är `color`) | | gradientColor1 | sträng | Nej | - | Första gradientfärgen i hex | | gradientColor2 | sträng | Nej | - | Andra gradientfärgen i hex | | gradientAngle | heltal | Nej | `180` | Gradientvinkel i grader (0-360) | | feather | heltal | Nej | `0` | Radie för kantutjämning (0-20) | | format | sträng | Nej | `"png"` | Utdataformat: `png` eller `webp` | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Följ förloppet via SSE på `GET /api/v1/jobs/{jobId}/progress`. När jobbet är klart avger SSE-strömmen en `completed`-händelse med nedladdnings-URL:en. ## Anteckningar {#notes} * Detta är ett AI-drivet verktyg som returnerar `202 Accepted` och bearbetar asynkront. Anslut till SSE-slutpunkten för att ta emot förloppsuppdateringar och slutresultatet. * Kräver att funktionspaketet **background-removal** är installerat. Returnerar `501` om paketet inte är tillgängligt. * HEIC-, RAW-, PSD- och SVG-indata avkodas automatiskt före bearbetning. * Utdata är som standard PNG för att bevara transparens runt motivet. --- --- url: https://docs.snapotter.com/sv/tools/video/replace-audio.md description: Byt ut ljudspåret i en video mot en annan fil. --- # Ersätt ljud {#replace-audio} Byt ut ljudspåret i en video mot en ljudfil. Ladda upp både en video och en ljudfil. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/replace-audio` Tar emot multipart-formulärdata med exakt två filer: en videofil följd av en ljudfil. ## Parametrar {#parameters} Detta verktyg har inga inställningsparametrar. Ladda upp en videofil och en ljudfil som två `file`-delar. ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/replace-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F "file=@voiceover.mp3" ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", "originalSize": 12500000, "processedSize": 13100000 } ``` ## Anteckningar {#notes} * Exakt två filer måste laddas upp: den första måste vara en video, den andra måste vara en ljudfil. * Om ljudfilen är längre än videon trimmas den för att matcha videons längd. Om den är kortare spelas den återstående videon upp i tystnad. * Videoströmmen kopieras utan omkodning, så det finns ingen förlust av videokvalitet. --- --- url: https://docs.snapotter.com/sv/tools/image/replace-color.md description: Ersätt en specifik färg i en bild med en annan färg eller gör den transparent. --- # Ersätt och invertera färg {#replace-invert-color} Ersätt pixlar som matchar en källfärg med en målfärg, eller gör dem transparenta. Använder euklidiskt avstånd i RGB-rymden med konfigurerbar tolerans för mjuk övergång vid färggränser. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/replace-color` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | sourceColor | string | Nej | `"#FF0000"` | Hex-färg att hitta (format: `#RRGGBB`) | | targetColor | string | Nej | `"#00FF00"` | Hex-färg att ersätta med (format: `#RRGGBB`) | | makeTransparent | boolean | Nej | `false` | Gör matchande pixlar transparenta istället för att ersätta med målfärgen | | tolerance | number | Nej | `30` | Tolerans för färgmatchning (0 till 255). Högre värden matchar ett bredare intervall av liknande färger | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/replace-color \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"sourceColor": "#FF0000", "targetColor": "#0000FF", "tolerance": 40}' ``` Gör en grön bakgrund transparent: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/replace-color \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@greenscreen.png" \ -F 'settings={"sourceColor": "#00FF00", "makeTransparent": true, "tolerance": 50}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 2100000 } ``` ## Anteckningar {#notes} * Färgmatchning använder euklidiskt avstånd i RGB-rymden, skalat med `tolerance * sqrt(3)`. * Ersättningsövergången är proportionell mot färgavståndet: pixlar närmare källfärgen får mer av målfärgen, vilket skapar mjuka övergångar. * När `makeTransparent` är `true` tvingas utdata till PNG (eller WebP/AVIF) om indataformatet inte stöder alfakanaler (t.ex. JPEG). * En tolerans på 0 matchar endast den exakta källfärgen. Högre värden (50+) matchar ett bredare intervall av liknande nyanser. * Utdataformatet matchar indataformatet om inte transparens behövs och indataformatet saknar stöd för alfa. --- --- url: https://docs.snapotter.com/de/guide/getting-started.md description: >- SnapOtter mit Docker in einem einzigen Befehl installieren. Enthält Docker-Compose-Einrichtung, Bauen aus dem Quellcode und eine vollständige Funktionsübersicht. --- # Erste Schritte {#getting-started} ::: tip Vor dem Installieren ausprobieren Erkunde die vollständige Oberfläche unter [demo.snapotter.com](https://demo.snapotter.com) - keine Anmeldung oder Installation erforderlich. ::: ## Schnellstart {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` Dieser einzelne Container führt alles aus, was er benötigt: Wenn kein `DATABASE_URL` festgelegt ist, startet er sein eigenes PostgreSQL und Redis auf der Loopback-Schnittstelle (eingebetteter Modus) und behält alle Daten im `SnapOtter-data`-Volume. Dies ist der schnellste Weg, SnapOtter auszuprobieren oder sich selbst auf einem Homelab zu hosten. Verwenden Sie für die Produktion den [kanonischen Docker Compose-Stack](#docker-compose), der PostgreSQL und Redis in ihren eigenen Containern hält. Der eingebettete Modus wird als Root ausgeführt (Standardeinstellung) und automatisch deaktiviert, sobald Sie `DATABASE_URL` festlegen. Du installierst auf einem Raspberry Pi, einem alten Laptop oder einem kleinen VPS? Siehe [Ressourcenarme Setups](/de/guide/low-resource) für eine abgestimmte Schritt-für-Schritt-Anleitung und einen Überblick darüber, was dich auf eingeschränkter Hardware erwartet. Du wirst beim ersten Login aufgefordert, dein Passwort zu ändern. ::: tip Anonyme Produkt-Analytics SnapOtter enthält standardmäßig anonyme Produkt-Analytics. Um sie auszuschalten, öffne **Einstellungen → System → Datenschutz** und schalte **Anonyme Produkt-Analytics** aus. Es stoppt sofort für die gesamte Instanz. Du kannst auch die Umgebungsvariable `SNAPOTTER_TELEMETRY=0` setzen (`false` und `off` funktionieren ebenfalls), um alle Telemetrie für die Instanz ohne Neuaufbau zu deaktivieren. Die Fehlerüberwachung wird von [Sentry](https://sentry.io) bereitgestellt, das SnapOtter über sein Open-Source-Programm unterstützt. Für Details darüber, was erfasst wird, siehe [Was SnapOtter erfasst](/de/guide/telemetry). ::: ::: tip NVIDIA-CUDA-Beschleunigung Fügen Sie `--gpus all` für NVIDIA CUDA-beschleunigte Hintergrundentfernung, Hochskalierung, Gesichtsverbesserung und Wiederherstellung hinzu. OCR bleibt CPU-basiert und funktioniert im selben Image mit oder ohne GPU-Zugriff: ```bash docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest ``` Erfordert das [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). Fällt automatisch auf die CPU zurück, wenn CUDA nicht verfügbar ist. Die Intel/AMD iGPU-Beschleunigung über VA-API, Quick Sync oder OpenCL wird derzeit für KI-Inferenz nicht unterstützt. Benchmarks finden Sie unter [Docker-Tags](/de/guide/docker-tags). Wenn KI-Tools trotz `--gpus all` auf der CPU laufen, siehe [GPU-Beschleunigung überprüfen](/de/guide/deployment#verify-gpu-acceleration). ::: ::: details Auch auf GHCR ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snapotter-hq/snapotter:latest ``` Beide Registries veröffentlichen bei jedem Release dasselbe Image. ::: ## Docker Compose {#docker-compose} Verwenden Sie die Produktionsdatei, die mit jeder Version gepflegt und getestet wird, anstatt ein verkürztes Compose-Beispiel von dieser Seite zu kopieren: ```bash install -d -m 700 snapotter && cd snapotter curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \ https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.2.0/docker/docker-compose.yml # Keep generated service credentials out of shell history and world-readable files. umask 077 POSTGRES_PASSWORD="$(openssl rand -hex 32)" REDIS_PASSWORD="$(openssl rand -hex 32)" printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \ "$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --no-build ``` Das kanonische [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.2.0/docker/docker-compose.yml) umfasst alle vier Laufzeit-Volumes, Gesundheitsprüfungen, Ressourcenlimits, dauerhafte Redis-Konfiguration, angeheftete Datenbank-/Cache-Images und die aktuelle Containerhärtung. Ändern Sie das Standard-Administratorkennwort sofort nach der ersten Anmeldung. Für eine reproduzierbare Bereitstellung heften Sie das SnapOtter-Anwendungsimage an das von Ihnen überprüfte Release-Tag oder Digest, anstatt `latest` zu folgen. Siehe [Konfiguration](/de/guide/configuration) für alle Umgebungsvariablen und [Sicherheit und Härtung](/de/guide/security) für Geheimnisse, Netzwerkrichtlinien und Backup-Anleitungen. ## Aus dem Quellcode bauen {#build-from-source} **Voraussetzungen:** Node.js 22.22+, pnpm 9+, Docker (für Postgres + Redis), Python 3.11+ (für KI-Funktionen), Git. ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` * Frontend: * Backend: ## Was du tun kannst {#what-you-can-do} ### Dateiverarbeitung (200+ Tools) {#file-processing-200-tools} | Modalität | Anzahl | Beispiel-Tools | |----------|-------|---------------| | **Bild** | 107 | Größe ändern, zuschneiden, komprimieren, konvertieren, Hintergrund entfernen, hochskalieren, OCR, Wasserzeichen, Collage, kolorieren, GIF-Tools, Format-Vorlagen | | **Video** | 57 | Trimmen, zuschneiden, komprimieren, konvertieren, zusammenführen, Audio extrahieren, Auto-Untertitel, Video zu GIF, Größe ändern, stabilisieren, Format-Vorlagen | | **Audio** | 27 | Trimmen, zusammenführen, konvertieren, normalisieren, Rauschunterdrückung, transkribieren, Tonhöhenverschiebung, Ein-/Ausblenden, Klingelton-Ersteller, Format-Vorlagen | | **PDF / Dokument** | 29 | Zusammenführen, teilen, komprimieren, OCR, Wasserzeichen, schwärzen, Word zu PDF, Excel zu PDF, drehen, schützen, reparieren | | **Dateien** | 23 | CSV zu JSON, JSON zu XML, CSVs zusammenführen, CSV teilen, ZIP erstellen, ZIP entpacken, Diagramm-Ersteller, YAML/JSON | ### Pipelines {#pipelines} Verkette Tools zu mehrstufigen Workflows und wende sie auf ein Bild oder einen ganzen Stapel an: 1. Öffne **Pipelines** in der Seitenleiste. 2. Füge Schritte hinzu (beliebiges Tool, beliebige Einstellungen). 3. Führe sie auf einer einzelnen Datei aus - oder auf einem ganzen Stapel auf einmal. 4. Speichere die Pipeline zur späteren Wiederverwendung. Pipelines erlauben standardmäßig 20 Schritte. Setze `MAX_PIPELINE_STEPS=0`, um das Limit unbegrenzt zu machen. ### Datei-Bibliothek {#file-library} Jede von dir verarbeitete Datei kann in deiner **Dateien**-Bibliothek gespeichert werden. SnapOtter verfolgt die vollständige Versionshistorie, sodass du jeden Verarbeitungsschritt vom ursprünglichen Upload bis zur finalen Ausgabe nachvollziehen kannst. Das Speichern ist explizit: Ergebnisse, die du in der Bibliothek speicherst, bleiben erhalten, bis du sie löschst, während Ergebnisse, die du verarbeitest und ungespeichert lässt, nach 72 Stunden automatisch entfernt werden (konfigurierbar über `FILE_MAX_AGE_HOURS`). ### REST-API & API-Schlüssel {#rest-api-api-keys} Jedes Tool ist über HTTP zugänglich: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800,"height":600,"fit":"cover"}' ``` Generiere API-Schlüssel unter **Einstellungen → API-Schlüssel**. Siehe die [REST-API-Referenz](/de/api/rest) für alle Endpunkte oder besuche für die interaktive Referenz. ### Mehrbenutzer & Teams {#multi-user-teams} Aktiviere mehrere Benutzer mit rollenbasierter Zugriffskontrolle: * **Admin**: voller Zugriff - Benutzer, Teams, Einstellungen, alle Dateien/Pipelines/API-Schlüssel verwalten * **Benutzer**: Tools nutzen, eigene Dateien/Pipelines/API-Schlüssel verwalten Erstelle Teams unter **Einstellungen → Teams**, um Benutzer zu gruppieren. Setze `AUTH_ENABLED=true` (oder `false` für Einzelbenutzer/Eigennutzung ohne Login). ## Vom Smartphone aus nutzen {#use-it-from-your-phone} SnapOtter läuft in mobilen Browsern, und du kannst es als App installieren. Öffne deine Instanz auf dem Smartphone, dann: * **iPhone / iPad (Safari)**: Tippe auf Teilen, dann auf **Zum Home-Bildschirm**. * **Android (Chrome)**: Öffne das Browsermenü und tippe auf **App installieren**. Die installierte App öffnet sich in einem eigenen Fenster, direkt in deiner Instanz. Ein Haken: Browser bieten die Installation nur über HTTPS an. Eine einfache HTTP-Adresse im LAN funktioniert im Browser-Tab weiterhin problemlos; für die echte Installation stellst du die Instanz hinter einen Reverse-Proxy mit Zertifikat (siehe [Deployment-Leitfaden](/de/guide/deployment)). Auf Smartphones und Tablets zeigen die Bild-Tools neben dem Upload-Button einen Button **Foto aufnehmen**. Fotografiere einen Kassenbon oder ein Whiteboard, und das Bild landet direkt im Tool. --- --- url: https://docs.snapotter.com/it/tools/image/ai-canvas-expand.md description: >- Espande la tela di un'immagine con outpainting basato su IA, estendendola in qualsiasi direzione e riempiendo le nuove aree in modo coerente con l'originale. --- # Espansione tela con IA {#ai-canvas-expand} Espande la tela di un'immagine con riempimento basato su IA (outpainting). Estende l'immagine in qualsiasi direzione e riempie le nuove aree con contenuto generato dall'IA in modo coerente con l'immagine esistente. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Elaborazione:** asincrona (restituisce 202, interroga `/api/v1/jobs/{jobId}/progress` per lo stato tramite SSE) **Bundle del modello:** `object-eraser-colorize` (1-2 GB) ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | file | file | Sì | - | File immagine (multipart) | | extendTop | integer | No | `0` | Pixel di estensione in alto | | extendRight | integer | No | `0` | Pixel di estensione a destra | | extendBottom | integer | No | `0` | Pixel di estensione in basso | | extendLeft | integer | No | `0` | Pixel di estensione a sinistra | | tier | string | No | `"balanced"` | Livello di qualità: `fast`, `balanced`, `high` | | format | string | No | `"auto"` | Formato di output: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | Qualità di output (1-100) | Almeno una direzione di estensione deve essere maggiore di 0. ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Risposta {#response} ### Risposta iniziale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Avanzamento (SSE su `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Risultato finale (tramite SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Note {#notes} * Richiede l'installazione del bundle del modello `object-eraser-colorize` (1-2 GB). * Usa l'outpainting basato su LaMa per generare contenuto per le regioni espanse. * Il parametro `tier` bilancia velocità e qualità: `fast` produce risultati rapidamente con possibili artefatti, `high` impiega più tempo ma produce riempimenti più uniformi e coerenti. * I valori di estensione sono in pixel. Le dimensioni finali dell'immagine saranno: larghezza originale + extendLeft + extendRight per altezza originale + extendTop + extendBottom. * Per i formati di output non visualizzabili in anteprima nel browser (HEIC, JXL, TIFF), viene generata un'anteprima WebP insieme all'output principale. * Supporta i formati di input HEIC/HEIF, RAW, TGA, PSD, EXR e HDR tramite decodifica automatica. --- --- url: https://docs.snapotter.com/it/tools/pdf/extract-pages.md description: Estrai pagine selezionate da un PDF in un nuovo documento. --- # Estrai pagine {#extract-pages} Estrai pagine selezionate da un PDF in un documento nuovo e più piccolo. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Accetta dati di form multipart con un file PDF e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | Intervallo di pagine nella sintassi qpdf, es. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Gli intervalli di pagine usano la sintassi qpdf: `1-5` per le pagine da 1 a 5, `z` per l'ultima pagina, e le virgole per combinare gli intervalli (es. `1-3,7,10-z`). * Le pagine estratte mantengono la formattazione, le annotazioni e i collegamenti originali. --- --- url: https://docs.snapotter.com/es/tools/files/excel-to-pdf.md description: Convierte hojas de cálculo a PDF. --- # Excel a PDF {#excel-to-pdf} Convierte hojas de cálculo de Excel, OpenDocument o CSV a PDF. Las hojas anchas pueden paginarse en varias páginas. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Acepta datos de formulario multipart con un archivo Excel/ODS/CSV. ## Parámetros {#parameters} Esta herramienta no tiene parámetros configurables. Sube una hoja de cálculo y se convertirá a PDF. ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Ejemplo de respuesta {#example-response} Devuelve `202 Accepted`. Sigue el progreso mediante SSE en `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceptados: `.xlsx`, `.xls`, `.ods`, `.csv`. * Las hojas anchas pueden dividirse en varias páginas en el PDF resultante. * Los gráficos y el formato condicional se renderizan en la salida PDF. * La conversión la gestiona LibreOffice ejecutándose sin interfaz gráfica en el servidor. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/excel-to-pdf.md description: Converta planilhas para PDF. --- # Excel para PDF {#excel-to-pdf} Converta planilhas Excel, OpenDocument ou CSV para PDF. Planilhas largas podem se estender por várias páginas. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Aceita dados de formulário multipart com um arquivo Excel/ODS/CSV. ## Parâmetros {#parameters} Esta ferramenta não tem parâmetros configuráveis. Envie uma planilha e ela será convertida para PDF. ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Exemplo de Resposta {#example-response} Retorna `202 Accepted`. Acompanhe o progresso via SSE em `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceitos: `.xlsx`, `.xls`, `.ods`, `.csv`. * Planilhas largas podem ser divididas em várias páginas no PDF resultante. * Gráficos e formatação condicional são renderizados na saída PDF. * A conversão é realizada pelo LibreOffice executando em modo headless no servidor. --- --- url: https://docs.snapotter.com/de/tools/files/excel-to-pdf.md description: Konvertiert Tabellenkalkulationen in PDF. --- # Excel to PDF {#excel-to-pdf} Konvertiert Excel-, OpenDocument- oder CSV-Tabellenkalkulationen in PDF. Breite Blätter können über mehrere Seiten paginiert werden. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Akzeptiert Multipart-Formulardaten mit einer Excel-/ODS-/CSV-Datei. ## Parameters {#parameters} Dieses Tool hat keine konfigurierbaren Parameter. Lade eine Tabellenkalkulation hoch, und sie wird in PDF konvertiert. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Gibt `202 Accepted` zurück. Verfolge den Fortschritt per SSE unter `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akzeptierte Eingabeformate: `.xlsx`, `.xls`, `.ods`, `.csv`. * Breite Blätter können im resultierenden PDF über mehrere Seiten aufgeteilt werden. * Diagramme und bedingte Formatierungen werden in der PDF-Ausgabe gerendert. * Die Konvertierung wird von LibreOffice im Headless-Modus auf dem Server durchgeführt. --- --- url: https://docs.snapotter.com/hi/tools/files/excel-to-pdf.md description: स्प्रेडशीट को PDF में कन्वर्ट करें। --- # Excel to PDF {#excel-to-pdf} Excel, OpenDocument, या CSV स्प्रेडशीट को PDF में कन्वर्ट करें। चौड़ी शीट कई पेजों में पृष्ठांकित हो सकती हैं। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` एक Excel/ODS/CSV फ़ाइल के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} इस टूल में कोई कॉन्फ़िगर करने योग्य पैरामीटर नहीं है। एक स्प्रेडशीट अपलोड करें और यह PDF में कन्वर्ट हो जाएगी। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} `202 Accepted` लौटाता है। `/api/v1/jobs/{jobId}/progress` पर SSE के माध्यम से प्रगति को ट्रैक करें। ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * स्वीकृत इनपुट फ़ॉर्मेट: `.xlsx`, `.xls`, `.ods`, `.csv`। * परिणामी PDF में चौड़ी शीट कई पेजों में विभाजित हो सकती हैं। * चार्ट और conditional formatting PDF आउटपुट में रेंडर किए जाते हैं। * कन्वर्ज़न सर्वर पर headless चल रहे LibreOffice द्वारा नियंत्रित किया जाता है। --- --- url: https://docs.snapotter.com/id/tools/files/excel-to-pdf.md description: Konversi spreadsheet ke PDF. --- # Excel to PDF {#excel-to-pdf} Konversi spreadsheet Excel, OpenDocument, atau CSV ke PDF. Sheet yang lebar dapat dipaginasi menjadi beberapa halaman. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Menerima multipart form data berisi file Excel/ODS/CSV. ## Parameters {#parameters} Tool ini tidak memiliki parameter yang dapat dikonfigurasi. Unggah spreadsheet dan file tersebut akan dikonversi ke PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Mengembalikan `202 Accepted`. Lacak progres melalui SSE di `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Format input yang diterima: `.xlsx`, `.xls`, `.ods`, `.csv`. * Sheet yang lebar dapat dipecah menjadi beberapa halaman dalam PDF yang dihasilkan. * Grafik dan pemformatan bersyarat dirender dalam output PDF. * Konversi ditangani oleh LibreOffice yang berjalan headless di server. --- --- url: https://docs.snapotter.com/it/tools/files/excel-to-pdf.md description: Converte i fogli di calcolo in PDF. --- # Excel to PDF {#excel-to-pdf} Converte i fogli di calcolo Excel, OpenDocument o CSV in PDF. I fogli larghi possono essere impaginati su più pagine. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Accetta dati form multipart con un file Excel/ODS/CSV. ## Parameters {#parameters} Questo strumento non ha parametri configurabili. Carica un foglio di calcolo e verrà convertito in PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Restituisce `202 Accepted`. Monitora l'avanzamento tramite SSE su `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Formati di input accettati: `.xlsx`, `.xls`, `.ods`, `.csv`. * I fogli larghi possono essere suddivisi su più pagine nel PDF risultante. * I grafici e la formattazione condizionale vengono renderizzati nell'output PDF. * La conversione è gestita da LibreOffice in esecuzione headless sul server. --- --- url: https://docs.snapotter.com/ja/tools/files/excel-to-pdf.md description: スプレッドシートを PDF に変換します。 --- # Excel to PDF {#excel-to-pdf} Excel、OpenDocument、または CSV のスプレッドシートを PDF に変換します。横に広いシートは複数ページにわたって分割されることがあります。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Excel/ODS/CSV ファイルを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} このツールには設定可能なパラメータはありません。スプレッドシートをアップロードすると PDF に変換されます。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} `202 Accepted` を返します。`/api/v1/jobs/{jobId}/progress` の SSE で進捗を追跡します。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 受け付ける入力形式: `.xlsx`、`.xls`、`.ods`、`.csv`。 * 横に広いシートは、生成される PDF で複数ページに分割されることがあります。 * グラフや条件付き書式は PDF 出力に描画されます。 * 変換はサーバー上でヘッドレスで動作する LibreOffice によって処理されます。 --- --- url: https://docs.snapotter.com/ko/tools/files/excel-to-pdf.md description: 스프레드시트를 PDF로 변환합니다. --- # Excel to PDF {#excel-to-pdf} Excel, OpenDocument, 또는 CSV 스프레드시트를 PDF로 변환합니다. 넓은 시트는 여러 페이지에 걸쳐 분할될 수 있습니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Excel/ODS/CSV 파일이 포함된 multipart form data를 받습니다. ## 매개변수 {#parameters} 이 도구에는 설정 가능한 매개변수가 없습니다. 스프레드시트를 업로드하면 PDF로 변환됩니다. ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## 응답 예시 {#example-response} `202 Accepted`을 반환합니다. `/api/v1/jobs/{jobId}/progress`에서 SSE를 통해 진행 상황을 추적하세요. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## 참고 사항 {#notes} * 허용 입력 형식: `.xlsx`, `.xls`, `.ods`, `.csv`. * 넓은 시트는 결과 PDF에서 여러 페이지에 걸쳐 분할될 수 있습니다. * 차트와 조건부 서식은 PDF 출력에 렌더링됩니다. * 변환은 서버에서 헤드리스로 실행되는 LibreOffice가 처리합니다. --- --- url: https://docs.snapotter.com/nl/tools/files/excel-to-pdf.md description: Converteer spreadsheets naar PDF. --- # Excel to PDF {#excel-to-pdf} Converteer Excel-, OpenDocument- of CSV-spreadsheets naar PDF. Brede bladen kunnen over meerdere pagina's worden gepagineerd. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Accepteert multipart-formulierdata met een Excel-/ODS-/CSV-bestand. ## Parameters {#parameters} Deze tool heeft geen instelbare parameters. Upload een spreadsheet en deze wordt naar PDF geconverteerd. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Retourneert `202 Accepted`. Volg de voortgang via SSE op `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Geaccepteerde invoerformaten: `.xlsx`, `.xls`, `.ods`, `.csv`. * Brede bladen kunnen over meerdere pagina's worden opgesplitst in de resulterende PDF. * Diagrammen en voorwaardelijke opmaak worden in de PDF-uitvoer weergegeven. * De conversie wordt uitgevoerd door LibreOffice dat headless op de server draait. --- --- url: https://docs.snapotter.com/pl/tools/files/excel-to-pdf.md description: Konwertuje arkusze kalkulacyjne na PDF. --- # Excel to PDF {#excel-to-pdf} Konwertuje arkusze kalkulacyjne Excel, OpenDocument lub CSV na PDF. Szerokie arkusze mogą być dzielone na wiele stron. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Przyjmuje dane formularza multipart z plikiem Excel/ODS/CSV. ## Parameters {#parameters} To narzędzie nie ma konfigurowalnych parametrów. Prześlij arkusz kalkulacyjny, a zostanie on przekonwertowany na PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Zwraca `202 Accepted`. Śledź postęp przez SSE pod `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Akceptowane formaty wejściowe: `.xlsx`, `.xls`, `.ods`, `.csv`. * Szerokie arkusze mogą zostać podzielone na wiele stron w wynikowym PDF. * Wykresy i formatowanie warunkowe są renderowane w wyniku PDF. * Konwersję obsługuje LibreOffice działający w trybie headless na serwerze. --- --- url: https://docs.snapotter.com/sv/tools/files/excel-to-pdf.md description: Konvertera kalkylblad till PDF. --- # Excel to PDF {#excel-to-pdf} Konvertera Excel-, OpenDocument- eller CSV-kalkylblad till PDF. Breda blad kan delas upp över flera sidor. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Tar emot multipart-formulärdata med en Excel/ODS/CSV-fil. ## Parameters {#parameters} Detta verktyg har inga konfigurerbara parametrar. Ladda upp ett kalkylblad så konverteras det till PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Returnerar `202 Accepted`. Följ förloppet via SSE på `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Godkända indataformat: `.xlsx`, `.xls`, `.ods`, `.csv`. * Breda blad kan delas upp över flera sidor i den resulterande PDF:en. * Diagram och villkorsstyrd formatering renderas i PDF-utdatan. * Konverteringen hanteras av LibreOffice som körs utan grafiskt gränssnitt på servern. --- --- url: https://docs.snapotter.com/th/tools/files/excel-to-pdf.md description: แปลงสเปรดชีตเป็น PDF --- # Excel to PDF {#excel-to-pdf} แปลงสเปรดชีต Excel, OpenDocument หรือ CSV เป็น PDF ชีตที่กว้างอาจแบ่งหน้าข้ามหลายหน้า ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` รับข้อมูล multipart form ที่มีไฟล์ Excel/ODS/CSV ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์ที่กำหนดค่าได้ อัปโหลดสเปรดชีตแล้วจะถูกแปลงเป็น PDF ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} ส่งคืน `202 Accepted` ติดตามความคืบหน้าผ่าน SSE ที่ `/api/v1/jobs/{jobId}/progress` ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * รูปแบบอินพุตที่รับได้: `.xlsx`, `.xls`, `.ods`, `.csv` * ชีตที่กว้างอาจถูกแบ่งข้ามหลายหน้าใน PDF ผลลัพธ์ * แผนภูมิและการจัดรูปแบบตามเงื่อนไขจะถูกเรนเดอร์ในผลลัพธ์ PDF * การแปลงจัดการโดย LibreOffice ที่ทำงานแบบ headless บนเซิร์ฟเวอร์ --- --- url: https://docs.snapotter.com/tr/tools/files/excel-to-pdf.md description: Hesap tablolarını PDF'e dönüştürün. --- # Excel to PDF {#excel-to-pdf} Excel, OpenDocument veya CSV hesap tablolarını PDF'e dönüştürün. Geniş sayfalar birden fazla sayfaya bölünebilir. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Bir Excel/ODS/CSV dosyası içeren multipart form verisi kabul eder. ## Parameters {#parameters} Bu aracın yapılandırılabilir parametresi yoktur. Bir hesap tablosu yükleyin ve PDF'e dönüştürülecektir. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} `202 Accepted` döndürür. İlerlemeyi `/api/v1/jobs/{jobId}/progress` adresinde SSE üzerinden izleyin. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Kabul edilen giriş formatları: `.xlsx`, `.xls`, `.ods`, `.csv`. * Geniş sayfalar sonuçtaki PDF'te birden fazla sayfaya bölünebilir. * Grafikler ve koşullu biçimlendirme PDF çıktısında işlenir. * Dönüştürme, sunucuda başsız (headless) çalışan LibreOffice tarafından gerçekleştirilir. --- --- url: https://docs.snapotter.com/uk/tools/files/excel-to-pdf.md description: Конвертація електронних таблиць у PDF. --- # Excel to PDF {#excel-to-pdf} Конвертація електронних таблиць Excel, OpenDocument або CSV у PDF. Широкі аркуші можуть розбиватися на кілька сторінок. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Приймає дані форми multipart з файлом Excel/ODS/CSV. ## Parameters {#parameters} Цей інструмент не має налаштовуваних параметрів. Завантажте електронну таблицю, і її буде конвертовано в PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Повертає `202 Accepted`. Відстежуйте прогрес через SSE за адресою `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Прийнятні вхідні формати: `.xlsx`, `.xls`, `.ods`, `.csv`. * Широкі аркуші можуть розбиватися на кілька сторінок у результуючому PDF. * Діаграми та умовне форматування рендеряться у виводі PDF. * Конвертація обробляється LibreOffice, що працює в безголовому режимі на сервері. --- --- url: https://docs.snapotter.com/vi/tools/files/excel-to-pdf.md description: Chuyển đổi bảng tính sang PDF. --- # Excel to PDF {#excel-to-pdf} Chuyển đổi bảng tính Excel, OpenDocument hoặc CSV sang PDF. Các trang tính rộng có thể được phân trang qua nhiều trang. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Nhận dữ liệu multipart form với một tệp Excel/ODS/CSV. ## Parameters {#parameters} Công cụ này không có tham số cấu hình. Tải lên một bảng tính và nó sẽ được chuyển đổi sang PDF. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} Trả về `202 Accepted`. Theo dõi tiến trình qua SSE tại `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * Các định dạng đầu vào được chấp nhận: `.xlsx`, `.xls`, `.ods`, `.csv`. * Các trang tính rộng có thể bị chia qua nhiều trang trong PDF kết quả. * Biểu đồ và định dạng có điều kiện được kết xuất trong đầu ra PDF. * Việc chuyển đổi được xử lý bởi LibreOffice chạy ở chế độ headless trên máy chủ. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/excel-to-pdf.md description: 将电子表格转换为 PDF。 --- # Excel to PDF {#excel-to-pdf} 将 Excel、OpenDocument 或 CSV 电子表格转换为 PDF。较宽的工作表可能会分页到多页。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` 接受包含 Excel/ODS/CSV 文件的 multipart 表单数据。 ## Parameters {#parameters} 此工具没有可配置的参数。上传电子表格即可将其转换为 PDF。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} 返回 `202 Accepted`。通过 `/api/v1/jobs/{jobId}/progress` 处的 SSE 跟踪进度。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 接受的输入格式:`.xlsx`、`.xls`、`.ods`、`.csv`。 * 较宽的工作表在生成的 PDF 中可能被拆分到多页。 * 图表和条件格式会在 PDF 输出中渲染。 * 转换由服务器上以无头模式运行的 LibreOffice 处理。 --- --- url: https://docs.snapotter.com/fr/tools/files/excel-to-pdf.md description: Convertit des feuilles de calcul en PDF. --- # Excel vers PDF {#excel-to-pdf} Convertit des feuilles de calcul Excel, OpenDocument ou CSV en PDF. Les feuilles larges peuvent être paginées sur plusieurs pages. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Accepte des données de formulaire multipart avec un fichier Excel/ODS/CSV. ## Paramètres {#parameters} Cet outil n'a aucun paramètre configurable. Chargez une feuille de calcul et elle sera convertie en PDF. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Exemple de réponse {#example-response} Renvoie `202 Accepted`. Suivez la progression via SSE à `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Remarques {#notes} * Formats d'entrée acceptés : `.xlsx`, `.xls`, `.ods`, `.csv`. * Les feuilles larges peuvent être réparties sur plusieurs pages dans le PDF résultant. * Les graphiques et la mise en forme conditionnelle sont rendus dans la sortie PDF. * La conversion est effectuée par LibreOffice exécuté en mode headless sur le serveur. --- --- url: https://docs.snapotter.com/ru/tools/files/excel-to-pdf.md description: Конвертация таблиц в PDF. --- # Excel в PDF {#excel-to-pdf} Конвертация таблиц Excel, OpenDocument или CSV в PDF. Широкие листы могут разбиваться на несколько страниц. ## Эндпоинт API {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` Принимает multipart form data с файлом Excel/ODS/CSV. ## Параметры {#parameters} У этого инструмента нет настраиваемых параметров. Загрузите таблицу, и она будет конвертирована в PDF. ## Пример запроса {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Пример ответа {#example-response} Возвращает `202 Accepted`. Отслеживайте прогресс через SSE по адресу `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Примечания {#notes} * Принимаемые входные форматы: `.xlsx`, `.xls`, `.ods`, `.csv`. * Широкие листы могут быть разбиты на несколько страниц в итоговом PDF. * Диаграммы и условное форматирование отрисовываются в выводе PDF. * Конвертация выполняется LibreOffice, работающим в безголовом режиме на сервере. --- --- url: https://docs.snapotter.com/ar/tools/files/excel-to-pdf.md description: تحويل جداول البيانات إلى PDF. --- # Excel إلى PDF {#excel-to-pdf} حوِّل جداول بيانات Excel أو OpenDocument أو CSV إلى PDF. قد تُقسَّم الأوراق العريضة على صفحات متعددة. ## نقطة نهاية API {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف Excel/ODS/CSV. ## المعاملات {#parameters} ليس لهذه الأداة معاملات قابلة للتهيئة. ارفع جدول بيانات وسيُحوَّل إلى PDF. ## مثال على الطلب {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## مثال على الاستجابة {#example-response} يُرجع `202 Accepted`. تابع التقدم عبر SSE على `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## ملاحظات {#notes} * تنسيقات الدخل المقبولة: `.xlsx`، `.xls`، `.ods`، `.csv`. * قد تُقسَّم الأوراق العريضة على صفحات متعددة في PDF الناتج. * تُصيَّر الرسوم البيانية والتنسيق الشرطي في خرج PDF. * يتولّى LibreOffice المعالجة أثناء تشغيله بلا واجهة رسومية على الخادم. --- --- url: https://docs.snapotter.com/zh-TW/tools/files/excel-to-pdf.md description: 將試算表轉換為 PDF。 --- # Excel 轉 PDF {#excel-to-pdf} 將 Excel、OpenDocument 或 CSV 試算表轉換為 PDF。過寬的工作表可能會跨多頁分頁。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/excel-to-pdf` 接受包含一個 Excel/ODS/CSV 檔案的 multipart form data。 ## Parameters {#parameters} 此工具沒有可設定的參數。上傳試算表,它就會被轉換為 PDF。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/excel-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@budget.xlsx" ``` ## Example Response {#example-response} 回傳 `202 Accepted`。透過 `/api/v1/jobs/{jobId}/progress` 的 SSE 追蹤進度。 ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notes {#notes} * 接受的輸入格式:`.xlsx`、`.xls`、`.ods`、`.csv`。 * 過寬的工作表在產生的 PDF 中可能會跨多頁分割。 * 圖表與設定格式化條件會在 PDF 輸出中呈現。 * 轉換由在伺服器上以無介面模式執行的 LibreOffice 處理。 --- --- url: https://docs.snapotter.com/pt-BR/tools/image/ai-canvas-expand.md description: >- Expanda a tela de uma imagem com outpainting por IA, estendendo-a em qualquer direção e preenchendo as novas áreas para combinar com a original. --- # Expandir Tela com IA {#ai-canvas-expand} Expanda a tela de uma imagem com preenchimento por IA (outpainting). Estende a imagem em qualquer direção e preenche as novas áreas com conteúdo gerado por IA que combina com a imagem existente. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/ai-canvas-expand` **Processamento:** Assíncrono (retorna 202, consulte `/api/v1/jobs/{jobId}/progress` para o status via SSE) **Pacote de modelo:** `object-eraser-colorize` (1-2 GB) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | extendTop | integer | Não | `0` | Pixels a estender no topo | | extendRight | integer | Não | `0` | Pixels a estender à direita | | extendBottom | integer | Não | `0` | Pixels a estender na parte inferior | | extendLeft | integer | Não | `0` | Pixels a estender à esquerda | | tier | string | Não | `"balanced"` | Nível de qualidade: `fast`, `balanced`, `high` | | format | string | Não | `"auto"` | Formato de saída: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | Não | `95` | Qualidade de saída (1-100) | Pelo menos uma direção de extensão deve ser maior que 0. ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/ai-canvas-expand \ -F "file=@photo.jpg" \ -F 'settings={"extendTop":200,"extendBottom":200,"extendLeft":100,"extendRight":100,"tier":"balanced"}' ``` ## Resposta {#response} ### Resposta Inicial (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progresso (SSE em `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Expanding canvas...","percent":50} ``` ### Resultado Final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_extended.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 300000, "processedSize": 520000 } } ``` ## Observações {#notes} * Requer que o pacote de modelo `object-eraser-colorize` esteja instalado (1-2 GB). * Usa outpainting baseado em LaMa para gerar conteúdo nas regiões expandidas. * O parâmetro `tier` troca velocidade por qualidade: `fast` produz resultados rapidamente com possíveis artefatos, `high` demora mais, mas produz preenchimentos mais suaves e coerentes. * Os valores de extensão são em pixels. As dimensões finais da imagem serão: largura original + extendLeft + extendRight por altura original + extendTop + extendBottom. * Para formatos de saída não pré-visualizáveis no navegador (HEIC, JXL, TIFF), uma pré-visualização WebP é gerada junto com a saída principal. * Suporta os formatos de entrada HEIC/HEIF, RAW, TGA, PSD, EXR e HDR por meio de decodificação automática. --- --- url: https://docs.snapotter.com/ar/tools/video/extract-audio.md description: استخراج مسار الصوت من الفيديو. --- # Extract Audio {#extract-audio} استخراج مسار الصوت من ملف فيديو وحفظه بصيغة MP3 أو WAV أو M4A أو OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو وحقل JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | صيغة الصوت الناتجة: `mp3` أو `wav` أو `m4a` أو `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * إذا لم يكن للفيديو مسار صوتي، يُرجع الطلب خطأ 400. * MP3 صيغة ذات فقد لكنها متوافقة على نطاق واسع. WAV بلا فقد لكنها كبيرة. توفر M4A (AAC) توازناً جيداً بين الجودة والحجم. تتوفر OGG لسير العمل بالبرامج مفتوحة الترميز. * عندما يكون الصوت المصدر بصيغة AAC بالفعل وتكون صيغة الإخراج M4A، يُنسَخ تدفق الصوت دون إعادة ترميز. --- --- url: https://docs.snapotter.com/de/tools/video/extract-audio.md description: Die Audiospur aus einem Video herausziehen. --- # Extract Audio {#extract-audio} Die Audiospur aus einer Videodatei extrahieren und als MP3, WAV, M4A oder OGG speichern. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Nimmt Multipart-Formulardaten mit einer Videodatei und einem JSON-Feld `settings` entgegen. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Ausgabe-Audioformat: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Wenn das Video keine Audiospur hat, gibt die Anfrage einen 400-Fehler zurück. * MP3 ist verlustbehaftet, aber weithin kompatibel. WAV ist verlustfrei, aber groß. M4A (AAC) bietet ein gutes Gleichgewicht zwischen Qualität und Größe. OGG ist für Workflows mit offenen Codecs verfügbar. * Wenn die Quellaudiospur bereits AAC ist und das Ausgabeformat M4A lautet, wird der Audiostream ohne Neukodierung kopiert. --- --- url: https://docs.snapotter.com/es/tools/video/extract-audio.md description: Extrae la pista de audio de un vídeo. --- # Extract Audio {#extract-audio} Extrae la pista de audio de un archivo de vídeo y la guarda como MP3, WAV, M4A u OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Acepta datos de formulario multipart con un archivo de vídeo y un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Formato de audio de salida: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Si el vídeo no tiene pista de audio, la petición devuelve un error 400. * MP3 tiene pérdida pero es ampliamente compatible. WAV es sin pérdida pero grande. M4A (AAC) ofrece un buen equilibrio entre calidad y tamaño. OGG está disponible para flujos de trabajo con códecs abiertos. * Cuando el audio de origen ya es AAC y el formato de salida es M4A, la pista de audio se copia sin recodificar. --- --- url: https://docs.snapotter.com/fr/tools/video/extract-audio.md description: Extrait la piste audio d'une vidéo. --- # Extract Audio {#extract-audio} Extrait la piste audio d'un fichier vidéo et l'enregistre au format MP3, WAV, M4A ou OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Accepte des données de formulaire multipart avec un fichier vidéo et un champ JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Format audio de sortie : `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Si la vidéo n'a pas de piste audio, la requête renvoie une erreur 400. * Le MP3 est avec perte mais largement compatible. Le WAV est sans perte mais volumineux. Le M4A (AAC) offre un bon compromis entre qualité et taille. L'OGG est disponible pour les workflows de codecs ouverts. * Lorsque l'audio source est déjà en AAC et que le format de sortie est M4A, le flux audio est copié sans réencodage. --- --- url: https://docs.snapotter.com/hi/tools/video/extract-audio.md description: किसी वीडियो में से ऑडियो ट्रैक निकालें। --- # Extract Audio {#extract-audio} किसी वीडियो फ़ाइल में से ऑडियो ट्रैक निकालें और उसे MP3, WAV, M4A, या OGG के रूप में सहेजें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` एक वीडियो फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | आउटपुट ऑडियो फ़ॉर्मैट: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * यदि वीडियो में कोई ऑडियो ट्रैक नहीं है, तो अनुरोध 400 त्रुटि लौटाता है। * MP3 लॉसी है लेकिन व्यापक रूप से संगत है। WAV लॉसलेस है लेकिन बड़ा है। M4A (AAC) गुणवत्ता और आकार का अच्छा संतुलन देता है। OGG ओपन कोडेक वर्कफ़्लो के लिए उपलब्ध है। * जब स्रोत ऑडियो पहले से ही AAC हो और आउटपुट फ़ॉर्मैट M4A हो, तो ऑडियो स्ट्रीम को फिर से एन्कोड किए बिना कॉपी किया जाता है। --- --- url: https://docs.snapotter.com/id/tools/video/extract-audio.md description: Menarik trek audio keluar dari sebuah video. --- # Extract Audio {#extract-audio} Mengekstrak trek audio dari file video dan menyimpannya sebagai MP3, WAV, M4A, atau OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Menerima multipart form data dengan file video dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Format audio keluaran: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Jika video tidak memiliki trek audio, permintaan akan mengembalikan galat 400. * MP3 bersifat lossy tetapi kompatibel secara luas. WAV bersifat lossless tetapi berukuran besar. M4A (AAC) menawarkan keseimbangan yang baik antara kualitas dan ukuran. OGG tersedia untuk alur kerja codec terbuka. * Ketika audio sumber sudah AAC dan format keluaran adalah M4A, aliran audio disalin tanpa enkoding ulang. --- --- url: https://docs.snapotter.com/it/tools/video/extract-audio.md description: Estrai la traccia audio da un video. --- # Extract Audio {#extract-audio} Estrai la traccia audio da un file video e salvala come MP3, WAV, M4A o OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Accetta dati form multipart con un file video e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Formato audio di output: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Se il video non ha una traccia audio, la richiesta restituisce un errore 400. * MP3 è con perdita ma ampiamente compatibile. WAV è senza perdita ma di grandi dimensioni. M4A (AAC) offre un buon equilibrio tra qualità e dimensione. OGG è disponibile per flussi di lavoro con codec aperti. * Quando l'audio sorgente è già AAC e il formato di output è M4A, il flusso audio viene copiato senza ricodifica. --- --- url: https://docs.snapotter.com/ja/tools/video/extract-audio.md description: 動画から音声トラックを抽出します。 --- # Extract Audio {#extract-audio} 動画ファイルから音声トラックを抽出し、MP3、WAV、M4A、または OGG として保存します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` 動画ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | 出力音声フォーマット: `mp3`、`wav`、`m4a`、`ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * 動画に音声トラックがない場合、リクエストは 400 エラーを返します。 * MP3 は非可逆ですが幅広く互換性があります。WAV は可逆ですがサイズが大きくなります。M4A(AAC)は品質とサイズのバランスが良好です。OGG はオープンコーデックのワークフロー向けに利用できます。 * ソース音声がすでに AAC で出力フォーマットが M4A の場合、音声ストリームは再エンコードせずにコピーされます。 --- --- url: https://docs.snapotter.com/ko/tools/video/extract-audio.md description: 비디오에서 오디오 트랙을 추출합니다. --- # Extract Audio {#extract-audio} 비디오 파일에서 오디오 트랙을 추출하여 MP3, WAV, M4A 또는 OGG로 저장합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` 비디오 파일과 JSON `settings` 필드가 담긴 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | 출력 오디오 형식: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * 비디오에 오디오 트랙이 없으면 요청은 400 오류를 반환합니다. * MP3는 손실 형식이지만 널리 호환됩니다. WAV는 무손실이지만 용량이 큽니다. M4A(AAC)는 품질과 크기의 균형이 좋습니다. OGG는 오픈 코덱 워크플로용으로 제공됩니다. * 원본 오디오가 이미 AAC이고 출력 형식이 M4A인 경우, 오디오 스트림은 재인코딩 없이 복사됩니다. --- --- url: https://docs.snapotter.com/nl/tools/video/extract-audio.md description: Het audiospoor uit een video halen. --- # Extract Audio {#extract-audio} Haal het audiospoor uit een videobestand en sla het op als MP3, WAV, M4A of OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Accepteert multipart form data met een videobestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Nee | `"mp3"` | Uitvoeraudioformaat: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Als de video geen audiospoor heeft, geeft het verzoek een 400-fout terug. * MP3 is lossy maar breed compatibel. WAV is lossless maar groot. M4A (AAC) biedt een goede balans tussen kwaliteit en grootte. OGG is beschikbaar voor workflows met open codecs. * Wanneer de bronaudio al AAC is en het uitvoerformaat M4A is, wordt het audiospoor gekopieerd zonder opnieuw te encoderen. --- --- url: https://docs.snapotter.com/pl/tools/video/extract-audio.md description: Wyodrębnienie ścieżki audio z wideo. --- # Extract Audio {#extract-audio} Wyodrębnia ścieżkę audio z pliku wideo i zapisuje ją jako MP3, WAV, M4A lub OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Przyjmuje dane formularza multipart z plikiem wideo i polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | format | string | Nie | `"mp3"` | Wyjściowy format audio: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Jeśli wideo nie ma ścieżki audio, żądanie zwraca błąd 400. * MP3 jest stratny, ale szeroko kompatybilny. WAV jest bezstratny, ale duży. M4A (AAC) oferuje dobrą równowagę między jakością a rozmiarem. OGG jest dostępny dla przepływów pracy z otwartymi kodekami. * Gdy źródłowe audio jest już w AAC, a format wyjściowy to M4A, strumień audio jest kopiowany bez ponownego kodowania. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/extract-audio.md description: Extrai a faixa de áudio de um vídeo. --- # Extract Audio {#extract-audio} Extrai a faixa de áudio de um arquivo de vídeo e a salva como MP3, WAV, M4A ou OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Aceita dados de formulário multipart com um arquivo de vídeo e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Não | `"mp3"` | Formato de áudio de saída: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Se o vídeo não tiver faixa de áudio, a requisição retorna um erro 400. * MP3 tem perdas, mas é amplamente compatível. WAV não tem perdas, mas é grande. M4A (AAC) oferece um bom equilíbrio entre qualidade e tamanho. OGG está disponível para fluxos de trabalho com codecs abertos. * Quando o áudio de origem já é AAC e o formato de saída é M4A, o stream de áudio é copiado sem recodificação. --- --- url: https://docs.snapotter.com/ru/tools/video/extract-audio.md description: Извлечение аудиодорожки из видео. --- # Extract Audio {#extract-audio} Извлечение аудиодорожки из файла видео и сохранение её в формате MP3, WAV, M4A или OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Принимает multipart form data с файлом видео и полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Выходной формат аудио: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Если у видео нет аудиодорожки, запрос возвращает ошибку 400. * MP3 использует сжатие с потерями, но широко совместим. WAV без потерь, но большой. M4A (AAC) обеспечивает хороший баланс качества и размера. OGG доступен для рабочих процессов с открытым кодеком. * Когда исходное аудио уже в формате AAC, а выходной формат - M4A, аудиопоток копируется без перекодирования. --- --- url: https://docs.snapotter.com/th/tools/video/extract-audio.md description: ดึงแทร็กเสียงออกจากวิดีโอ --- # Extract Audio {#extract-audio} ดึงแทร็กเสียงออกจากไฟล์วิดีโอและบันทึกเป็น MP3, WAV, M4A หรือ OGG ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | รูปแบบเสียงเอาต์พุต: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * หากวิดีโอไม่มีแทร็กเสียง คำขอจะคืนค่าข้อผิดพลาด 400 * MP3 เป็นแบบ lossy แต่รองรับได้อย่างกว้างขวาง WAV เป็นแบบ lossless แต่ไฟล์ใหญ่ M4A (AAC) ให้สมดุลที่ดีระหว่างคุณภาพและขนาด OGG มีให้ใช้สำหรับเวิร์กโฟลว์โคเดกแบบเปิด * เมื่อเสียงต้นฉบับเป็น AAC อยู่แล้วและรูปแบบเอาต์พุตเป็น M4A สตรีมเสียงจะถูกคัดลอกโดยไม่เข้ารหัสใหม่ --- --- url: https://docs.snapotter.com/tr/tools/video/extract-audio.md description: Ses parçasını bir videodan çıkarın. --- # Extract Audio {#extract-audio} Bir video dosyasından ses parçasını çıkarın ve MP3, WAV, M4A veya OGG olarak kaydedin. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Bir video dosyası ve bir JSON `settings` alanı içeren multipart form data kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Çıktı ses formatı: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Videoda ses parçası yoksa, istek 400 hatası döndürür. * MP3 kayıplıdır ancak yaygın olarak uyumludur. WAV kayıpsızdır ancak büyüktür. M4A (AAC) kalite ile boyut arasında iyi bir denge sunar. OGG, açık codec iş akışları için mevcuttur. * Kaynak ses zaten AAC olduğunda ve çıktı formatı M4A olduğunda, ses akışı yeniden kodlanmadan kopyalanır. --- --- url: https://docs.snapotter.com/uk/tools/video/extract-audio.md description: Витягує аудіодоріжку з відео. --- # Extract Audio {#extract-audio} Витягує аудіодоріжку з відеофайлу й зберігає її як MP3, WAV, M4A або OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Приймає дані форми multipart із відеофайлом і полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Вихідний формат аудіо: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Якщо у відео немає аудіодоріжки, запит повертає помилку 400. * MP3 із втратами, але широко сумісний. WAV без втрат, але великий. M4A (AAC) забезпечує гарний баланс якості та розміру. OGG доступний для робочих процесів із відкритими кодеками. * Коли вихідне аудіо вже в AAC, а вихідний формат M4A, аудіопотік копіюється без перекодування. --- --- url: https://docs.snapotter.com/vi/tools/video/extract-audio.md description: Tách track âm thanh ra khỏi video. --- # Extract Audio {#extract-audio} Trích xuất track âm thanh từ một file video và lưu dưới dạng MP3, WAV, M4A hoặc OGG. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Nhận multipart form data gồm một file video và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | Định dạng âm thanh đầu ra: `mp3`, `wav`, `m4a`, `ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * Nếu video không có track âm thanh, yêu cầu trả về lỗi 400. * MP3 có mất dữ liệu nhưng tương thích rộng rãi. WAV không mất dữ liệu nhưng lớn. M4A (AAC) mang lại sự cân bằng tốt giữa chất lượng và kích thước. OGG có sẵn cho các quy trình dùng codec mở. * Khi âm thanh nguồn đã là AAC và định dạng đầu ra là M4A, luồng âm thanh được sao chép mà không mã hóa lại. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/extract-audio.md description: 从视频中提取音轨。 --- # Extract Audio {#extract-audio} 从视频文件中提取音轨,并保存为 MP3、WAV、M4A 或 OGG。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` 接受包含视频文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | 输出音频格式:`mp3`、`wav`、`m4a`、`ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * 如果视频没有音轨,请求将返回 400 错误。 * MP3 是有损格式,但兼容性广泛。WAV 是无损格式,但体积大。M4A(AAC)在质量与大小之间取得良好平衡。OGG 可用于开放编解码器工作流。 * 当源音频已是 AAC 且输出格式为 M4A 时,音频流会被直接复制而不重新编码。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/extract-audio.md description: 從影片中取出音訊軌。 --- # Extract Audio {#extract-audio} 從影片檔案中擷取音訊軌,並儲存為 MP3、WAV、M4A 或 OGG。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-audio` 接受包含一個影片檔案和一個 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp3"` | 輸出音訊格式:`mp3`、`wav`、`m4a`、`ogg` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Notes {#notes} * 若影片沒有音訊軌,請求會回傳 400 錯誤。 * MP3 是有損格式但相容性廣泛。WAV 是無損格式但檔案較大。M4A(AAC)在品質和大小之間取得良好的平衡。OGG 可用於開放編解碼器工作流程。 * 當來源音訊已是 AAC 且輸出格式為 M4A 時,音訊串流會直接複製而不重新編碼。 --- --- url: https://docs.snapotter.com/ar/tools/pdf/extract-pages.md description: سحب صفحات مختارة من ملف PDF إلى مستند جديد. --- # Extract Pages {#extract-pages} اسحب صفحات مختارة من ملف PDF إلى مستند جديد أصغر. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` يقبل بيانات نموذج multipart تحتوي على ملف PDF وحقل `settings` بصيغة JSON. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | نطاق الصفحات بصيغة qpdf، مثل `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * تستخدم نطاقات الصفحات صيغة qpdf: `1-5` للصفحات من 1 إلى 5، و`z` للصفحة الأخيرة، والفواصل لدمج النطاقات (مثل `1-3,7,10-z`). * تحتفظ الصفحات المستخرَجة بتنسيقها الأصلي وتعليقاتها التوضيحية وروابطها. --- --- url: https://docs.snapotter.com/hi/tools/pdf/extract-pages.md description: चयनित पृष्ठों को PDF से निकालकर एक नए दस्तावेज़ में डालें। --- # Extract Pages {#extract-pages} चयनित पृष्ठों को PDF से निकालकर एक नए, छोटे दस्तावेज़ में डालें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` एक PDF फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | qpdf सिंटैक्स में पृष्ठ रेंज, उदा. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * पृष्ठ रेंज qpdf सिंटैक्स का उपयोग करती हैं: पृष्ठ 1 से 5 तक के लिए `1-5`, अंतिम पृष्ठ के लिए `z`, और रेंज संयोजित करने के लिए कॉमा (उदा. `1-3,7,10-z`)। * निकाले गए पृष्ठ अपनी मूल फ़ॉर्मेटिंग, एनोटेशन और लिंक बनाए रखते हैं। --- --- url: https://docs.snapotter.com/id/tools/pdf/extract-pages.md description: Ambil halaman yang dipilih dari PDF ke dalam dokumen baru. --- # Extract Pages {#extract-pages} Ambil halaman yang dipilih dari PDF ke dalam dokumen baru yang lebih kecil. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Menerima data form multipart berisi file PDF dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | Rentang halaman dalam sintaks qpdf, mis. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Rentang halaman menggunakan sintaks qpdf: `1-5` untuk halaman 1 sampai 5, `z` untuk halaman terakhir, dan koma untuk menggabungkan rentang (mis. `1-3,7,10-z`). * Halaman yang diekstrak mempertahankan format, anotasi, dan tautan aslinya. --- --- url: https://docs.snapotter.com/ja/tools/pdf/extract-pages.md description: PDF から選択したページを取り出して新しいドキュメントを作成します。 --- # Extract Pages {#extract-pages} PDF から選択したページを取り出して、より小さな新しいドキュメントを作成します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` PDF ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | qpdf 構文のページ範囲。例: `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * ページ範囲には qpdf 構文を使用します: 1〜5 ページには `1-5`、最終ページには `z`、複数の範囲をまとめるにはカンマを使います(例: `1-3,7,10-z`)。 * 取り出したページは元の書式、注釈、リンクを保持します。 --- --- url: https://docs.snapotter.com/ko/tools/pdf/extract-pages.md description: PDF에서 선택한 페이지를 뽑아 새 문서로 만듭니다. --- # Extract Pages {#extract-pages} PDF에서 선택한 페이지를 뽑아 더 작은 새 문서로 만듭니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` PDF 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | qpdf 문법의 페이지 범위, 예: `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * 페이지 범위는 qpdf 문법을 사용합니다: 1페이지부터 5페이지까지는 `1-5`, 마지막 페이지는 `z`, 그리고 쉼표로 범위를 결합합니다(예: `1-3,7,10-z`). * 추출된 페이지는 원본 서식, 주석, 링크를 그대로 유지합니다. --- --- url: https://docs.snapotter.com/nl/tools/pdf/extract-pages.md description: Haal geselecteerde pagina's uit een PDF in een nieuw document. --- # Extract Pages {#extract-pages} Haal geselecteerde pagina's uit een PDF in een nieuw, kleiner document. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Accepteert multipart-formuliergegevens met een PDF-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | range | string | Ja | - | Paginabereik in qpdf-syntaxis, bijv. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Paginabereiken gebruiken qpdf-syntaxis: `1-5` voor pagina's 1 tot en met 5, `z` voor de laatste pagina, en komma's om bereiken te combineren (bijv. `1-3,7,10-z`). * De geëxtraheerde pagina's behouden hun oorspronkelijke opmaak, annotaties en links. --- --- url: https://docs.snapotter.com/pl/tools/pdf/extract-pages.md description: Wyodrębnij wybrane strony z pliku PDF do nowego dokumentu. --- # Extract Pages {#extract-pages} Wyodrębnij wybrane strony z pliku PDF do nowego, mniejszego dokumentu. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Przyjmuje dane formularza multipart z plikiem PDF oraz polem JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | Zakres stron w składni qpdf, np. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Zakresy stron używają składni qpdf: `1-5` dla stron od 1 do 5, `z` dla ostatniej strony oraz przecinki do łączenia zakresów (np. `1-3,7,10-z`). * Wyodrębnione strony zachowują oryginalne formatowanie, adnotacje i odnośniki. --- --- url: https://docs.snapotter.com/pt-BR/tools/pdf/extract-pages.md description: Extraia páginas selecionadas de um PDF para um novo documento. --- # Extract Pages {#extract-pages} Extraia páginas selecionadas de um PDF para um novo documento, menor. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Aceita dados de formulário multipart com um arquivo PDF e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | range | string | Sim | - | Intervalo de páginas na sintaxe qpdf, por exemplo `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Os intervalos de páginas usam a sintaxe qpdf: `1-5` para as páginas 1 a 5, `z` para a última página, e vírgulas para combinar intervalos (por exemplo `1-3,7,10-z`). * As páginas extraídas mantêm a formatação, anotações e links originais. --- --- url: https://docs.snapotter.com/ru/tools/pdf/extract-pages.md description: Извлечение выбранных страниц из PDF в новый документ. --- # Extract Pages {#extract-pages} Извлеките выбранные страницы из PDF в новый, меньший по размеру документ. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Принимает данные multipart form с PDF-файлом и JSON-полем `settings`. ## Parameters {#parameters} | Параметр | Тип | Обязательный | По умолчанию | Описание | |-----------|------|----------|---------|-------------| | range | string | Да | - | Диапазон страниц в синтаксисе qpdf, например `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Диапазоны страниц используют синтаксис qpdf: `1-5` для страниц с 1 по 5, `z` для последней страницы, а запятые объединяют диапазоны (например, `1-3,7,10-z`). * Извлечённые страницы сохраняют исходное форматирование, аннотации и ссылки. --- --- url: https://docs.snapotter.com/sv/tools/pdf/extract-pages.md description: Plocka ut valda sidor från en PDF till ett nytt dokument. --- # Extract Pages {#extract-pages} Plocka ut valda sidor från en PDF till ett nytt, mindre dokument. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Tar emot multipart-formulärdata med en PDF-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | range | string | Ja | - | Sidintervall i qpdf-syntax, t.ex. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Sidintervall använder qpdf-syntax: `1-5` för sidorna 1 till 5, `z` för den sista sidan, och kommatecken för att kombinera intervall (t.ex. `1-3,7,10-z`). * De extraherade sidorna behåller sin ursprungliga formatering, sina anteckningar och länkar. --- --- url: https://docs.snapotter.com/th/tools/pdf/extract-pages.md description: ดึงหน้าที่เลือกจาก PDF ออกมาเป็นเอกสารใหม่ --- # Extract Pages {#extract-pages} ดึงหน้าที่เลือกจาก PDF ออกมาเป็นเอกสารใหม่ที่เล็กลง ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` รับข้อมูลแบบ multipart form data พร้อมไฟล์ PDF และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | ช่วงหน้าตามไวยากรณ์ qpdf เช่น `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * ช่วงหน้าใช้ไวยากรณ์ qpdf: `1-5` สำหรับหน้า 1 ถึง 5, `z` สำหรับหน้าสุดท้าย และใช้จุลภาคเพื่อรวมช่วงต่าง ๆ (เช่น `1-3,7,10-z`) * หน้าที่ดึงออกมาจะคงรูปแบบ คำอธิบายประกอบ และลิงก์เดิมไว้ --- --- url: https://docs.snapotter.com/uk/tools/pdf/extract-pages.md description: Витягання вибраних сторінок з PDF у новий документ. --- # Extract Pages {#extract-pages} Витягайте вибрані сторінки з PDF у новий, менший документ. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Приймає багаточастинні (multipart) дані форми з файлом PDF та полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | Діапазон сторінок у синтаксисі qpdf, наприклад `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Діапазони сторінок використовують синтаксис qpdf: `1-5` для сторінок з 1 по 5, `z` для останньої сторінки, а коми поєднують діапазони (наприклад `1-3,7,10-z`). * Витягнуті сторінки зберігають своє початкове форматування, анотації та посилання. --- --- url: https://docs.snapotter.com/vi/tools/pdf/extract-pages.md description: Trích xuất các trang đã chọn từ một PDF thành một tài liệu mới. --- # Extract Pages {#extract-pages} Trích xuất các trang đã chọn từ một PDF thành một tài liệu mới, nhỏ hơn. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Chấp nhận dữ liệu biểu mẫu multipart với một tệp PDF và một trường JSON `settings`. ## Parameters {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | range | string | Có | - | Phạm vi trang theo cú pháp qpdf, ví dụ `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Phạm vi trang dùng cú pháp qpdf: `1-5` cho các trang 1 đến 5, `z` cho trang cuối cùng, và dấu phẩy để kết hợp các phạm vi (ví dụ `1-3,7,10-z`). * Các trang được trích xuất giữ nguyên định dạng, chú thích và liên kết gốc của chúng. --- --- url: https://docs.snapotter.com/zh-CN/tools/pdf/extract-pages.md description: 从 PDF 中提取选定页面到一个新文档。 --- # Extract Pages {#extract-pages} 从 PDF 中提取选定页面,生成一个新的、更小的文档。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` 接受包含一个 PDF 文件和一个 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | range | string | Yes | - | 采用 qpdf 语法的页面范围,例如 `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * 页面范围使用 qpdf 语法:`1-5` 表示第 1 到第 5 页,`z` 表示最后一页,用逗号组合多个范围(例如 `1-3,7,10-z`)。 * 提取出的页面保留其原始格式、注释和链接。 --- --- url: https://docs.snapotter.com/ar/tools/video/extract-subtitles.md description: استخراج مسار الترجمة من الفيديو كملف SRT. --- # Extract Subtitles {#extract-subtitles} استخراج مسار الترجمة المدمج من حاوية الفيديو وتنزيله كملف SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف فيديو. لا توجد إعدادات قابلة للتهيئة لهذه الأداة. ## Parameters {#parameters} لا توجد معلمات لهذه الأداة. تستخرج أول مسار ترجمة يُعثَر عليه في حاوية الفيديو. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * يجب أن يحتوي الفيديو على مسار ترجمة مدمج. إذا لم يُعثَر على مسار ترجمة، يُرجع الطلب خطأ 400. * إذا كان للفيديو عدة مسارات ترجمة، يُستخرَج الأول. * صيغة الإخراج هي SRT بغض النظر عن صيغة الترجمة الأصلية في الحاوية. --- --- url: https://docs.snapotter.com/de/tools/video/extract-subtitles.md description: Die Untertitelspur als SRT-Datei aus einem Video herausziehen. --- # Extract Subtitles {#extract-subtitles} Die eingebettete Untertitelspur aus einem Videocontainer extrahieren und als SRT-Datei herunterladen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Nimmt Multipart-Formulardaten mit einer Videodatei entgegen. Dieses Tool hat keine konfigurierbaren Einstellungen. ## Parameters {#parameters} Dieses Tool hat keine Parameter. Es extrahiert die erste im Videocontainer gefundene Untertitelspur. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Das Video muss eine eingebettete Untertitelspur enthalten. Wenn keine Untertitelspur gefunden wird, gibt die Anfrage einen 400-Fehler zurück. * Wenn das Video mehrere Untertitelspuren hat, wird die erste extrahiert. * Das Ausgabeformat ist SRT, unabhängig vom ursprünglichen Untertitelformat im Container. --- --- url: https://docs.snapotter.com/es/tools/video/extract-subtitles.md description: Extrae la pista de subtítulos de un vídeo como un archivo SRT. --- # Extract Subtitles {#extract-subtitles} Extrae la pista de subtítulos incrustada de un contenedor de vídeo y la descarga como un archivo SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Acepta datos de formulario multipart con un archivo de vídeo. Esta herramienta no tiene ajustes configurables. ## Parameters {#parameters} Esta herramienta no tiene parámetros. Extrae la primera pista de subtítulos que encuentra en el contenedor de vídeo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * El vídeo debe contener una pista de subtítulos incrustada. Si no se encuentra ninguna pista de subtítulos, la petición devuelve un error 400. * Si el vídeo tiene varias pistas de subtítulos, se extrae la primera. * El formato de salida es SRT independientemente del formato de subtítulos original en el contenedor. --- --- url: https://docs.snapotter.com/fr/tools/video/extract-subtitles.md description: Extrait la piste de sous-titres d'une vidéo sous forme de fichier SRT. --- # Extract Subtitles {#extract-subtitles} Extrait la piste de sous-titres intégrée d'un conteneur vidéo et la télécharge sous forme de fichier SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Accepte des données de formulaire multipart avec un fichier vidéo. Cet outil n'a aucun réglage configurable. ## Parameters {#parameters} Cet outil n'a aucun paramètre. Il extrait la première piste de sous-titres trouvée dans le conteneur vidéo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * La vidéo doit contenir une piste de sous-titres intégrée. Si aucune piste de sous-titres n'est trouvée, la requête renvoie une erreur 400. * Si la vidéo comporte plusieurs pistes de sous-titres, la première est extraite. * Le format de sortie est SRT, quel que soit le format de sous-titres d'origine dans le conteneur. --- --- url: https://docs.snapotter.com/hi/tools/video/extract-subtitles.md description: किसी वीडियो में से सबटाइटल ट्रैक को SRT फ़ाइल के रूप में निकालें। --- # Extract Subtitles {#extract-subtitles} किसी वीडियो कंटेनर में से एम्बेडेड सबटाइटल ट्रैक निकालें और उसे SRT फ़ाइल के रूप में डाउनलोड करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` एक वीडियो फ़ाइल के साथ multipart form data स्वीकार करता है। इस टूल में कोई समायोज्य सेटिंग नहीं है। ## Parameters {#parameters} इस टूल में कोई पैरामीटर नहीं है। यह वीडियो कंटेनर में मिले पहले सबटाइटल ट्रैक को निकालता है। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * वीडियो में एक एम्बेडेड सबटाइटल ट्रैक होना चाहिए। यदि कोई सबटाइटल ट्रैक नहीं मिलता, तो अनुरोध 400 त्रुटि लौटाता है। * यदि वीडियो में कई सबटाइटल ट्रैक हैं, तो पहला निकाला जाता है। * कंटेनर में मूल सबटाइटल फ़ॉर्मैट चाहे जो भी हो, आउटपुट फ़ॉर्मैट SRT ही होता है। --- --- url: https://docs.snapotter.com/id/tools/video/extract-subtitles.md description: Menarik trek subtitle keluar dari video sebagai file SRT. --- # Extract Subtitles {#extract-subtitles} Mengekstrak trek subtitle tersemat dari kontainer video dan mengunduhnya sebagai file SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Menerima multipart form data dengan file video. Alat ini tidak memiliki pengaturan yang dapat dikonfigurasi. ## Parameters {#parameters} Alat ini tidak memiliki parameter. Ia mengekstrak trek subtitle pertama yang ditemukan di dalam kontainer video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Video harus berisi trek subtitle tersemat. Jika tidak ada trek subtitle yang ditemukan, permintaan akan mengembalikan galat 400. * Jika video memiliki beberapa trek subtitle, yang pertama akan diekstrak. * Format keluaran adalah SRT terlepas dari format subtitle asli di dalam kontainer. --- --- url: https://docs.snapotter.com/it/tools/video/extract-subtitles.md description: Estrai la traccia dei sottotitoli da un video come file SRT. --- # Extract Subtitles {#extract-subtitles} Estrai la traccia di sottotitoli incorporata da un contenitore video e scaricala come file SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Accetta dati form multipart con un file video. Questo strumento non ha impostazioni configurabili. ## Parameters {#parameters} Questo strumento non ha parametri. Estrae la prima traccia di sottotitoli trovata nel contenitore video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Il video deve contenere una traccia di sottotitoli incorporata. Se non viene trovata alcuna traccia di sottotitoli, la richiesta restituisce un errore 400. * Se il video ha più tracce di sottotitoli, viene estratta la prima. * Il formato di output è SRT indipendentemente dal formato originale dei sottotitoli nel contenitore. --- --- url: https://docs.snapotter.com/ja/tools/video/extract-subtitles.md description: 動画から字幕トラックを SRT ファイルとして抽出します。 --- # Extract Subtitles {#extract-subtitles} 動画コンテナから埋め込まれた字幕トラックを抽出し、SRT ファイルとしてダウンロードします。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` 動画ファイルを含む multipart フォームデータを受け付けます。このツールに設定可能な項目はありません。 ## Parameters {#parameters} このツールにパラメータはありません。動画コンテナ内で見つかった最初の字幕トラックを抽出します。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * 動画には埋め込み字幕トラックが含まれている必要があります。字幕トラックが見つからない場合、リクエストは 400 エラーを返します。 * 動画に複数の字幕トラックがある場合、最初の1つが抽出されます。 * コンテナ内の元の字幕フォーマットにかかわらず、出力フォーマットは SRT です。 --- --- url: https://docs.snapotter.com/ko/tools/video/extract-subtitles.md description: 비디오에서 자막 트랙을 SRT 파일로 추출합니다. --- # Extract Subtitles {#extract-subtitles} 비디오 컨테이너에서 임베드된 자막 트랙을 추출하여 SRT 파일로 다운로드합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` 비디오 파일이 담긴 multipart form data를 받습니다. 이 도구에는 구성 가능한 설정이 없습니다. ## Parameters {#parameters} 이 도구에는 매개변수가 없습니다. 비디오 컨테이너에서 발견된 첫 번째 자막 트랙을 추출합니다. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * 비디오에는 임베드된 자막 트랙이 있어야 합니다. 자막 트랙을 찾을 수 없으면 요청은 400 오류를 반환합니다. * 비디오에 여러 자막 트랙이 있으면 첫 번째 트랙이 추출됩니다. * 컨테이너 내 원본 자막 형식과 상관없이 출력 형식은 SRT입니다. --- --- url: https://docs.snapotter.com/nl/tools/video/extract-subtitles.md description: Het ondertitelspoor uit een video halen als een SRT-bestand. --- # Extract Subtitles {#extract-subtitles} Haal het ingebedde ondertitelspoor uit een videocontainer en download het als een SRT-bestand. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Accepteert multipart form data met een videobestand. Deze tool heeft geen instelbare opties. ## Parameters {#parameters} Deze tool heeft geen parameters. Het haalt het eerste ondertitelspoor eruit dat in de videocontainer wordt gevonden. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * De video moet een ingebed ondertitelspoor bevatten. Als er geen ondertitelspoor wordt gevonden, geeft het verzoek een 400-fout terug. * Als de video meerdere ondertitelsporen heeft, wordt het eerste eruit gehaald. * Het uitvoerformaat is SRT, ongeacht het oorspronkelijke ondertitelformaat in de container. --- --- url: https://docs.snapotter.com/pl/tools/video/extract-subtitles.md description: Wyodrębnienie ścieżki napisów z wideo jako pliku SRT. --- # Extract Subtitles {#extract-subtitles} Wyodrębnia osadzoną ścieżkę napisów z kontenera wideo i pobiera ją jako plik SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Przyjmuje dane formularza multipart z plikiem wideo. To narzędzie nie ma konfigurowalnych ustawień. ## Parameters {#parameters} To narzędzie nie ma parametrów. Wyodrębnia pierwszą ścieżkę napisów znalezioną w kontenerze wideo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Wideo musi zawierać osadzoną ścieżkę napisów. Jeśli nie znaleziono ścieżki napisów, żądanie zwraca błąd 400. * Jeśli wideo ma wiele ścieżek napisów, wyodrębniana jest pierwsza z nich. * Format wyjściowy to SRT, niezależnie od oryginalnego formatu napisów w kontenerze. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/extract-subtitles.md description: Extrai a faixa de legenda de um vídeo como um arquivo SRT. --- # Extract Subtitles {#extract-subtitles} Extrai a faixa de legenda embutida de um contêiner de vídeo e a baixa como um arquivo SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Aceita dados de formulário multipart com um arquivo de vídeo. Esta ferramenta não tem configurações ajustáveis. ## Parameters {#parameters} Esta ferramenta não tem parâmetros. Ela extrai a primeira faixa de legenda encontrada no contêiner do vídeo. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * O vídeo deve conter uma faixa de legenda embutida. Se nenhuma faixa de legenda for encontrada, a requisição retorna um erro 400. * Se o vídeo tiver várias faixas de legenda, a primeira é extraída. * O formato de saída é SRT, independentemente do formato original da legenda no contêiner. --- --- url: https://docs.snapotter.com/ru/tools/video/extract-subtitles.md description: Извлечение дорожки субтитров из видео в виде файла SRT. --- # Extract Subtitles {#extract-subtitles} Извлечение встроенной дорожки субтитров из контейнера видео и её загрузка в виде файла SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Принимает multipart form data с файлом видео. У этого инструмента нет настраиваемых параметров. ## Parameters {#parameters} У этого инструмента нет параметров. Он извлекает первую найденную дорожку субтитров в контейнере видео. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Видео должно содержать встроенную дорожку субтитров. Если дорожка субтитров не найдена, запрос возвращает ошибку 400. * Если у видео несколько дорожек субтитров, извлекается первая. * Выходной формат - SRT независимо от исходного формата субтитров в контейнере. --- --- url: https://docs.snapotter.com/th/tools/video/extract-subtitles.md description: ดึงแทร็กคำบรรยายออกจากวิดีโอเป็นไฟล์ SRT --- # Extract Subtitles {#extract-subtitles} ดึงแทร็กคำบรรยายที่ฝังอยู่ออกจากคอนเทนเนอร์วิดีโอและดาวน์โหลดเป็นไฟล์ SRT ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` รับข้อมูลแบบ multipart form พร้อมไฟล์วิดีโอ เครื่องมือนี้ไม่มีการตั้งค่าที่กำหนดค่าได้ ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์ โดยจะดึงแทร็กคำบรรยายแทร็กแรกที่พบในคอนเทนเนอร์วิดีโอ ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * วิดีโอต้องมีแทร็กคำบรรยายที่ฝังอยู่ หากไม่พบแทร็กคำบรรยาย คำขอจะคืนค่าข้อผิดพลาด 400 * หากวิดีโอมีแทร็กคำบรรยายหลายแทร็ก จะดึงแทร็กแรกออกมา * รูปแบบเอาต์พุตเป็น SRT ไม่ว่ารูปแบบคำบรรยายเดิมในคอนเทนเนอร์จะเป็นอะไร --- --- url: https://docs.snapotter.com/tr/tools/video/extract-subtitles.md description: Altyazı parçasını bir videodan SRT dosyası olarak çıkarın. --- # Extract Subtitles {#extract-subtitles} Gömülü altyazı parçasını bir video konteynerinden çıkarın ve SRT dosyası olarak indirin. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Bir video dosyası içeren multipart form data kabul eder. Bu aracın yapılandırılabilir ayarı yoktur. ## Parameters {#parameters} Bu aracın parametresi yoktur. Video konteynerinde bulunan ilk altyazı parçasını çıkarır. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Video, gömülü bir altyazı parçası içermelidir. Altyazı parçası bulunamazsa, istek 400 hatası döndürür. * Videoda birden fazla altyazı parçası varsa, ilki çıkarılır. * Konteynerdeki orijinal altyazı formatından bağımsız olarak çıktı formatı SRT'dir. --- --- url: https://docs.snapotter.com/uk/tools/video/extract-subtitles.md description: Витягує доріжку субтитрів із відео як файл SRT. --- # Extract Subtitles {#extract-subtitles} Витягує вбудовану доріжку субтитрів із відеоконтейнера й завантажує її як файл SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Приймає дані форми multipart із відеофайлом. Цей інструмент не має налаштувань. ## Parameters {#parameters} Цей інструмент не має параметрів. Він витягує першу знайдену доріжку субтитрів у відеоконтейнері. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Відео має містити вбудовану доріжку субтитрів. Якщо доріжку субтитрів не знайдено, запит повертає помилку 400. * Якщо відео має кілька доріжок субтитрів, витягується перша. * Вихідний формат - SRT, незалежно від оригінального формату субтитрів у контейнері. --- --- url: https://docs.snapotter.com/vi/tools/video/extract-subtitles.md description: Tách track phụ đề ra khỏi video dưới dạng file SRT. --- # Extract Subtitles {#extract-subtitles} Trích xuất track phụ đề nhúng từ một container video và tải xuống dưới dạng file SRT. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Nhận multipart form data gồm một file video. Công cụ này không có cài đặt nào có thể cấu hình. ## Parameters {#parameters} Công cụ này không có tham số nào. Nó trích xuất track phụ đề đầu tiên tìm thấy trong container video. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * Video phải chứa một track phụ đề nhúng. Nếu không tìm thấy track phụ đề nào, yêu cầu trả về lỗi 400. * Nếu video có nhiều track phụ đề, track đầu tiên sẽ được trích xuất. * Định dạng đầu ra là SRT bất kể định dạng phụ đề gốc trong container là gì. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/extract-subtitles.md description: 将视频中的字幕轨道提取为 SRT 文件。 --- # Extract Subtitles {#extract-subtitles} 从视频容器中提取内嵌的字幕轨道,并将其下载为 SRT 文件。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` 接受包含视频文件的 multipart 表单数据。此工具没有可配置的设置。 ## Parameters {#parameters} 此工具没有参数。它会提取视频容器中找到的第一个字幕轨道。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * 视频必须包含内嵌的字幕轨道。如果未找到字幕轨道,请求将返回 400 错误。 * 如果视频包含多个字幕轨道,则提取第一个。 * 无论容器中原始字幕格式如何,输出格式均为 SRT。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/extract-subtitles.md description: 從影片中取出字幕軌並儲存為 SRT 檔案。 --- # Extract Subtitles {#extract-subtitles} 從影片容器中擷取嵌入的字幕軌,並以 SRT 檔案的形式下載。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` 接受包含一個影片檔案的 multipart form data。此工具沒有可設定的選項。 ## Parameters {#parameters} 此工具沒有參數。它會擷取影片容器中找到的第一個字幕軌。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Notes {#notes} * 影片必須包含嵌入的字幕軌。若找不到字幕軌,請求會回傳 400 錯誤。 * 若影片有多個字幕軌,則會擷取第一個。 * 無論容器中的原始字幕格式為何,輸出格式一律為 SRT。 --- --- url: https://docs.snapotter.com/de/tools/files/extract-zip.md description: Extrahiert Dateien sicher aus einem ZIP-Archiv mit Schutz vor ZIP-Bomben. --- # Extract ZIP {#extract-zip} Extrahiert Dateien sicher aus einem ZIP-Archiv. Archive mit einer einzelnen Datei geben die enthaltene Datei direkt zurück; Archive mit mehreren Dateien geben ein flaches ZIP mit den extrahierten Inhalten zurück. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Akzeptiert Multipart-Formulardaten mit einer ZIP-Datei. Es ist kein Einstellungsfeld erforderlich. ## Parameters {#parameters} Dieses Tool hat keine konfigurierbaren Parameter. Lade eine `.zip`-Datei zum Extrahieren hoch. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Nur `.zip`-Dateien werden als Eingabe akzeptiert. * Wenn das Archiv eine einzelne Datei enthält, wird diese Datei direkt zurückgegeben (nicht in ein ZIP verpackt). * Wenn das Archiv mehrere Dateien enthält, wird ein flaches ZIP zurückgegeben, in dem alle Dateien auf die Wurzelebene extrahiert werden (die verschachtelte Verzeichnisstruktur wird abgeflacht). * Der integrierte Schutz vor ZIP-Bomben lehnt Archive mit übermäßigen Komprimierungsverhältnissen oder Dateianzahlen ab, um Ressourcenerschöpfung zu verhindern. --- --- url: https://docs.snapotter.com/hi/tools/files/extract-zip.md description: bomb सुरक्षा के साथ ZIP संग्रह से फ़ाइलों को सुरक्षित रूप से निकालें। --- # Extract ZIP {#extract-zip} ZIP संग्रह से फ़ाइलों को सुरक्षित रूप से निकालें। सिंगल-फ़ाइल संग्रह निहित फ़ाइल को सीधे लौटाते हैं; multi-file संग्रह निकाली गई सामग्री के साथ एक flat ZIP लौटाते हैं। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` एक ZIP फ़ाइल के साथ multipart form data स्वीकार करता है। किसी settings फ़ील्ड की आवश्यकता नहीं है। ## Parameters {#parameters} इस टूल में कोई कॉन्फ़िगर करने योग्य पैरामीटर नहीं है। निकालने के लिए एक `.zip` फ़ाइल अपलोड करें। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * केवल `.zip` फ़ाइलें इनपुट के रूप में स्वीकार की जाती हैं। * यदि संग्रह में एक ही फ़ाइल है, तो वह फ़ाइल सीधे लौटाई जाती है (ZIP में लपेटी नहीं जाती)। * यदि संग्रह में कई फ़ाइलें हैं, तो सभी फ़ाइलों के साथ रूट स्तर पर निकाली गई एक flat ZIP लौटाई जाती है (नेस्टेड डायरेक्टरी संरचना समतल कर दी जाती है)। * अंतर्निहित bomb सुरक्षा संसाधन समाप्ति को रोकने के लिए अत्यधिक संपीड़न अनुपात या फ़ाइल संख्या वाले संग्रहों को अस्वीकार कर देती है। --- --- url: https://docs.snapotter.com/id/tools/files/extract-zip.md description: Ekstrak file dari arsip ZIP dengan aman disertai perlindungan bomb. --- # Extract ZIP {#extract-zip} Ekstrak file dari arsip ZIP dengan aman. Arsip berisi satu file mengembalikan file yang terkandung secara langsung; arsip berisi banyak file mengembalikan ZIP datar dengan konten yang telah diekstrak. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Menerima multipart form data berisi file ZIP. Tidak diperlukan field settings. ## Parameters {#parameters} Tool ini tidak memiliki parameter yang dapat dikonfigurasi. Unggah file `.zip` untuk diekstrak. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Hanya file `.zip` yang diterima sebagai input. * Jika arsip berisi satu file, file tersebut dikembalikan secara langsung (tidak dibungkus dalam ZIP). * Jika arsip berisi banyak file, ZIP datar dikembalikan dengan semua file diekstrak ke level root (struktur direktori bersarang diratakan). * Perlindungan bomb bawaan menolak arsip dengan rasio kompresi atau jumlah file yang berlebihan untuk mencegah penipisan sumber daya. --- --- url: https://docs.snapotter.com/it/tools/files/extract-zip.md description: Estrae in sicurezza i file da un archivio ZIP con protezione dalle bomb. --- # Extract ZIP {#extract-zip} Estrae in sicurezza i file da un archivio ZIP. Gli archivi con un solo file restituiscono direttamente il file contenuto; gli archivi con più file restituiscono uno ZIP piatto con i contenuti estratti. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Accetta dati form multipart con un file ZIP. Non è richiesto alcun campo settings. ## Parameters {#parameters} Questo strumento non ha parametri configurabili. Carica un file `.zip` da estrarre. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Come input sono accettati solo file `.zip`. * Se l'archivio contiene un solo file, quel file viene restituito direttamente (non racchiuso in uno ZIP). * Se l'archivio contiene più file, viene restituito uno ZIP piatto con tutti i file estratti al livello radice (la struttura delle directory annidate viene appiattita). * La protezione integrata dalle bomb rifiuta gli archivi con rapporti di compressione o conteggi di file eccessivi per prevenire l'esaurimento delle risorse. --- --- url: https://docs.snapotter.com/ja/tools/files/extract-zip.md description: ボム保護付きで ZIP アーカイブから安全にファイルを展開します。 --- # Extract ZIP {#extract-zip} ZIP アーカイブから安全にファイルを展開します。単一ファイルのアーカイブは含まれるファイルを直接返し、複数ファイルのアーカイブは展開された内容をフラットな ZIP で返します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` ZIP ファイルを含む multipart フォームデータを受け付けます。settings フィールドは不要です。 ## Parameters {#parameters} このツールには設定可能なパラメータはありません。展開する `.zip` ファイルをアップロードします。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * 入力として受け付けるのは `.zip` ファイルのみです。 * アーカイブに単一のファイルが含まれる場合、そのファイルは直接返されます(ZIP でラップされません)。 * アーカイブに複数のファイルが含まれる場合、すべてのファイルをルートレベルに展開したフラットな ZIP が返されます(ネストされたディレクトリ構造はフラット化されます)。 * 組み込みのボム保護により、リソース枯渇を防ぐため、圧縮率やファイル数が過大なアーカイブは拒否されます。 --- --- url: https://docs.snapotter.com/nl/tools/files/extract-zip.md description: Pak bestanden veilig uit een ZIP-archief uit met bombeveiliging. --- # Extract ZIP {#extract-zip} Pak bestanden veilig uit een ZIP-archief. Archieven met één bestand retourneren het bevatte bestand rechtstreeks; archieven met meerdere bestanden retourneren een platte ZIP met de uitgepakte inhoud. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Accepteert multipart-formulierdata met een ZIP-bestand. Er is geen instellingenveld vereist. ## Parameters {#parameters} Deze tool heeft geen instelbare parameters. Upload een `.zip`-bestand om uit te pakken. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Alleen `.zip`-bestanden worden als invoer geaccepteerd. * Als het archief één bestand bevat, wordt dat bestand rechtstreeks geretourneerd (niet in een ZIP verpakt). * Als het archief meerdere bestanden bevat, wordt een platte ZIP geretourneerd met alle bestanden uitgepakt op het rootniveau (geneste mappenstructuur wordt afgevlakt). * Ingebouwde bombeveiliging weigert archieven met buitensporige compressieverhoudingen of bestandsaantallen om uitputting van bronnen te voorkomen. --- --- url: https://docs.snapotter.com/pl/tools/files/extract-zip.md description: Bezpiecznie wypakowuje pliki z archiwum ZIP z ochroną przed bombami. --- # Extract ZIP {#extract-zip} Bezpiecznie wypakowuje pliki z archiwum ZIP. Archiwa jednoplikowe zwracają zawarty plik bezpośrednio; archiwa wieloplikowe zwracają płaski ZIP z wypakowaną zawartością. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Przyjmuje dane formularza multipart z plikiem ZIP. Pole ustawień nie jest wymagane. ## Parameters {#parameters} To narzędzie nie ma konfigurowalnych parametrów. Prześlij plik `.zip` do wypakowania. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Jako wejście akceptowane są tylko pliki `.zip`. * Jeśli archiwum zawiera pojedynczy plik, jest on zwracany bezpośrednio (nie jest zawijany w ZIP). * Jeśli archiwum zawiera wiele plików, zwracany jest płaski ZIP ze wszystkimi plikami wypakowanymi do poziomu głównego (zagnieżdżona struktura katalogów jest spłaszczana). * Wbudowana ochrona przed bombami odrzuca archiwa o nadmiernych współczynnikach kompresji lub liczbie plików, aby zapobiec wyczerpaniu zasobów. --- --- url: https://docs.snapotter.com/sv/tools/files/extract-zip.md description: Extrahera filer säkert ur ett ZIP-arkiv med bombskydd. --- # Extract ZIP {#extract-zip} Extrahera filer säkert ur ett ZIP-arkiv. Arkiv med en enda fil returnerar den innehållna filen direkt; arkiv med flera filer returnerar en platt ZIP med det extraherade innehållet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Tar emot multipart-formulärdata med en ZIP-fil. Inget inställningsfält krävs. ## Parameters {#parameters} Detta verktyg har inga konfigurerbara parametrar. Ladda upp en `.zip`-fil att extrahera. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Endast `.zip`-filer godtas som indata. * Om arkivet innehåller en enda fil returneras den filen direkt (inte inpackad i en ZIP). * Om arkivet innehåller flera filer returneras en platt ZIP med alla filer extraherade till rotnivån (den kapslade katalogstrukturen plattas ut). * Inbyggt bombskydd avvisar arkiv med orimliga komprimeringsförhållanden eller filantal för att förhindra resursutmattning. --- --- url: https://docs.snapotter.com/th/tools/files/extract-zip.md description: แตกไฟล์จากไฟล์เก็บถาวร ZIP อย่างปลอดภัยพร้อมการป้องกัน bomb --- # Extract ZIP {#extract-zip} แตกไฟล์จากไฟล์เก็บถาวร ZIP อย่างปลอดภัย ไฟล์เก็บถาวรที่มีไฟล์เดียวจะส่งคืนไฟล์ที่บรรจุอยู่โดยตรง ไฟล์เก็บถาวรที่มีหลายไฟล์จะส่งคืน ZIP แบบแบนพร้อมเนื้อหาที่แตกออกมา ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` รับข้อมูล multipart form ที่มีไฟล์ ZIP ไม่จำเป็นต้องมีฟิลด์การตั้งค่า ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์ที่กำหนดค่าได้ อัปโหลดไฟล์ `.zip` เพื่อแตก ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * รับเฉพาะไฟล์ `.zip` เป็นอินพุตเท่านั้น * หากไฟล์เก็บถาวรมีไฟล์เดียว ไฟล์นั้นจะถูกส่งคืนโดยตรง (ไม่ห่อด้วย ZIP) * หากไฟล์เก็บถาวรมีหลายไฟล์ จะส่งคืน ZIP แบบแบนพร้อมไฟล์ทั้งหมดที่แตกออกไปยังระดับราก (โครงสร้างไดเรกทอรีที่ซ้อนกันจะถูกทำให้แบน) * การป้องกัน bomb ในตัวจะปฏิเสธไฟล์เก็บถาวรที่มีอัตราส่วนการบีบอัดหรือจำนวนไฟล์ที่มากเกินไป เพื่อป้องกันการใช้ทรัพยากรจนหมด --- --- url: https://docs.snapotter.com/tr/tools/files/extract-zip.md description: Bomba korumasıyla bir ZIP arşivinden dosyaları güvenle çıkarın. --- # Extract ZIP {#extract-zip} Bir ZIP arşivinden dosyaları güvenle çıkarın. Tek dosyalı arşivler içerdikleri dosyayı doğrudan döndürür; çok dosyalı arşivler çıkarılan içerikle düz bir ZIP döndürür. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Bir ZIP dosyası içeren multipart form verisi kabul eder. Bir ayarlar alanı gerekmez. ## Parameters {#parameters} Bu aracın yapılandırılabilir parametresi yoktur. Çıkarmak için bir `.zip` dosyası yükleyin. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Giriş olarak yalnızca `.zip` dosyaları kabul edilir. * Arşiv tek bir dosya içeriyorsa, o dosya doğrudan döndürülür (bir ZIP içine sarılmaz). * Arşiv birden fazla dosya içeriyorsa, tüm dosyalar kök seviyeye çıkarılmış şekilde düz bir ZIP döndürülür (iç içe dizin yapısı düzleştirilir). * Yerleşik bomba koruması, kaynak tükenmesini önlemek için aşırı sıkıştırma oranlarına veya dosya sayılarına sahip arşivleri reddeder. --- --- url: https://docs.snapotter.com/uk/tools/files/extract-zip.md description: Безпечне вилучення файлів з архіву ZIP із захистом від бомб. --- # Extract ZIP {#extract-zip} Безпечне вилучення файлів з архіву ZIP. Архіви з одним файлом повертають вміщений файл безпосередньо; архіви з кількома файлами повертають плаский ZIP із вилученим вмістом. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Приймає дані форми multipart з файлом ZIP. Поле налаштувань не потрібне. ## Parameters {#parameters} Цей інструмент не має налаштовуваних параметрів. Завантажте файл `.zip` для вилучення. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Як вхідні дані приймаються лише файли `.zip`. * Якщо архів містить один файл, цей файл повертається безпосередньо (не загорнутий у ZIP). * Якщо архів містить кілька файлів, повертається плаский ZIP з усіма файлами, вилученими на кореневий рівень (вкладена структура каталогів вирівнюється). * Вбудований захист від бомб відхиляє архіви з надмірними коефіцієнтами стиснення або кількістю файлів, щоб запобігти вичерпанню ресурсів. --- --- url: https://docs.snapotter.com/vi/tools/files/extract-zip.md description: Trích xuất tệp từ tệp lưu trữ ZIP một cách an toàn với bảo vệ chống bom nén. --- # Extract ZIP {#extract-zip} Trích xuất tệp từ tệp lưu trữ ZIP một cách an toàn. Tệp lưu trữ chỉ chứa một tệp sẽ trả về trực tiếp tệp bên trong; tệp lưu trữ chứa nhiều tệp sẽ trả về một ZIP phẳng với nội dung đã trích xuất. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Nhận dữ liệu multipart form với một tệp ZIP. Không cần trường settings. ## Parameters {#parameters} Công cụ này không có tham số cấu hình. Tải lên một tệp `.zip` để trích xuất. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * Chỉ các tệp `.zip` được chấp nhận làm đầu vào. * Nếu tệp lưu trữ chứa một tệp duy nhất, tệp đó được trả về trực tiếp (không bọc trong ZIP). * Nếu tệp lưu trữ chứa nhiều tệp, một ZIP phẳng được trả về với tất cả tệp được trích xuất ra cấp gốc (cấu trúc thư mục lồng nhau bị làm phẳng). * Bảo vệ chống bom nén tích hợp sẵn sẽ từ chối các tệp lưu trữ có tỷ lệ nén hoặc số lượng tệp quá lớn để ngăn cạn kiệt tài nguyên. --- --- url: https://docs.snapotter.com/zh-CN/tools/files/extract-zip.md description: 安全地从 ZIP 压缩包中提取文件,并防范压缩炸弹。 --- # Extract ZIP {#extract-zip} 安全地从 ZIP 压缩包中提取文件。单文件压缩包直接返回其中包含的文件;多文件压缩包返回一个包含所提取内容的扁平 ZIP。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` 接受包含 ZIP 文件的 multipart 表单数据。不需要 settings 字段。 ## Parameters {#parameters} 此工具没有可配置的参数。上传要提取的 `.zip` 文件。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notes {#notes} * 只接受 `.zip` 文件作为输入。 * 如果压缩包只包含一个文件,则直接返回该文件(不再包裹在 ZIP 中)。 * 如果压缩包包含多个文件,则返回一个扁平 ZIP,所有文件都提取到根级别(嵌套目录结构会被扁平化)。 * 内置的压缩炸弹防护会拒绝压缩率过高或文件数量过多的压缩包,以防止资源耗尽。 --- --- url: https://docs.snapotter.com/es/tools/pdf/extract-pages.md description: Extrae páginas seleccionadas de un PDF a un documento nuevo. --- # Extraer páginas {#extract-pages} Extrae páginas seleccionadas de un PDF a un documento nuevo y más pequeño. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Acepta datos de formulario multipart con un archivo PDF y un campo JSON `settings`. ## Parameters {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | range | string | Sí | - | Rango de páginas en sintaxis qpdf, p. ej. `"1-5,8,10-z"` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Notes {#notes} * Los rangos de páginas usan la sintaxis de qpdf: `1-5` para las páginas 1 a 5, `z` para la última página y comas para combinar rangos (p. ej. `1-3,7,10-z`). * Las páginas extraídas conservan su formato, anotaciones y enlaces originales. --- --- url: https://docs.snapotter.com/es/tools/files/extract-zip.md description: >- Extrae archivos de forma segura de un archivo ZIP con protección contra bombas. --- # Extraer ZIP {#extract-zip} Extrae archivos de forma segura de un archivo ZIP. Los archivos con un solo fichero devuelven directamente el fichero contenido; los archivos con varios ficheros devuelven un ZIP plano con el contenido extraído. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Acepta datos de formulario multipart con un archivo ZIP. No se requiere un campo de ajustes. ## Parámetros {#parameters} Esta herramienta no tiene parámetros configurables. Sube un archivo `.zip` para extraerlo. ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notas {#notes} * Solo se aceptan archivos `.zip` como entrada. * Si el archivo contiene un solo fichero, ese fichero se devuelve directamente (no envuelto en un ZIP). * Si el archivo contiene varios ficheros, se devuelve un ZIP plano con todos los ficheros extraídos al nivel raíz (la estructura de directorios anidada se aplana). * La protección integrada contra bombas rechaza los archivos con ratios de compresión o cantidades de ficheros excesivas para evitar el agotamiento de recursos. --- --- url: https://docs.snapotter.com/sv/tools/video/extract-audio.md description: Dra ut ljudspåret ur en video. --- # Extrahera ljud {#extract-audio} Extrahera ljudspåret från en videofil och spara det som MP3, WAV, M4A eller OGG. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/extract-audio` Tar emot multipart-formulärdata med en videofil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | format | string | Nej | `"mp3"` | Utdataljudformat: `mp3`, `wav`, `m4a`, `ogg` | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" \ -F 'settings={"format": "mp3"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", "originalSize": 12500000, "processedSize": 3200000 } ``` ## Anteckningar {#notes} * Om videon inte har något ljudspår returnerar begäran ett 400-fel. * MP3 är förstörande men brett kompatibelt. WAV är förlustfritt men stort. M4A (AAC) erbjuder en bra balans mellan kvalitet och storlek. OGG finns tillgängligt för arbetsflöden med öppna codecs. * När källjudet redan är AAC och utdataformatet är M4A kopieras ljudströmmen utan omkodning. --- --- url: https://docs.snapotter.com/sv/tools/video/extract-subtitles.md description: Dra ut undertextspåret ur en video som en SRT-fil. --- # Extrahera undertexter {#extract-subtitles} Extrahera det inbäddade undertextspåret från en videocontainer och ladda ner det som en SRT-fil. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/extract-subtitles` Tar emot multipart-formulärdata med en videofil. Detta verktyg har inga konfigurerbara inställningar. ## Parametrar {#parameters} Detta verktyg har inga parametrar. Det extraherar det första undertextspåret som hittas i videocontainern. ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/extract-subtitles \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@clip.mp4" ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", "originalSize": 12500000, "processedSize": 4500 } ``` ## Anteckningar {#notes} * Videon måste innehålla ett inbäddat undertextspår. Om inget undertextspår hittas returnerar begäran ett 400-fel. * Om videon har flera undertextspår extraheras det första. * Utdataformatet är SRT oavsett det ursprungliga undertextformatet i containern. --- --- url: https://docs.snapotter.com/pt-BR/tools/files/extract-zip.md description: >- Extraia arquivos de um arquivo ZIP com segurança, com proteção contra zip bombs. --- # Extrair ZIP {#extract-zip} Extraia arquivos de um arquivo ZIP com segurança. Arquivos ZIP de um único arquivo retornam o arquivo contido diretamente; arquivos ZIP com vários arquivos retornam um ZIP plano com o conteúdo extraído. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Aceita dados de formulário multipart com um arquivo ZIP. Nenhum campo de configurações é necessário. ## Parâmetros {#parameters} Esta ferramenta não tem parâmetros configuráveis. Envie um arquivo `.zip` para extrair. ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Notas {#notes} * Apenas arquivos `.zip` são aceitos como entrada. * Se o arquivo contiver um único arquivo, esse arquivo é retornado diretamente (sem ser empacotado em um ZIP). * Se o arquivo contiver vários arquivos, um ZIP plano é retornado com todos os arquivos extraídos para o nível raiz (a estrutura de diretórios aninhados é achatada). * A proteção interna contra zip bombs rejeita arquivos com taxas de compressão ou quantidades de arquivos excessivas, para evitar o esgotamento de recursos. --- --- url: https://docs.snapotter.com/fr/tools/pdf/extract-pages.md description: Extraire des pages sélectionnées d'un PDF vers un nouveau document. --- # Extraire des pages {#extract-pages} Extrayez des pages sélectionnées d'un PDF vers un nouveau document plus petit. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/extract-pages` Accepte des données de formulaire multipart avec un fichier PDF et un champ `settings` au format JSON. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | range | string | Oui | - | Plage de pages en syntaxe qpdf, par exemple `"1-5,8,10-z"` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/extract-pages \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"range": "1-5,8,10-z"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 1100000 } ``` ## Remarques {#notes} * Les plages de pages utilisent la syntaxe qpdf : `1-5` pour les pages 1 à 5, `z` pour la dernière page, et des virgules pour combiner des plages (par exemple `1-3,7,10-z`). * Les pages extraites conservent leur mise en forme, leurs annotations et leurs liens d'origine. --- --- url: https://docs.snapotter.com/fr/tools/files/extract-zip.md description: >- Extrait en toute sécurité les fichiers d'une archive ZIP avec protection contre les bombes. --- # Extraire un ZIP {#extract-zip} Extrait en toute sécurité les fichiers d'une archive ZIP. Les archives à fichier unique renvoient directement le fichier contenu ; les archives à plusieurs fichiers renvoient un ZIP à plat avec le contenu extrait. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/extract-zip` Accepte des données de formulaire multipart avec un fichier ZIP. Aucun champ de réglages n'est requis. ## Paramètres {#parameters} Cet outil n'a aucun paramètre configurable. Chargez un fichier `.zip` à extraire. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/extract-zip \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@archive.zip" ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive_extracted.zip", "originalSize": 2800000, "processedSize": 3500000 } ``` ## Remarques {#notes} * Seuls les fichiers `.zip` sont acceptés en entrée. * Si l'archive contient un seul fichier, ce fichier est renvoyé directement (et non enveloppé dans un ZIP). * Si l'archive contient plusieurs fichiers, un ZIP à plat est renvoyé avec tous les fichiers extraits à la racine (la structure de répertoires imbriqués est aplatie). * Une protection intégrée contre les bombes rejette les archives présentant des taux de compression ou des nombres de fichiers excessifs afin d'éviter l'épuisement des ressources. --- --- url: https://docs.snapotter.com/ar/tools/image/enhance-faces.md description: >- استعادة وتحسين حدّة الوجوه المشوّشة أو منخفضة الجودة في الصور باستخدام نموذجَي الذكاء الاصطناعي GFPGAN وCodeFormer. --- # Face Enhancement {#face-enhancement} استعِد وحسّن الوجوه في الصور باستخدام نماذج الذكاء الاصطناعي (GFPGAN/CodeFormer). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **المعالجة:** غير متزامنة (تُعيد 202، استعلِم من `/api/v1/jobs/{jobId}/progress` عن الحالة عبر SSE) **حزم النماذج:** `upscale-enhance` (5-6 غيغابايت) و`face-detection` (200-300 ميغابايت) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | ملف الصورة (multipart) | | model | string | No | `"auto"` | النموذج المستخدم: `auto`، `gfpgan`، `codeformer` | | strength | number | No | `0.8` | قوة التحسين (0-1). القيم الأعلى تنتج تحسينًا أقوى | | onlyCenterFace | boolean | No | `false` | تحسين الوجه الأكثر مركزية/بروزًا فقط | | sensitivity | number | No | `0.5` | حساسية اكتشاف الوجه (0-1) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Notes {#notes} * يتطلب كلًّا من حزمة النموذج `upscale-enhance` (5-6 غيغابايت) وحزمة النموذج `face-detection` (200-300 ميغابايت). * ينتج GFPGAN تحسينًا أكثر حدّة؛ ويحافظ CodeFormer على الهوية بشكل أفضل. يختار `auto` أفضل نموذج للمدخل. * الإخراج دائمًا بصيغة PNG لأقصى جودة. * تُولَّد معاينة WebP إلى جانب الإخراج بدقّته الكاملة لعرض أسرع في الواجهة الأمامية. * يمزج المُعامِل `strength` الوجه المُحسَّن مع الأصل. استخدم القيم الأقل (0.3-0.5) للتحسينات الخفيفة، والقيم الأعلى (0.7-1.0) للاستعادة الأقوى. * يدعم صيغ الإدخال HEIC/HEIF وRAW وTGA وPSD وEXR وHDR عبر فكّ الشفرة التلقائي. --- --- url: https://docs.snapotter.com/hi/tools/image/enhance-faces.md description: >- GFPGAN और CodeFormer AI मॉडल के साथ छवियों में धुंधले या निम्न-गुणवत्ता वाले चेहरों को पुनर्स्थापित और तीक्ष्ण करें। --- # Face Enhancement {#face-enhancement} AI मॉडल (GFPGAN/CodeFormer) का उपयोग करके छवियों में चेहरों को पुनर्स्थापित और उन्नत करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Processing:** अतुल्यकालिक (202 लौटाता है, SSE के माध्यम से स्थिति के लिए `/api/v1/jobs/{jobId}/progress` पर पोल करें) **Model bundles:** `upscale-enhance` (5-6 GB) और `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | छवि फ़ाइल (मल्टीपार्ट) | | model | string | No | `"auto"` | उपयोग करने के लिए मॉडल: `auto`, `gfpgan`, `codeformer` | | strength | number | No | `0.8` | उन्नयन शक्ति (0-1)। उच्च मान अधिक प्रबल उन्नयन उत्पन्न करते हैं | | onlyCenterFace | boolean | No | `false` | केवल सबसे केंद्रीय/प्रमुख चेहरे को उन्नत करें | | sensitivity | number | No | `0.5` | चेहरा पहचान संवेदनशीलता (0-1) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Notes {#notes} * `upscale-enhance` मॉडल बंडल (5-6 GB) और `face-detection` मॉडल बंडल (200-300 MB) दोनों आवश्यक हैं। * GFPGAN अधिक आक्रामक उन्नयन उत्पन्न करता है; CodeFormer पहचान को बेहतर संरक्षित करता है। `auto` इनपुट के लिए सर्वोत्तम मॉडल का चयन करता है। * अधिकतम गुणवत्ता के लिए आउटपुट हमेशा PNG फ़ॉर्मेट होता है। * तेज़ फ़्रंटएंड प्रदर्शन के लिए पूर्ण-विभेदन आउटपुट के साथ एक WebP पूर्वावलोकन उत्पन्न किया जाता है। * `strength` पैरामीटर उन्नत चेहरे को मूल के साथ मिश्रित करता है। सूक्ष्म सुधारों के लिए कम मान (0.3-0.5), प्रबल पुनर्स्थापना के लिए उच्च मान (0.7-1.0) का उपयोग करें। * स्वचालित डिकोडिंग के माध्यम से HEIC/HEIF, RAW, TGA, PSD, EXR, और HDR इनपुट फ़ॉर्मेट का समर्थन करता है। --- --- url: https://docs.snapotter.com/th/tools/image/enhance-faces.md description: >- ฟื้นฟูและทำให้ใบหน้าที่เบลอหรือคุณภาพต่ำในภาพคมชัดขึ้นด้วยโมเดล AI GFPGAN และ CodeFormer --- # Face Enhancement {#face-enhancement} ฟื้นฟูและปรับปรุงใบหน้าในภาพด้วยโมเดล AI (GFPGAN/CodeFormer) ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **การประมวลผล:** แบบอะซิงโครนัส (ส่งคืน 202, ดึงสถานะจาก `/api/v1/jobs/{jobId}/progress` ผ่าน SSE) **ชุดโมเดล:** `upscale-enhance` (5-6 GB) และ `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | ไฟล์ภาพ (multipart) | | model | string | No | `"auto"` | โมเดลที่จะใช้: `auto`, `gfpgan`, `codeformer` | | strength | number | No | `0.8` | ความแรงของการปรับปรุง (0-1) ค่าที่สูงกว่าจะให้การปรับปรุงที่แรงกว่า | | onlyCenterFace | boolean | No | `false` | ปรับปรุงเฉพาะใบหน้าที่อยู่ตรงกลาง/โดดเด่นที่สุด | | sensitivity | number | No | `0.5` | ความไวในการตรวจจับใบหน้า (0-1) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Notes {#notes} * ต้องใช้ทั้งชุดโมเดล `upscale-enhance` (5-6 GB) และชุดโมเดล `face-detection` (200-300 MB) * GFPGAN ให้การปรับปรุงที่เชิงรุกกว่า ส่วน CodeFormer รักษาอัตลักษณ์ได้ดีกว่า `auto` เลือกโมเดลที่ดีที่สุดสำหรับอินพุต * เอาต์พุตเป็นรูปแบบ PNG เสมอเพื่อคุณภาพสูงสุด * ระบบจะสร้างตัวอย่าง WebP ควบคู่ไปกับเอาต์พุตความละเอียดเต็มเพื่อการแสดงผลที่เร็วขึ้นในส่วนหน้า * พารามิเตอร์ `strength` ผสมใบหน้าที่ปรับปรุงแล้วกับต้นฉบับ ใช้ค่าที่ต่ำกว่า (0.3-0.5) สำหรับการปรับปรุงเล็กน้อย และค่าที่สูงกว่า (0.7-1.0) สำหรับการฟื้นฟูที่แรงขึ้น * รองรับรูปแบบอินพุต HEIC/HEIF, RAW, TGA, PSD, EXR และ HDR ผ่านการถอดรหัสอัตโนมัติ --- --- url: https://docs.snapotter.com/uk/tools/image/enhance-faces.md description: >- Відновлюйте та підвищуйте різкість розмитих або низькоякісних облич на зображеннях за допомогою AI-моделей GFPGAN та CodeFormer. --- # Face Enhancement {#face-enhancement} Відновлюйте та покращуйте обличчя на зображеннях за допомогою AI-моделей (GFPGAN/CodeFormer). ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Processing:** Асинхронна (повертає 202, опитуйте `/api/v1/jobs/{jobId}/progress` для отримання статусу через SSE) **Model bundles:** `upscale-enhance` (5-6 GB) та `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | Файл зображення (multipart) | | model | string | No | `"auto"` | Модель для використання: `auto`, `gfpgan`, `codeformer` | | strength | number | No | `0.8` | Сила покращення (0-1). Вищі значення дають сильніше покращення | | onlyCenterFace | boolean | No | `false` | Покращувати лише найбільш центральне/помітне обличчя | | sensitivity | number | No | `0.5` | Чутливість виявлення облич (0-1) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Notes {#notes} * Потрібні обидва пакети моделей: `upscale-enhance` (5-6 GB) та `face-detection` (200-300 MB). * GFPGAN дає агресивніше покращення; CodeFormer краще зберігає ідентичність. `auto` обирає найкращу модель для вхідних даних. * Вивід завжди у форматі PNG для максимальної якості. * Поряд із виводом повної роздільної здатності генерується попередній перегляд WebP для швидшого відображення у фронтенді. * Параметр `strength` змішує покращене обличчя з оригіналом. Використовуйте нижчі значення (0.3-0.5) для м'яких покращень, вищі значення (0.7-1.0) для сильнішого відновлення. * Підтримує вхідні формати HEIC/HEIF, RAW, TGA, PSD, EXR та HDR через автоматичне декодування. --- --- url: https://docs.snapotter.com/hi/tools/audio/fade-audio.md description: audio में fade-in और fade-out प्रभाव जोड़ें। --- # Fade Audio {#fade-audio} किसी audio फ़ाइल के आरंभ और अंत में fade-in और fade-out प्रभाव जोड़ें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` एक audio फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fadeInS | number | No | `1` | सेकंड में fade-in अवधि (0 से 30) | | fadeOutS | number | No | `1` | सेकंड में fade-out अवधि (0 से 30) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * उस fade दिशा को छोड़ने के लिए किसी भी मान को `0` पर सेट करें। कम से कम एक 0 से अधिक होना चाहिए। * यदि fade अवधि audio की लंबाई से अधिक हो जाती है तो इसे audio लंबाई तक सीमित कर दिया जाता है। * आउटपुट आमतौर पर इनपुट container रखता है। AAC इनपुट M4A के रूप में लिखा जाता है, और असमर्थित डिकोड-ओनली इनपुट MP3 पर वापस चले जाते हैं। --- --- url: https://docs.snapotter.com/id/tools/audio/fade-audio.md description: Tambahkan efek fade-in dan fade-out ke audio. --- # Fade Audio {#fade-audio} Tambahkan efek fade-in dan fade-out ke awal dan akhir file audio. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Menerima data formulir multipart dengan file audio dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | fadeInS | number | Tidak | `1` | Durasi fade-in dalam detik (0 hingga 30) | | fadeOutS | number | Tidak | `1` | Durasi fade-out dalam detik (0 hingga 30) | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Catatan {#notes} * Setel salah satu nilai ke `0` untuk melewati arah fade tersebut. Setidaknya satu harus lebih besar dari 0. * Durasi fade dibatasi ke panjang audio jika melebihinya. * Output biasanya mempertahankan kontainer input. Input AAC ditulis sebagai M4A, dan input decode-only yang tidak didukung beralih ke MP3. --- --- url: https://docs.snapotter.com/ko/tools/audio/fade-audio.md description: 오디오에 페이드 인 및 페이드 아웃 효과를 추가합니다. --- # Fade Audio {#fade-audio} 오디오 파일의 시작과 끝에 페이드 인 및 페이드 아웃 효과를 추가합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` 오디오 파일과 JSON `settings` 필드가 포함된 multipart form data를 받습니다. ## 파라미터 {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fadeInS | number | No | `1` | 페이드 인 길이(초 단위, 0 ~ 30) | | fadeOutS | number | No | `1` | 페이드 아웃 길이(초 단위, 0 ~ 30) | ## 요청 예시 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## 응답 예시 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## 참고 {#notes} * 해당 페이드 방향을 건너뛰려면 값을 `0`으로 설정하세요. 최소 하나는 0보다 커야 합니다. * 페이드 길이가 오디오 길이를 초과하면 오디오 길이로 제한됩니다. * 출력은 보통 입력 컨테이너를 유지합니다. AAC 입력은 M4A로 작성되며, 지원되지 않는 디코드 전용 입력은 MP3로 폴백됩니다. --- --- url: https://docs.snapotter.com/nl/tools/audio/fade-audio.md description: Voeg fade-in- en fade-out-effecten toe aan audio. --- # Fade Audio {#fade-audio} Voeg fade-in- en fade-out-effecten toe aan het begin en einde van een audiobestand. ## API-endpoint {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Accepteert multipart-formuliergegevens met een audiobestand en een JSON `settings`-veld. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | fadeInS | number | Nee | `1` | Fade-in-duur in seconden (0 tot 30) | | fadeOutS | number | Nee | `1` | Fade-out-duur in seconden (0 tot 30) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Voorbeeldrespons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Opmerkingen {#notes} * Stel een van beide waarden in op `0` om die faderichting over te slaan. Ten minste één moet groter zijn dan 0. * De fadeduur wordt afgekapt tot de audiolengte als deze die overschrijdt. * De uitvoer behoudt meestal de invoercontainer. AAC-invoer wordt geschreven als M4A, en niet-ondersteunde decode-only-invoer valt terug op MP3. --- --- url: https://docs.snapotter.com/sv/tools/audio/fade-audio.md description: Lägg till in- och uttoningseffekter i ljud. --- # Fade Audio {#fade-audio} Lägg till in- och uttoningseffekter i början och slutet av en ljudfil. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Accepterar multipart-formulärdata med en ljudfil och ett JSON `settings`-fält. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | fadeInS | number | Nej | `1` | Intoningslängd i sekunder (0 till 30) | | fadeOutS | number | Nej | `1` | Uttoningslängd i sekunder (0 till 30) | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Anteckningar {#notes} * Sätt något av värdena till `0` för att hoppa över den toningsriktningen. Minst ett måste vara större än 0. * Toningslängden begränsas till ljudets längd om den överstiger den. * Utdata behåller vanligtvis inmatningens container. AAC-inmatning skrivs som M4A, och inmatningar som endast kan avkodas och inte stöds faller tillbaka till MP3. --- --- url: https://docs.snapotter.com/th/tools/audio/fade-audio.md description: เพิ่มเอฟเฟกต์ fade-in และ fade-out ให้กับเสียง --- # Fade Audio {#fade-audio} เพิ่มเอฟเฟกต์ fade-in และ fade-out ที่จุดเริ่มต้นและจุดสิ้นสุดของไฟล์เสียง ## API Endpoint {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` รับข้อมูลฟอร์มแบบ multipart พร้อมไฟล์เสียงและฟิลด์ JSON `settings` ## พารามิเตอร์ {#parameters} | พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย | |-----------|------|----------|---------|-------------| | fadeInS | number | ไม่ | `1` | ระยะเวลา fade-in เป็นวินาที (0 ถึง 30) | | fadeOutS | number | ไม่ | `1` | ระยะเวลา fade-out เป็นวินาที (0 ถึง 30) | ## ตัวอย่างคำขอ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## ตัวอย่างการตอบกลับ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## หมายเหตุ {#notes} * ตั้งค่าใดค่าหนึ่งเป็น `0` เพื่อข้ามทิศทางการเฟดนั้น อย่างน้อยหนึ่งค่าต้องมากกว่า 0 * ระยะเวลาการเฟดถูกจำกัดไว้ที่ความยาวของเสียงหากมันเกิน * เอาต์พุตมักคงคอนเทนเนอร์อินพุตไว้ อินพุต AAC จะเขียนเป็น M4A และอินพุตแบบถอดรหัสอย่างเดียวที่ไม่รองรับจะถอยกลับเป็น MP3 --- --- url: https://docs.snapotter.com/tr/tools/audio/fade-audio.md description: Sese içeri ve dışarı solma efektleri ekleyin. --- # Fade Audio {#fade-audio} Bir ses dosyasının başına ve sonuna içeri solma (fade-in) ve dışarı solma (fade-out) efektleri ekleyin. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Bir ses dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | fadeInS | number | Hayır | `1` | Saniye cinsinden içeri solma süresi (0 ile 30 arası) | | fadeOutS | number | Hayır | `1` | Saniye cinsinden dışarı solma süresi (0 ile 30 arası) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notlar {#notes} * O solma yönünü atlamak için değerlerden birini `0` olarak ayarlayın. En az biri 0'dan büyük olmalıdır. * Solma süresi, ses uzunluğunu aşarsa ona kırpılır. * Çıktı genellikle girdi konteynerini korur. AAC girdisi M4A olarak yazılır ve desteklenmeyen yalnızca-çözümleme (decode-only) girdileri MP3'e geri döner. --- --- url: https://docs.snapotter.com/pt-BR/tools/audio/fade-audio.md description: Adicione efeitos de fade-in e fade-out ao áudio. --- # Fade de Áudio {#fade-audio} Adicione efeitos de fade-in e fade-out ao início e ao fim de um arquivo de áudio. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Aceita dados de formulário multipart com um arquivo de áudio e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | fadeInS | number | Não | `1` | Duração do fade-in em segundos (0 a 30) | | fadeOutS | number | Não | `1` | Duração do fade-out em segundos (0 a 30) | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notas {#notes} * Defina qualquer um dos valores como `0` para pular aquela direção de fade. Pelo menos um deles precisa ser maior que 0. * A duração do fade é limitada ao comprimento do áudio se ultrapassá-lo. * A saída normalmente mantém o contêiner de entrada. Entrada AAC é gravada como M4A, e entradas apenas de decodificação não suportadas recorrem a MP3. --- --- url: https://docs.snapotter.com/fr/tools/pdf/rotate-pdf.md description: Faire pivoter les pages d'un PDF de 90, 180 ou 270 degrés. --- # Faire pivoter un PDF {#rotate-pdf} Faites pivoter toutes les pages ou des pages sélectionnées d'un PDF d'un angle spécifié. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/rotate-pdf` Accepte des données de formulaire multipart avec un fichier PDF et un champ `settings` au format JSON. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | angle | integer | Non | `90` | Angle de rotation : `90`, `180`, ou `270` | | range | string | Non | `"1-z"` | Plage de pages en syntaxe qpdf, par exemple `"1-5,8"` (`"1-z"` = toutes les pages) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/rotate-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"angle": 90, "range": "1-3"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2450000 } ``` ## Remarques {#notes} * La rotation se fait dans le sens des aiguilles d'une montre. * Les plages de pages utilisent la syntaxe qpdf : `1-5` pour les pages 1 à 5, `z` pour la dernière page, et des virgules pour combiner des plages. * La plage par défaut `"1-z"` fait pivoter toutes les pages. --- --- url: https://docs.snapotter.com/de/tools/image/replace-color.md description: >- Ersetze eine bestimmte Farbe in einem Bild durch eine andere Farbe oder mache sie transparent. --- # Farbe ersetzen & umkehren {#replace-invert-color} Ersetze Pixel, die einer Quellfarbe entsprechen, durch eine Zielfarbe oder mache sie transparent. Verwendet die euklidische Distanz im RGB-Raum mit konfigurierbarer Toleranz für sanfte Übergänge an Farbgrenzen. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/replace-color` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | sourceColor | string | Nein | `"#FF0000"` | Zu findende Hex-Farbe (Format: `#RRGGBB`) | | targetColor | string | Nein | `"#00FF00"` | Hex-Farbe, durch die ersetzt wird (Format: `#RRGGBB`) | | makeTransparent | boolean | Nein | `false` | Übereinstimmende Pixel transparent machen, statt sie durch die Zielfarbe zu ersetzen | | tolerance | number | Nein | `30` | Toleranz für die Farbübereinstimmung (0 bis 255). Höhere Werte erfassen einen größeren Bereich ähnlicher Farben | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/replace-color \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"sourceColor": "#FF0000", "targetColor": "#0000FF", "tolerance": 40}' ``` Einen grünen Hintergrund transparent machen: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/replace-color \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@greenscreen.png" \ -F 'settings={"sourceColor": "#00FF00", "makeTransparent": true, "tolerance": 50}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", "originalSize": 2450000, "processedSize": 2100000 } ``` ## Hinweise {#notes} * Die Farbübereinstimmung verwendet die euklidische Distanz im RGB-Raum, skaliert durch `tolerance * sqrt(3)`. * Die Überblendung beim Ersetzen ist proportional zur Farbdistanz: Pixel, die näher an der Quellfarbe liegen, erhalten mehr von der Zielfarbe, was sanfte Übergänge erzeugt. * Wenn `makeTransparent` auf `true` gesetzt ist, wird die Ausgabe auf PNG (oder WebP/AVIF) erzwungen, falls das Eingabeformat keine Alphakanäle unterstützt (z. B. JPEG). * Eine Toleranz von 0 erfasst nur die exakte Quellfarbe. Höhere Werte (50+) erfassen einen breiteren Bereich ähnlicher Farbtöne. * Das Ausgabeformat entspricht dem Eingabeformat, sofern keine Transparenz benötigt wird und das Eingabeformat keine Alpha-Unterstützung bietet. --- --- url: https://docs.snapotter.com/de/tools/image/adjust-colors.md description: >- Helligkeit, Kontrast, Sättigung, Temperatur, Farbton und Kanäle anpassen sowie Farbeffekte anwenden. --- # Farben anpassen {#adjust-colors} Umfassendes Werkzeug zur Farbanpassung, das Helligkeit, Kontrast, Belichtung, Sättigung, Temperatur, Tönung, Farbtonrotation, kanalweise Pegel und Ein-Klick-Effekte (Graustufen, Sepia, Invertieren) in einem einzigen Endpunkt vereint. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/adjust-colors` Nimmt Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | brightness | number | Nein | `0` | Helligkeitsanpassung (-100 bis 100) | | contrast | number | Nein | `0` | Kontrastanpassung (-100 bis 100) | | exposure | number | Nein | `0` | Belichtung / Mittelton-Gamma (-100 bis 100) | | saturation | number | Nein | `0` | Farbsättigung (-100 bis 100) | | temperature | number | Nein | `0` | Weißabgleich: kühl/blau bis warm/orange (-100 bis 100) | | tint | number | Nein | `0` | Tönungsverschiebung: grün bis magenta (-100 bis 100) | | hue | number | Nein | `0` | Farbtonrotation in Grad (-180 bis 180) | | sharpness | number | Nein | `0` | Schärfungsstärke (0 bis 100) | | red | number | Nein | `100` | Pegel des Rotkanals (0 bis 200, 100 = unverändert) | | green | number | Nein | `100` | Pegel des Grünkanals (0 bis 200, 100 = unverändert) | | blue | number | Nein | `100` | Pegel des Blaukanals (0 bis 200, 100 = unverändert) | | effect | string | Nein | `"none"` | Farbeffekt: `none`, `grayscale`, `sepia`, `invert` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"brightness": 20, "contrast": 10, "saturation": -30, "effect": "none"}' ``` Einen warmen Vintage-Look anwenden: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/adjust-colors \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"temperature": 40, "saturation": -15, "contrast": 10, "effect": "sepia"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Hinweise {#notes} * Alle Parameter haben neutrale Standardwerte, sodass Sie nur das anpassen können, was Sie benötigen. * Die Anpassungen werden in dieser Reihenfolge angewendet: Helligkeit, Kontrast, Belichtung, Sättigung/Farbton, Temperatur/Tönung, Schärfe, Kanäle, Effekte. * Die Temperatur verwendet eine 3x3-Farbrekombinationsmatrix auf den Achsen Blau-Orange und Grün-Magenta. * Die Belichtung wird auf die Gamma-Funktion von Sharp abgebildet (positive Werte hellen Mitteltöne auf, negative verdunkeln sie). * Dieser Endpunkt antwortet auch unter den Alt-Pfaden `/api/v1/tools/image/brightness-contrast`, `/api/v1/tools/image/saturation`, `/api/v1/tools/image/color-channels` und `/api/v1/tools/image/color-effects`. Alle verwenden dasselbe Schema. * Das Ausgabeformat entspricht dem Eingabeformat. Eingaben in HEIC, RAW, PSD und SVG werden vor der Verarbeitung automatisch dekodiert. --- --- url: https://docs.snapotter.com/de/tools/image/color-blindness.md description: >- Simuliert, wie Bilder für Menschen mit verschiedenen Arten von Farbfehlsichtigkeit erscheinen. --- # Farbenblindheits-Simulation {#color-blindness-simulation} Simuliert Farbfehlsichtigkeit (CVD), um vorab zu zeigen, wie Bilder für Menschen mit verschiedenen Arten von Farbenblindheit erscheinen. Nützlich für Barrierefreiheitstests von Designs, Diagrammen und Benutzeroberflächen. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/color-blindness` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | simulationType | string | Nein | `"deuteranomaly"` | Art der zu simulierenden Farbfehlsichtigkeit | ### Simulationstypen {#simulation-types} | Wert | Zustand | Beschreibung | |-------|-----------|-------------| | `protanopia` | Rotblind | Vollständiges Fehlen der roten Zapfenzellen | | `deuteranopia` | Grünblind | Vollständiges Fehlen der grünen Zapfenzellen | | `tritanopia` | Blaublind | Vollständiges Fehlen der blauen Zapfenzellen | | `protanomaly` | Rotschwäche | Verringerte Empfindlichkeit der roten Zapfen | | `deuteranomaly` | Grünschwäche | Verringerte Empfindlichkeit der grünen Zapfen (am häufigsten) | | `tritanomaly` | Blauschwäche | Verringerte Empfindlichkeit der blauen Zapfen | | `achromatopsia` | Vollständig farbenblind | Vollständiges Fehlen des Farbsehens | | `blueConeMonochromacy` | Nur Blauzapfen | Nur die blauen Zapfen sind funktionsfähig | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-blindness \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@design.png" \ -F 'settings={"simulationType": "deuteranopia"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/design.png", "originalSize": 1850000, "processedSize": 1820000 } ``` ## Hinweise {#notes} * Deuteranomalie (Grünschwäche) ist die Voreinstellung, da sie die häufigste Form der Farbfehlsichtigkeit ist und etwa 6 % der Männer betrifft. * Die Simulation verwendet Farbtransformationsmatrizen, die modellieren, wie verringerte oder fehlende Zapfenphotorezeptoren die wahrgenommenen Farben verändern. * Dieses Werkzeug ist zerstörungsfrei und erzeugt nur eine Vorschau. Es verändert das Originalbild nicht im Sinne der Barrierefreiheit. * Das Ausgabeformat entspricht dem Eingabeformat. HEIC-, RAW-, PSD- und SVG-Eingaben werden vor der Verarbeitung automatisch dekodiert. --- --- url: https://docs.snapotter.com/de/tools/image/color-palette.md description: Extrahiert die dominierenden Farben eines Bildes als Farbpalette. --- # Farbpalette {#color-palette} Extrahiert die dominierenden Farben eines Bildes und gibt sie als Hex-Farbwerte zurück. Verwendet eine quantisierte Häufigkeitsanalyse, um die auffälligsten und optisch am deutlichsten unterscheidbaren Farben zu ermitteln. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/color-palette` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem optionalen JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | count | integer | Nein | `8` | Anzahl der zu extrahierenden Farben (2-16) | | format | string | Nein | `"hex"` | Farbformat: `hex`, `rgb`, `hsl` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Beispielantwort {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Antwortfelder {#response-fields} | Feld | Typ | Beschreibung | |-------|------|-------------| | filename | string | Bereinigter Dateiname | | colors | array | Array von Farbstrings im angeforderten Format, sortiert nach Dominanz (häufigste zuerst) | | hex | array | Array von Hex-Farbstrings (immer Hex, unabhängig von der Einstellung `format`) | | count | number | Anzahl der extrahierten Farben | ## Hinweise {#notes} * Gibt bis zu `count` dominierende Farben zurück (Standard 8, Bereich 2-16), sortiert nach Häufigkeit (häufigste zuerst). * Das Bild wird intern auf 100x100 Pixel verkleinert, um es zu analysieren, sodass die Palette die gesamte Farbverteilung und nicht kleine Details widerspiegelt. * Die Farben werden mit Median-Cut-Quantisierung extrahiert, die die Pixelmengen rekursiv entlang des Kanals mit dem größten Wertebereich aufteilt. * Der Alphakanal wird vor der Analyse entfernt, sodass transparente Bereiche nicht berücksichtigt werden. * Dies ist ein reiner Lese-Endpunkt. Er erzeugt weder eine herunterladbare Ausgabedatei noch ein `jobId`. * HEIC-, RAW-, PSD- und SVG-Eingaben werden vor der Analyse automatisch dekodiert. --- --- url: https://docs.snapotter.com/sv/tools/image/color-palette.md description: Extrahera dominerande färger från en bild som en färgpalett. --- # Färgpalett {#color-palette} Extrahera de dominerande färgerna från en bild och returnera dem som hex-färgvärden. Använder kvantiserad frekvensanalys för att identifiera de mest framträdande och visuellt distinkta färgerna. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/color-palette` Tar emot multipart-formulärdata med en bildfil och ett valfritt JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | count | integer | Nej | `8` | Antal färger att extrahera (2-16) | | format | string | Nej | `"hex"` | Färgformat: `hex`, `rgb`, `hsl` | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/color-palette \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"count": 6, "format": "hex"}' ``` ## Exempelsvar {#example-response} ```json { "filename": "photo.jpg", "colors": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "hex": [ "#304080", "#e0a060", "#f0f0f0", "#203020", "#a0c0e0", "#806040" ], "count": 6 } ``` ## Svarsfält {#response-fields} | Fält | Typ | Beskrivning | |-------|------|-------------| | filename | string | Sanerat filnamn | | colors | array | Array med färgsträngar i det begärda formatet, ordnade efter dominans (mest frekvent först) | | hex | array | Array med hex-färgsträngar (alltid hex, oavsett inställningen `format`) | | count | number | Antal extraherade färger | ## Anteckningar {#notes} * Returnerar upp till `count` dominerande färger (standard 8, intervall 2-16), sorterade efter frekvens (vanligast först). * Bilden storleksändras internt till 100x100 pixlar för analys, så paletten representerar den övergripande färgfördelningen snarare än små detaljer. * Färger extraheras med median-cut-kvantisering, som rekursivt delar upp pixelpopulationer längs kanalen med det bredaste intervallet. * Alfakanalen tas bort före analysen, så transparenta områden beaktas inte. * Detta är en skrivskyddad slutpunkt. Den genererar ingen nedladdningsbar utdatafil eller `jobId`. * Indata i HEIC, RAW, PSD och SVG avkodas automatiskt före analysen. --- --- url: https://docs.snapotter.com/hi/tools/image/favicon.md description: किसी स्रोत छवि से सभी मानक favicon और app आइकन आकार जनरेट करें। --- # Favicon Generator {#favicon-generator} किसी स्रोत छवि से favicon और app आइकन फ़ाइलों का पूरा सेट जनरेट करें। ब्राउज़रों, Apple डिवाइसों और Android के लिए आवश्यक सभी मानक आकार बनाता है, साथ ही एक web manifest और एक HTML स्निपेट भी। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/favicon` एक या अधिक image फ़ाइलों और एक वैकल्पिक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | background | string | नहीं | - | Background hex रंग (जैसे `"#ffffff"`)। सेट होने पर, आइकन को इस रंग पर फ़्लैट कर दिया जाता है। | | padding | integer | नहीं | `0` | आइकन सामग्री के चारों ओर Padding प्रतिशत (0 से 40) | | radius | integer | नहीं | `0` | गोल आइकनों के लिए Corner radius प्रतिशत (0 से 50) | | sizes | integer\[] | नहीं | - | आउटपुट को विशिष्ट पिक्सेल आकारों तक सीमित करें (जैसे `[16, 32, 180]`)। सभी मानक आकार जनरेट करने के लिए इसे छोड़ दें। | | themeColor | string | नहीं | `"#ffffff"` | web manifest के लिए Theme रंग hex | ## Generated Files {#generated-files} प्रत्येक इनपुट छवि के लिए, निम्नलिखित फ़ाइलें बनाई जाती हैं: | File | Size | Purpose | |------|------|---------| | `favicon-16x16.png` | 16x16 | Browser tab आइकन | | `favicon-32x32.png` | 32x32 | Browser tab आइकन (HiDPI) | | `favicon-48x48.png` | 48x48 | Desktop शॉर्टकट | | `apple-touch-icon.png` | 180x180 | iOS होम स्क्रीन | | `android-chrome-192x192.png` | 192x192 | Android होम स्क्रीन | | `android-chrome-512x512.png` | 512x512 | Android स्प्लैश स्क्रीन | | `favicon.ico` | 32x32 | Legacy ICO प्रारूप | | `manifest.json` | - | आइकन संदर्भों के साथ web app manifest | | `favicon-snippet.html` | - | उपयोग के लिए तैयार HTML link टैग | ## Example Request {#example-request} गोल किनारों और padding के साथ एकल स्रोत छवि: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` एकाधिक स्रोत छवियाँ (प्रत्येक को एक सबफ़ोल्डर में अपना सेट मिलता है): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Example Response {#example-response} प्रतिक्रिया एक ZIP फ़ाइल है जो सीधे स्ट्रीम की जाती है। प्रतिक्रिया हेडर इस प्रकार हैं: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## HTML Snippet Included {#html-snippet-included} ZIP में एक `favicon-snippet.html` फ़ाइल शामिल है जिसे आप अपने HTML `` में पेस्ट कर सकते हैं: ```html ``` ## Notes {#notes} * स्रोत छवियों का आकार `cover` fit मोड का उपयोग करके बदला जाता है, यानी उन्हें प्रत्येक वर्गाकार आकार को भरने के लिए क्रॉप किया जाता है। सर्वोत्तम परिणामों के लिए, एक वर्गाकार स्रोत छवि का उपयोग करें। * जब एकाधिक फ़ाइलें अपलोड की जाती हैं, तो प्रत्येक को ZIP में अपना सबफ़ोल्डर मिलता है (स्रोत फ़ाइल के नाम पर)। * एकल फ़ाइल अपलोड के लिए, सभी आउटपुट बिना किसी सबफ़ोल्डर के ZIP की जड़ में होते हैं। * जो फ़ाइलें सत्यापन या डिकोडिंग में विफल होती हैं उन्हें छोड़ दिया जाता है, और समस्याओं को समझाने वाला एक `skipped-files.txt` ZIP में शामिल किया जाता है। * समर्थित इनपुट प्रारूप: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD और अन्य। * आकार बदलने से पहले EXIF orientation स्वतः लागू किया जाता है। --- --- url: https://docs.snapotter.com/id/tools/image/favicon.md description: Hasilkan semua ukuran favicon dan ikon aplikasi standar dari gambar sumber. --- # Favicon Generator {#favicon-generator} Hasilkan satu set lengkap file favicon dan ikon aplikasi dari gambar sumber. Menghasilkan semua ukuran standar yang dibutuhkan untuk browser, perangkat Apple, dan Android, beserta web manifest dan cuplikan HTML. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/favicon` Menerima multipart form data dengan satu atau lebih file gambar dan sebuah field JSON `settings` opsional. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | background | string | No | - | Warna hex latar belakang (mis. `"#ffffff"`). Bila diatur, ikon akan diratakan ke warna ini. | | padding | integer | No | `0` | Persentase padding di sekitar konten ikon (0 hingga 40) | | radius | integer | No | `0` | Persentase radius sudut untuk ikon dengan sudut membulat (0 hingga 50) | | sizes | integer\[] | No | - | Batasi output ke ukuran piksel tertentu (mis. `[16, 32, 180]`). Kosongkan untuk menghasilkan semua ukuran standar. | | themeColor | string | No | `"#ffffff"` | Warna hex tema untuk web manifest | ## Generated Files {#generated-files} Untuk setiap gambar input, file-file berikut dihasilkan: | File | Size | Purpose | |------|------|---------| | `favicon-16x16.png` | 16x16 | Ikon tab browser | | `favicon-32x32.png` | 32x32 | Ikon tab browser (HiDPI) | | `favicon-48x48.png` | 48x48 | Pintasan desktop | | `apple-touch-icon.png` | 180x180 | Layar utama iOS | | `android-chrome-192x192.png` | 192x192 | Layar utama Android | | `android-chrome-512x512.png` | 512x512 | Splash screen Android | | `favicon.ico` | 32x32 | Format ICO lawas | | `manifest.json` | - | Web app manifest dengan referensi ikon | | `favicon-snippet.html` | - | Tag link HTML siap pakai | ## Example Request {#example-request} Gambar sumber tunggal dengan sudut membulat dan padding: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Beberapa gambar sumber (masing-masing mendapat setnya sendiri di subfolder): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Example Response {#example-response} Responsnya adalah file ZIP yang di-stream langsung. Header respons adalah: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## HTML Snippet Included {#html-snippet-included} ZIP menyertakan sebuah file `favicon-snippet.html` yang bisa Anda tempelkan ke `` HTML Anda: ```html ``` ## Notes {#notes} * Gambar sumber diubah ukurannya menggunakan mode fit `cover`, artinya gambar dipotong untuk mengisi setiap ukuran persegi. Untuk hasil terbaik, gunakan gambar sumber berbentuk persegi. * Bila beberapa file diunggah, masing-masing mendapat subfoldernya sendiri di ZIP (dinamai sesuai file sumber). * Untuk unggahan satu file, semua output berada di root ZIP tanpa subfolder. * File yang gagal validasi atau decoding akan dilewati, dan sebuah `skipped-files.txt` disertakan di ZIP untuk menjelaskan masalahnya. * Format input yang didukung: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD, dan lainnya. * Orientasi EXIF diterapkan otomatis sebelum pengubahan ukuran. --- --- url: https://docs.snapotter.com/th/tools/image/favicon.md description: สร้างไอคอน favicon และไอคอนแอปในทุกขนาดมาตรฐานจากภาพต้นฉบับ --- # Favicon Generator {#favicon-generator} สร้างชุดไฟล์ favicon และไอคอนแอปที่ครบถ้วนจากภาพต้นฉบับ ผลิตทุกขนาดมาตรฐานที่จำเป็นสำหรับเบราว์เซอร์ อุปกรณ์ Apple และ Android พร้อมกับ web manifest และ HTML snippet ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/favicon` รับข้อมูลแบบ multipart form data ที่มีไฟล์ภาพหนึ่งไฟล์หรือมากกว่า และฟิลด์ JSON `settings` ที่เป็นทางเลือก ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | background | string | No | - | สีพื้นหลังแบบ hex (เช่น `"#ffffff"`) เมื่อกำหนดค่า ไอคอนจะถูกทำให้เรียบลงบนสีนี้ | | padding | integer | No | `0` | เปอร์เซ็นต์ระยะขอบรอบเนื้อหาไอคอน (0 ถึง 40) | | radius | integer | No | `0` | เปอร์เซ็นต์รัศมีมุมสำหรับไอคอนมุมโค้ง (0 ถึง 50) | | sizes | integer\[] | No | - | จำกัดผลลัพธ์ให้อยู่ในขนาดพิกเซลที่ระบุ (เช่น `[16, 32, 180]`) ละไว้เพื่อสร้างทุกขนาดมาตรฐาน | | themeColor | string | No | `"#ffffff"` | สีธีมแบบ hex สำหรับ web manifest | ## Generated Files {#generated-files} สำหรับภาพนำเข้าแต่ละภาพ จะผลิตไฟล์ต่อไปนี้: | File | Size | Purpose | |------|------|---------| | `favicon-16x16.png` | 16x16 | ไอคอนแท็บเบราว์เซอร์ | | `favicon-32x32.png` | 32x32 | ไอคอนแท็บเบราว์เซอร์ (HiDPI) | | `favicon-48x48.png` | 48x48 | ทางลัดบนเดสก์ท็อป | | `apple-touch-icon.png` | 180x180 | หน้าจอหลักของ iOS | | `android-chrome-192x192.png` | 192x192 | หน้าจอหลักของ Android | | `android-chrome-512x512.png` | 512x512 | หน้าจอ splash ของ Android | | `favicon.ico` | 32x32 | รูปแบบ ICO แบบเดิม | | `manifest.json` | - | Web app manifest พร้อมการอ้างอิงไอคอน | | `favicon-snippet.html` | - | แท็ก HTML link ที่พร้อมใช้งาน | ## Example Request {#example-request} ภาพต้นฉบับเดียวที่มีมุมโค้งและระยะขอบ: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` ภาพต้นฉบับหลายภาพ (แต่ละภาพได้ชุดของตัวเองในโฟลเดอร์ย่อย): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Example Response {#example-response} การตอบกลับเป็นไฟล์ ZIP ที่สตรีมมาโดยตรง ส่วนหัวของการตอบกลับคือ: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## HTML Snippet Included {#html-snippet-included} ไฟล์ ZIP มีไฟล์ `favicon-snippet.html` ที่คุณสามารถวางลงในส่วน `` ของ HTML ได้: ```html ``` ## Notes {#notes} * ภาพต้นฉบับจะถูกปรับขนาดโดยใช้โหมด fit แบบ `cover` ซึ่งหมายความว่าจะถูกครอบตัดให้เต็มแต่ละขนาดสี่เหลี่ยมจัตุรัส เพื่อผลลัพธ์ที่ดีที่สุด ให้ใช้ภาพต้นฉบับที่เป็นสี่เหลี่ยมจัตุรัส * เมื่ออัปโหลดหลายไฟล์ แต่ละไฟล์จะได้โฟลเดอร์ย่อยของตัวเองใน ZIP (ตั้งชื่อตามไฟล์ต้นฉบับ) * สำหรับการอัปโหลดไฟล์เดียว ผลลัพธ์ทั้งหมดจะอยู่ที่รากของ ZIP โดยไม่มีโฟลเดอร์ย่อย * ไฟล์ที่ไม่ผ่านการตรวจสอบหรือถอดรหัสไม่ได้จะถูกข้ามไป และจะมีไฟล์ `skipped-files.txt` รวมอยู่ใน ZIP เพื่ออธิบายปัญหา * รูปแบบนำเข้าที่รองรับ: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD และอื่นๆ * ทิศทาง EXIF จะถูกใช้โดยอัตโนมัติก่อนการปรับขนาด --- --- url: https://docs.snapotter.com/tr/tools/image/favicon.md description: >- Bir kaynak görselden tüm standart favicon ve uygulama simgesi boyutlarını üretin. --- # Favicon Üretici {#favicon-generator} Bir kaynak görselden eksiksiz bir favicon ve uygulama simgesi dosyaları seti üretin. Tarayıcılar, Apple cihazları ve Android için gereken tüm standart boyutları, bir web manifestosu ve bir HTML parçacığıyla birlikte üretir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/favicon` Bir veya daha fazla görsel dosyası ve isteğe bağlı bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | background | string | Hayır | - | Arka plan hex rengi (örn. `"#ffffff"`). Ayarlandığında simge bu rengin üzerine düzleştirilir. | | padding | integer | Hayır | `0` | Simge içeriğinin çevresindeki dolgu yüzdesi (0 ile 40 arası) | | radius | integer | Hayır | `0` | Yuvarlatılmış simgeler için köşe yarıçapı yüzdesi (0 ile 50 arası) | | sizes | integer\[] | Hayır | - | Çıktıyı belirli piksel boyutlarıyla sınırlar (örn. `[16, 32, 180]`). Tüm standart boyutları üretmek için atlayın. | | themeColor | string | Hayır | `"#ffffff"` | Web manifestosu için tema rengi hex değeri | ## Üretilen Dosyalar {#generated-files} Her giriş görseli için aşağıdaki dosyalar üretilir: | Dosya | Boyut | Amaç | |------|------|---------| | `favicon-16x16.png` | 16x16 | Tarayıcı sekmesi simgesi | | `favicon-32x32.png` | 32x32 | Tarayıcı sekmesi simgesi (HiDPI) | | `favicon-48x48.png` | 48x48 | Masaüstü kısayolu | | `apple-touch-icon.png` | 180x180 | iOS ana ekranı | | `android-chrome-192x192.png` | 192x192 | Android ana ekranı | | `android-chrome-512x512.png` | 512x512 | Android açılış ekranı | | `favicon.ico` | 32x32 | Eski ICO biçimi | | `manifest.json` | - | Simge referanslarını içeren web uygulaması manifestosu | | `favicon-snippet.html` | - | Kullanıma hazır HTML link etiketleri | ## Örnek İstek {#example-request} Yuvarlatılmış köşeler ve dolguya sahip tek kaynak görsel: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Birden fazla kaynak görsel (her biri bir alt klasörde kendi setini alır): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Örnek Yanıt {#example-response} Yanıt, doğrudan akıtılan bir ZIP dosyasıdır. Yanıt başlıkları şunlardır: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Dahil Edilen HTML Parçacığı {#html-snippet-included} ZIP, HTML `` bölümünüze yapıştırabileceğiniz bir `favicon-snippet.html` dosyası içerir: ```html ``` ## Notlar {#notes} * Kaynak görseller `cover` sığdırma modu kullanılarak yeniden boyutlandırılır; yani her kare boyutu doldurmak için kırpılır. En iyi sonuç için kare bir kaynak görsel kullanın. * Birden fazla dosya yüklendiğinde, her biri ZIP içinde kendi alt klasörünü alır (kaynak dosyaya göre adlandırılır). * Tek dosya yüklemesinde, tüm çıktılar alt klasör olmadan ZIP kökünde bulunur. * Doğrulama veya çözümlemede başarısız olan dosyalar atlanır ve sorunları açıklayan bir `skipped-files.txt` ZIP'e dahil edilir. * Desteklenen giriş biçimleri: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD ve daha fazlası. * EXIF yönlendirmesi yeniden boyutlandırmadan önce otomatik olarak uygulanır. --- --- url: https://docs.snapotter.com/zh-CN/tools/image/favicon.md description: 从源图像生成所有标准的 favicon 和应用图标尺寸。 --- # Favicon 生成器 {#favicon-generator} 从源图像生成一整套 favicon 和应用图标文件。生成浏览器、Apple 设备和 Android 所需的所有标准尺寸,并附带一个 web manifest 和一段 HTML 代码片段。 ## API 端点 {#api-endpoint} `POST /api/v1/tools/image/favicon` 接受包含一个或多个图像文件的 multipart 表单数据,以及一个可选的 JSON `settings` 字段。 ## 参数 {#parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | background | string | 否 | - | 背景十六进制颜色(例如 `"#ffffff"`)。设置后,图标会被平整到此颜色上。 | | padding | integer | 否 | `0` | 图标内容周围的内边距百分比(0 到 40) | | radius | integer | 否 | `0` | 圆角图标的圆角半径百分比(0 到 50) | | sizes | integer\[] | 否 | - | 将输出限制为指定的像素尺寸(例如 `[16, 32, 180]`)。省略则生成所有标准尺寸。 | | themeColor | string | 否 | `"#ffffff"` | web manifest 的主题色十六进制值 | ## 生成的文件 {#generated-files} 对于每张输入图像,会生成以下文件: | 文件 | 尺寸 | 用途 | |------|------|---------| | `favicon-16x16.png` | 16x16 | 浏览器标签页图标 | | `favicon-32x32.png` | 32x32 | 浏览器标签页图标(HiDPI) | | `favicon-48x48.png` | 48x48 | 桌面快捷方式 | | `apple-touch-icon.png` | 180x180 | iOS 主屏幕 | | `android-chrome-192x192.png` | 192x192 | Android 主屏幕 | | `android-chrome-512x512.png` | 512x512 | Android 启动画面 | | `favicon.ico` | 32x32 | 传统 ICO 格式 | | `manifest.json` | - | 带图标引用的 Web 应用 manifest | | `favicon-snippet.html` | - | 即用型 HTML link 标签 | ## 请求示例 {#example-request} 带圆角和内边距的单个源图像: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` 多个源图像(每个都会在子文件夹中获得自己的一套文件): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## 响应示例 {#example-response} 响应是直接流式传输的 ZIP 文件。响应头为: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## 包含的 HTML 代码片段 {#html-snippet-included} ZIP 中包含一个 `favicon-snippet.html` 文件,你可以将其粘贴到 HTML 的 `` 中: ```html ``` ## 说明 {#notes} * 源图像使用 `cover` 适配模式进行缩放,也就是说会被裁剪以填满每个方形尺寸。为获得最佳效果,请使用方形源图像。 * 上传多个文件时,每个文件都会在 ZIP 中获得自己的子文件夹(以源文件命名)。 * 对于单个文件上传,所有输出都位于 ZIP 的根目录,没有子文件夹。 * 验证或解码失败的文件会被跳过,ZIP 中会包含一个 `skipped-files.txt` 来说明相关问题。 * 支持的输入格式:JPEG、PNG、WebP、AVIF、TIFF、GIF、HEIC、SVG、RAW、PSD 等。 * 在缩放前会自动应用 EXIF 方向信息。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/favicon.md description: 從來源圖片產生所有標準的 favicon 與應用程式圖示尺寸。 --- # Favicon 產生器 {#favicon-generator} 從來源圖片產生一整套 favicon 與應用程式圖示檔案。可產生瀏覽器、Apple 裝置與 Android 所需的所有標準尺寸,並附帶一份 web manifest 與一段 HTML 程式碼片段。 ## API 端點 {#api-endpoint} `POST /api/v1/tools/image/favicon` 接受包含一個或多個圖片檔案的 multipart 表單資料,以及一個選填的 JSON `settings` 欄位。 ## 參數 {#parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | background | string | 否 | - | 背景十六進位色碼(例如 `"#ffffff"`)。設定後,圖示會平整化到此顏色之上。 | | padding | integer | 否 | `0` | 圖示內容周圍的內距百分比(0 到 40) | | radius | integer | 否 | `0` | 圓角圖示的圓角半徑百分比(0 到 50) | | sizes | integer\[] | 否 | - | 將輸出限制為特定像素尺寸(例如 `[16, 32, 180]`)。省略則產生所有標準尺寸。 | | themeColor | string | 否 | `"#ffffff"` | web manifest 的主題色十六進位色碼 | ## 產生的檔案 {#generated-files} 每一張輸入圖片會產生以下檔案: | 檔案 | 尺寸 | 用途 | |------|------|---------| | `favicon-16x16.png` | 16x16 | 瀏覽器分頁圖示 | | `favicon-32x32.png` | 32x32 | 瀏覽器分頁圖示(HiDPI) | | `favicon-48x48.png` | 48x48 | 桌面捷徑 | | `apple-touch-icon.png` | 180x180 | iOS 主畫面 | | `android-chrome-192x192.png` | 192x192 | Android 主畫面 | | `android-chrome-512x512.png` | 512x512 | Android 啟動畫面 | | `favicon.ico` | 32x32 | 傳統 ICO 格式 | | `manifest.json` | - | 含圖示參照的 web app manifest | | `favicon-snippet.html` | - | 可直接使用的 HTML link 標籤 | ## 範例請求 {#example-request} 含圓角與內距的單張來源圖片: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` 多張來源圖片(每張都在各自的子資料夾中產生一整套): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## 範例回應 {#example-response} 回應是直接串流的 ZIP 檔案。回應標頭為: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## 內含的 HTML 程式碼片段 {#html-snippet-included} ZIP 中包含一個 `favicon-snippet.html` 檔案,你可以將其貼到 HTML 的 `` 中: ```html ``` ## 注意事項 {#notes} * 來源圖片會使用 `cover` 縮放模式調整大小,也就是會裁切以填滿每個正方形尺寸。為求最佳效果,請使用正方形的來源圖片。 * 上傳多個檔案時,每個檔案會在 ZIP 中取得各自的子資料夾(以來源檔名命名)。 * 單一檔案上傳時,所有輸出都位於 ZIP 的根目錄,沒有子資料夾。 * 驗證或解碼失敗的檔案會被略過,並在 ZIP 中附上一個 `skipped-files.txt` 說明問題所在。 * 支援的輸入格式:JPEG、PNG、WebP、AVIF、TIFF、GIF、HEIC、SVG、RAW、PSD 等。 * 縮放前會自動套用 EXIF 方向資訊。 --- --- url: https://docs.snapotter.com/nl/tools/image/favicon.md description: >- Genereer alle standaard favicon- en app-icoongroottes vanuit een bronafbeelding. --- # Favicon-generator {#favicon-generator} Genereer een complete set favicon- en app-icoonbestanden vanuit een bronafbeelding. Produceert alle standaardgroottes die nodig zijn voor browsers, Apple-apparaten en Android, samen met een web-manifest en een HTML-snippet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/favicon` Accepteert multipart-formuliergegevens met een of meer afbeeldingsbestanden en een optioneel JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | background | string | Nee | - | Achtergrondkleur in hex (bijv. `"#ffffff"`). Indien ingesteld wordt het icoon op deze kleur samengevoegd. | | padding | integer | Nee | `0` | Padding-percentage rond de icooninhoud (0 tot 40) | | radius | integer | Nee | `0` | Percentage hoekafronding voor afgeronde iconen (0 tot 50) | | sizes | integer\[] | Nee | - | Beperk de uitvoer tot specifieke pixelgroottes (bijv. `[16, 32, 180]`). Laat weg om alle standaardgroottes te genereren. | | themeColor | string | Nee | `"#ffffff"` | Themakleur in hex voor het web-manifest | ## Gegenereerde bestanden {#generated-files} Voor elke invoerafbeelding worden de volgende bestanden geproduceerd: | Bestand | Grootte | Doel | |------|------|---------| | `favicon-16x16.png` | 16x16 | Browsertabbladicoon | | `favicon-32x32.png` | 32x32 | Browsertabbladicoon (HiDPI) | | `favicon-48x48.png` | 48x48 | Bureaubladsnelkoppeling | | `apple-touch-icon.png` | 180x180 | iOS-beginscherm | | `android-chrome-192x192.png` | 192x192 | Android-beginscherm | | `android-chrome-512x512.png` | 512x512 | Android-opstartscherm | | `favicon.ico` | 32x32 | Verouderd ICO-formaat | | `manifest.json` | - | Web-app-manifest met icoonverwijzingen | | `favicon-snippet.html` | - | Kant-en-klare HTML link-tags | ## Voorbeeldverzoek {#example-request} Eén bronafbeelding met afgeronde hoeken en padding: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Meerdere bronafbeeldingen (elke krijgt zijn eigen set in een submap): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Voorbeeldantwoord {#example-response} Het antwoord is een ZIP-bestand dat rechtstreeks wordt gestreamd. De antwoordheaders zijn: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Meegeleverde HTML-snippet {#html-snippet-included} De ZIP bevat een bestand `favicon-snippet.html` dat je in je HTML `` kunt plakken: ```html ``` ## Opmerkingen {#notes} * Bronafbeeldingen worden vergroot/verkleind met de fit-modus `cover`, wat betekent dat ze worden bijgesneden om elke vierkante grootte te vullen. Gebruik voor het beste resultaat een vierkante bronafbeelding. * Wanneer meerdere bestanden worden geüpload, krijgt elk zijn eigen submap in de ZIP (genoemd naar het bronbestand). * Bij een upload van één bestand staan alle uitvoerbestanden in de hoofdmap van de ZIP zonder submap. * Bestanden die niet slagen voor validatie of decodering worden overgeslagen, en er wordt een `skipped-files.txt` opgenomen in de ZIP die de problemen uitlegt. * Ondersteunde invoerformaten: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD en meer. * EXIF-oriëntatie wordt automatisch toegepast vóór het vergroten/verkleinen. --- --- url: https://docs.snapotter.com/sv/tools/image/favicon.md description: Generera alla standardstorlekar för favicon och appikoner från en källbild. --- # Favicon-generator {#favicon-generator} Generera en komplett uppsättning favicon- och appikonfiler från en källbild. Producerar alla standardstorlekar som behövs för webbläsare, Apple-enheter och Android, tillsammans med ett webbmanifest och ett HTML-utdrag. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/favicon` Tar emot multipart-formulärdata med en eller flera bildfiler och ett valfritt JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | background | string | Nej | - | Bakgrundens hexfärg (t.ex. `"#ffffff"`). När den anges plattas ikonen ut mot denna färg. | | padding | integer | Nej | `0` | Utfyllnadsprocent runt ikoninnehållet (0 till 40) | | radius | integer | Nej | `0` | Hörnradieprocent för rundade ikoner (0 till 50) | | sizes | integer\[] | Nej | - | Begränsa utdata till specifika pixelstorlekar (t.ex. `[16, 32, 180]`). Utelämna för att generera alla standardstorlekar. | | themeColor | string | Nej | `"#ffffff"` | Temafärg i hex för webbmanifestet | ## Genererade filer {#generated-files} För varje inmatad bild produceras följande filer: | Fil | Storlek | Syfte | |------|------|---------| | `favicon-16x16.png` | 16x16 | Ikon för webbläsarflik | | `favicon-32x32.png` | 32x32 | Ikon för webbläsarflik (HiDPI) | | `favicon-48x48.png` | 48x48 | Skrivbordsgenväg | | `apple-touch-icon.png` | 180x180 | iOS-hemskärm | | `android-chrome-192x192.png` | 192x192 | Android-hemskärm | | `android-chrome-512x512.png` | 512x512 | Android-startskärm | | `favicon.ico` | 32x32 | Äldre ICO-format | | `manifest.json` | - | Webbappsmanifest med ikonreferenser | | `favicon-snippet.html` | - | Färdiga HTML-länktaggar | ## Exempelbegäran {#example-request} Enstaka källbild med rundade hörn och utfyllnad: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Flera källbilder (varje får sin egen uppsättning i en undermapp): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Exempelsvar {#example-response} Svaret är en ZIP-fil som strömmas direkt. Svarshuvudena är: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Inkluderat HTML-utdrag {#html-snippet-included} ZIP-filen innehåller en `favicon-snippet.html`-fil som du kan klistra in i din HTML-``: ```html ``` ## Anmärkningar {#notes} * Källbilder storleksändras med fit-läget `cover`, vilket innebär att de beskärs för att fylla varje kvadratisk storlek. För bästa resultat, använd en kvadratisk källbild. * När flera filer laddas upp får varje sin egen undermapp i ZIP-filen (namngiven efter källfilen). * Vid uppladdning av en enda fil ligger alla utdata i roten av ZIP-filen utan undermapp. * Filer som misslyckas med validering eller avkodning hoppas över, och en `skipped-files.txt` inkluderas i ZIP-filen som förklarar problemen. * Format som stöds för inmatning: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD med flera. * EXIF-orientering tillämpas automatiskt före storleksändring. --- --- url: https://docs.snapotter.com/de/tools/image/favicon.md description: Generiert alle gängigen Favicon- und App-Icon-Größen aus einem Ausgangsbild. --- # Favicon-Generator {#favicon-generator} Erzeugt einen vollständigen Satz an Favicon- und App-Icon-Dateien aus einem Ausgangsbild. Produziert alle gängigen Größen, die für Browser, Apple-Geräte und Android benötigt werden, zusammen mit einem Web-Manifest und einem HTML-Snippet. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/favicon` Akzeptiert Multipart-Formulardaten mit einer oder mehreren Bilddateien und einem optionalen JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | background | string | Nein | - | Hintergrund-Hexfarbe (z. B. `"#ffffff"`). Wenn gesetzt, wird das Icon auf diese Farbe abgeflacht. | | padding | integer | Nein | `0` | Innenabstand in Prozent um den Icon-Inhalt (0 bis 40) | | radius | integer | Nein | `0` | Eckenradius in Prozent für abgerundete Icons (0 bis 50) | | sizes | integer\[] | Nein | - | Ausgabe auf bestimmte Pixelgrößen beschränken (z. B. `[16, 32, 180]`). Weglassen, um alle gängigen Größen zu erzeugen. | | themeColor | string | Nein | `"#ffffff"` | Theme-Farbe als Hexwert für das Web-Manifest | ## Erzeugte Dateien {#generated-files} Für jedes Eingabebild werden die folgenden Dateien erstellt: | Datei | Größe | Zweck | |------|------|---------| | `favicon-16x16.png` | 16x16 | Browser-Tab-Icon | | `favicon-32x32.png` | 32x32 | Browser-Tab-Icon (HiDPI) | | `favicon-48x48.png` | 48x48 | Desktop-Verknüpfung | | `apple-touch-icon.png` | 180x180 | iOS-Startbildschirm | | `android-chrome-192x192.png` | 192x192 | Android-Startbildschirm | | `android-chrome-512x512.png` | 512x512 | Android-Splash-Screen | | `favicon.ico` | 32x32 | Klassisches ICO-Format | | `manifest.json` | - | Web-App-Manifest mit Icon-Verweisen | | `favicon-snippet.html` | - | Fertige HTML-Link-Tags | ## Beispielanfrage {#example-request} Einzelnes Ausgangsbild mit abgerundeten Ecken und Innenabstand: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Mehrere Ausgangsbilder (jedes erhält seinen eigenen Satz in einem Unterordner): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Beispielantwort {#example-response} Die Antwort ist eine ZIP-Datei, die direkt gestreamt wird. Die Antwort-Header lauten: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Enthaltenes HTML-Snippet {#html-snippet-included} Die ZIP-Datei enthält eine Datei `favicon-snippet.html`, die Sie in den `` Ihres HTML einfügen können: ```html ``` ## Hinweise {#notes} * Ausgangsbilder werden mit dem Fit-Modus `cover` skaliert, das heißt, sie werden zugeschnitten, um jede quadratische Größe auszufüllen. Für beste Ergebnisse verwenden Sie ein quadratisches Ausgangsbild. * Wenn mehrere Dateien hochgeladen werden, erhält jede ihren eigenen Unterordner in der ZIP-Datei (benannt nach der Quelldatei). * Bei einem Upload einer einzelnen Datei liegen alle Ausgaben im Stammverzeichnis der ZIP-Datei ohne Unterordner. * Dateien, die die Validierung oder Decodierung nicht bestehen, werden übersprungen, und eine `skipped-files.txt` wird in die ZIP-Datei aufgenommen, die die Probleme erläutert. * Unterstützte Eingabeformate: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD und mehr. * Die EXIF-Ausrichtung wird vor dem Skalieren automatisch angewendet. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/gif-tools.md description: >- Redimensione, otimize, altere a velocidade, inverta, gire e extraia quadros de GIFs animados em uma única ferramenta. --- # Ferramentas de GIF {#gif-tools} Redimensione, otimize, altere a velocidade, inverta, extraia quadros e gire GIFs animados. Oferece vários modos de operação em uma única ferramenta. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parâmetros {#parameters} ### Parâmetros Comuns {#common-parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | mode | string | Não | `"resize"` | Modo de operação: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | Não | 0 | Número de repetições do GIF de saída (0 = infinito, 1-100 = repetições finitas) | ### Parâmetros do Modo Redimensionar {#resize-mode-parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | width | integer | Não | - | Largura alvo em pixels (1 a 16384) | | height | integer | Não | - | Altura alvo em pixels (1 a 16384) | | percentage | number | Não | - | Escala por percentual (1 a 500). Sobrepõe width/height se definido. | ### Parâmetros do Modo Otimizar {#optimize-mode-parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | colors | number | Não | 256 | Número máximo de cores na paleta (2 a 256) | | dither | number | Não | 1.0 | Intensidade de dithering (0 a 1, onde 0 desativa o dithering) | | effort | number | Não | 7 | Nível de esforço de otimização (1 a 10, maior = mais lento porém menor) | ### Parâmetros do Modo Velocidade {#speed-mode-parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | speedFactor | number | Não | 1.0 | Multiplicador de velocidade (0.1 a 10). Valores > 1 aceleram, < 1 desaceleram. | ### Parâmetros do Modo Extrair {#extract-mode-parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | extractMode | string | Não | `"single"` | Modo de extração: `single`, `range`, `all` | | frameNumber | number | Não | 0 | Índice do quadro a extrair no modo `single` (base 0) | | frameStart | number | Não | 0 | Índice do quadro inicial para o modo `range` (base 0) | | frameEnd | number | Não | - | Índice do quadro final para o modo `range` (base 0, inclusivo) | | extractFormat | string | Não | `"png"` | Formato para os quadros extraídos: `png`, `webp` | ### Parâmetros do Modo Girar {#rotate-mode-parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | angle | number | Não | - | Ângulo de rotação: `90`, `180` ou `270` graus | | flipH | boolean | Não | `false` | Inverter horizontalmente | | flipV | boolean | Não | `false` | Inverter verticalmente | ## Exemplos de Requisição {#example-requests} ### Redimensionar {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Otimizar {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Acelerar {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Extrair Quadro Único {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Sub-rota de Info {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Retorna metadados sobre um GIF animado sem processá-lo. ### Requisição de Info {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Resposta de Info {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Observações {#notes} * Usa a fábrica padrão `createToolRoute` para o endpoint principal de processamento. * O endpoint de info requer apenas o envio de um arquivo (não são necessárias configurações). * No modo `resize`, se `percentage` for fornecido ele tem prioridade sobre `width`/`height`. O redimensionamento usa `fit: inside` para manter a proporção. * No modo `speed`, os atrasos dos quadros são divididos pelo fator de velocidade. O atraso mínimo por quadro é de 20ms (limitação da especificação do GIF). * No modo `reverse`, o parâmetro `speedFactor` também está disponível para ajustar a velocidade simultaneamente à inversão. * No modo `extract` com `range` ou `all`, a saída é um arquivo ZIP contendo os quadros individuais. * No modo `rotate`, cada quadro é processado individualmente e remontado em uma animação. * O parâmetro `loop` controla quantas vezes o GIF de saída se repete. Use 0 para repetição infinita. * O campo `duration` na resposta de info é a duração total da animação em milissegundos. --- --- url: https://docs.snapotter.com/fr/tools/image/sprite-sheet.md description: >- Combine plusieurs images en une seule grille de feuille de sprites avec des métadonnées d'images. --- # Feuille de sprites {#sprite-sheet} Combine plusieurs images en une seule grille de feuille de sprites. Chaque image est redimensionnée pour correspondre aux dimensions de la première image et placée dans la grille. Renvoie l'image de la feuille de sprites accompagnée des métadonnées de coordonnées par image. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/sprite-sheet` Accepte des données de formulaire multipart avec deux fichiers image ou plus et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | columns | integer | Non | `4` | Nombre de colonnes de la grille (1-16) | | padding | integer | Non | `0` | Marge entre les cellules en pixels (0-64) | | background | string | Non | `"#ffffff"` | Couleur d'arrière-plan hexadécimale | | format | string | Non | `"png"` | Format de sortie : `png`, `webp` ou `jpeg` | | quality | integer | Non | `90` | Qualité de sortie (1-100) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sprite-sheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@frame1.png" \ -F "file=@frame2.png" \ -F "file=@frame3.png" \ -F "file=@frame4.png" \ -F 'settings={"columns": 2, "padding": 4, "format": "png"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sprite-sheet.png", "originalSize": 120000, "processedSize": 95000, "frames": [ { "index": 0, "left": 0, "top": 0, "width": 128, "height": 128 }, { "index": 1, "left": 132, "top": 0, "width": 128, "height": 128 }, { "index": 2, "left": 0, "top": 132, "width": 128, "height": 128 }, { "index": 3, "left": 132, "top": 132, "width": 128, "height": 128 } ], "cols": 2, "rows": 2, "cellWidth": 128, "cellHeight": 128, "canvasWidth": 260, "canvasHeight": 260 } ``` ## Remarques {#notes} * Accepte de 2 à 64 images. Toutes les images sont redimensionnées pour correspondre aux dimensions de la première image téléversée. * Le tableau `frames` fournit les coordonnées en pixels exactes de chaque image dans la sortie, adaptées aux définitions de sprites CSS ou aux cartes d'images de moteur de jeu. * Le nombre de lignes est calculé automatiquement à partir du nombre d'images et de la valeur `columns`. * Utilisez le paramètre `padding` pour ajouter de l'espacement entre les cellules. La couleur `background` est visible dans les zones de marge et dans toute cellule finale vide. * Les entrées HEIC, RAW, PSD et SVG sont automatiquement décodées avant le traitement. --- --- url: https://docs.snapotter.com/it/tools/image/watermark-text.md description: >- Aggiunge filigrane di testo con posizione, opacità, rotazione e ripetizione a mosaico configurabili. --- # Filigrana di testo {#text-watermark} Aggiunge una sovrapposizione di filigrana di testo alle immagini. Supporta il posizionamento singolo agli angoli/al centro o la ripetizione a mosaico sull'intera immagine, con dimensione del carattere, colore, opacità e rotazione configurabili. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/watermark-text` Accetta dati di form multipart con un file immagine e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | text | string | Sì | - | Testo della filigrana (da 1 a 500 caratteri) | | fontSize | number | No | `48` | Dimensione del carattere in pixel (da 8 a 1000) | | color | string | No | `"#000000"` | Colore del testo in formato esadecimale (`#RRGGBB`) | | opacity | number | No | `50` | Percentuale di opacità del testo (da 0 a 100) | | position | string | No | `"center"` | Posizionamento: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right`, `tiled` | | rotation | number | No | `0` | Angolo di rotazione del testo in gradi (da -360 a 360) | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-text \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "SAMPLE", "fontSize": 64, "opacity": 30, "position": "center", "rotation": -30}' ``` Filigrana a mosaico sull'intera immagine: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-text \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "DRAFT", "fontSize": 36, "opacity": 20, "position": "tiled", "rotation": -45}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Note {#notes} * La filigrana viene renderizzata come testo SVG e composta sull'immagine, preservando la qualità dell'output. * La modalità a mosaico spazia gli elementi di testo in base alla dimensione del carattere (spaziatura orizzontale 6x, verticale 4x), con un limite massimo di 500 elementi. * Per le posizioni agli angoli, il margine dal bordo è pari alla dimensione del carattere. * Il carattere usato è il carattere sans-serif predefinito del sistema. * I caratteri speciali XML nel testo (`&`, `<`, `>`, `"`, `'`) vengono sottoposti a escape in modo sicuro. * Il formato di output corrisponde al formato di input. Gli input HEIC, RAW, PSD e SVG vengono decodificati automaticamente prima dell'elaborazione. --- --- url: https://docs.snapotter.com/it/tools/image/watermark-image.md description: >- Sovrappone un logo o un'immagine come filigrana con posizione, opacità e scala configurabili. --- # Filigrana immagine {#image-watermark} Sovrappone un logo o un'immagine secondaria come filigrana su un'immagine di base. La filigrana viene scalata in relazione alla larghezza dell'immagine di base e posizionata in un angolo o al centro. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/watermark-image` Accetta dati di form multipart con **due** file immagine e un campo JSON `settings`. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | position | string | No | `"bottom-right"` | Posizionamento della filigrana: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` | | opacity | number | No | `50` | Percentuale di opacità della filigrana (da 0 a 100) | | scale | number | No | `25` | Larghezza della filigrana come percentuale della larghezza dell'immagine principale (da 1 a 100) | ### Campi dei file {#file-fields} | Nome del campo | Obbligatorio | Descrizione | |------------|----------|-------------| | file | Sì | L'immagine principale/di base | | watermark | Sì | L'immagine della filigrana/del logo | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "watermark=@logo.png" \ -F 'settings={"position": "bottom-right", "opacity": 60, "scale": 20}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2520000 } ``` ## Note {#notes} * Entrambe le immagini vengono validate e decodificate (HEIC, RAW, PSD, SVG supportati). * La filigrana viene ridimensionata proporzionalmente in modo che la sua larghezza sia pari al `scale`% della larghezza dell'immagine principale. * L'opacità viene applicata tramite una maschera alfa composta con fusione `dest-in`. * Le posizioni agli angoli usano un margine di 20px dal bordo dell'immagine. * Se l'immagine della filigrana ha trasparenza (ad esempio un logo PNG), questa viene preservata durante la composizione. * L'orientamento EXIF viene applicato automaticamente su entrambe le immagini prima dell'elaborazione. --- --- url: https://docs.snapotter.com/it/tools/pdf/watermark-pdf.md description: Aggiungi una filigrana di testo a ogni pagina di un PDF. --- # Filigrana PDF {#watermark-pdf} Applica una filigrana di testo su ogni pagina di un PDF con posizione, dimensione, opacità e rotazione configurabili. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/watermark-pdf` Accetta dati di form multipart con un file PDF e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | - | Testo della filigrana (1-200 caratteri) | | position | string | No | `"c"` | Posizionamento sulla pagina: `tl`, `tc`, `tr`, `l`, `c`, `r`, `bl`, `bc`, `br` | | fontSize | integer | No | `48` | Dimensione del carattere in punti (6-72) | | opacity | number | No | `0.3` | Opacità della filigrana (0.05-1) | | rotation | number | No | `45` | Angolo di rotazione in gradi (da -180 a 180) | ### Position Values {#position-values} * `tl` in alto a sinistra, `tc` in alto al centro, `tr` in alto a destra * `l` al centro a sinistra, `c` al centro, `r` al centro a destra * `bl` in basso a sinistra, `bc` in basso al centro, `br` in basso a destra ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/watermark-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"text": "CONFIDENTIAL", "position": "c", "opacity": 0.2, "rotation": 45}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2500000 } ``` ## Notes {#notes} * La filigrana viene resa come una sovrapposizione di testo su ogni pagina. * Lo stesso testo, posizione e stile della filigrana vengono applicati in modo uniforme a tutte le pagine. * Usa valori di opacità più bassi (0.1-0.3) per filigrane discrete che non oscurano il contenuto. --- --- url: https://docs.snapotter.com/fr/tools/image/watermark-image.md description: >- Superpose un logo ou une image comme filigrane avec une position, une opacité et une échelle configurables. --- # Filigrane image {#image-watermark} Superpose un logo ou une image secondaire comme filigrane sur une image de base. Le filigrane est mis à l'échelle par rapport à la largeur de l'image de base et positionné dans un coin ou au centre. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/watermark-image` Accepte des données de formulaire multipart avec **deux** fichiers image et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | position | string | Non | `"bottom-right"` | Placement du filigrane : `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` | | opacity | number | Non | `50` | Pourcentage d'opacité du filigrane (0 à 100) | | scale | number | Non | `25` | Largeur du filigrane en pourcentage de la largeur de l'image principale (1 à 100) | ### Champs de fichier {#file-fields} | Nom du champ | Requis | Description | |------------|----------|-------------| | file | Oui | L'image principale/de base | | watermark | Oui | L'image du filigrane/logo | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "watermark=@logo.png" \ -F 'settings={"position": "bottom-right", "opacity": 60, "scale": 20}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2520000 } ``` ## Remarques {#notes} * Les deux images sont validées et décodées (HEIC, RAW, PSD, SVG pris en charge). * Le filigrane est redimensionné proportionnellement afin que sa largeur soit égale à `scale` % de la largeur de l'image principale. * L'opacité est appliquée via un masque alpha composité avec un mélange `dest-in`. * Les positions dans les coins utilisent une marge de 20 px par rapport au bord de l'image. * Si l'image du filigrane comporte de la transparence (par exemple un logo PNG), celle-ci est préservée lors de la composition. * L'orientation EXIF est appliquée automatiquement sur les deux images avant le traitement. --- --- url: https://docs.snapotter.com/fr/tools/image/watermark-text.md description: >- Ajoute des filigranes de texte avec une position, une opacité, une rotation et un motif en mosaïque configurables. --- # Filigrane texte {#text-watermark} Ajoute une superposition de filigrane de texte aux images. Prend en charge un placement unique dans les coins/au centre ou une répétition en mosaïque sur toute l'image, avec une taille de police, une couleur, une opacité et une rotation configurables. ## Point d'accès de l'API {#api-endpoint} `POST /api/v1/tools/image/watermark-text` Accepte des données de formulaire multipart avec un fichier image et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | text | string | Oui | - | Texte du filigrane (1 à 500 caractères) | | fontSize | number | Non | `48` | Taille de police en pixels (8 à 1000) | | color | string | Non | `"#000000"` | Couleur du texte au format hexadécimal (`#RRGGBB`) | | opacity | number | Non | `50` | Pourcentage d'opacité du texte (0 à 100) | | position | string | Non | `"center"` | Placement : `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right`, `tiled` | | rotation | number | Non | `0` | Angle de rotation du texte en degrés (-360 à 360) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-text \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "SAMPLE", "fontSize": 64, "opacity": 30, "position": "center", "rotation": -30}' ``` Filigrane en mosaïque sur toute l'image : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-text \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"text": "DRAFT", "fontSize": 36, "opacity": 20, "position": "tiled", "rotation": -45}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Remarques {#notes} * Le filigrane est rendu sous forme de texte SVG et composité sur l'image, préservant la qualité de sortie. * Le mode mosaïque espace les éléments de texte en fonction de la taille de police (espacement horizontal de 6x, vertical de 4x), plafonné à un maximum de 500 éléments. * Pour les positions dans les coins, la marge par rapport au bord est égale à la taille de police. * La police utilisée est la police sans empattement par défaut du système. * Les caractères spéciaux XML dans le texte (`&`, `<`, `>`, `"`, `'`) sont échappés de manière sûre. * Le format de sortie correspond au format d'entrée. Les entrées HEIC, RAW, PSD et SVG sont automatiquement décodées avant le traitement. --- --- url: https://docs.snapotter.com/fr/tools/pdf/watermark-pdf.md description: Ajouter un filigrane textuel à chaque page d'un PDF. --- # Filigraner un PDF {#watermark-pdf} Apposez un filigrane textuel sur chaque page d'un PDF avec une position, une taille, une opacité et une rotation configurables. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/watermark-pdf` Accepte des données de formulaire multipart avec un fichier PDF et un champ `settings` au format JSON. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | text | string | Oui | - | Texte du filigrane (1-200 caractères) | | position | string | Non | `"c"` | Emplacement sur la page : `tl`, `tc`, `tr`, `l`, `c`, `r`, `bl`, `bc`, `br` | | fontSize | integer | Non | `48` | Taille de police en points (6-72) | | opacity | number | Non | `0.3` | Opacité du filigrane (0.05-1) | | rotation | number | Non | `45` | Angle de rotation en degrés (-180 à 180) | ### Valeurs de position {#position-values} * `tl` en haut à gauche, `tc` en haut au centre, `tr` en haut à droite * `l` au centre à gauche, `c` au centre, `r` au centre à droite * `bl` en bas à gauche, `bc` en bas au centre, `br` en bas à droite ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/watermark-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"text": "CONFIDENTIAL", "position": "c", "opacity": 0.2, "rotation": 45}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2500000 } ``` ## Remarques {#notes} * Le filigrane est rendu sous forme de superposition de texte sur chaque page. * Le même texte, la même position et le même style de filigrane sont appliqués uniformément à toutes les pages. * Utilisez des valeurs d'opacité plus faibles (0.1-0.3) pour des filigranes subtils qui n'obscurcissent pas le contenu. --- --- url: https://docs.snapotter.com/hi/tools/image/find-duplicates.md description: >- perceptual hashing का उपयोग करके डुप्लिकेट और लगभग-डुप्लिकेट छवियों का पता लगाएँ। --- # Find Duplicates {#find-duplicates} perceptual hashing (dHash) का उपयोग करके डुप्लिकेट और लगभग-डुप्लिकेट का पता लगाने के लिए कई छवियाँ अपलोड करें। समान छवियों को एक साथ समूहित करता है, प्रत्येक समूह में सर्वोत्तम गुणवत्ता वाले संस्करण की पहचान करता है, और संभावित स्थान बचत की गणना करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` एकाधिक image फ़ाइलों और एक वैकल्पिक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | threshold | number | नहीं | `8` | छवियों को डुप्लिकेट मानने के लिए अधिकतम Hamming दूरी (0 से 20)। कम = सख़्त मिलान | ### File Fields {#file-fields} multipart अनुरोध में कम से कम 2 image फ़ाइलें अपलोड करें (सभी `file` फ़ील्ड नाम का उपयोग करते हुए या फ़ाइल भागों के लिए कोई भी फ़ील्ड नाम)। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Example Response {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | totalImages | number | सफलतापूर्वक विश्लेषित छवियों की संख्या | | duplicateGroups | array | डुप्लिकेट छवियों के समूह | | uniqueImages | number | किसी भी डुप्लिकेट समूह का हिस्सा न होने वाली छवियों की संख्या | | spaceSaveable | number | गैर-सर्वोत्तम डुप्लिकेट हटाकर बचाए जा सकने वाले कुल बाइट | | skippedFiles | array | ऐसी फ़ाइलें जिन्हें संसाधित नहीं किया जा सका (फ़ाइलनाम और कारण के साथ) | ### Duplicate Group Object {#duplicate-group-object} | Field | Type | Description | |-------|------|-------------| | groupId | number | समूह पहचानकर्ता | | files | array | इस डुप्लिकेट समूह की छवियाँ | ### File Object (within a group) {#file-object-within-a-group} | Field | Type | Description | |-------|------|-------------| | filename | string | मूल फ़ाइलनाम | | similarity | number | संदर्भ छवि (समूह में पहली) के साथ समानता प्रतिशत | | width | number | छवि चौड़ाई पिक्सेल में | | height | number | छवि ऊँचाई पिक्सेल में | | fileSize | number | फ़ाइल आकार बाइट में | | format | string | छवि प्रारूप | | isBest | boolean | क्या यह उच्चतम गुणवत्ता वाला संस्करण है (सबसे अधिक पिक्सेल, सबसे बड़ी फ़ाइल) | | thumbnail | string या null | पूर्वावलोकन के लिए Base64 JPEG थंबनेल (200px चौड़ा) | ## Notes {#notes} * perceptual समानता का पता लगाने के लिए 128-bit dHash (64-bit पंक्ति + 64-bit स्तंभ) का उपयोग करता है। यह आकार बदलने, पुनः-संपीड़न और छोटे संपादनों के बावजूद भी डुप्लिकेट पकड़ता है। * threshold, hashes के बीच अधिकतम Hamming दूरी को दर्शाता है। 8 का डिफ़ॉल्ट झूठी सकारात्मकता से बचते हुए लगभग-डुप्लिकेट पकड़ता है। केवल पिक्सेल-समरूप के लिए 0 का उपयोग करें, या बहुत ढीले मिलान के लिए 15-20 का। * प्रत्येक समूह में "सर्वोत्तम" छवि वह होती है जिसमें सबसे अधिक पिक्सेल (चौड़ाई x ऊँचाई) होते हैं, और फ़ाइल आकार टाईब्रेकर के रूप में होता है। * कम से कम 2 छवियाँ आवश्यक हैं। जो फ़ाइलें सत्यापन या डिकोडिंग में विफल होती हैं उन्हें पूरे अनुरोध को विफल करने के बजाय `skippedFiles` में रिपोर्ट किया जाता है। * थंबनेल 200px-चौड़े JPEG पूर्वावलोकन हैं जो data URIs के रूप में एन्कोड किए जाते हैं। * सभी सामान्य प्रारूप समर्थित हैं (HEIC, RAW, PSD, SVG स्वचालित रूप से डिकोड किए जाते हैं)। --- --- url: https://docs.snapotter.com/id/tools/image/find-duplicates.md description: Deteksi gambar duplikat dan nyaris-duplikat menggunakan perceptual hashing. --- # Find Duplicates {#find-duplicates} Unggah beberapa gambar untuk mendeteksi duplikat dan nyaris-duplikat menggunakan perceptual hashing (dHash). Mengelompokkan gambar serupa, mengidentifikasi versi berkualitas terbaik di setiap grup, dan menghitung potensi penghematan ruang. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` Menerima multipart form data dengan beberapa file gambar dan sebuah field JSON `settings` opsional. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | threshold | number | No | `8` | Jarak Hamming maksimum untuk menganggap gambar sebagai duplikat (0 hingga 20). Lebih rendah = pencocokan lebih ketat | ### File Fields {#file-fields} Unggah setidaknya 2 file gambar dalam permintaan multipart (semuanya menggunakan nama field `file` atau nama field apa pun untuk bagian file). ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Example Response {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | totalImages | number | Jumlah gambar yang berhasil dianalisis | | duplicateGroups | array | Grup gambar duplikat | | uniqueImages | number | Jumlah gambar yang bukan bagian dari grup duplikat mana pun | | spaceSaveable | number | Total byte yang bisa dihemat dengan menghapus duplikat non-terbaik | | skippedFiles | array | File yang tidak dapat diproses (dengan nama file dan alasannya) | ### Duplicate Group Object {#duplicate-group-object} | Field | Type | Description | |-------|------|-------------| | groupId | number | Pengenal grup | | files | array | Gambar dalam grup duplikat ini | ### File Object (within a group) {#file-object-within-a-group} | Field | Type | Description | |-------|------|-------------| | filename | string | Nama file asli | | similarity | number | Persentase kemiripan terhadap gambar referensi (yang pertama dalam grup) | | width | number | Lebar gambar dalam piksel | | height | number | Tinggi gambar dalam piksel | | fileSize | number | Ukuran file dalam byte | | format | string | Format gambar | | isBest | boolean | Apakah ini versi berkualitas tertinggi (piksel terbanyak, file terbesar) | | thumbnail | string or null | Thumbnail JPEG base64 (lebar 200px) untuk pratinjau | ## Notes {#notes} * Menggunakan dHash 128-bit (baris 64-bit + kolom 64-bit) untuk deteksi kemiripan perseptual. Ini menangkap duplikat bahkan lintas pengubahan ukuran, kompresi ulang, dan penyuntingan kecil. * Threshold mewakili jarak Hamming maksimum antar hash. Nilai default 8 menangkap nyaris-duplikat sambil menghindari positif palsu. Gunakan 0 untuk yang identik piksel saja, atau 15-20 untuk pencocokan yang sangat longgar. * Gambar "terbaik" di setiap grup adalah yang memiliki piksel terbanyak (lebar x tinggi), dengan ukuran file sebagai pemecah seri. * Diperlukan setidaknya 2 gambar. File yang gagal validasi atau decoding dilaporkan di `skippedFiles` alih-alih menyebabkan seluruh permintaan gagal. * Thumbnail adalah pratinjau JPEG selebar 200px yang dikodekan sebagai data URI. * Semua format umum didukung (HEIC, RAW, PSD, SVG di-decode otomatis). --- --- url: https://docs.snapotter.com/th/tools/image/find-duplicates.md description: ตรวจหาภาพซ้ำและภาพที่เกือบซ้ำโดยใช้ perceptual hashing --- # Find Duplicates {#find-duplicates} อัปโหลดภาพหลายภาพเพื่อตรวจหาภาพซ้ำและภาพที่เกือบซ้ำโดยใช้ perceptual hashing (dHash) จัดกลุ่มภาพที่คล้ายกันเข้าด้วยกัน ระบุเวอร์ชันที่มีคุณภาพดีที่สุดในแต่ละกลุ่ม และคำนวณพื้นที่ที่อาจประหยัดได้ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` รับข้อมูลแบบ multipart form data ที่มีไฟล์ภาพหลายไฟล์ และฟิลด์ JSON `settings` ที่เป็นทางเลือก ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | threshold | number | No | `8` | ระยะ Hamming distance สูงสุดที่จะถือว่าภาพเป็นภาพซ้ำ (0 ถึง 20) ยิ่งต่ำ = การจับคู่ยิ่งเข้มงวด | ### File Fields {#file-fields} อัปโหลดไฟล์ภาพอย่างน้อย 2 ไฟล์ในคำขอ multipart (ทั้งหมดใช้ชื่อฟิลด์ `file` หรือชื่อฟิลด์ใดก็ได้สำหรับส่วนที่เป็นไฟล์) ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Example Response {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Response Fields {#response-fields} | Field | Type | Description | |-------|------|-------------| | totalImages | number | จำนวนภาพที่วิเคราะห์สำเร็จ | | duplicateGroups | array | กลุ่มของภาพซ้ำ | | uniqueImages | number | จำนวนภาพที่ไม่ได้อยู่ในกลุ่มภาพซ้ำใดๆ | | spaceSaveable | number | จำนวนไบต์ทั้งหมดที่ประหยัดได้จากการลบภาพซ้ำที่ไม่ใช่ภาพที่ดีที่สุด | | skippedFiles | array | ไฟล์ที่ประมวลผลไม่ได้ (พร้อมชื่อไฟล์และเหตุผล) | ### Duplicate Group Object {#duplicate-group-object} | Field | Type | Description | |-------|------|-------------| | groupId | number | ตัวระบุกลุ่ม | | files | array | ภาพในกลุ่มภาพซ้ำนี้ | ### File Object (within a group) {#file-object-within-a-group} | Field | Type | Description | |-------|------|-------------| | filename | string | ชื่อไฟล์เดิม | | similarity | number | เปอร์เซ็นต์ความคล้ายกับภาพอ้างอิง (ภาพแรกในกลุ่ม) | | width | number | ความกว้างของภาพเป็นพิกเซล | | height | number | ความสูงของภาพเป็นพิกเซล | | fileSize | number | ขนาดไฟล์เป็นไบต์ | | format | string | รูปแบบของภาพ | | isBest | boolean | ว่าเป็นเวอร์ชันคุณภาพสูงสุดหรือไม่ (พิกเซลมากที่สุด ไฟล์ใหญ่ที่สุด) | | thumbnail | string or null | ภาพขนาดย่อ Base64 JPEG (กว้าง 200px) สำหรับดูตัวอย่าง | ## Notes {#notes} * ใช้ dHash แบบ 128 บิต (แถว 64 บิต + คอลัมน์ 64 บิต) เพื่อตรวจจับความคล้ายเชิงการรับรู้ ซึ่งจับภาพซ้ำได้แม้ผ่านการปรับขนาด การบีบอัดซ้ำ และการแก้ไขเล็กน้อย * threshold แทนระยะ Hamming distance สูงสุดระหว่าง hash ค่าเริ่มต้นที่ 8 จับภาพที่เกือบซ้ำได้ในขณะที่หลีกเลี่ยง false positive ใช้ 0 สำหรับภาพที่เหมือนกันในระดับพิกเซลเท่านั้น หรือ 15-20 สำหรับการจับคู่ที่หลวมมาก * ภาพ "ที่ดีที่สุด" ในแต่ละกลุ่มคือภาพที่มีพิกเซลมากที่สุด (width x height) โดยใช้ขนาดไฟล์เป็นตัวตัดสินเสมอ * ต้องมีภาพอย่างน้อย 2 ภาพ ไฟล์ที่ไม่ผ่านการตรวจสอบหรือถอดรหัสไม่ได้จะถูกรายงานใน `skippedFiles` แทนที่จะทำให้คำขอทั้งหมดล้มเหลว * ภาพขนาดย่อเป็นภาพตัวอย่าง JPEG กว้าง 200px ที่เข้ารหัสเป็น data URI * รองรับรูปแบบทั่วไปทั้งหมด (HEIC, RAW, PSD, SVG ถอดรหัสโดยอัตโนมัติ) --- --- url: https://docs.snapotter.com/it/tools/pdf/sign-pdf.md description: >- Applica immagini di firma caricate su un PDF usando posizionamenti normalizzati per pagina. --- # Firma PDF {#sign-pdf} Applica una o più immagini di firma PNG caricate su qualsiasi pagina di un PDF. Questa route usa un contratto multipart personalizzato perché necessita del PDF, di una o più immagini di firma e delle coordinate di posizionamento. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/sign-pdf` Accetta dati di form multipart. Il PDF viene inviato come `file`; le firme vengono inviate come `sig0`, `sig1`, e così via; i posizionamenti vengono inviati in un campo JSON `placements`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | file | file | Yes | - | File PDF da firmare | | sig0 | file | Yes | - | Prima immagine di firma. Le immagini aggiuntive usano `sig1`, `sig2`, e così via | | placements | JSON string | Yes | - | Array di oggetti di posizionamento: `{ "sig": 0, "page": 0, "x": 0.2, "y": 0.7, "w": 0.25, "h": 0.08 }` | | clientJobId | string | No | - | UUID opzionale per il monitoraggio dell'avanzamento tramite SSE | | fileId | string | No | - | ID opzionale della libreria file per salvare il risultato firmato come nuova versione | ## Placement Coordinates {#placement-coordinates} | Field | Type | Description | |-------|------|-------------| | sig | integer | Indice dell'immagine di firma. `0` corrisponde a `sig0` | | page | integer | Indice di pagina PDF a base zero | | x | number | Posizione sinistra come frazione della pagina | | y | number | Posizione superiore come frazione della pagina | | w | number | Larghezza della firma come frazione della pagina | | h | number | Altezza della firma come frazione della pagina | Le coordinate usano un'origine in alto a sinistra. I valori possono sconfinare leggermente oltre il bordo della pagina; il renderer PDF ritaglia il timbro finale alla pagina. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/sign-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@contract.pdf" \ -F "sig0=@signature.png" \ -F 'placements=[{"sig":0,"page":0,"x":0.64,"y":0.82,"w":0.22,"h":0.08}]' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/contract_signed.pdf", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/preview.png", "originalSize": 245000, "processedSize": 249000 } ``` Se la richiesta non riesce a completarsi entro la finestra di attesa sincrona, l'API restituisce: ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Connettiti a `/api/v1/jobs//progress` e scarica il risultato quando il job è completato. ## Notes {#notes} * Formato di input PDF accettato: `.pdf`. * Le immagini di firma devono essere file immagine validi, tipicamente PNG con trasparenza. * Sono accettate fino a 100 immagini di firma e 100 posizionamenti. * `sign-pdf` è una route personalizzata e non usa il campo JSON standard `settings` dello strumento. --- --- url: https://docs.snapotter.com/es/tools/pdf/sign-pdf.md description: >- Estampa imágenes de firma subidas en un PDF mediante ubicaciones de página normalizadas. --- # Firmar PDF {#sign-pdf} Estampa una o varias imágenes PNG de firma subidas en cualquier página de un PDF. Esta ruta usa un contrato multipart personalizado porque necesita el PDF, una o varias imágenes de firma y las coordenadas de ubicación. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/sign-pdf` Acepta datos de formulario multipart. El PDF se envía como `file`; las firmas se envían como `sig0`, `sig1`, y así sucesivamente; las ubicaciones se envían en un campo JSON `placements`. ## Parameters {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo PDF a firmar | | sig0 | file | Sí | - | Primera imagen de firma. Las imágenes adicionales usan `sig1`, `sig2`, y así sucesivamente | | placements | JSON string | Sí | - | Array de objetos de ubicación: `{ "sig": 0, "page": 0, "x": 0.2, "y": 0.7, "w": 0.25, "h": 0.08 }` | | clientJobId | string | No | - | UUID opcional para el seguimiento del progreso mediante SSE | | fileId | string | No | - | ID opcional de la biblioteca de archivos para guardar el resultado firmado como una nueva versión | ## Coordenadas de ubicación {#placement-coordinates} | Campo | Tipo | Descripción | |-------|------|-------------| | sig | integer | Índice de la imagen de firma. `0` se asigna a `sig0` | | page | integer | Índice de página del PDF basado en cero | | x | number | Posición izquierda como fracción de la página | | y | number | Posición superior como fracción de la página | | w | number | Ancho de la firma como fracción de la página | | h | number | Alto de la firma como fracción de la página | Las coordenadas usan un origen en la esquina superior izquierda. Los valores pueden sobresalir ligeramente del borde de la página; el renderizador de PDF recorta el sello final a la página. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/sign-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@contract.pdf" \ -F "sig0=@signature.png" \ -F 'placements=[{"sig":0,"page":0,"x":0.64,"y":0.82,"w":0.22,"h":0.08}]' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/contract_signed.pdf", "previewUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/preview.png", "originalSize": 245000, "processedSize": 249000 } ``` Si la solicitud no puede completarse dentro de la ventana de espera síncrona, la API devuelve: ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Conéctate a `/api/v1/jobs//progress` y descarga el resultado cuando el trabajo se complete. ## Notes {#notes} * Formato de entrada PDF aceptado: `.pdf`. * Las imágenes de firma deben ser archivos de imagen válidos, normalmente PNG con transparencia. * Se aceptan hasta 100 imágenes de firma y 100 ubicaciones. * `sign-pdf` es una ruta personalizada y no usa el campo JSON `settings` estándar de la herramienta. --- --- url: https://docs.snapotter.com/ar/tools/pdf/flatten-pdf.md description: دمج النماذج والتعليقات التوضيحية داخل محتوى الصفحة. --- # Flatten PDF {#flatten-pdf} ادمج حقول النماذج التفاعلية والتعليقات التوضيحية داخل محتوى الصفحة، مُنتِجاً ملف PDF ثابتاً يظهر بالشكل نفسه في كل مكان. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` يقبل بيانات نموذج multipart تحتوي على ملف PDF. ## Parameters {#parameters} ليس لهذه الأداة أي معاملات قابلة للتهيئة. ارفع ملف PDF وستُدمج جميع النماذج والتعليقات التوضيحية. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * صيغة الإدخال المقبولة: `.pdf`. * هذه أداة سريعة (متزامنة) تُعيد النتيجة مباشرة. * تُحفظ قيم حقول النماذج كنص ثابت في المخرجات. * تصبح التعليقات التوضيحية (التعليقات والتمييزات والملاحظات اللاصقة) جزءاً من محتوى الصفحة ولا يمكن تحريرها بعد ذلك. --- --- url: https://docs.snapotter.com/hi/tools/pdf/flatten-pdf.md description: फ़ॉर्म और एनोटेशन को पृष्ठ सामग्री में बेक करें। --- # Flatten PDF {#flatten-pdf} इंटरैक्टिव फ़ॉर्म फ़ील्ड और एनोटेशन को पृष्ठ सामग्री में बेक करें, जिससे एक स्थिर PDF बने जो हर जगह एक जैसा दिखे। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` एक PDF फ़ाइल के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} इस टूल में कोई कॉन्फ़िगर करने योग्य पैरामीटर नहीं हैं। एक PDF अपलोड करें और सभी फ़ॉर्म और एनोटेशन फ़्लैट कर दिए जाएंगे। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * स्वीकृत इनपुट फ़ॉर्मेट: `.pdf`। * यह एक फ़ास्ट (सिंक्रोनस) टूल है जो परिणाम सीधे लौटाता है। * फ़ॉर्म फ़ील्ड मान आउटपुट में स्थिर टेक्स्ट के रूप में संरक्षित रहते हैं। * एनोटेशन (टिप्पणियाँ, हाइलाइट, स्टिकी नोट्स) पृष्ठ सामग्री का हिस्सा बन जाते हैं और उन्हें अब संपादित नहीं किया जा सकता। --- --- url: https://docs.snapotter.com/id/tools/pdf/flatten-pdf.md description: Satukan form dan anotasi ke dalam konten halaman. --- # Flatten PDF {#flatten-pdf} Satukan field form interaktif dan anotasi ke dalam konten halaman, menghasilkan PDF statis yang tampil sama di mana pun. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Menerima data form multipart berisi file PDF. ## Parameters {#parameters} Alat ini tidak memiliki parameter yang dapat dikonfigurasi. Unggah PDF dan semua form serta anotasi akan disatukan. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Format input yang diterima: `.pdf`. * Ini adalah alat cepat (sinkron) yang mengembalikan hasil secara langsung. * Nilai field form dipertahankan sebagai teks statis dalam output. * Anotasi (komentar, sorotan, catatan tempel) menjadi bagian dari konten halaman dan tidak dapat diedit lagi. --- --- url: https://docs.snapotter.com/ja/tools/pdf/flatten-pdf.md description: フォームと注釈をページコンテンツに焼き込みます。 --- # Flatten PDF {#flatten-pdf} インタラクティブなフォームフィールドと注釈をページコンテンツに焼き込み、どこでも同じ見た目になる静的な PDF を生成します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` PDF ファイルを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} このツールに設定可能なパラメータはありません。PDF をアップロードすると、すべてのフォームと注釈が焼き込まれます。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * 受け付ける入力形式: `.pdf`。 * これは結果を直接返す高速(同期)ツールです。 * フォームフィールドの値は出力内で静的なテキストとして保持されます。 * 注釈(コメント、ハイライト、付箋)はページコンテンツの一部となり、以降は編集できなくなります。 --- --- url: https://docs.snapotter.com/ko/tools/pdf/flatten-pdf.md description: 양식과 주석을 페이지 콘텐츠에 굽습니다. --- # Flatten PDF {#flatten-pdf} 대화형 양식 필드와 주석을 페이지 콘텐츠에 구워 넣어, 어디서나 동일하게 보이는 정적 PDF를 생성합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` PDF 파일이 포함된 multipart form data를 받습니다. ## Parameters {#parameters} 이 도구에는 구성 가능한 매개변수가 없습니다. PDF를 업로드하면 모든 양식과 주석이 평탄화됩니다. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * 허용되는 입력 형식: `.pdf`. * 이 도구는 결과를 직접 반환하는 빠른(동기) 도구입니다. * 양식 필드 값은 출력에서 정적 텍스트로 보존됩니다. * 주석(댓글, 강조 표시, 스티커 메모)은 페이지 콘텐츠의 일부가 되어 더 이상 편집할 수 없습니다. --- --- url: https://docs.snapotter.com/nl/tools/pdf/flatten-pdf.md description: Bak formulieren en annotaties in de pagina-inhoud. --- # Flatten PDF {#flatten-pdf} Bak interactieve formuliervelden en annotaties in de pagina-inhoud en produceer een statische PDF die er overal hetzelfde uitziet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Accepteert multipart-formuliergegevens met een PDF-bestand. ## Parameters {#parameters} Dit hulpmiddel heeft geen configureerbare parameters. Upload een PDF en alle formulieren en annotaties worden afgevlakt. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Geaccepteerd invoerformaat: `.pdf`. * Dit is een snel (synchroon) hulpmiddel dat het resultaat direct teruggeeft. * Formulierveldwaarden blijven behouden als statische tekst in de uitvoer. * Annotaties (opmerkingen, markeringen, plaknotities) worden onderdeel van de pagina-inhoud en kunnen niet meer worden bewerkt. --- --- url: https://docs.snapotter.com/pl/tools/pdf/flatten-pdf.md description: Wtop formularze i adnotacje w treść strony. --- # Flatten PDF {#flatten-pdf} Wtop interaktywne pola formularzy i adnotacje w treść strony, tworząc statyczny plik PDF wyglądający tak samo wszędzie. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Przyjmuje dane formularza multipart z plikiem PDF. ## Parameters {#parameters} To narzędzie nie ma konfigurowalnych parametrów. Prześlij plik PDF, a wszystkie formularze i adnotacje zostaną spłaszczone. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Akceptowany format wejściowy: `.pdf`. * To szybkie (synchroniczne) narzędzie, które zwraca wynik bezpośrednio. * Wartości pól formularza są zachowywane jako statyczny tekst w pliku wynikowym. * Adnotacje (komentarze, wyróżnienia, notatki) stają się częścią treści strony i nie można ich już edytować. --- --- url: https://docs.snapotter.com/pt-BR/tools/pdf/flatten-pdf.md description: Incorpore formulários e anotações ao conteúdo da página. --- # Flatten PDF {#flatten-pdf} Incorpore campos de formulário interativos e anotações ao conteúdo da página, produzindo um PDF estático que fica igual em qualquer lugar. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Aceita dados de formulário multipart com um arquivo PDF. ## Parameters {#parameters} Esta ferramenta não tem parâmetros configuráveis. Envie um PDF e todos os formulários e anotações serão achatados. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Formato de entrada aceito: `.pdf`. * Esta é uma ferramenta rápida (síncrona) que retorna o resultado diretamente. * Os valores dos campos de formulário são preservados como texto estático na saída. * As anotações (comentários, destaques, notas adesivas) passam a fazer parte do conteúdo da página e não podem mais ser editadas. --- --- url: https://docs.snapotter.com/ru/tools/pdf/flatten-pdf.md description: Запекание форм и аннотаций в содержимое страниц. --- # Flatten PDF {#flatten-pdf} Запеките интерактивные поля форм и аннотации в содержимое страниц, получив статический PDF, который выглядит одинаково везде. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Принимает данные multipart form с PDF-файлом. ## Parameters {#parameters} У этого инструмента нет настраиваемых параметров. Загрузите PDF, и все формы и аннотации будут сведены. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Принимаемый входной формат: `.pdf`. * Это быстрый (синхронный) инструмент, который возвращает результат напрямую. * Значения полей форм сохраняются в выходном файле как статический текст. * Аннотации (комментарии, выделения, стикеры) становятся частью содержимого страницы и больше не могут редактироваться. --- --- url: https://docs.snapotter.com/sv/tools/pdf/flatten-pdf.md description: Baka in formulär och anteckningar i sidinnehållet. --- # Flatten PDF {#flatten-pdf} Baka in interaktiva formulärfält och anteckningar i sidinnehållet, vilket skapar en statisk PDF som ser likadan ut överallt. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Tar emot multipart-formulärdata med en PDF-fil. ## Parameters {#parameters} Detta verktyg har inga konfigurerbara parametrar. Ladda upp en PDF så plattas alla formulär och anteckningar ut. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Godkänt indataformat: `.pdf`. * Detta är ett snabbt (synkront) verktyg som returnerar resultatet direkt. * Formulärfältens värden bevaras som statisk text i utdata. * Anteckningar (kommentarer, markeringar, klisterlappar) blir en del av sidinnehållet och kan inte längre redigeras. --- --- url: https://docs.snapotter.com/th/tools/pdf/flatten-pdf.md description: ฝังฟอร์มและคำอธิบายประกอบลงในเนื้อหาหน้า --- # Flatten PDF {#flatten-pdf} ฝังฟิลด์ฟอร์มแบบโต้ตอบและคำอธิบายประกอบลงในเนื้อหาหน้า สร้าง PDF แบบคงที่ที่แสดงผลเหมือนกันทุกที่ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` รับข้อมูลแบบ multipart form data พร้อมไฟล์ PDF ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์ที่ปรับได้ อัปโหลด PDF แล้วฟอร์มและคำอธิบายประกอบทั้งหมดจะถูกฝังลงไป ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * รูปแบบอินพุตที่รองรับ: `.pdf` * นี่เป็นเครื่องมือแบบเร็ว (ซิงโครนัส) ที่คืนผลลัพธ์โดยตรง * ค่าฟิลด์ฟอร์มจะถูกเก็บไว้เป็นข้อความคงที่ในผลลัพธ์ * คำอธิบายประกอบ (ความคิดเห็น การไฮไลต์ โน้ตแปะ) จะกลายเป็นส่วนหนึ่งของเนื้อหาหน้าและไม่สามารถแก้ไขได้อีกต่อไป --- --- url: https://docs.snapotter.com/uk/tools/pdf/flatten-pdf.md description: Запікання форм та анотацій у вміст сторінки. --- # Flatten PDF {#flatten-pdf} Запікайте інтерактивні поля форм та анотації у вміст сторінки, отримуючи статичний PDF, який виглядає однаково всюди. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Приймає багаточастинні (multipart) дані форми з файлом PDF. ## Parameters {#parameters} Цей інструмент не має налаштовуваних параметрів. Завантажте PDF, і всі форми та анотації буде запечено. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Прийнятний формат вхідних даних: `.pdf`. * Це швидкий (синхронний) інструмент, який повертає результат напряму. * Значення полів форми зберігаються як статичний текст у вихідному файлі. * Анотації (коментарі, виділення, нотатки) стають частиною вмісту сторінки, і їх більше не можна редагувати. --- --- url: https://docs.snapotter.com/vi/tools/pdf/flatten-pdf.md description: Nung biểu mẫu và chú thích vào nội dung trang. --- # Flatten PDF {#flatten-pdf} Nung các trường biểu mẫu tương tác và chú thích vào nội dung trang, tạo ra một PDF tĩnh trông giống nhau ở mọi nơi. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` Chấp nhận dữ liệu biểu mẫu multipart với một tệp PDF. ## Parameters {#parameters} Công cụ này không có tham số nào có thể cấu hình. Tải lên một PDF và tất cả biểu mẫu và chú thích sẽ được làm phẳng. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * Định dạng đầu vào được chấp nhận: `.pdf`. * Đây là một công cụ nhanh (đồng bộ) trả về kết quả trực tiếp. * Giá trị của các trường biểu mẫu được giữ lại dưới dạng văn bản tĩnh trong đầu ra. * Các chú thích (bình luận, tô sáng, ghi chú dán) trở thành một phần của nội dung trang và không thể chỉnh sửa được nữa. --- --- url: https://docs.snapotter.com/zh-CN/tools/pdf/flatten-pdf.md description: 将表单和注释固化到页面内容中。 --- # Flatten PDF {#flatten-pdf} 将交互式表单字段和注释固化到页面内容中,生成一个在任何地方看起来都一致的静态 PDF。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/flatten-pdf` 接受包含一个 PDF 文件的 multipart 表单数据。 ## Parameters {#parameters} 此工具没有可配置参数。上传 PDF,所有表单和注释都会被扁平化。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/flatten-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@form.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", "originalSize": 185000, "processedSize": 172000 } ``` ## Notes {#notes} * 接受的输入格式:`.pdf`。 * 这是一个快速(同步)工具,直接返回结果。 * 表单字段的值在输出中被保留为静态文本。 * 注释(评论、高亮、便签)会成为页面内容的一部分,不再可编辑。 --- --- url: https://docs.snapotter.com/fr/tools/image/blur-background.md description: Floute l'arrière-plan tout en gardant le sujet net grâce à l'IA. --- # Flouter l'arrière-plan {#blur-background} Floute l'arrière-plan d'une image tout en gardant le sujet net. Le modèle d'IA isole le sujet, applique un flou à l'arrière-plan d'origine et compose le sujet net par-dessus. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/blur-background` Accepte des données de formulaire multipart contenant un fichier image et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | intensity | entier | Non | `50` | Intensité du flou (1 à 100) | | feather | entier | Non | `0` | Rayon d'adoucissement des bords (0 à 20) | | format | chaîne | Non | `"png"` | Format de sortie : `png` ou `webp` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Suivez la progression via SSE sur `GET /api/v1/jobs/{jobId}/progress`. Une fois le travail terminé, le flux SSE émet un événement `completed` contenant l'URL de téléchargement. ## Remarques {#notes} * Il s'agit d'un outil assisté par IA qui renvoie `202 Accepted` et traite de façon asynchrone. Connectez-vous au point de terminaison SSE pour recevoir les mises à jour de progression et le résultat final. * Nécessite l'installation du bundle de fonctionnalités **background-removal**. Renvoie `501` si le bundle n'est pas disponible. * Des valeurs d'intensité plus élevées produisent un effet de flou plus prononcé. Les valeurs supérieures à 80 créent une séparation prononcée de type bokeh. * Les entrées HEIC, RAW, PSD et SVG sont automatiquement décodées avant le traitement. --- --- url: https://docs.snapotter.com/fr/tools/image/blur-faces.md description: >- Détecte et floute automatiquement les visages dans les images grâce à la détection de visages par IA, pour la confidentialité et une anonymisation conforme au RGPD. --- # Flouter les visages et données sensibles {#face-pii-blur} Détecte et floute automatiquement les visages dans les images grâce à la détection de visages assistée par IA (MediaPipe). ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Traitement :** asynchrone (renvoie 202, interrogez `/api/v1/jobs/{jobId}/progress` pour connaître le statut via SSE) **Bundle de modèles :** `face-detection` (200 à 300 Mo) ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | file | fichier | Oui | - | Fichier image (multipart) | | blurRadius | nombre | Non | `30` | Rayon de flou appliqué aux visages détectés (1 à 100) | | sensitivity | nombre | Non | `0.5` | Sensibilité de la détection de visages (0 à 1). Des valeurs plus faibles détectent moins de visages avec une confiance plus élevée | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Réponse {#response} ### Réponse initiale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progression (SSE sur `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Résultat final (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### Aucun visage détecté {#no-faces-detected} Si aucun visage n'est trouvé, le résultat inclut un avertissement : ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Remarques {#notes} * Nécessite l'installation du bundle de modèles `face-detection` (200 à 300 Mo). * Le format de sortie correspond automatiquement au format d'entrée. * Le tableau `faces` contient les coordonnées du cadre de délimitation (x, y, largeur, hauteur) de chaque visage détecté. * Augmentez `sensitivity` (proche de 1.0) pour détecter davantage de visages, y compris ceux partiellement masqués. * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR via un décodage automatique. --- --- url: https://docs.snapotter.com/es/tools/pdf/booklet-pdf.md description: Ordena las páginas de un PDF para plegarlas y formar un folleto. --- # Folleto PDF {#booklet-pdf} Impone las páginas para la impresión a doble cara de modo que las hojas impresas puedan plegarse para formar un folleto. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Acepta datos de formulario multipart con un archivo PDF y un campo `settings` en JSON. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | Páginas por hoja: `2`, `4`, `6` o `8` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notas {#notes} * El valor predeterminado `perSheet: 2` coloca dos páginas una al lado de la otra en cada hoja, que es el diseño de folleto estándar para la impresión a doble cara. * Se añaden páginas en blanco automáticamente si el número total de páginas no es múltiplo del tamaño de la hoja. * Imprime la salida a doble cara con encuadernación por el borde corto, luego pliega y grapa. --- --- url: https://docs.snapotter.com/fr/tools/audio/fade-audio.md description: Ajouter des effets de fondu en ouverture et en fermeture à l'audio. --- # Fondu audio {#fade-audio} Ajouter des effets de fondu en ouverture et en fermeture au début et à la fin d'un fichier audio. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Accepte des données de formulaire multipart avec un fichier audio et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | fadeInS | number | Non | `1` | Durée du fondu en ouverture en secondes (0 à 30) | | fadeOutS | number | Non | `1` | Durée du fondu en fermeture en secondes (0 à 30) | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notes {#notes} * Réglez l'une ou l'autre des valeurs sur `0` pour ignorer ce sens de fondu. Au moins une doit être supérieure à 0. * La durée du fondu est bornée à la longueur de l'audio si elle la dépasse. * La sortie conserve généralement le conteneur d'entrée. Une entrée AAC est écrite en M4A, et les entrées à décodage seul non prises en charge se replient sur le MP3. --- --- url: https://docs.snapotter.com/id/guide/supported-formats.md description: >- Format file yang didukung di semua modalitas - 55+ format masukan gambar, video, audio, PDF, dan format file. --- # Format yang Didukung {#supported-formats} SnapOtter memproses file di lima modalitas: image, video, audio, PDF, dan files. Halaman ini mencantumkan semua format yang didukung. ## Format Gambar {#image-formats} SnapOtter mendukung 55+ format gambar untuk masukan dan 17 format untuk keluaran. ## Format Masukan {#input-formats} ### Standar Web (9) {#web-standards-9} | Format | Ekstensi | Decoder | Catatan | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (native) | | | PNG | .png | Sharp (native) | Frame pertama APNG diekstrak | | WebP | .webp | Sharp (native) | | | GIF | .gif | Sharp (native) | Animasi didukung | | AVIF | .avif | Sharp (native) | | | SVG | .svg | Sharp (librsvg) | Disanitasi untuk XXE/SSRF | | SVGZ | .svgz | gunzip + Sharp | Proteksi gzip bomb | | APNG | .apng | Sharp (native) | Hanya frame pertama | | JPEG XL | .jxl | djxl / ImageMagick | Fallback dua tingkat | ### Profesional (7) {#professional-7} | Format | Ekstensi | Decoder | Catatan | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (native) | Multi-halaman didukung | | PSD | .psd | ImageMagick | Komposit yang diratakan | | EPS | .eps, .epsf | ImageMagick + Ghostscript | Rasterisasi 300dpi, diperkuat keamanannya | | OpenEXR | .exr | ImageMagick | Konversi linear-ke-sRGB | | Radiance HDR | .hdr | ImageMagick | Konversi linear-ke-sRGB | | DPX | .dpx | ImageMagick | Konversi log-ke-sRGB | | Cineon | .cin | ImageMagick | Format Film/VFX | ### Camera RAW (23) {#camera-raw-23} | Format | Ekstensi | Merek Kamera | Decoder | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (universal) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (sebelum 2018) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (lawas) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (compact) | exiftool / ImageMagick + LibRaw | ### Format Modern (3) {#modern-formats-3} | Format | Ekstensi | Decoder | Catatan | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Sinema digital, pencitraan medis | | QOI | .qoi | Codec TypeScript inline | Pengembangan game, sistem tertanam | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | Foto iPhone | ### Lawas/Sistem (4) {#legacy-system-4} | Format | Ekstensi | Decoder | Catatan | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | Layer terbesar diekstrak | | CUR | .cur | ImageMagick | Kursor Windows (varian ICO) | | TGA | .tga | ImageMagick | Deteksi hanya lewat ekstensi | ### Ilmiah dan Gaming (2) {#scientific-and-gaming-2} | Format | Ekstensi | Decoder | Catatan | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Astronomi (standar NASA) | | DDS | .dds | ImageMagick | Tekstur game (DirectX) | ### Interchange (6) {#interchange-6} | Format | Ekstensi | Decoder | Catatan | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (native) | Pixmap berwarna | | PGM | .pgm | Sharp (native) | Grayscale | | PBM | .pbm | Sharp (native) | Bitmap 1-bit | | PNM | .pnm | Sharp (native) | Format payung | | PAM | .pam | Sharp (native) | Peta arbitrer | | PFM | .pfm | Sharp (native) | Peta float | ## Format Keluaran (17) {#output-formats-13} | Format | Encoder | Kontrol Kualitas | Tersedia Di | |--------|---------|----------------|-------------| | JPEG | Sharp native | 1-100 | Semua alat | | PNG | Sharp native | Kompresi 0-9 | Semua alat | | WebP | Sharp native | 1-100 | Semua alat | | AVIF | Sharp native | 1-100 | Semua alat | | TIFF | Sharp native | 1-100 | Alat konversi penuh | | GIF | Sharp native | 1-100 | Alat konversi penuh | | JXL | Sharp native | 1-100 | Semua alat | | HEIC | heif-enc CLI | 1-100 | Alat konversi penuh | | HEIF | heif-enc CLI | 1-100 | Alat konversi penuh | | BMP | ImageMagick CLI | Lossless | Alat convert | | ICO | ImageMagick CLI | Lossless | Alat convert | | JP2 | opj\_compress CLI | Rasio kompresi | Alat convert | | QOI | Codec inline | Lossless | Alat convert | | PSD | ImageMagick CLI | Lossless | Alat convert | | PPM | ImageMagick CLI | Lossless | Alat convert | | EPS | ImageMagick CLI | Lossless | Alat convert | | TGA | ImageMagick CLI | Lossless | Alat convert | ## Format Video {#video-formats} Penguraian dan pengodean video ditangani oleh FFmpeg (build statis), sehingga setiap container dan codec umum didukung pada masukan. ### Container Masukan (15) {#input-containers-15} | Format | Ekstensi | Codec umum | Catatan | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | Container yang paling banyak digunakan | | QuickTime | .mov | H.264, ProRes | Perekaman/penyuntingan Apple | | WebM | .webm | VP8, VP9, AV1 | Format web bebas royalti | | Matroska | .mkv | Apa pun | Container terbuka yang fleksibel | | AVI | .avi | Beragam | Container lawas Microsoft | | M4V | .m4v | H.264 | Varian MP4 Apple | | AVCHD | .mts | H.264 | Rekaman camcorder | | BDAV | .m2ts | H.264 | Transport stream Blu-ray / AVCHD | | 3GP | .3gp | H.264, MPEG-4 | Perekaman seluler | | Flash Video | .flv | H.264, VP6 | Streaming lawas | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | Video era DVD | | MPEG-TS | .ts | MPEG-2, H.264 | Transport stream siaran | | Ogg | .ogv | Theora | Video Ogg terbuka | ### Format Keluaran {#output-formats} | Format | Ekstensi | Codec video | Dihasilkan oleh | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Convert, compress, dan sebagian besar alat video | | QuickTime | .mov | H.264 | Convert Video | | WebM | .webm | VP9 | Convert Video | | GIF | .gif | - | Video to GIF | | WebP | .webp | - | Video to WebP (animasi) | ### Subtitle {#subtitles} | Format | Ekstensi | Operasi | |--------|-----------|-----------| | SubRip | .srt | Embed, burn-in, ekstrak, buat otomatis | | WebVTT | .vtt | Embed, burn-in, ekstrak, buat otomatis | | ASS / SSA | .ass | Embed, burn-in (mendukung styling) | ## Format Audio {#audio-formats} Audio juga diproses oleh FFmpeg. ### Format Masukan (11) {#input-formats-11} | Format | Ekstensi | Kompresi | Catatan | |--------|-----------|-------------|-------| | MP3 | .mp3 | Lossy | Kompatibilitas universal | | WAV | .wav | Tanpa kompresi (PCM) | Studio / penyuntingan | | FLAC | .flac | Lossless | Codec lossless terbuka | | AAC | .aac | Lossy | Aliran AAC mentah | | M4A | .m4a | Lossy (AAC) / Lossless (ALAC) | Audio MPEG-4 | | Ogg Vorbis | .ogg | Lossy | Format terbuka | | Opus | .opus | Lossy | Modern, latensi rendah | | WMA | .wma | Lossy | Windows Media Audio | | AIFF | .aiff | Tanpa kompresi (PCM) | Tanpa kompresi Apple | | AMR | .amr | Lossy | Suara / seluler | | AC-3 | .ac3 | Lossy | Dolby Digital | ### Format Keluaran {#output-formats-1} | Format | Ekstensi | Codec | Dihasilkan oleh | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Convert Audio, Extract Audio | | WAV | .wav | PCM | Convert Audio, Extract Audio | | FLAC | .flac | FLAC (lossless) | Convert Audio | | Ogg | .ogg | Vorbis | Convert Audio | | M4A | .m4a | AAC | Convert Audio, Extract Audio | ## Format Dokumen {#document-formats} Pemrosesan dokumen menggunakan qpdf, LibreOffice, Ghostscript, Pandoc, dan WeasyPrint. ### Format Masukan (15) {#input-formats-15} | Format | Ekstensi | Engine | Catatan | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Format dokumen inti | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Teks, lembar, presentasi | | Rich Text | .rtf | LibreOffice | Rich text lintas aplikasi | | Plain Text | .txt | LibreOffice, Pandoc | Teks UTF-8 | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | Dirender ke PDF | | EPUB | .epub | Pandoc, LibreOffice | Format e-book | ### Format Keluaran {#output-formats-2} | Format | Ekstensi | Dihasilkan oleh | |--------|-----------|-------------| | PDF | .pdf | Word/Excel/PowerPoint ke PDF, Markdown ke PDF, HTML ke PDF | | PDF/A | .pdf | PDF/A Convert (arsip) | | Word | .docx, .odt, .rtf, .txt | Convert Document, PDF ke Word, Markdown ke Word | | Presentasi | .pptx, .odp | Convert Presentation | | Spreadsheet | .xlsx, .ods, .csv | Convert Spreadsheet | | HTML | .html | Markdown ke HTML | | EPUB | .epub | Convert ke EPUB | | Gambar | .png, .jpg | PDF ke Image | ## Format File {#file-formats} Alat data dan arsip mengonversi antar format terstruktur dan mengemas file. | Format | Ekstensi | Konversi | |--------|-----------|-------------| | CSV | .csv | Ke/dari JSON dan Excel; split dan merge; dari XML | | JSON | .json | Ke/dari CSV, XML, dan YAML | | XML | .xml | Ke/dari JSON; ke CSV | | YAML | .yaml, .yml | Ke/dari JSON | | Excel | .xlsx | Ke/dari CSV | | ZIP | .zip | Buat arsip, ekstrak isi | --- --- url: https://docs.snapotter.com/it/guide/supported-formats.md description: >- Formati di file supportati in tutte le modalità: oltre 55 formati di input immagine, video, audio, PDF e file. --- # Formati supportati {#supported-formats} SnapOtter elabora file in cinque modalità: immagine, video, audio, PDF e file. Questa pagina elenca tutti i formati supportati. ## Formati immagine {#image-formats} SnapOtter supporta oltre 55 formati immagine in input e 17 formati in output. ## Formati di input {#input-formats} ### Standard web (9) {#web-standards-9} | Formato | Estensioni | Decoder | Note | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (nativo) | | | PNG | .png | Sharp (nativo) | Primo frame APNG estratto | | WebP | .webp | Sharp (nativo) | | | GIF | .gif | Sharp (nativo) | Animazioni supportate | | AVIF | .avif | Sharp (nativo) | | | SVG | .svg | Sharp (librsvg) | Sanitizzato contro XXE/SSRF | | SVGZ | .svgz | gunzip + Sharp | Protezione contro gzip bomb | | APNG | .apng | Sharp (nativo) | Solo primo frame | | JPEG XL | .jxl | djxl / ImageMagick | Fallback a due livelli | ### Professionali (7) {#professional-7} | Formato | Estensioni | Decoder | Note | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (nativo) | Multipagina supportato | | PSD | .psd | ImageMagick | Composito appiattito | | EPS | .eps, .epsf | ImageMagick + Ghostscript | Rasterizzazione a 300dpi, con sicurezza rafforzata | | OpenEXR | .exr | ImageMagick | Conversione da lineare a sRGB | | Radiance HDR | .hdr | ImageMagick | Conversione da lineare a sRGB | | DPX | .dpx | ImageMagick | Conversione da logaritmico a sRGB | | Cineon | .cin | ImageMagick | Formato Film/VFX | ### Camera RAW (23) {#camera-raw-23} | Formato | Estensioni | Marca fotocamera | Decoder | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (universale) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (pre-2018) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (legacy) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (compatta) | exiftool / ImageMagick + LibRaw | ### Formati moderni (3) {#modern-formats-3} | Formato | Estensioni | Decoder | Note | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Cinema digitale, imaging medico | | QOI | .qoi | Codec TypeScript inline | Sviluppo giochi, sistemi embedded | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | Foto iPhone | ### Legacy/di sistema (4) {#legacy-system-4} | Formato | Estensioni | Decoder | Note | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | Estratto il layer più grande | | CUR | .cur | ImageMagick | Cursore Windows (variante ICO) | | TGA | .tga | ImageMagick | Rilevamento solo per estensione | ### Scientifici e gaming (2) {#scientific-and-gaming-2} | Formato | Estensioni | Decoder | Note | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Astronomia (standard NASA) | | DDS | .dds | ImageMagick | Texture di gioco (DirectX) | ### Interscambio (6) {#interchange-6} | Formato | Estensioni | Decoder | Note | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (nativo) | Pixmap a colori | | PGM | .pgm | Sharp (nativo) | Scala di grigi | | PBM | .pbm | Sharp (nativo) | Bitmap a 1 bit | | PNM | .pnm | Sharp (nativo) | Formato ombrello | | PAM | .pam | Sharp (nativo) | Mappa arbitraria | | PFM | .pfm | Sharp (nativo) | Mappa float | ## Formati di output (17) {#output-formats-13} | Formato | Encoder | Controllo qualità | Disponibile in | |--------|---------|----------------|-------------| | JPEG | Sharp nativo | 1-100 | Tutti gli strumenti | | PNG | Sharp nativo | Compressione 0-9 | Tutti gli strumenti | | WebP | Sharp nativo | 1-100 | Tutti gli strumenti | | AVIF | Sharp nativo | 1-100 | Tutti gli strumenti | | TIFF | Sharp nativo | 1-100 | Strumenti di conversione completa | | GIF | Sharp nativo | 1-100 | Strumenti di conversione completa | | JXL | Sharp nativo | 1-100 | Tutti gli strumenti | | HEIC | heif-enc CLI | 1-100 | Strumenti di conversione completa | | HEIF | heif-enc CLI | 1-100 | Strumenti di conversione completa | | BMP | ImageMagick CLI | Senza perdita | Strumento di conversione | | ICO | ImageMagick CLI | Senza perdita | Strumento di conversione | | JP2 | opj\_compress CLI | Rapporto di compressione | Strumento di conversione | | QOI | Codec inline | Senza perdita | Strumento di conversione | | PSD | ImageMagick CLI | Senza perdita | Strumento di conversione | | PPM | ImageMagick CLI | Senza perdita | Strumento di conversione | | EPS | ImageMagick CLI | Senza perdita | Strumento di conversione | | TGA | ImageMagick CLI | Senza perdita | Strumento di conversione | ## Formati video {#video-formats} La decodifica e la codifica video sono gestite da FFmpeg (build statica), quindi ogni container e codec comune è supportato in input. ### Container di input (15) {#input-containers-15} | Formato | Estensioni | Codec tipici | Note | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | Il container più usato | | QuickTime | .mov | H.264, ProRes | Cattura/editing Apple | | WebM | .webm | VP8, VP9, AV1 | Formato web royalty-free | | Matroska | .mkv | Qualsiasi | Container aperto e flessibile | | AVI | .avi | Vari | Container Microsoft legacy | | M4V | .m4v | H.264 | Variante MP4 di Apple | | AVCHD | .mts | H.264 | Registrazioni da videocamera | | BDAV | .m2ts | H.264 | Transport stream Blu-ray / AVCHD | | 3GP | .3gp | H.264, MPEG-4 | Cattura da mobile | | Flash Video | .flv | H.264, VP6 | Streaming legacy | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | Video dell'era DVD | | MPEG-TS | .ts | MPEG-2, H.264 | Transport stream broadcast | | Ogg | .ogv | Theora | Video Ogg aperto | ### Formati di output {#output-formats} | Formato | Estensione | Codec video | Prodotto da | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Converti, comprimi e la maggior parte degli strumenti video | | QuickTime | .mov | H.264 | Converti video | | WebM | .webm | VP9 | Converti video | | GIF | .gif | - | Da video a GIF | | WebP | .webp | - | Da video a WebP (animato) | ### Sottotitoli {#subtitles} | Formato | Estensione | Operazioni | |--------|-----------|-----------| | SubRip | .srt | Incorpora, applica in sovrimpressione, estrai, genera automaticamente | | WebVTT | .vtt | Incorpora, applica in sovrimpressione, estrai, genera automaticamente | | ASS / SSA | .ass | Incorpora, applica in sovrimpressione (supporta lo stile) | ## Formati audio {#audio-formats} Anche l'audio è elaborato da FFmpeg. ### Formati di input (11) {#input-formats-11} | Formato | Estensioni | Compressione | Note | |--------|-----------|-------------|-------| | MP3 | .mp3 | Con perdita | Compatibilità universale | | WAV | .wav | Non compresso (PCM) | Studio / editing | | FLAC | .flac | Senza perdita | Codec lossless aperto | | AAC | .aac | Con perdita | Stream AAC grezzo | | M4A | .m4a | Con perdita (AAC) / Senza perdita (ALAC) | Audio MPEG-4 | | Ogg Vorbis | .ogg | Con perdita | Formato aperto | | Opus | .opus | Con perdita | Moderno, a bassa latenza | | WMA | .wma | Con perdita | Windows Media Audio | | AIFF | .aiff | Non compresso (PCM) | Non compresso Apple | | AMR | .amr | Con perdita | Voce / mobile | | AC-3 | .ac3 | Con perdita | Dolby Digital | ### Formati di output {#output-formats-1} | Formato | Estensione | Codec | Prodotto da | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Converti audio, Estrai audio | | WAV | .wav | PCM | Converti audio, Estrai audio | | FLAC | .flac | FLAC (senza perdita) | Converti audio | | Ogg | .ogg | Vorbis | Converti audio | | M4A | .m4a | AAC | Converti audio, Estrai audio | ## Formati documento {#document-formats} L'elaborazione dei documenti usa qpdf, LibreOffice, Ghostscript, Pandoc e WeasyPrint. ### Formati di input (15) {#input-formats-15} | Formato | Estensioni | Motore | Note | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Formato documento principale | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Testo, foglio, presentazione | | Rich Text | .rtf | LibreOffice | Rich text multi-app | | Testo semplice | .txt | LibreOffice, Pandoc | Testo UTF-8 | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | Renderizzato in PDF | | EPUB | .epub | Pandoc, LibreOffice | Formato e-book | ### Formati di output {#output-formats-2} | Formato | Estensioni | Prodotto da | |--------|-----------|-------------| | PDF | .pdf | Da Word/Excel/PowerPoint a PDF, da Markdown a PDF, da HTML a PDF | | PDF/A | .pdf | Converti in PDF/A (archiviazione) | | Word | .docx, .odt, .rtf, .txt | Converti documento, da PDF a Word, da Markdown a Word | | Presentazione | .pptx, .odp | Converti presentazione | | Foglio di calcolo | .xlsx, .ods, .csv | Converti foglio di calcolo | | HTML | .html | Da Markdown a HTML | | EPUB | .epub | Converti in EPUB | | Immagini | .png, .jpg | Da PDF a immagine | ## Formati file {#file-formats} Gli strumenti per dati e archivi convertono tra formati strutturati e raggruppano file. | Formato | Estensioni | Conversioni | |--------|-----------|-------------| | CSV | .csv | Da/verso JSON ed Excel; dividi e unisci; da XML | | JSON | .json | Da/verso CSV, XML e YAML | | XML | .xml | Da/verso JSON; verso CSV | | YAML | .yaml, .yml | Da/verso JSON | | Excel | .xlsx | Da/verso CSV | | ZIP | .zip | Crea archivi, estrai contenuti | --- --- url: https://docs.snapotter.com/es/guide/supported-formats.md description: >- Formatos de archivo admitidos en todas las modalidades: más de 55 formatos de entrada de imagen, vídeo, audio, PDF y archivos. --- # Formatos admitidos {#supported-formats} SnapOtter procesa archivos en cinco modalidades: imagen, vídeo, audio, PDF y archivos. Esta página enumera todos los formatos admitidos. ## Formatos de imagen {#image-formats} SnapOtter admite más de 55 formatos de imagen para entrada y 17 formatos para salida. ## Formatos de entrada {#input-formats} ### Estándares web (9) {#web-standards-9} | Formato | Extensiones | Decodificador | Notas | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (nativo) | | | PNG | .png | Sharp (nativo) | Se extrae el primer fotograma de APNG | | WebP | .webp | Sharp (nativo) | | | GIF | .gif | Sharp (nativo) | Animado admitido | | AVIF | .avif | Sharp (nativo) | | | SVG | .svg | Sharp (librsvg) | Saneado frente a XXE/SSRF | | SVGZ | .svgz | gunzip + Sharp | Protección contra bomba gzip | | APNG | .apng | Sharp (nativo) | Solo el primer fotograma | | JPEG XL | .jxl | djxl / ImageMagick | Reserva en dos niveles | ### Profesionales (7) {#professional-7} | Formato | Extensiones | Decodificador | Notas | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (nativo) | Multipágina admitido | | PSD | .psd | ImageMagick | Composición aplanada | | EPS | .eps, .epsf | ImageMagick + Ghostscript | Rasterización a 300 ppp, reforzado en seguridad | | OpenEXR | .exr | ImageMagick | Conversión lineal a sRGB | | Radiance HDR | .hdr | ImageMagick | Conversión lineal a sRGB | | DPX | .dpx | ImageMagick | Conversión logarítmica a sRGB | | Cineon | .cin | ImageMagick | Formato de cine/VFX | ### RAW de cámara (23) {#camera-raw-23} | Formato | Extensiones | Marca de cámara | Decodificador | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (universal) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (antes de 2018) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (heredado) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (compacta) | exiftool / ImageMagick + LibRaw | ### Formatos modernos (3) {#modern-formats-3} | Formato | Extensiones | Decodificador | Notas | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Cine digital, imagen médica | | QOI | .qoi | Códec TypeScript en línea | Desarrollo de juegos, sistemas embebidos | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | Fotos de iPhone | ### Heredados/de sistema (4) {#legacy-system-4} | Formato | Extensiones | Decodificador | Notas | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | Se extrae la capa más grande | | CUR | .cur | ImageMagick | Cursor de Windows (variante de ICO) | | TGA | .tga | ImageMagick | Detección solo por extensión | ### Científicos y de videojuegos (2) {#scientific-and-gaming-2} | Formato | Extensiones | Decodificador | Notas | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Astronomía (estándar de la NASA) | | DDS | .dds | ImageMagick | Texturas de juegos (DirectX) | ### Intercambio (6) {#interchange-6} | Formato | Extensiones | Decodificador | Notas | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (nativo) | Pixmap de color | | PGM | .pgm | Sharp (nativo) | Escala de grises | | PBM | .pbm | Sharp (nativo) | Mapa de bits de 1 bit | | PNM | .pnm | Sharp (nativo) | Formato paraguas | | PAM | .pam | Sharp (nativo) | Mapa arbitrario | | PFM | .pfm | Sharp (nativo) | Mapa de coma flotante | ## Formatos de salida (17) {#output-formats-13} | Formato | Codificador | Control de calidad | Disponible en | |--------|---------|----------------|-------------| | JPEG | Sharp nativo | 1-100 | Todas las herramientas | | PNG | Sharp nativo | Compresión 0-9 | Todas las herramientas | | WebP | Sharp nativo | 1-100 | Todas las herramientas | | AVIF | Sharp nativo | 1-100 | Todas las herramientas | | TIFF | Sharp nativo | 1-100 | Herramientas de conversión completa | | GIF | Sharp nativo | 1-100 | Herramientas de conversión completa | | JXL | Sharp nativo | 1-100 | Todas las herramientas | | HEIC | CLI heif-enc | 1-100 | Herramientas de conversión completa | | HEIF | CLI heif-enc | 1-100 | Herramientas de conversión completa | | BMP | CLI ImageMagick | Sin pérdidas | Herramienta de conversión | | ICO | CLI ImageMagick | Sin pérdidas | Herramienta de conversión | | JP2 | CLI opj\_compress | Ratio de compresión | Herramienta de conversión | | QOI | Códec en línea | Sin pérdidas | Herramienta de conversión | | PSD | CLI ImageMagick | Sin pérdidas | Herramienta de conversión | | PPM | CLI ImageMagick | Sin pérdidas | Herramienta de conversión | | EPS | CLI ImageMagick | Sin pérdidas | Herramienta de conversión | | TGA | CLI ImageMagick | Sin pérdidas | Herramienta de conversión | ## Formatos de vídeo {#video-formats} La decodificación y codificación de vídeo las gestiona FFmpeg (compilación estática), así que se admite en la entrada cualquier contenedor y códec común. ### Contenedores de entrada (15) {#input-containers-15} | Formato | Extensiones | Códecs típicos | Notas | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | El contenedor más usado | | QuickTime | .mov | H.264, ProRes | Captura/edición de Apple | | WebM | .webm | VP8, VP9, AV1 | Formato web libre de regalías | | Matroska | .mkv | Cualquiera | Contenedor abierto y flexible | | AVI | .avi | Varios | Contenedor heredado de Microsoft | | M4V | .m4v | H.264 | Variante de MP4 de Apple | | AVCHD | .mts | H.264 | Grabaciones de videocámara | | BDAV | .m2ts | H.264 | Flujo de transporte de Blu-ray / AVCHD | | 3GP | .3gp | H.264, MPEG-4 | Captura móvil | | Flash Video | .flv | H.264, VP6 | Streaming heredado | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | Vídeo de la era del DVD | | MPEG-TS | .ts | MPEG-2, H.264 | Flujo de transporte de difusión | | Ogg | .ogv | Theora | Vídeo Ogg abierto | ### Formatos de salida {#output-formats} | Formato | Extensión | Códec de vídeo | Producido por | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Convertir, comprimir y la mayoría de herramientas de vídeo | | QuickTime | .mov | H.264 | Convertir vídeo | | WebM | .webm | VP9 | Convertir vídeo | | GIF | .gif | - | Vídeo a GIF | | WebP | .webp | - | Vídeo a WebP (animado) | ### Subtítulos {#subtitles} | Formato | Extensión | Operaciones | |--------|-----------|-----------| | SubRip | .srt | Incrustar, quemar, extraer, generar automáticamente | | WebVTT | .vtt | Incrustar, quemar, extraer, generar automáticamente | | ASS / SSA | .ass | Incrustar, quemar (admite estilos) | ## Formatos de audio {#audio-formats} El audio también se procesa con FFmpeg. ### Formatos de entrada (11) {#input-formats-11} | Formato | Extensiones | Compresión | Notas | |--------|-----------|-------------|-------| | MP3 | .mp3 | Con pérdidas | Compatibilidad universal | | WAV | .wav | Sin comprimir (PCM) | Estudio / edición | | FLAC | .flac | Sin pérdidas | Códec abierto sin pérdidas | | AAC | .aac | Con pérdidas | Flujo AAC en bruto | | M4A | .m4a | Con pérdidas (AAC) / Sin pérdidas (ALAC) | Audio MPEG-4 | | Ogg Vorbis | .ogg | Con pérdidas | Formato abierto | | Opus | .opus | Con pérdidas | Moderno, de baja latencia | | WMA | .wma | Con pérdidas | Windows Media Audio | | AIFF | .aiff | Sin comprimir (PCM) | Sin comprimir de Apple | | AMR | .amr | Con pérdidas | Voz / móvil | | AC-3 | .ac3 | Con pérdidas | Dolby Digital | ### Formatos de salida {#output-formats-1} | Formato | Extensión | Códec | Producido por | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Convertir audio, Extraer audio | | WAV | .wav | PCM | Convertir audio, Extraer audio | | FLAC | .flac | FLAC (sin pérdidas) | Convertir audio | | Ogg | .ogg | Vorbis | Convertir audio | | M4A | .m4a | AAC | Convertir audio, Extraer audio | ## Formatos de documento {#document-formats} El procesamiento de documentos usa qpdf, LibreOffice, Ghostscript, Pandoc y WeasyPrint. ### Formatos de entrada (15) {#input-formats-15} | Formato | Extensiones | Motor | Notas | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Formato de documento principal | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Texto, hoja, presentación | | Rich Text | .rtf | LibreOffice | Texto enriquecido multiaplicación | | Texto plano | .txt | LibreOffice, Pandoc | Texto UTF-8 | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | Renderizado a PDF | | EPUB | .epub | Pandoc, LibreOffice | Formato de libro electrónico | ### Formatos de salida {#output-formats-2} | Formato | Extensiones | Producido por | |--------|-----------|-------------| | PDF | .pdf | Word/Excel/PowerPoint a PDF, Markdown a PDF, HTML a PDF | | PDF/A | .pdf | Conversión a PDF/A (archivo) | | Word | .docx, .odt, .rtf, .txt | Convertir documento, PDF a Word, Markdown a Word | | Presentación | .pptx, .odp | Convertir presentación | | Hoja de cálculo | .xlsx, .ods, .csv | Convertir hoja de cálculo | | HTML | .html | Markdown a HTML | | EPUB | .epub | Convertir a EPUB | | Imágenes | .png, .jpg | PDF a imagen | ## Formatos de archivo {#file-formats} Las herramientas de datos y archivado convierten entre formatos estructurados y empaquetan archivos. | Formato | Extensiones | Conversiones | |--------|-----------|-------------| | CSV | .csv | Hacia/desde JSON y Excel; dividir y combinar; desde XML | | JSON | .json | Hacia/desde CSV, XML y YAML | | XML | .xml | Hacia/desde JSON; a CSV | | YAML | .yaml, .yml | Hacia/desde JSON | | Excel | .xlsx | Hacia/desde CSV | | ZIP | .zip | Crear archivos, extraer contenido | --- --- url: https://docs.snapotter.com/pt-BR/guide/supported-formats.md description: >- Formatos de arquivo suportados em todas as modalidades - mais de 55 formatos de entrada de imagem, além de vídeo, áudio, PDF e formatos de arquivo. --- # Formatos Suportados {#supported-formats} O SnapOtter processa arquivos em cinco modalidades: imagem, vídeo, áudio, PDF e arquivos. Esta página lista todos os formatos suportados. ## Formatos de Imagem {#image-formats} O SnapOtter suporta mais de 55 formatos de imagem para entrada e 17 formatos para saída. ## Formatos de Entrada {#input-formats} ### Padrões da Web (9) {#web-standards-9} | Formato | Extensões | Decodificador | Observações | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (nativo) | | | PNG | .png | Sharp (nativo) | Primeiro quadro do APNG extraído | | WebP | .webp | Sharp (nativo) | | | GIF | .gif | Sharp (nativo) | Animado suportado | | AVIF | .avif | Sharp (nativo) | | | SVG | .svg | Sharp (librsvg) | Higienizado contra XXE/SSRF | | SVGZ | .svgz | gunzip + Sharp | Proteção contra bomba de Gzip | | APNG | .apng | Sharp (nativo) | Apenas o primeiro quadro | | JPEG XL | .jxl | djxl / ImageMagick | Fallback em duas camadas | ### Profissional (7) {#professional-7} | Formato | Extensões | Decodificador | Observações | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (nativo) | Múltiplas páginas suportadas | | PSD | .psd | ImageMagick | Composição achatada | | EPS | .eps, .epsf | ImageMagick + Ghostscript | Rasterização a 300dpi, reforçado quanto à segurança | | OpenEXR | .exr | ImageMagick | Conversão linear para sRGB | | Radiance HDR | .hdr | ImageMagick | Conversão linear para sRGB | | DPX | .dpx | ImageMagick | Conversão log para sRGB | | Cineon | .cin | ImageMagick | Formato de cinema/VFX | ### Camera RAW (23) {#camera-raw-23} | Formato | Extensões | Marca de Câmera | Decodificador | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (universal) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (anterior a 2018) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (legado) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (compacta) | exiftool / ImageMagick + LibRaw | ### Formatos Modernos (3) {#modern-formats-3} | Formato | Extensões | Decodificador | Observações | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Cinema digital, imagem médica | | QOI | .qoi | Codec TypeScript inline | Desenvolvimento de jogos, sistemas embarcados | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | Fotos de iPhone | ### Legado/Sistema (4) {#legacy-system-4} | Formato | Extensões | Decodificador | Observações | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | Maior camada extraída | | CUR | .cur | ImageMagick | Cursor do Windows (variante do ICO) | | TGA | .tga | ImageMagick | Detecção somente por extensão | ### Científico e Jogos (2) {#scientific-and-gaming-2} | Formato | Extensões | Decodificador | Observações | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Astronomia (padrão da NASA) | | DDS | .dds | ImageMagick | Texturas de jogos (DirectX) | ### Intercâmbio (6) {#interchange-6} | Formato | Extensões | Decodificador | Observações | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (nativo) | Pixmap colorido | | PGM | .pgm | Sharp (nativo) | Escala de cinza | | PBM | .pbm | Sharp (nativo) | Bitmap de 1 bit | | PNM | .pnm | Sharp (nativo) | Formato guarda-chuva | | PAM | .pam | Sharp (nativo) | Mapa arbitrário | | PFM | .pfm | Sharp (nativo) | Mapa de ponto flutuante | ## Formatos de Saída (17) {#output-formats-13} | Formato | Codificador | Controle de Qualidade | Disponível Em | |--------|---------|----------------|-------------| | JPEG | Sharp nativo | 1-100 | Todas as ferramentas | | PNG | Sharp nativo | Compressão 0-9 | Todas as ferramentas | | WebP | Sharp nativo | 1-100 | Todas as ferramentas | | AVIF | Sharp nativo | 1-100 | Todas as ferramentas | | TIFF | Sharp nativo | 1-100 | Ferramentas de conversão completa | | GIF | Sharp nativo | 1-100 | Ferramentas de conversão completa | | JXL | Sharp nativo | 1-100 | Todas as ferramentas | | HEIC | CLI heif-enc | 1-100 | Ferramentas de conversão completa | | HEIF | CLI heif-enc | 1-100 | Ferramentas de conversão completa | | BMP | CLI ImageMagick | Sem perdas | Ferramenta de conversão | | ICO | CLI ImageMagick | Sem perdas | Ferramenta de conversão | | JP2 | CLI opj\_compress | Taxa de compressão | Ferramenta de conversão | | QOI | Codec inline | Sem perdas | Ferramenta de conversão | | PSD | CLI ImageMagick | Sem perdas | Ferramenta de conversão | | PPM | CLI ImageMagick | Sem perdas | Ferramenta de conversão | | EPS | CLI ImageMagick | Sem perdas | Ferramenta de conversão | | TGA | CLI ImageMagick | Sem perdas | Ferramenta de conversão | ## Formatos de Vídeo {#video-formats} A decodificação e a codificação de vídeo são feitas pelo FFmpeg (build estático), então todo contêiner e codec comum é suportado na entrada. ### Contêineres de Entrada (15) {#input-containers-15} | Formato | Extensões | Codecs típicos | Observações | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | Contêiner mais utilizado | | QuickTime | .mov | H.264, ProRes | Captura/edição Apple | | WebM | .webm | VP8, VP9, AV1 | Formato web livre de royalties | | Matroska | .mkv | Qualquer | Contêiner aberto e flexível | | AVI | .avi | Vários | Contêiner legado da Microsoft | | M4V | .m4v | H.264 | Variante MP4 da Apple | | AVCHD | .mts | H.264 | Gravações de filmadora | | BDAV | .m2ts | H.264 | Fluxo de transporte Blu-ray / AVCHD | | 3GP | .3gp | H.264, MPEG-4 | Captura móvel | | Flash Video | .flv | H.264, VP6 | Streaming legado | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | Vídeo da era do DVD | | MPEG-TS | .ts | MPEG-2, H.264 | Fluxo de transporte de broadcast | | Ogg | .ogv | Theora | Vídeo Ogg aberto | ### Formatos de Saída {#output-formats} | Formato | Extensão | Codec de vídeo | Produzido por | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Converter, comprimir e a maioria das ferramentas de vídeo | | QuickTime | .mov | H.264 | Converter Vídeo | | WebM | .webm | VP9 | Converter Vídeo | | GIF | .gif | - | Vídeo para GIF | | WebP | .webp | - | Vídeo para WebP (animado) | ### Legendas {#subtitles} | Formato | Extensão | Operações | |--------|-----------|-----------| | SubRip | .srt | Incorporar, gravar na imagem, extrair, gerar automaticamente | | WebVTT | .vtt | Incorporar, gravar na imagem, extrair, gerar automaticamente | | ASS / SSA | .ass | Incorporar, gravar na imagem (suporta estilização) | ## Formatos de Áudio {#audio-formats} O áudio também é processado pelo FFmpeg. ### Formatos de Entrada (11) {#input-formats-11} | Formato | Extensões | Compressão | Observações | |--------|-----------|-------------|-------| | MP3 | .mp3 | Com perdas | Compatibilidade universal | | WAV | .wav | Sem compressão (PCM) | Estúdio / edição | | FLAC | .flac | Sem perdas | Codec aberto sem perdas | | AAC | .aac | Com perdas | Fluxo AAC bruto | | M4A | .m4a | Com perdas (AAC) / Sem perdas (ALAC) | Áudio MPEG-4 | | Ogg Vorbis | .ogg | Com perdas | Formato aberto | | Opus | .opus | Com perdas | Moderno, baixa latência | | WMA | .wma | Com perdas | Windows Media Audio | | AIFF | .aiff | Sem compressão (PCM) | Sem compressão da Apple | | AMR | .amr | Com perdas | Fala / dispositivos móveis | | AC-3 | .ac3 | Com perdas | Dolby Digital | ### Formatos de Saída {#output-formats-1} | Formato | Extensão | Codec | Produzido por | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Converter Áudio, Extrair Áudio | | WAV | .wav | PCM | Converter Áudio, Extrair Áudio | | FLAC | .flac | FLAC (sem perdas) | Converter Áudio | | Ogg | .ogg | Vorbis | Converter Áudio | | M4A | .m4a | AAC | Converter Áudio, Extrair Áudio | ## Formatos de Documento {#document-formats} O processamento de documentos usa qpdf, LibreOffice, Ghostscript, Pandoc e WeasyPrint. ### Formatos de Entrada (15) {#input-formats-15} | Formato | Extensões | Motor | Observações | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Formato de documento principal | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Texto, planilha, apresentação | | Rich Text | .rtf | LibreOffice | Rich text multiaplicativo | | Texto Simples | .txt | LibreOffice, Pandoc | Texto UTF-8 | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | Renderizado para PDF | | EPUB | .epub | Pandoc, LibreOffice | Formato de e-book | ### Formatos de Saída {#output-formats-2} | Formato | Extensões | Produzido por | |--------|-----------|-------------| | PDF | .pdf | Word/Excel/PowerPoint para PDF, Markdown para PDF, HTML para PDF | | PDF/A | .pdf | Converter para PDF/A (arquivamento) | | Word | .docx, .odt, .rtf, .txt | Converter Documento, PDF para Word, Markdown para Word | | Apresentação | .pptx, .odp | Converter Apresentação | | Planilha | .xlsx, .ods, .csv | Converter Planilha | | HTML | .html | Markdown para HTML | | EPUB | .epub | Converter para EPUB | | Imagens | .png, .jpg | PDF para Imagem | ## Formatos de Arquivo {#file-formats} As ferramentas de dados e arquivamento convertem entre formatos estruturados e empacotam arquivos. | Formato | Extensões | Conversões | |--------|-----------|-------------| | CSV | .csv | Para/de JSON e Excel; dividir e mesclar; de XML | | JSON | .json | Para/de CSV, XML e YAML | | XML | .xml | Para/de JSON; para CSV | | YAML | .yaml, .yml | Para/de JSON | | Excel | .xlsx | Para/de CSV | | ZIP | .zip | Criar arquivos compactados, extrair conteúdo | --- --- url: https://docs.snapotter.com/fr/guide/supported-formats.md description: >- Formats de fichiers pris en charge dans toutes les modalités - plus de 55 formats d'image en entrée, vidéo, audio, PDF et formats de fichiers. --- # Formats pris en charge {#supported-formats} SnapOtter traite les fichiers selon cinq modalités : image, vidéo, audio, PDF et fichiers. Cette page liste tous les formats pris en charge. ## Formats d'image {#image-formats} SnapOtter prend en charge plus de 55 formats d'image en entrée et 17 formats en sortie. ## Formats d'entrée {#input-formats} ### Standards du web (9) {#web-standards-9} | Format | Extensions | Décodeur | Notes | |--------|-----------|---------|-------| | JPEG | .jpg, .jpeg | Sharp (natif) | | | PNG | .png | Sharp (natif) | Première image APNG extraite | | WebP | .webp | Sharp (natif) | | | GIF | .gif | Sharp (natif) | Animé pris en charge | | AVIF | .avif | Sharp (natif) | | | SVG | .svg | Sharp (librsvg) | Nettoyé contre XXE/SSRF | | SVGZ | .svgz | gunzip + Sharp | Protection contre les bombes gzip | | APNG | .apng | Sharp (natif) | Première image uniquement | | JPEG XL | .jxl | djxl / ImageMagick | Repli à deux niveaux | ### Professionnels (7) {#professional-7} | Format | Extensions | Décodeur | Notes | |--------|-----------|---------|-------| | TIFF | .tiff, .tif | Sharp (natif) | Multi-pages pris en charge | | PSD | .psd | ImageMagick | Composite aplati | | EPS | .eps, .epsf | ImageMagick + Ghostscript | Rastérisation à 300 ppp, sécurité durcie | | OpenEXR | .exr | ImageMagick | Conversion linéaire vers sRGB | | Radiance HDR | .hdr | ImageMagick | Conversion linéaire vers sRGB | | DPX | .dpx | ImageMagick | Conversion logarithmique vers sRGB | | Cineon | .cin | ImageMagick | Format film/VFX | ### RAW appareil photo (23) {#camera-raw-23} | Format | Extensions | Marque d'appareil | Décodeur | |--------|-----------|-------------|---------| | DNG | .dng | Adobe (universel) | exiftool / ImageMagick + LibRaw | | CR2 | .cr2 | Canon (avant 2018) | exiftool / ImageMagick + LibRaw | | CR3 | .cr3 | Canon (2018+) | exiftool / ImageMagick + LibRaw | | NEF | .nef | Nikon | exiftool / ImageMagick + LibRaw | | NRW | .nrw | Nikon (Coolpix) | exiftool / ImageMagick + LibRaw | | ARW | .arw | Sony | exiftool / ImageMagick + LibRaw | | ORF | .orf | Olympus | exiftool / ImageMagick + LibRaw | | RW2 | .rw2 | Panasonic | exiftool / ImageMagick + LibRaw | | RAF | .raf | Fujifilm | exiftool / ImageMagick + LibRaw | | PEF | .pef | Pentax/Ricoh | exiftool / ImageMagick + LibRaw | | 3FR | .3fr | Hasselblad | exiftool / ImageMagick + LibRaw | | IIQ | .iiq | Phase One | exiftool / ImageMagick + LibRaw | | SRW | .srw | Samsung | exiftool / ImageMagick + LibRaw | | X3F | .x3f | Sigma | exiftool / ImageMagick + LibRaw | | RWL | .rwl | Leica | exiftool / ImageMagick + LibRaw | | GPR | .gpr | GoPro | exiftool / ImageMagick + LibRaw | | FFF | .fff | Hasselblad (ancien) | exiftool / ImageMagick + LibRaw | | MRW | .mrw | Minolta | exiftool / ImageMagick + LibRaw | | MEF | .mef | Mamiya | exiftool / ImageMagick + LibRaw | | KDC | .kdc | Kodak | exiftool / ImageMagick + LibRaw | | DCR | .dcr | Kodak | exiftool / ImageMagick + LibRaw | | ERF | .erf | Epson | exiftool / ImageMagick + LibRaw | | PTX | .ptx | Pentax (compact) | exiftool / ImageMagick + LibRaw | ### Formats modernes (3) {#modern-formats-3} | Format | Extensions | Décodeur | Notes | |--------|-----------|---------|-------| | JPEG 2000 | .jp2, .j2k, .j2c, .jpc, .jpf, .jpx | opj\_decompress / ImageMagick | Cinéma numérique, imagerie médicale | | QOI | .qoi | Codec TypeScript intégré | Développement de jeux, systèmes embarqués | | HEIC/HEIF | .heic, .heif | heif-convert / heif-dec | Photos iPhone | ### Ancien/Système (4) {#legacy-system-4} | Format | Extensions | Décodeur | Notes | |--------|-----------|---------|-------| | BMP | .bmp | ImageMagick | | | ICO | .ico | ImageMagick | Plus grand calque extrait | | CUR | .cur | ImageMagick | Curseur Windows (variante ICO) | | TGA | .tga | ImageMagick | Détection par extension uniquement | ### Scientifiques et jeux vidéo (2) {#scientific-and-gaming-2} | Format | Extensions | Décodeur | Notes | |--------|-----------|---------|-------| | FITS | .fits, .fit, .fts | ImageMagick | Astronomie (standard NASA) | | DDS | .dds | ImageMagick | Textures de jeu (DirectX) | ### Échange (6) {#interchange-6} | Format | Extensions | Décodeur | Notes | |--------|-----------|---------|-------| | PPM | .ppm | Sharp (natif) | Pixmap couleur | | PGM | .pgm | Sharp (natif) | Niveaux de gris | | PBM | .pbm | Sharp (natif) | Bitmap 1 bit | | PNM | .pnm | Sharp (natif) | Format générique | | PAM | .pam | Sharp (natif) | Carte arbitraire | | PFM | .pfm | Sharp (natif) | Carte flottante | ## Formats de sortie (17) {#output-formats-13} | Format | Encodeur | Contrôle de la qualité | Disponible dans | |--------|---------|----------------|-------------| | JPEG | Sharp natif | 1-100 | Tous les outils | | PNG | Sharp natif | Compression 0-9 | Tous les outils | | WebP | Sharp natif | 1-100 | Tous les outils | | AVIF | Sharp natif | 1-100 | Tous les outils | | TIFF | Sharp natif | 1-100 | Outils de conversion complète | | GIF | Sharp natif | 1-100 | Outils de conversion complète | | JXL | Sharp natif | 1-100 | Tous les outils | | HEIC | CLI heif-enc | 1-100 | Outils de conversion complète | | HEIF | CLI heif-enc | 1-100 | Outils de conversion complète | | BMP | CLI ImageMagick | Sans perte | Outil de conversion | | ICO | CLI ImageMagick | Sans perte | Outil de conversion | | JP2 | CLI opj\_compress | Taux de compression | Outil de conversion | | QOI | Codec intégré | Sans perte | Outil de conversion | | PSD | CLI ImageMagick | Sans perte | Outil de conversion | | PPM | CLI ImageMagick | Sans perte | Outil de conversion | | EPS | CLI ImageMagick | Sans perte | Outil de conversion | | TGA | CLI ImageMagick | Sans perte | Outil de conversion | ## Formats vidéo {#video-formats} Le décodage et l'encodage vidéo sont gérés par FFmpeg (build statique), de sorte que tous les conteneurs et codecs courants sont pris en charge en entrée. ### Conteneurs d'entrée (15) {#input-containers-15} | Format | Extensions | Codecs typiques | Notes | |--------|-----------|----------------|-------| | MP4 | .mp4 | H.264, H.265, AV1 | Conteneur le plus utilisé | | QuickTime | .mov | H.264, ProRes | Capture/montage Apple | | WebM | .webm | VP8, VP9, AV1 | Format web libre de redevances | | Matroska | .mkv | Tous | Conteneur ouvert flexible | | AVI | .avi | Divers | Ancien conteneur Microsoft | | M4V | .m4v | H.264 | Variante MP4 d'Apple | | AVCHD | .mts | H.264 | Enregistrements de caméscope | | BDAV | .m2ts | H.264 | Flux de transport Blu-ray / AVCHD | | 3GP | .3gp | H.264, MPEG-4 | Capture mobile | | Flash Video | .flv | H.264, VP6 | Streaming ancien | | Windows Media | .wmv | VC-1, WMV | Windows Media | | MPEG | .mpg, .mpeg | MPEG-1, MPEG-2 | Vidéo de l'ère DVD | | MPEG-TS | .ts | MPEG-2, H.264 | Flux de transport de diffusion | | Ogg | .ogv | Theora | Vidéo Ogg ouverte | ### Formats de sortie {#output-formats} | Format | Extension | Codec vidéo | Produit par | |--------|-----------|-------------|-------------| | MP4 | .mp4 | H.264 | Convertir, compresser et la plupart des outils vidéo | | QuickTime | .mov | H.264 | Convertir la vidéo | | WebM | .webm | VP9 | Convertir la vidéo | | GIF | .gif | - | Vidéo vers GIF | | WebP | .webp | - | Vidéo vers WebP (animé) | ### Sous-titres {#subtitles} | Format | Extension | Opérations | |--------|-----------|-----------| | SubRip | .srt | Intégrer, incruster, extraire, générer automatiquement | | WebVTT | .vtt | Intégrer, incruster, extraire, générer automatiquement | | ASS / SSA | .ass | Intégrer, incruster (prend en charge le style) | ## Formats audio {#audio-formats} L'audio est également traité par FFmpeg. ### Formats d'entrée (11) {#input-formats-11} | Format | Extensions | Compression | Notes | |--------|-----------|-------------|-------| | MP3 | .mp3 | Avec perte | Compatibilité universelle | | WAV | .wav | Non compressé (PCM) | Studio / montage | | FLAC | .flac | Sans perte | Codec ouvert sans perte | | AAC | .aac | Avec perte | Flux AAC brut | | M4A | .m4a | Avec perte (AAC) / Sans perte (ALAC) | Audio MPEG-4 | | Ogg Vorbis | .ogg | Avec perte | Format ouvert | | Opus | .opus | Avec perte | Moderne, faible latence | | WMA | .wma | Avec perte | Windows Media Audio | | AIFF | .aiff | Non compressé (PCM) | Non compressé Apple | | AMR | .amr | Avec perte | Parole / mobile | | AC-3 | .ac3 | Avec perte | Dolby Digital | ### Formats de sortie {#output-formats-1} | Format | Extension | Codec | Produit par | |--------|-----------|-------|-------------| | MP3 | .mp3 | LAME | Convertir l'audio, Extraire l'audio | | WAV | .wav | PCM | Convertir l'audio, Extraire l'audio | | FLAC | .flac | FLAC (sans perte) | Convertir l'audio | | Ogg | .ogg | Vorbis | Convertir l'audio | | M4A | .m4a | AAC | Convertir l'audio, Extraire l'audio | ## Formats de document {#document-formats} Le traitement des documents utilise qpdf, LibreOffice, Ghostscript, Pandoc et WeasyPrint. ### Formats d'entrée (15) {#input-formats-15} | Format | Extensions | Moteur | Notes | |--------|-----------|--------|-------| | PDF | .pdf | qpdf, Ghostscript, pdfcpu | Format de document principal | | Word | .docx, .doc | LibreOffice | Microsoft Word | | Excel | .xlsx, .xls | LibreOffice | Microsoft Excel | | PowerPoint | .pptx, .ppt | LibreOffice | Microsoft PowerPoint | | OpenDocument | .odt, .ods, .odp | LibreOffice | Texte, feuille, présentation | | Rich Text | .rtf | LibreOffice | Texte enrichi multiplateforme | | Texte brut | .txt | LibreOffice, Pandoc | Texte UTF-8 | | Markdown | .md | Pandoc | CommonMark / GFM | | HTML | .html | WeasyPrint | Rendu en PDF | | EPUB | .epub | Pandoc, LibreOffice | Format de livre électronique | ### Formats de sortie {#output-formats-2} | Format | Extensions | Produit par | |--------|-----------|-------------| | PDF | .pdf | Word/Excel/PowerPoint vers PDF, Markdown vers PDF, HTML vers PDF | | PDF/A | .pdf | Conversion PDF/A (archivage) | | Word | .docx, .odt, .rtf, .txt | Convertir un document, PDF vers Word, Markdown vers Word | | Présentation | .pptx, .odp | Convertir une présentation | | Feuille de calcul | .xlsx, .ods, .csv | Convertir une feuille de calcul | | HTML | .html | Markdown vers HTML | | EPUB | .epub | Convertir en EPUB | | Images | .png, .jpg | PDF vers image | ## Formats de fichiers {#file-formats} Les outils de données et d'archives convertissent entre des formats structurés et regroupent des fichiers. | Format | Extensions | Conversions | |--------|-----------|-------------| | CSV | .csv | Vers/depuis JSON et Excel ; scinder et fusionner ; depuis XML | | JSON | .json | Vers/depuis CSV, XML et YAML | | XML | .xml | Vers/depuis JSON ; vers CSV | | YAML | .yaml, .yml | Vers/depuis JSON | | Excel | .xlsx | Vers/depuis CSV | | ZIP | .zip | Créer des archives, extraire le contenu | --- --- url: https://docs.snapotter.com/sv/tools/image/beautify.md description: >- Förvandla vanliga skärmbilder till polerade bilder med gradientbakgrunder, enhetsramar, skuggor och storleksanpassning för sociala medier. --- # Försköna skärmbild {#beautify-screenshot} Lägg till gradientbakgrunder, enhetsramar, skuggor, vattenstämplar och storleksanpassning för sociala medier till skärmbilder. Idealiskt för att skapa polerade bilder för produktmarknadsföring, sociala medier och dokumentation. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/beautify` ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | backgroundType | sträng | Nej | `"linear-gradient"` | Bakgrundstyp: `solid`, `linear-gradient`, `radial-gradient`, `image`, `transparent` | | backgroundColor | sträng | Nej | `"#667eea"` | Enfärgad bakgrundsfärg (används när `backgroundType` är `solid`) | | gradientStops | array | Nej | `[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}]` | Gradientens färgstopp (minst 2). Varje stopp har `color` (hex) och `position` (0-100). | | gradientAngle | tal | Nej | 135 | Gradientvinkel i grader (0 till 360) | | padding | tal | Nej | 64 | Utfyllnad runt bilden i pixlar (0 till 256) | | borderRadius | tal | Nej | 12 | Hörnradie på skärmbilden (0 till 64) | | shadowPreset | sträng | Nej | `"subtle"` | Skuggförinställning: `none`, `subtle`, `medium`, `dramatic`, `custom` | | shadowBlur | tal | Nej | 20 | Anpassad radie för skuggoskärpa (0 till 100, används när `shadowPreset` är `custom`) | | shadowOffsetX | tal | Nej | 0 | Anpassad horisontell skuggförskjutning (-50 till 50) | | shadowOffsetY | tal | Nej | 10 | Anpassad vertikal skuggförskjutning (-50 till 50) | | shadowColor | sträng | Nej | `"#000000"` | Anpassad skuggfärg i hex | | shadowOpacity | tal | Nej | 30 | Anpassad skuggopacitet (0 till 100) | | frame | sträng | Nej | `"none"` | Enhets- eller fönsterram: `none`, `macos-light`, `macos-dark`, `windows-light`, `windows-dark`, `browser-light`, `browser-dark`, `iphone`, `iphone-dark`, `macbook`, `macbook-dark`, `ipad`, `ipad-dark` | | frameTitle | sträng | Nej | - | Titeltext som visas i namnlisten på fönsterramar | | socialPreset | sträng | Nej | `"none"` | Storleksanpassa till dimensioner för sociala medier: `none`, `twitter`, `linkedin`, `instagram-square`, `instagram-story`, `facebook`, `producthunt` | | watermarkText | sträng | Nej | - | Valfri vattenstämpeltext som överlägg | | watermarkPosition | sträng | Nej | `"bottom-right"` | Vattenstämpelns position: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `center` | | watermarkOpacity | tal | Nej | 50 | Vattenstämpelns opacitet (0 till 100) | | outputFormat | sträng | Nej | `"png"` | Utdataformat: `png`, `jpeg`, `webp` | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F 'settings={"backgroundType":"linear-gradient","gradientStops":[{"color":"#667eea","position":0},{"color":"#764ba2","position":100}],"gradientAngle":135,"padding":64,"borderRadius":12,"shadowPreset":"medium","frame":"macos-dark","socialPreset":"twitter"}' ``` ### Med bakgrundsbild {#with-background-image} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/beautify \ -F "file=@screenshot.png" \ -F "backgroundImage=@bg-texture.jpg" \ -F 'settings={"backgroundType":"image","padding":80,"borderRadius":16,"shadowPreset":"dramatic"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 234567, "processedSize": 567890 } ``` ## Anteckningar {#notes} * Tar emot två filfält: `file` (obligatoriskt, den huvudsakliga skärmbilden) och `backgroundImage` (valfritt, används när `backgroundType` är `image`). * Stöder indataformaten HEIC, RAW, PSD och SVG (avkodas automatiskt). * Skuggförinställningarna mappas till specifika värden: * `subtle`: oskärpa 20, offsetY 4, opacitet 20 % * `medium`: oskärpa 40, offsetY 10, opacitet 35 % * `dramatic`: oskärpa 80, offsetY 20, opacitet 50 % * Förinställningar för sociala medier storleksanpassar den slutliga utdata så att den passar målmåtten med läget `contain`: * `twitter`: 1600x900 * `linkedin`: 1200x627 * `instagram-square`: 1080x1080 * `instagram-story`: 1080x1920 * `facebook`: 1200x630 * `producthunt`: 1270x760 * Enhetsramar (`iphone`, `macbook`, `ipad`) lägger en hårdvaruram runt bilden och hoppar över inställningen `borderRadius`. * När transparens krävs (skugga, hörnradie, enhetsramar eller transparent bakgrund) tvingas utdata till PNG även om `jpeg` är valt. * Bildbakgrunder stöds inte i pipeline-/batchläge. --- --- url: https://docs.snapotter.com/es/tools/image/passport-photo.md description: >- Generador de fotos de pasaporte y de identificación con IA, con detección de rostros, eliminación de fondo y composición para hojas de impresión. --- # Foto de pasaporte {#passport-photo} Generador de fotos de pasaporte y de identificación con IA. Flujo de trabajo en dos fases: analizar (detección de rostros + eliminación de fondo) y luego generar (recortar, redimensionar y componer para impresión). ## Endpoints de la API {#api-endpoints} Esta herramienta usa un flujo de dos fases con endpoints separados para el análisis y la generación. **Paquetes de modelos:** `background-removal` y `face-detection` *** ### Fase 1: Analizar {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` Detecta los puntos de referencia del rostro y elimina el fondo. Devuelve los datos de los puntos de referencia y una vista previa para que el frontend muestre una previsualización del recorte. #### Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | file | file | Sí | - | Archivo de imagen (multipart) | | clientJobId | string | No | - | ID de trabajo opcional para el seguimiento del progreso vía SSE | #### Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/passport-photo/analyze \ -F "file=@headshot.jpg" ``` #### Respuesta (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "filename": "headshot.jpg", "preview": "", "previewWidth": 800, "previewHeight": 1067, "landmarks": { "leftEye": { "x": 0.42, "y": 0.35 }, "rightEye": { "x": 0.58, "y": 0.35 }, "eyeCenter": { "x": 0.50, "y": 0.35 }, "chin": { "x": 0.50, "y": 0.65 }, "forehead": { "x": 0.50, "y": 0.22 }, "crown": { "x": 0.50, "y": 0.18 }, "nose": { "x": 0.50, "y": 0.48 }, "faceCenterX": 0.50 }, "imageWidth": 2400, "imageHeight": 3200 } ``` #### Progreso (SSE, opcional) {#progress-sse-optional} Si se proporciona `clientJobId`, el progreso se transmite (0-30 % para la detección de rostros, 30-95 % para la eliminación de fondo). #### Error: no se detectó ningún rostro (422) {#error-no-face-detected-422} ```json { "error": "No face detected", "details": "Could not detect a face in the uploaded image. Please upload a clear, front-facing photo with good lighting." } ``` *** ### Fase 2: Generar {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` Recorta, redimensiona y, opcionalmente, compone la foto en una hoja de impresión. Usa las imágenes en caché de la Fase 1 (sin volver a ejecutar la IA). #### Parámetros (cuerpo JSON) {#parameters-json-body} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | jobId | string | Sí | - | ID de trabajo de la Fase 1 | | filename | string | Sí | - | Nombre de archivo original de la Fase 1 | | countryCode | string | Sí | - | Código de país para la especificación de pasaporte (por ejemplo, `US`, `GB`, `IN`) | | documentType | string | No | `"passport"` | Tipo de documento (según la especificación del país) | | bgColor | string | No | `"#FFFFFF"` | Color de fondo en hexadecimal | | printLayout | string | No | `"none"` | Diseño del papel de impresión: `none`, `4x6`, `a4` | | maxFileSizeKb | number | No | `0` | Restricción de tamaño máximo de archivo en KB (0 = sin límite) | | dpi | number | No | `300` | DPI de salida (72-1200) | | customWidthMm | number | No | - | Ancho de foto personalizado en mm (anula la especificación del país) | | customHeightMm | number | No | - | Alto de foto personalizado en mm (anula la especificación del país) | | zoom | number | No | `1` | Factor de zoom (0.5-3). Los valores > 1 recortan más ajustado | | adjustX | number | No | `0` | Ajuste de posición horizontal | | adjustY | number | No | `0` | Ajuste de posición vertical | | landmarks | object | Sí | - | Objeto de puntos de referencia de la respuesta de la Fase 1 | | imageWidth | number | Sí | - | Ancho de imagen de la respuesta de la Fase 1 | | imageHeight | number | Sí | - | Alto de imagen de la respuesta de la Fase 1 | #### Ejemplo de solicitud {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/passport-photo/generate \ -H "Content-Type: application/json" \ -d '{ "jobId": "a1b2c3d4-...", "filename": "headshot.jpg", "countryCode": "US", "documentType": "passport", "bgColor": "#FFFFFF", "printLayout": "4x6", "dpi": 300, "zoom": 1, "adjustX": 0, "adjustY": 0, "landmarks": { "leftEye": {"x":0.42,"y":0.35}, "rightEye": {"x":0.58,"y":0.35}, "eyeCenter": {"x":0.50,"y":0.35}, "chin": {"x":0.50,"y":0.65}, "forehead": {"x":0.50,"y":0.22}, "crown": {"x":0.50,"y":0.18}, "nose": {"x":0.50,"y":0.48}, "faceCenterX": 0.50 }, "imageWidth": 2400, "imageHeight": 3200 }' ``` #### Respuesta (200 OK) {#response-200-ok-1} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/headshot_passport.jpg", "dimensions": { "widthMm": 51, "heightMm": 51, "widthPx": 602, "heightPx": 602, "dpi": 300 }, "spec": { "country": "United States", "countryCode": "US", "documentType": "passport", "documentLabel": "Passport" }, "printDownloadUrl": "/api/v1/download/{jobId}/headshot_passport_print_4x6.jpg" } ``` *** ### Ruta base {#base-route} `POST /api/v1/tools/image/passport-photo` Devuelve orientación sobre cómo usar el sub-endpoint correcto. ```json { "error": "Use /api/v1/tools/image/passport-photo/analyze or /generate" } ``` ## Notas {#notes} * Requiere que los paquetes de modelos `background-removal` y `face-detection` estén instalados. * La Fase 1 ejecuta la IA (puntos de referencia del rostro + eliminación de fondo) y almacena los resultados en caché. La Fase 2 es pura manipulación de imágenes con Sharp (rápida, sin necesidad de IA). * Los puntos de referencia se devuelven como coordenadas normalizadas (rango de 0-1 relativo a las dimensiones de la imagen). * El campo `preview` de la respuesta del análisis es un PNG codificado en base64 (máximo 800 px de ancho) para una visualización rápida. * Las especificaciones de país incluyen las dimensiones del documento, las proporciones de la altura de la cabeza y la posición de la línea de los ojos según los requisitos oficiales de las fotos de pasaporte. * La opción `printLayout` genera una hoja compuesta en papel de 4x6" o A4 con separaciones de 2 mm entre las fotos. * Cuando se establece `maxFileSizeKb`, la salida se comprime de forma iterativa para ajustarse al límite de tamaño. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/passport-photo.md description: >- Gerador de fotos de passaporte e documento de identidade com IA, com detecção de rosto, remoção de fundo e montagem de folha para impressão. --- # Foto de Passaporte {#passport-photo} Gerador de fotos de passaporte e documento de identidade com IA. Fluxo de trabalho em duas fases: analisar (detecção de rosto + remoção de fundo) e depois gerar (recortar, redimensionar e montar para impressão). ## Endpoints da API {#api-endpoints} Esta ferramenta usa um fluxo de duas fases com endpoints separados para análise e geração. **Pacotes de modelo:** `background-removal` e `face-detection` *** ### Fase 1: Analisar {#phase-1-analyze} `POST /api/v1/tools/image/passport-photo/analyze` Detecta os pontos de referência do rosto e remove o fundo. Retorna os dados dos pontos de referência e uma pré-visualização para o frontend exibir uma prévia do recorte. #### Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | file | file | Sim | - | Arquivo de imagem (multipart) | | clientJobId | string | Não | - | ID de job opcional para acompanhamento de progresso via SSE | #### Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/passport-photo/analyze \ -F "file=@headshot.jpg" ``` #### Resposta (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "filename": "headshot.jpg", "preview": "", "previewWidth": 800, "previewHeight": 1067, "landmarks": { "leftEye": { "x": 0.42, "y": 0.35 }, "rightEye": { "x": 0.58, "y": 0.35 }, "eyeCenter": { "x": 0.50, "y": 0.35 }, "chin": { "x": 0.50, "y": 0.65 }, "forehead": { "x": 0.50, "y": 0.22 }, "crown": { "x": 0.50, "y": 0.18 }, "nose": { "x": 0.50, "y": 0.48 }, "faceCenterX": 0.50 }, "imageWidth": 2400, "imageHeight": 3200 } ``` #### Progresso (SSE, opcional) {#progress-sse-optional} Se `clientJobId` for fornecido, o progresso é transmitido (0-30% para detecção de rosto, 30-95% para remoção de fundo). #### Erro: Nenhum Rosto Detectado (422) {#error-no-face-detected-422} ```json { "error": "No face detected", "details": "Could not detect a face in the uploaded image. Please upload a clear, front-facing photo with good lighting." } ``` *** ### Fase 2: Gerar {#phase-2-generate} `POST /api/v1/tools/image/passport-photo/generate` Recorta, redimensiona e, opcionalmente, monta a foto em uma folha para impressão. Usa imagens em cache da Fase 1 (sem reexecução da IA). #### Parâmetros (corpo JSON) {#parameters-json-body} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | jobId | string | Sim | - | ID do job da Fase 1 | | filename | string | Sim | - | Nome do arquivo original da Fase 1 | | countryCode | string | Sim | - | Código do país para a especificação do passaporte (por exemplo, `US`, `GB`, `IN`) | | documentType | string | Não | `"passport"` | Tipo de documento (da especificação do país) | | bgColor | string | Não | `"#FFFFFF"` | Cor de fundo em hexadecimal | | printLayout | string | Não | `"none"` | Layout do papel de impressão: `none`, `4x6`, `a4` | | maxFileSizeKb | number | Não | `0` | Restrição de tamanho máximo do arquivo em KB (0 = sem limite) | | dpi | number | Não | `300` | DPI de saída (72-1200) | | customWidthMm | number | Não | - | Largura personalizada da foto em mm (substitui a especificação do país) | | customHeightMm | number | Não | - | Altura personalizada da foto em mm (substitui a especificação do país) | | zoom | number | Não | `1` | Fator de zoom (0.5-3). Valores > 1 recortam mais próximo | | adjustX | number | Não | `0` | Ajuste de posição horizontal | | adjustY | number | Não | `0` | Ajuste de posição vertical | | landmarks | object | Sim | - | Objeto de pontos de referência da resposta da Fase 1 | | imageWidth | number | Sim | - | Largura da imagem da resposta da Fase 1 | | imageHeight | number | Sim | - | Altura da imagem da resposta da Fase 1 | #### Exemplo de Requisição {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/passport-photo/generate \ -H "Content-Type: application/json" \ -d '{ "jobId": "a1b2c3d4-...", "filename": "headshot.jpg", "countryCode": "US", "documentType": "passport", "bgColor": "#FFFFFF", "printLayout": "4x6", "dpi": 300, "zoom": 1, "adjustX": 0, "adjustY": 0, "landmarks": { "leftEye": {"x":0.42,"y":0.35}, "rightEye": {"x":0.58,"y":0.35}, "eyeCenter": {"x":0.50,"y":0.35}, "chin": {"x":0.50,"y":0.65}, "forehead": {"x":0.50,"y":0.22}, "crown": {"x":0.50,"y":0.18}, "nose": {"x":0.50,"y":0.48}, "faceCenterX": 0.50 }, "imageWidth": 2400, "imageHeight": 3200 }' ``` #### Resposta (200 OK) {#response-200-ok-1} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/headshot_passport.jpg", "dimensions": { "widthMm": 51, "heightMm": 51, "widthPx": 602, "heightPx": 602, "dpi": 300 }, "spec": { "country": "United States", "countryCode": "US", "documentType": "passport", "documentLabel": "Passport" }, "printDownloadUrl": "/api/v1/download/{jobId}/headshot_passport_print_4x6.jpg" } ``` *** ### Rota Base {#base-route} `POST /api/v1/tools/image/passport-photo` Retorna orientação para usar o sub-endpoint correto. ```json { "error": "Use /api/v1/tools/image/passport-photo/analyze or /generate" } ``` ## Notas {#notes} * Requer que os pacotes de modelo `background-removal` e `face-detection` estejam instalados. * A Fase 1 executa a IA (pontos de referência do rosto + remoção de fundo) e armazena os resultados em cache. A Fase 2 é pura manipulação de imagem com Sharp (rápida, sem necessidade de IA). * Os pontos de referência são retornados como coordenadas normalizadas (intervalo de 0-1 em relação às dimensões da imagem). * O campo `preview` na resposta da análise é um PNG codificado em base64 (máximo de 800px de largura) para exibição rápida. * As especificações de país incluem dimensões do documento, proporções de altura da cabeça e posicionamento da linha dos olhos com base nos requisitos oficiais de foto de passaporte. * A opção `printLayout` gera uma folha com fotos lado a lado em papel 4x6" ou A4, com espaçamentos de 2mm entre as fotos. * Quando `maxFileSizeKb` está definido, a saída é comprimida iterativamente para caber dentro do limite de tamanho. --- --- url: https://docs.snapotter.com/de/tools/image/restore-photo.md description: >- Repariere Kratzer, Risse und Schäden an alten Fotos mit einer KI-Pipeline für Restaurierung, Gesichtsverbesserung und Farbe. --- # Foto-Restaurierung {#photo-restoration} Behebe Kratzer, Risse und Schäden an alten Fotos mit einer mehrstufigen KI-Pipeline. Kombiniert Kratzerreparatur, Gesichtsverbesserung, Rauschunterdrückung und optionale Kolorierung. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/restore-photo` **Verarbeitung:** Asynchron (gibt 202 zurück, Status über SSE per `/api/v1/jobs/{jobId}/progress` abfragen) **Modell-Bundle:** `photo-restoration` (4-5 GB) ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bilddatei (multipart) | | scratchRemoval | boolean | Nein | `true` | Kratzer und Oberflächenschäden entfernen | | faceEnhancement | boolean | Nein | `true` | Gesichter im restaurierten Foto verbessern | | fidelity | number | Nein | `0.7` | Treue der Gesichtsverbesserung (0-1). Höhere Werte erhalten die ursprünglichen Merkmale stärker | | denoise | boolean | Nein | `true` | Rauschunterdrückung auf das restaurierte Ergebnis anwenden | | denoiseStrength | number | Nein | `25` | Stärke der Rauschunterdrückung (0-100) | | colorize | boolean | Nein | `false` | Das restaurierte Foto kolorieren (für Graustufenbilder) | | colorizeStrength | number | Nein | `85` | Intensität der Kolorierung (0-100) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/restore-photo \ -F "file=@damaged-old-photo.jpg" \ -F 'settings={"scratchRemoval":true,"faceEnhancement":true,"fidelity":0.6,"colorize":true}' ``` ## Antwort {#response} ### Erste Antwort (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Fortschritt (SSE unter `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing scratches...","percent":30} ``` ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Endergebnis (über SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/damaged-old-photo_restored.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 200000, "processedSize": 350000, "width": 1200, "height": 900, "steps": ["scratch_removal", "face_enhancement", "denoise", "colorize"], "scratchCoverage": 12.5, "facesEnhanced": 2, "isGrayscale": true, "colorized": true } } ``` ## Hinweise {#notes} * Erfordert das installierte Modell-Bundle `photo-restoration` (4-5 GB). * Die Pipeline führt mehrere KI-Schritte nacheinander aus: Kratzerreparatur, Gesichtsverbesserung (GFPGAN), Rauschunterdrückung und optional Kolorierung. * Das Array `steps` im Ergebnis zeigt an, welche Verarbeitungsschritte tatsächlich ausgeführt wurden. * `scratchCoverage` ist ein geschätzter Prozentsatz der Bildfläche, die Kratzschäden aufwies. * `fidelity` steuert, wie stark Gesichter verbessert werden im Vergleich zur Erhaltung des ursprünglichen Aussehens. Niedrigere Werte erzeugen eine aggressivere Verbesserung; höhere Werte sind konservativer. * Die Option `colorize` erkennt automatisch, ob das Bild in Graustufen vorliegt. Das Flag `isGrayscale` im Ergebnis bestätigt diese Erkennung. * Das Ausgabeformat entspricht automatisch dem Eingabeformat. * Unterstützt die Eingabeformate HEIC/HEIF, RAW, TGA, PSD, EXR, HDR und AVIF durch automatische Dekodierung. --- --- url: https://docs.snapotter.com/tr/tools/image/restore-photo.md description: >- Restorasyon, yüz iyileştirme ve renk için bir yapay zeka boru hattıyla eski fotoğraflardaki çizik, yırtık ve hasarları onarın. --- # Fotoğraf Restorasyonu {#photo-restoration} Çok adımlı bir yapay zeka boru hattı kullanarak eski fotoğraflardaki çizik, yırtık ve hasarları onarın. Çizik onarımı, yüz iyileştirme, gürültü giderme ve isteğe bağlı renklendirmeyi bir araya getirir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/restore-photo` **İşleme:** Eşzamansız (202 döndürür, durum için SSE aracılığıyla `/api/v1/jobs/{jobId}/progress` sorgulayın) **Model paketi:** `photo-restoration` (4-5 GB) ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | file | Evet | - | Görsel dosyası (çok parçalı) | | scratchRemoval | boolean | Hayır | `true` | Çizikleri ve yüzey hasarını kaldır | | faceEnhancement | boolean | Hayır | `true` | Restore edilen fotoğraftaki yüzleri iyileştir | | fidelity | number | Hayır | `0.7` | Yüz iyileştirme sadakati (0-1). Daha yüksek değerler orijinal özellikleri daha fazla korur | | denoise | boolean | Hayır | `true` | Restore edilen sonuca gürültü giderme uygula | | denoiseStrength | number | Hayır | `25` | Gürültü giderme gücü (0-100) | | colorize | boolean | Hayır | `false` | Restore edilen fotoğrafı renklendir (gri tonlamalı görseller için) | | colorizeStrength | number | Hayır | `85` | Renklendirme yoğunluğu (0-100) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/restore-photo \ -F "file=@damaged-old-photo.jpg" \ -F 'settings={"scratchRemoval":true,"faceEnhancement":true,"fidelity":0.6,"colorize":true}' ``` ## Yanıt {#response} ### İlk Yanıt (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### İlerleme (`/api/v1/jobs/{jobId}/progress` konumunda SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing scratches...","percent":30} ``` ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Nihai Sonuç (SSE aracılığıyla) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/damaged-old-photo_restored.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 200000, "processedSize": 350000, "width": 1200, "height": 900, "steps": ["scratch_removal", "face_enhancement", "denoise", "colorize"], "scratchCoverage": 12.5, "facesEnhanced": 2, "isGrayscale": true, "colorized": true } } ``` ## Notlar {#notes} * `photo-restoration` model paketinin kurulu olmasını gerektirir (4-5 GB). * Boru hattı birden fazla yapay zeka adımını sırayla yürütür: çizik onarımı, yüz iyileştirme (GFPGAN), gürültü giderme ve isteğe bağlı olarak renklendirme. * Sonuçtaki `steps` dizisi, gerçekte hangi işleme adımlarının yürütüldüğünü gösterir. * `scratchCoverage`, görsel alanının çizik hasarı olan tahmini yüzdesidir. * `fidelity`, yüzlerin orijinal görünümü koruma karşısında ne kadar güçlü iyileştirileceğini denetler. Daha düşük değerler daha agresif iyileştirme üretir; daha yüksek değerler daha korumacıdır. * `colorize` seçeneği, görselin gri tonlamalı olup olmadığını otomatik olarak algılar. Sonuçtaki `isGrayscale` bayrağı bu algılamayı doğrular. * Çıktı biçimi girdi biçimiyle otomatik olarak eşleşir. * HEIC/HEIF, RAW, TGA, PSD, EXR, HDR ve AVIF girdi biçimlerini otomatik çözme yoluyla destekler. --- --- url: https://docs.snapotter.com/sv/tools/image/restore-photo.md description: >- Reparera repor, revor och skador på gamla foton med en AI-pipeline för restaurering, ansiktsförbättring och färg. --- # Fotorestaurering {#photo-restoration} Åtgärda repor, revor och skador på gamla foton med en AI-pipeline i flera steg. Kombinerar reparation av repor, ansiktsförbättring, brusreducering och valfri färgläggning. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/restore-photo` **Bearbetning:** Asynkron (returnerar 202, polla `/api/v1/jobs/{jobId}/progress` för status via SSE) **Modellpaket:** `photo-restoration` (4-5 GB) ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bildfil (multipart) | | scratchRemoval | boolean | Nej | `true` | Ta bort repor och ytskador | | faceEnhancement | boolean | Nej | `true` | Förbättra ansikten i det restaurerade fotot | | fidelity | number | Nej | `0.7` | Trohet för ansiktsförbättring (0-1). Högre värden bevarar originaldragen mer | | denoise | boolean | Nej | `true` | Applicera brusreducering på det restaurerade resultatet | | denoiseStrength | number | Nej | `25` | Brusreduceringsstyrka (0-100) | | colorize | boolean | Nej | `false` | Färglägg det restaurerade fotot (för gråskalebilder) | | colorizeStrength | number | Nej | `85` | Färgläggningsintensitet (0-100) | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/restore-photo \ -F "file=@damaged-old-photo.jpg" \ -F 'settings={"scratchRemoval":true,"faceEnhancement":true,"fidelity":0.6,"colorize":true}' ``` ## Svar {#response} ### Inledande svar (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Förlopp (SSE på `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing scratches...","percent":30} ``` ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Slutresultat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/damaged-old-photo_restored.jpg", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 200000, "processedSize": 350000, "width": 1200, "height": 900, "steps": ["scratch_removal", "face_enhancement", "denoise", "colorize"], "scratchCoverage": 12.5, "facesEnhanced": 2, "isGrayscale": true, "colorized": true } } ``` ## Anteckningar {#notes} * Kräver att modellpaketet `photo-restoration` är installerat (4-5 GB). * Pipelinen kör flera AI-steg i följd: reparation av repor, ansiktsförbättring (GFPGAN), brusreducering och valfritt färgläggning. * Arrayen `steps` i resultatet visar vilka bearbetningssteg som faktiskt utfördes. * `scratchCoverage` är en uppskattad procentandel av bildytan som hade reporskador. * `fidelity` styr hur starkt ansikten förbättras kontra att originalets utseende bevaras. Lägre värden ger mer aggressiv förbättring; högre värden är mer konservativa. * Alternativet `colorize` detekterar automatiskt om bilden är gråskala. Flaggan `isGrayscale` i resultatet bekräftar denna detektering. * Utdataformatet matchar indataformatet automatiskt. * Stöder HEIC/HEIF-, RAW-, TGA-, PSD-, EXR-, HDR- och AVIF-indataformat via automatisk avkodning. --- --- url: https://docs.snapotter.com/es/tools/audio/fade-audio.md description: Añade efectos de fundido de entrada y de salida al audio. --- # Fundido de audio {#fade-audio} Añade efectos de fundido de entrada y de salida al principio y al final de un archivo de audio. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/audio/fade-audio` Acepta datos de formulario multipart con un archivo de audio y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | fadeInS | number | No | `1` | Duración del fundido de entrada en segundos (0 a 30) | | fadeOutS | number | No | `1` | Duración del fundido de salida en segundos (0 a 30) | ## Solicitud de ejemplo {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/fade-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"fadeInS": 2, "fadeOutS": 3}' ``` ## Respuesta de ejemplo {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Notas {#notes} * Establece cualquiera de los valores en `0` para omitir ese sentido del fundido. Al menos uno debe ser mayor que 0. * La duración del fundido se limita a la longitud del audio si la supera. * La salida suele conservar el contenedor de entrada. La entrada AAC se escribe como M4A, y las entradas de solo decodificación no compatibles recurren a MP3. --- --- url: https://docs.snapotter.com/de/tools/image/optimize-for-web.md description: >- Optimiere Bilder für die Web-Auslieferung mit Formatkonvertierung, Qualitätssteuerung, Größenänderung und Metadaten-Entfernung. --- # Für Web optimieren {#optimize-for-web} Optimiere Bilder für die Web-Auslieferung in einem einzigen Schritt. Kombiniert Formatkonvertierung, Qualitätsanpassung, optionale Größenänderung, progressive Kodierung und Metadaten-Entfernung. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/optimize-for-web` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. Ein Live-Vorschau-Endpunkt ist außerdem unter `POST /api/v1/tools/image/optimize-for-web/preview` verfügbar, der das verarbeitete Bild direkt als Binärdaten zurückgibt (ohne Workspace-Erstellung) für die Echtzeit-Anpassung von Parametern. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | format | string | Nein | `"webp"` | Ausgabeformat: `webp`, `jpeg`, `avif`, `png`, `jxl` | | quality | number | Nein | `80` | Ausgabequalität (1-100) | | maxWidth | number | Nein | - | Maximale Breite in Pixeln. Das Bild wird herunterskaliert, wenn es breiter ist. | | maxHeight | number | Nein | - | Maximale Höhe in Pixeln. Das Bild wird herunterskaliert, wenn es höher ist. | | progressive | boolean | Nein | `true` | Progressive/interlaced Kodierung aktivieren | | stripMetadata | boolean | Nein | `true` | EXIF-, GPS-, ICC- und XMP-Metadaten entfernen | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/optimize-for-web \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 75, "maxWidth": 1920}' ``` Für AVIF mit aggressiver Kompression optimieren: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/optimize-for-web \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "avif", "quality": 50, "maxWidth": 1200, "maxHeight": 800}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 4500000, "processedSize": 320000 } ``` ### Antwort des Vorschau-Endpunkts {#preview-endpoint-response} Der Vorschau-Endpunkt (`/api/v1/tools/image/optimize-for-web/preview`) gibt das Bild direkt als Binärdaten mit informativen Headern zurück: * `X-Original-Size` - Ursprüngliche Dateigröße in Bytes * `X-Processed-Size` - Verarbeitete Dateigröße in Bytes * `X-Output-Filename` - URL-kodierter Ausgabedateiname ## Hinweise {#notes} * Dieses Werkzeug ist als vollständige Optimierungs-Pipeline für Web-Assets konzipiert. Es übernimmt Formatkonvertierung, Qualitätsanpassung, Begrenzung der maximalen Abmessungen und Metadaten-Entfernung in einem einzigen Durchlauf. * Die Endung des Ausgabedateinamens wird an das gewählte Format angepasst. * Die JXL-Kodierung (JPEG XL) verwendet einen spezialisierten CLI-Encoder. Das Bild wird zunächst als PNG verarbeitet und dann in JXL kodiert. * Progressive Kodierung verbessert die wahrgenommene Ladezeit von JPEG und PNG, da Browser eine Vorschau in niedriger Qualität rendern können, bevor das vollständige Bild geladen ist. * Der Vorschau-Endpunkt ist ressourcenschonender (keine Workspace-/Job-Erstellung) und für die Live-Parameteranpassung im Frontend gedacht. --- --- url: https://docs.snapotter.com/fr/tools/files/merge-csvs.md description: Combine plusieurs fichiers CSV ou TSV aux colonnes identiques en un seul. --- # Fusionner des CSV {#merge-csvs} Combine plusieurs fichiers CSV ou TSV aux colonnes identiques en un seul fichier fusionné. Tous les fichiers d'entrée doivent avoir les mêmes en-têtes de colonnes. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/files/merge-csvs` Accepte des données de formulaire multipart contenant deux fichiers CSV ou plus. Aucun champ de paramètres n'est requis. ## Paramètres {#parameters} Cet outil n'a aucun paramètre configurable. Téléversez 2 à 20 fichiers CSV ou TSV ayant les mêmes en-têtes de colonnes. ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/merge-csvs \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@january.csv" \ -F "file=@february.csv" \ -F "file=@march.csv" ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", "originalSize": 30000, "processedSize": 28500 } ``` ## Remarques {#notes} * Nécessite entre 2 et 20 fichiers d'entrée. * Tous les fichiers doivent partager les mêmes en-têtes de colonnes. La fusion échoue si les colonnes ne correspondent pas. * La ligne d'en-tête est incluse une seule fois dans la sortie ; les lignes de données de tous les fichiers sont concaténées dans l'ordre de téléversement. * Les fichiers CSV et TSV sont tous deux acceptés, mais tous les fichiers d'une même requête doivent utiliser le même délimiteur. --- --- url: https://docs.snapotter.com/fr/tools/pdf/merge-pdf.md description: Combiner plusieurs PDF en un seul document. --- # Fusionner des PDF {#merge-pdfs} Combinez deux fichiers PDF ou plus en un seul document, en préservant l'ordre des pages de chaque fichier d'entrée. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/pdf/merge-pdf` Accepte des données de formulaire multipart avec deux fichiers PDF ou plus. Aucun champ `settings` n'est requis. ## Paramètres {#parameters} Cet outil n'a aucun paramètre de réglage. Il suffit de téléverser deux fichiers PDF ou plus. | Contrainte | Valeur | |------------|-------| | Nombre minimal de fichiers | 2 | | Nombre maximal de fichiers | 20 | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/merge-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document1.pdf" \ -F "file=@document2.pdf" \ -F "file=@document3.pdf" ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.pdf", "originalSize": 4500000, "processedSize": 4200000 } ``` ## Remarques {#notes} * Les fichiers sont fusionnés dans l'ordre où ils sont téléversés. * Au moins deux fichiers PDF sont requis ; la requête échoue avec une erreur 400 si moins sont fournis. * Le nombre maximal de fichiers d'entrée est de 20. * Les PDF chiffrés doivent être déverrouillés avant la fusion. --- --- url: https://docs.snapotter.com/fr/tools/audio/merge-audio.md description: Combiner plusieurs fichiers audio en une seule piste séquentielle. --- # Fusionner l'audio {#merge-audio} Combiner deux fichiers audio ou plus en une seule piste séquentielle, concaténés dans l'ordre de leur envoi. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/audio/merge-audio` Accepte des données de formulaire multipart avec plusieurs fichiers audio et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | format | string | Non | `"mp3"` | Format de sortie : `mp3`, `wav`, `flac`, `m4a` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/merge-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@intro.mp3" \ -F "file=@main.mp3" \ -F "file=@outro.mp3" \ -F 'settings={"format": "mp3"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.mp3", "originalSize": 9500000, "processedSize": 9200000 } ``` ## Notes {#notes} * Accepte de 2 à 10 fichiers audio par requête. * Les fichiers sont concaténés dans l'ordre d'envoi. * Tous les fichiers d'entrée sont réencodés au format de sortie et à la fréquence d'échantillonnage choisis pour un raccord sans coupure. * Les formats d'entrée mixtes sont pris en charge (par exemple, un WAV et un MP3). --- --- url: https://docs.snapotter.com/id/tools/files/merge-csvs.md description: Gabungkan beberapa berkas CSV atau TSV dengan kolom yang cocok menjadi satu. --- # Gabungkan CSV {#merge-csvs} Gabungkan beberapa berkas CSV atau TSV dengan kolom yang cocok menjadi satu berkas gabungan. Semua berkas input harus memiliki header kolom yang sama. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/merge-csvs` Menerima data formulir multipart dengan dua atau lebih berkas CSV. Tidak diperlukan bidang pengaturan. ## Parameter {#parameters} Alat ini tidak memiliki parameter yang dapat dikonfigurasi. Unggah 2-20 berkas CSV atau TSV dengan header kolom yang cocok. ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/merge-csvs \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@january.csv" \ -F "file=@february.csv" \ -F "file=@march.csv" ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", "originalSize": 30000, "processedSize": 28500 } ``` ## Catatan {#notes} * Memerlukan antara 2 hingga 20 berkas input. * Semua berkas harus memiliki header kolom yang sama. Penggabungan akan gagal jika kolom tidak cocok. * Baris header disertakan sekali dalam keluaran; baris data dari semua berkas digabungkan sesuai urutan pengunggahan. * Baik berkas CSV maupun TSV diterima, tetapi semua berkas dalam satu permintaan harus menggunakan pembatas yang sama. --- --- url: https://docs.snapotter.com/id/tools/image/stitch.md description: >- Menggabungkan gambar berdampingan, ditumpuk, atau dalam grid dengan kontrol atas perataan, celah, tepi, dan mode pengubahan ukuran. --- # Gabungkan Gambar {#stitch-combine} Menggabungkan beberapa gambar berdampingan, ditumpuk secara vertikal, atau disusun dalam grid. Mendukung perataan, celah, tepi, radius sudut, dan beberapa mode pengubahan ukuran. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/stitch` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | direction | string | No | `"horizontal"` | Arah tata letak: `horizontal`, `vertical`, `grid` | | gridColumns | integer | No | 2 | Jumlah kolom ketika direction adalah `grid` (2 hingga 100) | | resizeMode | string | No | `"fit"` | Cara gambar diubah ukurannya: `fit`, `original`, `stretch`, `crop` | | alignment | string | No | `"center"` | Perataan sumbu-silang: `start`, `center`, `end` | | gap | number | No | 0 | Celah antar gambar dalam piksel (0 hingga 1000) | | border | number | No | 0 | Lebar tepi luar dalam piksel (0 hingga 500) | | cornerRadius | number | No | 0 | Radius sudut yang diterapkan pada keluaran akhir (0 hingga 500) | | backgroundColor | string | No | `"#FFFFFF"` | Warna latar belakang/tepi sebagai hex (mis. `#FF0000`) | | format | string | No | `"png"` | Format keluaran: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | No | 90 | Kualitas keluaran (1 hingga 100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/stitch \ -F "file=@image1.png" \ -F "file=@image2.png" \ -F "file=@image3.png" \ -F 'settings={"direction":"horizontal","resizeMode":"fit","gap":10,"backgroundColor":"#FFFFFF","format":"png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stitch.png", "originalSize": 1234567, "processedSize": 987654 } ``` ## Notes {#notes} * Memerlukan setidaknya 2 gambar. Unggah beberapa file gambar dalam permintaan multipart. * Mendukung format masukan HEIC, RAW, PSD, dan SVG (otomatis didekode). * Mode pengubahan ukuran: * `fit` - Menskalakan gambar agar sesuai dengan dimensi terkecil di sepanjang sumbu penggabungan. * `original` - Mempertahankan ukuran asli (dapat menghasilkan tepi yang tidak rata). * `stretch` - Memaksa gambar agar sesuai dengan dimensi terkecil tanpa mempertahankan rasio aspek. * `crop` - Memangkas-menutupi gambar agar sesuai dengan dimensi terkecil. * Dalam mode `grid`, sel diukur sesuai dimensi median dari semua gambar. * `cornerRadius` diterapkan ke seluruh keluaran akhir, bukan gambar individual. * Ukuran kanvas dibatasi oleh konfigurasi server `MAX_CANVAS_PIXELS` untuk mencegah kehabisan memori. --- --- url: https://docs.snapotter.com/id/tools/image/background-replace.md description: Ganti latar belakang gambar dengan warna solid atau gradien menggunakan AI. --- # Ganti Latar Belakang {#background-replace} Ganti latar belakang gambar dengan warna solid atau gradien. Model AI mendeteksi subjek, menghapus latar belakang asli, dan menggabungkan subjek ke latar belakang pilihan Anda. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/background-replace` Menerima data formulir multipart dengan berkas gambar dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | backgroundType | string | Tidak | `"color"` | Mode latar belakang: `color` atau `gradient` | | color | string | Tidak | `"#ffffff"` | Warna hex latar belakang (ketika backgroundType bernilai `color`) | | gradientColor1 | string | Tidak | - | Warna hex gradien pertama | | gradientColor2 | string | Tidak | - | Warna hex gradien kedua | | gradientAngle | integer | Tidak | `180` | Sudut gradien dalam derajat (0-360) | | feather | integer | Tidak | `0` | Radius pelunakan tepi (0-20) | | format | string | Tidak | `"png"` | Format keluaran: `png` atau `webp` | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Lacak progres melalui SSE di `GET /api/v1/jobs/{jobId}/progress`. Ketika pekerjaan selesai, aliran SSE memancarkan peristiwa `completed` dengan URL unduhan. ## Catatan {#notes} * Ini adalah alat bertenaga AI yang mengembalikan `202 Accepted` dan memproses secara asinkron. Sambungkan ke endpoint SSE untuk menerima pembaruan progres dan hasil akhir. * Memerlukan bundel fitur **background-removal** untuk dipasang. Mengembalikan `501` jika bundel tidak tersedia. * Input HEIC, RAW, PSD, dan SVG didekode secara otomatis sebelum diproses. * Keluaran bawaan ke PNG untuk mempertahankan transparansi di sekitar subjek. --- --- url: https://docs.snapotter.com/id/tools/image/bulk-rename.md description: Ganti nama beberapa berkas menggunakan templat pola dan unduh sebagai ZIP. --- # Ganti Nama Massal {#bulk-rename} Ganti nama beberapa berkas menggunakan templat pola dengan placeholder untuk indeks, indeks berpad, dan nama berkas asli. Mengembalikan arsip ZIP yang berisi semua berkas yang telah diganti namanya. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/bulk-rename` Menerima data formulir multipart dengan beberapa berkas dan bidang JSON `settings`. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | pattern | string | Tidak | `"image-{{index}}"` | Pola penamaan dengan placeholder (maks 1000 karakter) | | startIndex | number | Tidak | `1` | Nomor indeks awal | ### Placeholder Pola {#pattern-placeholders} | Placeholder | Deskripsi | Contoh | |-------------|-------------|---------| | `{{index}}` | Nomor berurutan mulai dari `startIndex` | `1`, `2`, `3` | | `{{padded}}` | Nomor berurutan berpad nol | `01`, `02`, `03` | | `{{original}}` | Nama berkas asli tanpa ekstensi | `photo`, `IMG_001` | Ekstensi berkas asli selalu dipertahankan. ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F 'settings={"pattern": "vacation-{{padded}}", "startIndex": 1}' ``` Ini menghasilkan: `vacation-1.jpg`, `vacation-2.jpg`, `vacation-3.jpg` Menggunakan nama berkas asli: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/bulk-rename \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@IMG_001.jpg" \ -F "file=@IMG_002.jpg" \ -F 'settings={"pattern": "2024-trip-{{original}}-{{index}}"}' ``` Ini menghasilkan: `2024-trip-IMG_001-1.jpg`, `2024-trip-IMG_002-2.jpg` ## Contoh Respons {#example-response} Respons berupa berkas ZIP yang dialirkan langsung (bukan respons JSON). Header respons adalah: ``` Content-Type: application/zip Content-Disposition: attachment; filename="renamed-a1b2c3d4.zip" ``` ## Catatan {#notes} * Alat ini tidak memproses gambar. Alat ini hanya mengganti nama berkas dan mengemasnya ke dalam arsip ZIP. * Lebar pad-nol untuk `{{padded}}` ditentukan secara otomatis berdasarkan jumlah total berkas (mis. 100 berkas akan menggunakan pad 3 digit: `001`, `002`, dll.). * Ekstensi berkas dipertahankan dari nama berkas asli. * Nama berkas dibersihkan untuk menghapus karakter yang tidak aman. * Setidaknya satu berkas harus disediakan. --- --- url: https://docs.snapotter.com/nl/guide/users-roles.md description: >- Beheer gebruikers, ingebouwde en aangepaste rollen, permissies, API-sleutels, teams, sessies en het auditlogboek in SnapOtter. --- # Gebruikers, rollen en permissies {#users-roles-permissions} SnapOtter wordt geleverd met drie ingebouwde rollen, 17 granulaire permissies en ondersteuning voor aangepaste rollen met optionele toegangscontrole per tool. Deze pagina behandelt het volledige autorisatiemodel, scoping van API-sleutels, teambeheer en auditlogging. ::: tip Gerelateerde pagina's [OIDC / SSO](/nl/guide/oidc) | [SAML SSO](/nl/guide/saml) | [SCIM-provisioning](/nl/guide/scim) | [Beveiliging en hardening](/nl/guide/security) ::: ## Gebruikers {#users} ### Gebruikers aanmaken {#creating-users} Beheerders kunnen gebruikers aanmaken via het beheerderspaneel of het `POST /api/auth/register`-endpoint. Elke gebruiker heeft een gebruikersnaam, rol, teamtoewijzing en een optioneel e-mailadres. ### Standaardbeheerder {#default-admin} Bij de eerste start maakt SnapOtter een standaardbeheerdersaccount aan. De inloggegevens komen uit omgevingsvariabelen: | Variabele | Standaard | Beschrijving | |---|---|---| | `DEFAULT_USERNAME` | `admin` | Gebruikersnaam voor het initiële beheerdersaccount | | `DEFAULT_PASSWORD` | `admin` | Wachtwoord voor het initiële beheerdersaccount | De standaardbeheerder moet zijn wachtwoord wijzigen bij de eerste aanmelding. ### Authenticatieproviders {#authentication-providers} Gebruikers kunnen zich authenticeren via verschillende methoden: * **Lokaal** - gebruikersnaam en wachtwoord opgeslagen in de SnapOtter-database * **OIDC** - elke OpenID Connect-provider (zie [OIDC / SSO](/nl/guide/oidc)) * **SAML** - SAML 2.0 identity providers (zie [SAML SSO](/nl/guide/saml)) * **SCIM** - geautomatiseerde provisioning vanuit een identity provider (zie [SCIM-provisioning](/nl/guide/scim)) ### Authenticatie uitschakelen {#disabling-authentication} Stel `AUTH_ENABLED=false` in om authenticatie volledig uit te schakelen. In deze modus wordt een synthetische anonieme gebruiker met de rol `admin` gebruikt voor alle verzoeken. Er is geen aanmelding vereist. ::: warning Het uitschakelen van authenticatie geeft volledige beheerderstoegang aan iedereen die de instantie kan bereiken. Gebruik dit alleen in vertrouwde omgevingen. ::: ## Ingebouwde rollen {#built-in-roles} SnapOtter bevat drie ingebouwde rollen. Ze kunnen niet worden gewijzigd of verwijderd. ### Admin {#admin} Alle 17 permissies. Volledige controle over de instantie. `tools:use` `files:own` `files:all` `apikeys:own` `apikeys:all` `pipelines:own` `pipelines:all` `settings:read` `settings:write` `users:manage` `teams:manage` `features:manage` `system:health` `audit:read` `compliance:manage` `webhooks:manage` `security:manage` ### Editor {#editor} 7 permissies. Kan alle tools gebruiken en alle bestanden en pipelines beheren, maar heeft geen toegang tot beheerdersfuncties. `tools:use` `files:own` `files:all` `apikeys:own` `pipelines:own` `pipelines:all` `settings:read` ### User {#user} 5 permissies. Kan tools gebruiken en eigen resources beheren. `tools:use` `files:own` `apikeys:own` `pipelines:own` `settings:read` ## Permissiereferentie {#permissions-reference} | Permissie | Beschrijving | |---|---| | `tools:use` | Elke verwerkingstool gebruiken | | `files:own` | Eigen bestanden bekijken en beheren | | `files:all` | Bestanden van alle gebruikers bekijken en beheren | | `apikeys:own` | Eigen API-sleutels aanmaken en beheren | | `apikeys:all` | API-sleutels van alle gebruikers bekijken | | `pipelines:own` | Eigen pipelines aanmaken en beheren | | `pipelines:all` | Pipelines van alle gebruikers bekijken en beheren | | `settings:read` | Instantie-instellingen bekijken | | `settings:write` | Instantie-instellingen wijzigen | | `users:manage` | Creëer en beheer gebruikersaccounts binnen de bevoegdheidsgrens van de actor | | `teams:manage` | Teams aanmaken, bijwerken en verwijderen | | `features:manage` | AI-featurebundels installeren en beheren | | `system:health` | Toegang tot health- en readiness-endpoints | | `audit:read` | Het auditlogboek bekijken en rollen weergeven | | `compliance:manage` | Beheer AVG-levenscyclus- en compliancefuncties; destructieve gebruikersbewerkingen blijven autoriteitsgebonden | | `webhooks:manage` | Uitgaande webhooks configureren | | `security:manage` | Beveiligingsinstellingen beheren (IP-allowlist, SSO-afdwinging) | ## Aangepaste rollen {#custom-roles} Beheerders met de permissie `security:manage` kunnen aangepaste rollen aanmaken via het beheerderspaneel of de rollen-API. Voor het weergeven van rollen is `audit:read` vereist. ### Een aangepaste rol aanmaken {#creating-a-custom-role} ```bash curl -X POST http://localhost:1349/api/v1/roles \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "reviewer", "description": "Can use tools and view all files", "permissions": ["tools:use", "files:own", "files:all", "settings:read"] }' ``` Rolnamen moeten 2-30 tekens zijn, kleine letters, alfanumeriek met koppeltekens en underscores. ### Gedelegeerde bestuursgrenzen {#delegated-administration-boundaries} Alle 17 machtigingen kunnen worden gedelegeerd via aangepaste rollen, maar een beheerdersmachtiging maakt die rol niet gelijkwaardig aan de ingebouwde `admin`-rol. Gebruikersmutaties geautoriseerd door `users:manage`, destructieve bewerkingen geautoriseerd door `compliance:manage`, en beheer van aangepaste rollen geautoriseerd door `security:manage` worden begrensd door de huidige autoriteit van de actor: * Ingebouwde rollen volgen `admin` > `editor` > `user`; aangepaste rollen staan ​​onder ingebouwde rollen. * De machtigingen van het doelwit moeten worden vastgelegd in de **effectieve** machtigingen van de acteur. Een API-sleutel met een bereik kan daarom geen machtigingen uitoefenen die zijn weggelaten uit het bereik ervan. * De tooltoegang van een doelrol moet beperkt zijn tot de tooltoegang van de actor zelf. * Een uitgeschakeld account wordt gecontroleerd aan de hand van de oorspronkelijke rol wanneer die rol wordt geregistreerd als `disabled:`. * Het verwijderen van een aangepaste rol vereist ook de bevoegdheid om de ingebouwde `user`-fallback toe te wijzen; gehandicapte leden blijven uitgeschakeld als `disabled:user`. De algemene inloggegevens en configuratie zijn strenger: voor het uitgeven of intrekken van het SCIM-token en het importeren van de instanceconfiguratie is de ingebouwde `admin`-rol met volledige effectieve beheerdersbevoegdheid vereist. ### Permissies op toolniveau {#tool-level-permissions} Aangepaste rollen kunnen optioneel beperken tot welke tools gebruikers toegang hebben. Twee modi zijn beschikbaar: | Modus | Gedrag | Licentievereiste | |---|---|---| | `category` | Beperken per modaliteit (image, video, audio, document, file) | Geen (gratis) | | `tool` | Beperken per individuele tool-ID | Vereist de enterprise-feature `per_tool_permissions` | Wanneer de modus `tool` is ingesteld maar de enterprise-feature niet beschikbaar is, degradeert SnapOtter netjes en staat het toegang tot alle tools toe. ```json { "name": "image-only", "permissions": ["tools:use", "files:own"], "toolPermissions": { "mode": "category", "allowed": ["image"] } } ``` ### Een aangepaste rol verwijderen {#deleting-a-custom-role} Wanneer een aangepaste rol wordt verwijderd, worden alle daaraan toegewezen gebruikers automatisch opnieuw toegewezen aan de rol `user`. ## Teams {#teams} Teams groeperen gebruikers voor opslag- en bewaarbeheer. Een `Default`-team wordt aangemaakt bij de eerste start. | Veld | Type | Beschrijving | |---|---|---| | `name` | string | Unieke teamnaam (1-50 tekens) | | `storageQuota` | number | Opslaglimiet per team in bytes (werkt zonder enterprise) | | `retentionHours` | number | Uitvoer automatisch verwijderen na dit aantal uren (vereist `team_retention_overrides`, enterprise) | | `legalHold` | boolean | Automatische verwijdering van bestanden van teamleden voorkomen (vereist `legal_hold`, enterprise) | ::: info Het `Default`-team kan niet worden verwijderd. Teams die nog leden hebben, kunnen niet worden verwijderd. Wijs de leden eerst opnieuw toe. ::: ## API-sleutels {#api-keys} Gebruikers kunnen API-sleutels genereren voor programmatische toegang. Elke sleutel gebruikt het `si_`-voorvoegsel en wordt slechts één keer getoond bij het aanmaken. ### Gescopede permissies {#scoped-permissions} API-sleutels kunnen optioneel een `permissions`-array dragen. Wanneer ingesteld, zijn de effectieve permissies voor een verzoek de **doorsnede** van de rolpermissies van de gebruiker en de gescopede permissies van de sleutel. Dit betekent dat een API-sleutel nooit verder kan escaleren dan de eigen permissies van de gebruiker. ```bash curl -X POST http://localhost:1349/api/v1/api-keys \ -H "Authorization: Bearer si_..." \ -H "Content-Type: application/json" \ -d '{ "name": "CI pipeline key", "permissions": ["tools:use", "files:own"], "expiresAt": "2027-01-01T00:00:00Z" }' ``` ### Vervaldatum {#expiration} Sleutels accepteren een optionele `expiresAt`-timestamp. Verlopen sleutels worden bij authenticatie geweigerd. ## Auditlogboek {#audit-log} SnapOtter registreert beveiligingsrelevante gebeurtenissen in een gestructureerd auditlogboek dat is opgeslagen in de databasetabel `audit_log`. ### Het auditlogboek bekijken {#viewing-the-audit-log} ``` GET /api/v1/audit-log?page=1&limit=50&action=LOGIN_FAILED&from=2026-01-01T00:00:00Z&to=2026-12-31T23:59:59Z ``` Vereist de permissie `audit:read`. Ondersteunt paginering (`page`, `limit`) en filters (`action`, `ip`, `from`, `to`). ### Auditing van tooloperaties {#tool-operation-auditing} ::: warning `TOOL_EXECUTED`-gebeurtenissen worden standaard **niet** gelogd. Ze zijn opt-in via een van twee paden: 1. Stel de beheerdersinstelling `auditToolOperations` in op `true`. 2. Bezit een actieve licentie met de feature `audit_export` (beschikbaar op zowel team- als enterprise-plannen). Zonder een van deze worden individuele tooluitvoeringen niet in het auditlogboek vastgelegd. ::: ### Exporteren {#exporting} ``` GET /api/v1/enterprise/audit/export?format=csv&from=2026-01-01T00:00:00Z ``` Vereist de permissie `audit:read` en de enterprise-feature `audit_export` (beschikbaar op zowel team- als enterprise-plannen). Ondersteunt CSV- en JSON-formaten, gefilterd op `action`, `actorId`, `targetType`, `targetId`, `from` en `to`. ### Sabotagebestendige ondertekening {#tamper-resistant-signing} Wanneer ingeschakeld, wordt elke auditlogboekvermelding ondertekend met een HMAC afgeleid van `DATA_ENCRYPTION_KEY`. Dit vereist: 1. Het instellen van `DATA_ENCRYPTION_KEY` in je omgeving. 2. Het inschakelen van de beheerdersinstelling `tamperResistantAudit`. 3. Een enterprise-licentie met de feature `tamper_resistant_audit`. ### Bewaring {#retention} Stel `AUDIT_RETENTION_DAYS` in om oude vermeldingen automatisch op te schonen. De standaard is `0`, wat betekent dat vermeldingen onbeperkt worden bewaard. ### Gebeurtenisreferentie {#event-reference} | Gebeurtenis | Categorie | |---|---| | `LOGIN_SUCCESS`, `LOGIN_FAILED` | Authenticatie | | `OIDC_LOGIN_SUCCESS`, `OIDC_LOGIN_FAILED` | Authenticatie | | `SAML_LOGIN_SUCCESS`, `SAML_LOGIN_FAILED` | Authenticatie | | `LOGOUT` | Authenticatie | | `USER_CREATED`, `USER_UPDATED`, `USER_DELETED` | Gebruikersbeheer | | `PASSWORD_CHANGED`, `PASSWORD_RESET` | Gebruikersbeheer | | `MFA_ENROLLED`, `MFA_DISABLED`, `MFA_VERIFIED`, `MFA_VERIFY_FAILED` | MFA | | `MFA_CHALLENGE_ISSUED`, `MFA_RECOVERY_USED`, `MFA_RESET` | MFA | | `ROLE_CREATED`, `ROLE_UPDATED`, `ROLE_DELETED` | Rollen | | `API_KEY_CREATED`, `API_KEY_DELETED` | API-sleutels | | `SETTINGS_UPDATED`, `IP_ALLOWLIST_UPDATED` | Instellingen | | `FILE_UPLOADED`, `FILE_DELETED` | Bestanden | | `TOOL_EXECUTED` | Tools (opt-in) | | `SCIM_USER_PROVISIONED`, `SCIM_USER_UPDATED`, `SCIM_USER_DEPROVISIONED` | SCIM | | `SCIM_GROUP_SYNCED` | SCIM | | `LEGAL_HOLD_APPLIED`, `LEGAL_HOLD_RELEASED` | Compliance | | `GDPR_EXPORT_INITIATED`, `GDPR_USER_PURGED`, `GDPR_TEAM_PURGED` | Compliance | | `CONFIG_EXPORTED`, `CONFIG_IMPORTED` | Configuratie | ## Sessiebeheer {#session-management} Sessies zijn cookie-gebaseerd, geregeld door `SESSION_DURATION_HOURS` (standaard: 168 uur / 7 dagen). ### Rolwijzigingen maken sessies ongeldig {#role-changes-invalidate-sessions} Wanneer een beheerder de rol van een gebruiker wijzigt, worden alle actieve sessies van die gebruiker verwijderd. De gebruiker moet opnieuw inloggen om de nieuwe permissies op te pikken. ### Veiligheidsmaatregelen {#safety-guards} * **Bescherming van de laatste beheerder**: de laatst overgebleven beheerder kan niet worden gedegradeerd naar een lagere rol. De API retourneert een fout als je het probeert. * **Voorkoming van zelfverwijdering**: beheerders kunnen hun eigen account niet via de API verwijderen. --- --- url: https://docs.snapotter.com/tr/guide/developer.md description: >- Yerel geliştirme kurulumu, komutlar, kod kuralları ve SnapOtter'a yeni bir araç ekleme. --- # Geliştirici kılavuzu {#developer-guide} Yerel bir geliştirme ortamı kurma ve SnapOtter'a kod katkısında bulunma. ## Ön koşullar {#prerequisites} * [Node.js](https://nodejs.org/) 22.22+ * [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`) * [Docker](https://www.docker.com/) (yerel Postgres + Redis, container derlemeleri ve AI özellikleri için gerekli) * Git Python 3.11+ yalnızca AI/ML yardımcı işlemi (arka plan kaldırma, ölçek büyütme, OCR) üzerinde çalışıyorsanız gereklidir. ## Kurulum {#setup} ```bash git clone https://github.com/snapotter-hq/snapotter.git cd snapotter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` Bu, iki geliştirme sunucusunu başlatır: | Servis | URL | Notlar | |----------|--------------------------|------------------------------------| | Ön uç | http://localhost:1351 | Vite geliştirme sunucusu, /api proxy'ler | | Arka uç | http://localhost:13490 | Fastify API (proxy üzerinden erişilir) | Tarayıcınızda http://localhost:1351 adresini açın. `admin` / `admin` ile oturum açın. İlk oturum açmada parolayı değiştirmeniz istenir. ## Proje yapısı {#project-structure} ``` apps/ api/ Fastify backend web/ Vite + React frontend docs/ VitePress documentation (this site) packages/ shared/ Constants, types, i18n strings image-engine/ Sharp-based image operations media-engine/ FFmpeg spawn + progress parsing doc-engine/ qpdf, LibreOffice, ghostscript wrappers ai/ Python sidecar bridge for ML models tests/ unit/ Vitest unit tests integration/ Vitest integration tests (full API) e2e/ Playwright end-to-end specs fixtures/ Small test images ``` ## Komutlar {#commands} ```bash pnpm dev # start frontend + backend pnpm build # build all workspaces pnpm typecheck # TypeScript check across monorepo pnpm lint # Biome lint + format check pnpm lint:fix # auto-fix lint + format pnpm test # unit + integration tests pnpm test:unit # unit tests only pnpm test:integration # integration tests only pnpm test:e2e # Playwright e2e tests pnpm test:coverage # tests with coverage report ``` ## Kod kuralları {#code-conventions} * Çift tırnak, noktalı virgül, 2 boşluk girinti (Biome tarafından zorlanır) * Tüm workspace'lerde ES modülleri * Semantic-release için [Conventional commits](https://www.conventionalcommits.org/) * Tüm API girdi doğrulaması için Zod * Biome, TypeScript ya da editör yapılandırma dosyalarında değişiklik yok. Linter'ı değil, kodu düzeltin. ## Veritabanı {#database} Drizzle ORM (pg-core) aracılığıyla PostgreSQL 17. Yerel geliştirme, Postgres ve Redis'in çalışıyor olmasını gerektirir; bunları şununla başlatın: ```bash docker compose -f docker-compose.dev.yml up -d ``` Bu size 5432 portunda Postgres ve 6379 portunda Redis verir. Ardından migration'ları oluşturup uygulayın: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Şema `apps/api/src/db/schema.ts` dosyasında tanımlanır. Tablolar: users, sessions, settings, jobs, apiKeys, pipelines, teams, userFiles, roles, auditLog. ## Yeni bir araç ekleme {#adding-a-new-tool} Her araç aynı deseni izler. İşte minimal bir örnek. ### 1. Arka uç route'u {#\_1-backend-route} `apps/api/src/routes/tools/my-tool.ts` dosyasını oluşturun: ```ts import { z } from "zod"; import type { FastifyInstance } from "fastify"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ intensity: z.number().min(0).max(100).default(50), }); export function registerMyTool(app: FastifyInstance) { createToolRoute(app, { toolId: "my-tool", settingsSchema, async process(inputBuffer, settings, filename) { // Use sharp or other libraries to process the image const sharp = (await import("sharp")).default; const result = await sharp(inputBuffer) // ... your processing logic .toBuffer(); return { buffer: result, filename: filename.replace(/\.[^.]+$/, ".png"), contentType: "image/png", }; }, }); } ``` Ardından `apps/api/src/routes/tools/index.ts` dosyasında kaydedin. ### 2. Ön uç ayarları bileşeni {#\_2-frontend-settings-component} `apps/web/src/components/tools/my-tool-settings.tsx` dosyasını oluşturun: ```tsx import { useState } from "react"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; export function MyToolSettings() { const { files } = useFileStore(); const { processFiles, processing, error, downloadUrl } = useToolProcessor("my-tool"); const [intensity, setIntensity] = useState(50); const handleProcess = () => { processFiles(files, { intensity }); }; return (
{/* your controls here */}
); } ``` Ardından `apps/web/src/lib/tool-registry.tsx` konumundaki ön uç araç kayıt defterinde kaydedin: ```tsx // Add the lazy import const MyToolSettings = lazy(() => import("@/components/tools/my-tool-settings").then((m) => ({ default: m.MyToolSettings, })), ); // Add to the toolRegistry Map ["my-tool", { displayMode: "before-after", Settings: MyToolSettings }], ``` Görüntüleme modları: `"side-by-side"`, `"before-after"`, `"live-preview"`, `"no-comparison"`, `"interactive-crop"`, `"interactive-eraser"`, `"no-dropzone"`. ### 3. i18n girdisi {#\_3-i18n-entry} `packages/shared/src/i18n/en.ts` dosyasına ekleyin: ```ts "my-tool": { name: "My Tool", description: "Short description of what this tool does", }, ``` ### 4. Testler {#\_4-tests} E2e testlerin güvenilir biçimde hedefleyebilmesi için eylem düğmenize bir `data-testid` özniteliği ekleyin (yukarıda gösterildiği gibi). ## Docker derlemeleri {#docker-builds} Tam üretim imajını yerelde derleyin: ```bash docker build -f docker/Dockerfile -t snapotter:latest . ``` Daha hızlı yeniden derlemeler için BuildKit önbellek bağlamalarını kullanın: ```bash DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest . ``` ## Sürüm etki alanlarını yayınlayın {#release-version-domains} SnapOtter kasıtlı olarak üç sürüm alanına sahiptir. Sürüm sırasında bir alanı diğerine kopyalamayın: * Uygulama yayın sürümü, kök bildirimi, tüm özel çalışma alanı paketlerini ve `APP_VERSION`'yi kapsar. Semantic-release bu değeri sağlar ve `pnpm version:sync `, bir uygulama yayınlanmadan önce her çalışma alanını günceller. * OpenAPI `info.version`, istikrarlı halka açık API ana sözleşmesidir. Tüm yerelleştirilmiş özellikler, uyumlu uygulama sürümleri için `.0.0`'de kalır ve yalnızca API sözleşmesi yeni bir ana sürüme taşındığında değişir. * `docker/feature-manifest.json`, `imageVersion: 2.0.0`'yi değişmez eski özellik paketi depolama çağı olarak koruyor. Bu v2 arşiv yolları uygulama paketi sürümleri değildir. Accurate OCR, çalışma zamanı formatı v3'ü kullanır ve uygulama yayın kaynağını ayrı olarak kaydeder. `tests/unit/infra/release-version-policy.test.ts` bu sınırları zorlar. Yeni bir sürüm etki alanı veya geçişi, söz konusu sözleşmeyi ve ilgili yapıt geçiş tasarımını birlikte güncellemelidir. Bağımsız API ve eski paket değerleri `config/release-version-policy.json`'de bulunur; uygulama sürümü senkronizasyonu bu politika dosyasını hiçbir zaman örtülü olarak yeniden yazmamalıdır. ## Ortam değişkenleri {#environment-variables} Tam liste için [Yapılandırma kılavuzu](/tr/guide/configuration) bölümüne bakın. Geliştirme için önemli olanlar: | Değişken | Varsayılan | Açıklama | |-----------------------------|-----------|------------------------------------------------| | `AUTH_ENABLED` | `true` | Kimlik doğrulamayı etkinleştir/devre dışı bırak | | `DEFAULT_USERNAME` | `admin` | Varsayılan yönetici kullanıcı adı | | `DEFAULT_PASSWORD` | `admin` | Varsayılan yönetici parolası | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Zorunlu parola değişimini atla (yalnızca CI/geliştirme) | | `RATE_LIMIT_PER_MIN` | `1000` | Dakikada API oran sınırı (0 = devre dışı) | | `MAX_UPLOAD_SIZE_MB` | `100` | MB cinsinden en fazla yükleme boyutu (0 = sınırsız) | --- --- url: https://docs.snapotter.com/es/tools/image/barcode-generate.md description: >- Genera códigos de barras en los formatos Code 128, EAN-13, UPC-A, Code 39, ITF-14 y Data Matrix. --- # Generador de códigos de barras {#barcode-generator} Genera imágenes de códigos de barras a partir de texto de entrada. Admite los formatos Code 128, EAN-13, UPC-A, Code 39, ITF-14 y Data Matrix. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Acepta un cuerpo `application/json` (no multipart). El código de barras se genera a partir del texto proporcionado, no de un archivo subido. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Sí | - | Texto a codificar en el código de barras (1-256 caracteres) | | type | string | No | `"code128"` | Formato del código de barras: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | No | `3` | Factor de escala de la imagen (1-8) | | includeText | boolean | No | `true` | Si se debe mostrar el texto debajo del código de barras | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notes {#notes} * A diferencia de la mayoría de las herramientas, este endpoint acepta un cuerpo JSON, no datos de formulario multipart, ya que los códigos de barras se generan a partir de texto en lugar de un archivo subido. * EAN-13 requiere exactamente 12 o 13 dígitos. UPC-A requiere exactamente 11 o 12 dígitos. Si se omite un dígito de control, se calcula automáticamente. * Code 128 es el formato más flexible y admite el conjunto completo de caracteres ASCII. * Data Matrix produce un código de barras 2D adecuado para codificar cadenas más largas en un cuadrado compacto. --- --- url: https://docs.snapotter.com/es/tools/image/qr-generate.md description: >- Genera códigos QR con colores personalizados y niveles de corrección de errores. --- # Generador de códigos QR {#qr-code-generator} Genera imágenes de códigos QR a partir de texto o URLs con tamaño, nivel de corrección de errores y colores de primer plano/fondo personalizables. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/qr-generate` Acepta un **cuerpo JSON** (no multipart). No es necesario subir un archivo. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | text | string | Sí | - | Contenido que se codificará en el código QR (1 a 2000 caracteres) | | size | number | No | `400` | Ancho/alto de la imagen de salida en píxeles (100 a 10000) | | errorCorrection | string | No | `"M"` | Nivel de corrección de errores: `L` (7 %), `M` (15 %), `Q` (25 %), `H` (30 %) | | foreground | string | No | `"#000000"` | Color del primer plano/módulo del código QR en hexadecimal (`#RRGGBB`) | | background | string | No | `"#FFFFFF"` | Color de fondo del código QR en hexadecimal (`#RRGGBB`) | | logoDataUri | string | No | - | Imagen del logo como URI de datos (`data:image/png;base64,...` o `data:image/jpeg;base64,...`, máximo 700 KB). Se centra en el código QR al 22 % de su tamaño. Fuerza la corrección de errores a `H` | ### Niveles de corrección de errores {#error-correction-levels} | Nivel | Recuperación | Caso de uso | |-------|----------|----------| | `L` | ~7 % | Densidad de datos máxima | | `M` | ~15 % | Equilibrado (predeterminado) | | `Q` | ~25 % | Bueno para códigos impresos | | `H` | ~30 % | El mejor para códigos con logos superpuestos | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "https://snapotter.com", "size": 500, "errorCorrection": "H"}' ``` Código QR de marca con colores personalizados: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "Hello World", "size": 300, "foreground": "#1a365d", "background": "#f7fafc"}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/qrcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notas {#notes} * Este endpoint acepta JSON, no datos de formulario multipart, ya que no es necesario subir ninguna imagen. * La salida es siempre una imagen PNG. * El nombre del archivo de salida es siempre `qrcode.png`. * `originalSize` es siempre 0, ya que esta herramienta genera imágenes desde cero. * Se incluye una zona de silencio (margen) de 2 módulos alrededor del código QR. * La longitud máxima del texto es de 2000 caracteres. La capacidad real depende del nivel de corrección de errores y la codificación de caracteres. * Los niveles de corrección de errores más altos permiten que el código QR siga siendo escaneable incluso si está parcialmente oculto, pero reducen la capacidad de datos. * Cuando se proporciona un `logoDataUri`, la corrección de errores se fuerza automáticamente a `H` (30 %) para que el código QR siga siendo escaneable a pesar de que el logo ocluye el centro. --- --- url: https://docs.snapotter.com/es/tools/image/favicon.md description: >- Genera todos los tamaños estándar de favicon e iconos de aplicación a partir de una imagen de origen. --- # Generador de favicons {#favicon-generator} Genera un conjunto completo de archivos de favicon e iconos de aplicación a partir de una imagen de origen. Produce todos los tamaños estándar necesarios para navegadores, dispositivos Apple y Android, junto con un manifiesto web y un fragmento de HTML. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/favicon` Acepta datos de formulario multipart con uno o varios archivos de imagen y un campo JSON `settings` opcional. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | background | string | No | - | Color hexadecimal de fondo (p. ej. `"#ffffff"`). Cuando se define, el icono se aplana sobre este color. | | padding | integer | No | `0` | Porcentaje de relleno alrededor del contenido del icono (0 a 40) | | radius | integer | No | `0` | Porcentaje de radio de las esquinas para iconos redondeados (0 a 50) | | sizes | integer\[] | No | - | Limita la salida a tamaños de píxel concretos (p. ej. `[16, 32, 180]`). Omítelo para generar todos los tamaños estándar. | | themeColor | string | No | `"#ffffff"` | Color de tema hexadecimal para el manifiesto web | ## Archivos generados {#generated-files} Por cada imagen de entrada se producen los siguientes archivos: | Archivo | Tamaño | Propósito | |------|------|---------| | `favicon-16x16.png` | 16x16 | Icono de pestaña del navegador | | `favicon-32x32.png` | 32x32 | Icono de pestaña del navegador (HiDPI) | | `favicon-48x48.png` | 48x48 | Acceso directo de escritorio | | `apple-touch-icon.png` | 180x180 | Pantalla de inicio de iOS | | `android-chrome-192x192.png` | 192x192 | Pantalla de inicio de Android | | `android-chrome-512x512.png` | 512x512 | Pantalla de bienvenida de Android | | `favicon.ico` | 32x32 | Formato ICO heredado | | `manifest.json` | - | Manifiesto de aplicación web con referencias de iconos | | `favicon-snippet.html` | - | Etiquetas de enlace HTML listas para usar | ## Ejemplo de solicitud {#example-request} Una sola imagen de origen con esquinas redondeadas y relleno: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Varias imágenes de origen (cada una obtiene su propio conjunto en una subcarpeta): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Ejemplo de respuesta {#example-response} La respuesta es un archivo ZIP transmitido directamente. Las cabeceras de la respuesta son: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Fragmento de HTML incluido {#html-snippet-included} El ZIP incluye un archivo `favicon-snippet.html` que puedes pegar en el `` de tu HTML: ```html ``` ## Notas {#notes} * Las imágenes de origen se redimensionan usando el modo de ajuste `cover`, lo que significa que se recortan para rellenar cada tamaño cuadrado. Para obtener los mejores resultados, usa una imagen de origen cuadrada. * Cuando se suben varios archivos, cada uno obtiene su propia subcarpeta en el ZIP (nombrada según el archivo de origen). * En el caso de subir un solo archivo, todas las salidas están en la raíz del ZIP sin subcarpeta. * Los archivos que no superan la validación o la decodificación se omiten, y se incluye un `skipped-files.txt` en el ZIP que explica los problemas. * Formatos de entrada admitidos: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD y más. * La orientación EXIF se aplica automáticamente antes de redimensionar. --- --- url: https://docs.snapotter.com/es/tools/image/meme-generator.md description: >- Crea memes con plantillas o imágenes personalizadas, cuadros de texto con estilo y opciones de fuente. --- # Generador de memes {#meme-generator} Crea memes usando plantillas integradas o imágenes personalizadas. Añade texto con el estilo clásico de los memes (texto en negrita con contorno), varios diseños predefinidos y opciones de fuente. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/meme-generator` Acepta cualquiera de estas opciones: * **Datos de formulario multipart** con un archivo de imagen y un campo JSON `settings` (modo de imagen personalizada) * **Cuerpo JSON** con un `templateId` (modo plantilla, sin necesidad de subir un archivo) ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | templateId | string | No | - | ID de plantilla de meme integrada. Si se proporciona, no es necesario subir una imagen | | textLayout | string | No | `"top-bottom"` | Diseño de los cuadros de texto: `top-bottom`, `top-only`, `bottom-only`, `center`, `side-by-side` | | textBoxes | array | No | `[]` | Array de objetos de cuadro de texto con campos `id` y `text` | | fontFamily | string | No | `"anton"` | Fuente: `anton`, `arial-black`, `comic-sans`, `montserrat`, `bebas-neue`, `permanent-marker`, `roboto` | | fontSize | number | No | auto | Tamaño de fuente en píxeles (8 a 200). Se calcula automáticamente si se omite | | textColor | string | No | `"#ffffff"` | Color de relleno del texto | | strokeColor | string | No | `"#000000"` | Color del trazo/contorno del texto | | textAlign | string | No | `"center"` | Alineación del texto: `left`, `center`, `right` | | allCaps | boolean | No | `true` | Convertir el texto a mayúsculas | ### Cuadros de texto {#text-boxes} Cada entrada del array `textBoxes` debe tener: | Campo | Tipo | Descripción | |-------|------|-------------| | id | string | Identificador del cuadro que coincide con el diseño (por ejemplo, `"top"`, `"bottom"`, `"left"`, `"right"`, `"center"`) | | text | string | El texto del meme que se mostrará | ### IDs de los cuadros según el diseño del texto {#text-layout-box-ids} | Diseño | IDs de cuadro disponibles | |--------|-------------------| | `top-bottom` | `top`, `bottom` | | `top-only` | `top` | | `bottom-only` | `bottom` | | `center` | `center` | | `side-by-side` | `left`, `right` | ## Ejemplo de solicitud {#example-request} Imagen personalizada con texto arriba y abajo: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"textLayout": "top-bottom", "textBoxes": [{"id": "top", "text": "When the code works"}, {"id": "bottom", "text": "On the first try"}], "fontFamily": "anton", "allCaps": true}' ``` Usando una plantilla integrada (cuerpo JSON, sin subir archivo): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"templateId": "drake", "textBoxes": [{"id": "top", "text": "Manual testing"}, {"id": "bottom", "text": "Automated tests"}]}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/meme-drake.png", "originalSize": 450000, "processedSize": 520000 } ``` ## Notas {#notes} * Se requiere `templateId` o un archivo de imagen subido. Si se proporcionan ambos, se usa la plantilla. * Las plantillas definen sus propias posiciones de cuadro de texto; el parámetro `textLayout` se ignora al usar plantillas. * El texto se renderiza como SVG con contornos de trazo para lograr el aspecto clásico del meme. * El tamaño de fuente se calcula automáticamente para ajustarse al cuadro de texto si no se establece de forma explícita. * Los cuadros de texto vacíos se omiten (no se renderiza nada si todos los cuadros están vacíos). * El nombre del archivo de salida incluye el ID de la plantilla cuando se usan plantillas (por ejemplo, `meme-drake.png`). * Las entradas HEIC, RAW, PSD y SVG se decodifican automáticamente antes del procesamiento. --- --- url: https://docs.snapotter.com/fr/tools/image/barcode-generate.md description: >- Génère des codes-barres aux formats Code 128, EAN-13, UPC-A, Code 39, ITF-14 et Data Matrix. --- # Générateur de codes-barres {#barcode-generator} Génère des images de codes-barres à partir d'un texte saisi. Prend en charge les formats Code 128, EAN-13, UPC-A, Code 39, ITF-14 et Data Matrix. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Accepte un corps `application/json` (et non multipart). Le code-barres est généré à partir du texte fourni, pas d'un fichier téléversé. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | text | chaîne | Oui | - | Texte à encoder dans le code-barres (1 à 256 caractères) | | type | chaîne | Non | `"code128"` | Format du code-barres : `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | entier | Non | `3` | Facteur d'échelle de l'image (1 à 8) | | includeText | booléen | Non | `true` | Indique si le texte doit être affiché sous le code-barres | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Remarques {#notes} * Contrairement à la plupart des outils, ce point de terminaison accepte un corps JSON, et non des données de formulaire multipart, puisque les codes-barres sont générés à partir d'un texte plutôt que d'un fichier téléversé. * EAN-13 exige exactement 12 ou 13 chiffres. UPC-A exige exactement 11 ou 12 chiffres. Si le chiffre de contrôle est omis, il est calculé automatiquement. * Code 128 est le format le plus souple et prend en charge l'ensemble du jeu de caractères ASCII. * Data Matrix produit un code-barres 2D adapté à l'encodage de chaînes plus longues dans un carré compact. --- --- url: https://docs.snapotter.com/fr/tools/image/favicon.md description: >- Générez toutes les tailles standard de favicon et d'icônes d'application à partir d'une image source. --- # Générateur de favicon {#favicon-generator} Générez un ensemble complet de fichiers de favicon et d'icônes d'application à partir d'une image source. Produit toutes les tailles standard nécessaires pour les navigateurs, les appareils Apple et Android, accompagnées d'un manifeste web et d'un extrait HTML. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/favicon` Accepte des données de formulaire multipart avec une ou plusieurs images et un champ JSON `settings` facultatif. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | background | string | Non | - | Couleur de fond hexadécimale (par exemple `"#ffffff"`). Lorsqu'elle est définie, l'icône est aplatie sur cette couleur. | | padding | integer | Non | `0` | Pourcentage de marge autour du contenu de l'icône (0 à 40) | | radius | integer | Non | `0` | Pourcentage de rayon des coins pour les icônes arrondies (0 à 50) | | sizes | integer\[] | Non | - | Restreint la sortie à des tailles en pixels spécifiques (par exemple `[16, 32, 180]`). Omettez pour générer toutes les tailles standard. | | themeColor | string | Non | `"#ffffff"` | Couleur de thème hexadécimale pour le manifeste web | ## Fichiers générés {#generated-files} Pour chaque image d'entrée, les fichiers suivants sont produits : | Fichier | Taille | Rôle | |------|------|---------| | `favicon-16x16.png` | 16x16 | Icône d'onglet de navigateur | | `favicon-32x32.png` | 32x32 | Icône d'onglet de navigateur (HiDPI) | | `favicon-48x48.png` | 48x48 | Raccourci du bureau | | `apple-touch-icon.png` | 180x180 | Écran d'accueil iOS | | `android-chrome-192x192.png` | 192x192 | Écran d'accueil Android | | `android-chrome-512x512.png` | 512x512 | Écran de démarrage Android | | `favicon.ico` | 32x32 | Format ICO hérité | | `manifest.json` | - | Manifeste d'application web avec références d'icônes | | `favicon-snippet.html` | - | Balises de lien HTML prêtes à l'emploi | ## Exemple de requête {#example-request} Image source unique avec coins arrondis et marge : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Plusieurs images sources (chacune obtient son propre ensemble dans un sous-dossier) : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Exemple de réponse {#example-response} La réponse est un fichier ZIP diffusé directement. Les en-têtes de réponse sont : ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Extrait HTML inclus {#html-snippet-included} Le ZIP inclut un fichier `favicon-snippet.html` que vous pouvez coller dans la section `` de votre HTML : ```html ``` ## Notes {#notes} * Les images sources sont redimensionnées avec le mode d'ajustement `cover`, ce qui signifie qu'elles sont recadrées pour remplir chaque taille carrée. Pour de meilleurs résultats, utilisez une image source carrée. * Lorsque plusieurs fichiers sont téléversés, chacun obtient son propre sous-dossier dans le ZIP (nommé d'après le fichier source). * Pour le téléversement d'un seul fichier, toutes les sorties se trouvent à la racine du ZIP sans sous-dossier. * Les fichiers qui échouent à la validation ou au décodage sont ignorés, et un `skipped-files.txt` est inclus dans le ZIP pour expliquer les problèmes. * Formats d'entrée pris en charge : JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD, et plus. * L'orientation EXIF est appliquée automatiquement avant le redimensionnement. --- --- url: https://docs.snapotter.com/fr/tools/image/meme-generator.md description: >- Créez des mèmes à partir de modèles ou d'images personnalisées, avec des zones de texte stylisées et des choix de police. --- # Générateur de mèmes {#meme-generator} Créez des mèmes à partir de modèles intégrés ou d'images personnalisées. Ajoutez du texte avec le style classique des mèmes (texte gras et contouré), plusieurs préréglages de disposition et des choix de police. ## Point de terminaison API {#api-endpoint} `POST /api/v1/tools/image/meme-generator` Accepte au choix : * **Données de formulaire multipart** avec un fichier image et un champ JSON `settings` (mode image personnalisée) * **Corps JSON** avec un `templateId` (mode modèle, aucun envoi de fichier nécessaire) ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | templateId | string | Non | - | ID du modèle de mème intégré. S'il est fourni, aucun envoi d'image n'est nécessaire | | textLayout | string | Non | `"top-bottom"` | Disposition des zones de texte : `top-bottom`, `top-only`, `bottom-only`, `center`, `side-by-side` | | textBoxes | array | Non | `[]` | Tableau d'objets de zone de texte avec les champs `id` et `text` | | fontFamily | string | Non | `"anton"` | Police : `anton`, `arial-black`, `comic-sans`, `montserrat`, `bebas-neue`, `permanent-marker`, `roboto` | | fontSize | number | Non | auto | Taille de police en pixels (8 à 200). Calculée automatiquement si omise | | textColor | string | Non | `"#ffffff"` | Couleur de remplissage du texte | | strokeColor | string | Non | `"#000000"` | Couleur du contour du texte | | textAlign | string | Non | `"center"` | Alignement du texte : `left`, `center`, `right` | | allCaps | boolean | Non | `true` | Convertir le texte en majuscules | ### Zones de texte {#text-boxes} Chaque entrée du tableau `textBoxes` doit comporter : | Champ | Type | Description | |-------|------|-------------| | id | string | Identifiant de zone correspondant à la disposition (par exemple `"top"`, `"bottom"`, `"left"`, `"right"`, `"center"`) | | text | string | Le texte du mème à afficher | ### ID de zones par disposition de texte {#text-layout-box-ids} | Disposition | ID de zones disponibles | |--------|-------------------| | `top-bottom` | `top`, `bottom` | | `top-only` | `top` | | `bottom-only` | `bottom` | | `center` | `center` | | `side-by-side` | `left`, `right` | ## Exemple de requête {#example-request} Image personnalisée avec texte en haut et en bas : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"textLayout": "top-bottom", "textBoxes": [{"id": "top", "text": "When the code works"}, {"id": "bottom", "text": "On the first try"}], "fontFamily": "anton", "allCaps": true}' ``` Utilisation d'un modèle intégré (corps JSON, aucun envoi de fichier) : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"templateId": "drake", "textBoxes": [{"id": "top", "text": "Manual testing"}, {"id": "bottom", "text": "Automated tests"}]}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/meme-drake.png", "originalSize": 450000, "processedSize": 520000 } ``` ## Remarques {#notes} * Soit un `templateId`, soit un fichier image envoyé est requis. Si les deux sont fournis, le modèle est utilisé. * Les modèles définissent leurs propres positions de zones de texte ; le paramètre `textLayout` est ignoré lors de l'utilisation d'un modèle. * Le texte est rendu en SVG avec des contours pour obtenir le look classique des mèmes. * La taille de police est calculée automatiquement pour s'adapter à la zone de texte si elle n'est pas définie explicitement. * Les zones de texte vides sont ignorées (aucun rendu n'a lieu si toutes les zones sont vides). * Le nom du fichier de sortie inclut l'ID du modèle lorsqu'un modèle est utilisé (par exemple `meme-drake.png`). * Les entrées HEIC, RAW, PSD et SVG sont automatiquement décodées avant le traitement. --- --- url: https://docs.snapotter.com/fr/tools/image/qr-generate.md description: >- Générez des QR codes avec des couleurs personnalisées et des niveaux de correction d'erreur. --- # Générateur de QR code {#qr-code-generator} Générez des images de QR code à partir de texte ou d'URL, avec une taille, un niveau de correction d'erreur et des couleurs de premier plan/arrière-plan configurables. ## Point de terminaison API {#api-endpoint} `POST /api/v1/tools/image/qr-generate` Accepte un **corps JSON** (pas de multipart). Aucun envoi de fichier n'est nécessaire. ## Paramètres {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | text | string | Oui | - | Contenu à encoder dans le QR code (1 à 2000 caractères) | | size | number | Non | `400` | Largeur/hauteur de l'image de sortie en pixels (100 à 10000) | | errorCorrection | string | Non | `"M"` | Niveau de correction d'erreur : `L` (7 %), `M` (15 %), `Q` (25 %), `H` (30 %) | | foreground | string | Non | `"#000000"` | Couleur de premier plan/module du QR code en hexadécimal (`#RRGGBB`) | | background | string | Non | `"#FFFFFF"` | Couleur d'arrière-plan du QR code en hexadécimal (`#RRGGBB`) | | logoDataUri | string | Non | - | Image de logo sous forme de data URI (`data:image/png;base64,...` ou `data:image/jpeg;base64,...`, max 700 Ko). Centrée sur le QR code à 22 % de sa taille. Force la correction d'erreur à `H` | ### Niveaux de correction d'erreur {#error-correction-levels} | Niveau | Récupération | Cas d'usage | |-------|----------|----------| | `L` | ~7 % | Densité de données maximale | | `M` | ~15 % | Équilibré (par défaut) | | `Q` | ~25 % | Adapté aux codes imprimés | | `H` | ~30 % | Idéal pour les codes avec logo superposé | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "https://snapotter.com", "size": 500, "errorCorrection": "H"}' ``` QR code de marque avec des couleurs personnalisées : ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "Hello World", "size": 300, "foreground": "#1a365d", "background": "#f7fafc"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/qrcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Remarques {#notes} * Ce point de terminaison accepte du JSON, pas des données de formulaire multipart, puisque aucun envoi d'image n'est nécessaire. * La sortie est toujours une image PNG. * Le nom du fichier de sortie est toujours `qrcode.png`. * `originalSize` vaut toujours 0 puisque cet outil génère des images à partir de rien. * Une zone de silence (marge) de 2 modules est incluse autour du QR code. * La longueur maximale du texte est de 2000 caractères. La capacité réelle dépend du niveau de correction d'erreur et de l'encodage des caractères. * Des niveaux de correction d'erreur plus élevés permettent au QR code de rester scannable même partiellement masqué, mais réduisent la capacité de données. * Lorsqu'un `logoDataUri` est fourni, la correction d'erreur est automatiquement forcée à `H` (30 %) pour que le QR code reste scannable malgré le logo qui occulte le centre. --- --- url: https://docs.snapotter.com/id/tools/image/barcode-generate.md description: >- Hasilkan barcode dalam format Code 128, EAN-13, UPC-A, Code 39, ITF-14, dan Data Matrix. --- # Generator Barcode {#barcode-generator} Hasilkan gambar barcode dari input teks. Mendukung format Code 128, EAN-13, UPC-A, Code 39, ITF-14, dan Data Matrix. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Menerima body `application/json` (bukan multipart). Barcode dihasilkan dari teks yang diberikan, bukan dari berkas yang diunggah. ## Parameter {#parameters} | Parameter | Tipe | Wajib | Bawaan | Deskripsi | |-----------|------|----------|---------|-------------| | text | string | Ya | - | Teks untuk dienkode dalam barcode (1-256 karakter) | | type | string | Tidak | `"code128"` | Format barcode: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | Tidak | `3` | Faktor skala gambar (1-8) | | includeText | boolean | Tidak | `true` | Apakah akan merender teks di bawah barcode | ## Contoh Permintaan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Contoh Respons {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Catatan {#notes} * Berbeda dari kebanyakan alat, endpoint ini menerima body JSON, bukan data formulir multipart, karena barcode dihasilkan dari teks alih-alih berkas yang diunggah. * EAN-13 memerlukan tepat 12 atau 13 digit. UPC-A memerlukan tepat 11 atau 12 digit. Jika digit cek dihilangkan, digit tersebut dihitung secara otomatis. * Code 128 adalah format paling fleksibel dan mendukung seluruh set karakter ASCII. * Data Matrix menghasilkan barcode 2D yang cocok untuk mengenkode string yang lebih panjang dalam persegi yang kompak. --- --- url: https://docs.snapotter.com/pl/tools/image/favicon.md description: >- Generuj wszystkie standardowe rozmiary ikon favicon i ikon aplikacji z obrazu źródłowego. --- # Generator favicon {#favicon-generator} Wygeneruj kompletny zestaw plików favicon i ikon aplikacji z obrazu źródłowego. Tworzy wszystkie standardowe rozmiary potrzebne przeglądarkom, urządzeniom Apple i Android, wraz z manifestem web oraz fragmentem HTML. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/favicon` Przyjmuje dane formularza multipart z jednym lub większą liczbą plików obrazów oraz opcjonalnym polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | background | string | Nie | - | Kolor tła w formacie hex (np. `"#ffffff"`). Gdy ustawiony, ikona jest spłaszczana na tym kolorze. | | padding | integer | Nie | `0` | Procent odstępu wokół zawartości ikony (0 do 40) | | radius | integer | Nie | `0` | Procent promienia zaokrąglenia narożników dla zaokrąglonych ikon (0 do 50) | | sizes | integer\[] | Nie | - | Ogranicz wynik do konkretnych rozmiarów w pikselach (np. `[16, 32, 180]`). Pomiń, aby wygenerować wszystkie standardowe rozmiary. | | themeColor | string | Nie | `"#ffffff"` | Kolor motywu w formacie hex dla manifestu web | ## Generowane pliki {#generated-files} Dla każdego obrazu wejściowego tworzone są następujące pliki: | Plik | Rozmiar | Przeznaczenie | |------|------|---------| | `favicon-16x16.png` | 16x16 | Ikona karty przeglądarki | | `favicon-32x32.png` | 32x32 | Ikona karty przeglądarki (HiDPI) | | `favicon-48x48.png` | 48x48 | Skrót na pulpicie | | `apple-touch-icon.png` | 180x180 | Ekran główny iOS | | `android-chrome-192x192.png` | 192x192 | Ekran główny Android | | `android-chrome-512x512.png` | 512x512 | Ekran powitalny Android | | `favicon.ico` | 32x32 | Starszy format ICO | | `manifest.json` | - | Manifest aplikacji web z odwołaniami do ikon | | `favicon-snippet.html` | - | Gotowe do użycia znaczniki link HTML | ## Przykładowe żądanie {#example-request} Pojedynczy obraz źródłowy z zaokrąglonymi narożnikami i odstępem: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Wiele obrazów źródłowych (każdy otrzymuje własny zestaw w podfolderze): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Przykładowa odpowiedź {#example-response} Odpowiedzią jest plik ZIP przesyłany strumieniowo bezpośrednio. Nagłówki odpowiedzi to: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Dołączony fragment HTML {#html-snippet-included} Plik ZIP zawiera plik `favicon-snippet.html`, który możesz wkleić do swojego HTML ``: ```html ``` ## Uwagi {#notes} * Obrazy źródłowe są skalowane w trybie dopasowania `cover`, co oznacza, że są przycinane, aby wypełnić każdy kwadratowy rozmiar. Dla najlepszych rezultatów użyj kwadratowego obrazu źródłowego. * Gdy przesłanych jest wiele plików, każdy otrzymuje własny podfolder w pliku ZIP (nazwany według pliku źródłowego). * W przypadku przesłania pojedynczego pliku wszystkie wyniki znajdują się w katalogu głównym pliku ZIP bez podfolderu. * Pliki, które nie przejdą walidacji lub dekodowania, są pomijane, a do pliku ZIP dołączany jest `skipped-files.txt` wyjaśniający problemy. * Obsługiwane formaty wejściowe: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD i inne. * Orientacja EXIF jest automatycznie stosowana przed skalowaniem. --- --- url: https://docs.snapotter.com/pl/tools/image/barcode-generate.md description: >- Generuj kody kreskowe w formatach Code 128, EAN-13, UPC-A, Code 39, ITF-14 i Data Matrix. --- # Generator kodów kreskowych {#barcode-generator} Generuj obrazy kodów kreskowych z wprowadzonego tekstu. Obsługuje formaty Code 128, EAN-13, UPC-A, Code 39, ITF-14 i Data Matrix. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Przyjmuje treść `application/json` (nie multipart). Kod kreskowy jest generowany z podanego tekstu, a nie z przesłanego pliku. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | text | string | Tak | - | Tekst do zakodowania w kodzie kreskowym (1-256 znaków) | | type | string | Nie | `"code128"` | Format kodu kreskowego: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | Nie | `3` | Współczynnik skali obrazu (1-8) | | includeText | boolean | Nie | `true` | Czy renderować tekst pod kodem kreskowym | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Uwagi {#notes} * W przeciwieństwie do większości narzędzi ten punkt końcowy przyjmuje treść JSON, a nie dane formularza multipart, ponieważ kody kreskowe są generowane z tekstu, a nie z przesłanego pliku. * EAN-13 wymaga dokładnie 12 lub 13 cyfr. UPC-A wymaga dokładnie 11 lub 12 cyfr. Jeśli cyfra kontrolna zostanie pominięta, jest obliczana automatycznie. * Code 128 jest najbardziej elastycznym formatem i obsługuje pełny zestaw znaków ASCII. * Data Matrix tworzy dwuwymiarowy kod kreskowy odpowiedni do kodowania dłuższych ciągów w zwartym kwadracie. --- --- url: https://docs.snapotter.com/pl/tools/image/qr-generate.md description: Generuj kody QR z niestandardowymi kolorami i poziomami korekcji błędów. --- # Generator kodów QR {#qr-code-generator} Generuj obrazy kodów QR z tekstu lub adresów URL z konfigurowalnym rozmiarem, poziomem korekcji błędów oraz niestandardowymi kolorami pierwszego planu i tła. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/qr-generate` Przyjmuje **treść JSON** (nie multipart). Nie jest potrzebne przesyłanie pliku. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | text | string | Tak | - | Treść do zakodowania w kodzie QR (od 1 do 2000 znaków) | | size | number | Nie | `400` | Szerokość/wysokość obrazu wynikowego w pikselach (100 do 10000) | | errorCorrection | string | Nie | `"M"` | Poziom korekcji błędów: `L` (7%), `M` (15%), `Q` (25%), `H` (30%) | | foreground | string | Nie | `"#000000"` | Kolor pierwszego planu/modułów kodu QR w hex (`#RRGGBB`) | | background | string | Nie | `"#FFFFFF"` | Kolor tła kodu QR w hex (`#RRGGBB`) | | logoDataUri | string | Nie | - | Obraz logo jako data URI (`data:image/png;base64,...` lub `data:image/jpeg;base64,...`, maks. 700 KB). Wyśrodkowany na kodzie QR na 22% jego rozmiaru. Wymusza korekcję błędów na `H` | ### Poziomy korekcji błędów {#error-correction-levels} | Poziom | Odzyskiwanie | Zastosowanie | |-------|----------|----------| | `L` | ~7% | Maksymalna gęstość danych | | `M` | ~15% | Zrównoważony (domyślny) | | `Q` | ~25% | Dobry dla kodów drukowanych | | `H` | ~30% | Najlepszy dla kodów z nakładką logo | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "https://snapotter.com", "size": 500, "errorCorrection": "H"}' ``` Kod QR z marką i niestandardowymi kolorami: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "Hello World", "size": 300, "foreground": "#1a365d", "background": "#f7fafc"}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/qrcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Uwagi {#notes} * Ten punkt końcowy przyjmuje JSON, a nie dane formularza multipart, ponieważ nie jest potrzebne przesyłanie obrazu. * Wynikiem jest zawsze obraz PNG. * Nazwa pliku wynikowego to zawsze `qrcode.png`. * `originalSize` zawsze wynosi 0, ponieważ to narzędzie generuje obrazy od zera. * Wokół kodu QR uwzględniana jest 2-modułowa strefa cichej (margines). * Maksymalna długość tekstu to 2000 znaków. Rzeczywista pojemność zależy od poziomu korekcji błędów i kodowania znaków. * Wyższe poziomy korekcji błędów pozwalają, by kod QR pozostał skanowalny nawet przy częściowym zasłonięciu, ale zmniejszają pojemność danych. * Gdy podano `logoDataUri`, korekcja błędów jest automatycznie wymuszana na `H` (30%), aby kod QR pozostał skanowalny mimo zasłonięcia środka przez logo. --- --- url: https://docs.snapotter.com/pl/tools/image/meme-generator.md description: >- Twórz memy z szablonów lub własnych obrazów, ze stylizowanymi polami tekstowymi i opcjami czcionek. --- # Generator memów {#meme-generator} Twórz memy przy użyciu wbudowanych szablonów lub własnych obrazów. Dodawaj tekst w klasycznej stylistyce memów (pogrubiony tekst z obrysem), z wieloma gotowymi układami i opcjami czcionek. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/meme-generator` Przyjmuje jedno z dwóch: * **Dane formularza multipart** z plikiem obrazu i polem JSON `settings` (tryb własnego obrazu) * **Treść JSON** z `templateId` (tryb szablonu, bez potrzeby przesyłania pliku) ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | templateId | string | Nie | - | ID wbudowanego szablonu memu. Jeśli podane, nie trzeba przesyłać obrazu | | textLayout | string | Nie | `"top-bottom"` | Układ pól tekstowych: `top-bottom`, `top-only`, `bottom-only`, `center`, `side-by-side` | | textBoxes | array | Nie | `[]` | Tablica obiektów pól tekstowych z polami `id` i `text` | | fontFamily | string | Nie | `"anton"` | Czcionka: `anton`, `arial-black`, `comic-sans`, `montserrat`, `bebas-neue`, `permanent-marker`, `roboto` | | fontSize | number | Nie | auto | Rozmiar czcionki w pikselach (8 do 200). Obliczany automatycznie, jeśli pominięty | | textColor | string | Nie | `"#ffffff"` | Kolor wypełnienia tekstu | | strokeColor | string | Nie | `"#000000"` | Kolor obrysu/konturu tekstu | | textAlign | string | Nie | `"center"` | Wyrównanie tekstu: `left`, `center`, `right` | | allCaps | boolean | Nie | `true` | Zamień tekst na wielkie litery | ### Pola tekstowe {#text-boxes} Każdy wpis w tablicy `textBoxes` powinien mieć: | Pole | Typ | Opis | |-------|------|-------------| | id | string | Identyfikator pola pasujący do układu (np. `"top"`, `"bottom"`, `"left"`, `"right"`, `"center"`) | | text | string | Tekst memu do wyświetlenia | ### Identyfikatory pól dla układów tekstu {#text-layout-box-ids} | Układ | Dostępne ID pól | |--------|-------------------| | `top-bottom` | `top`, `bottom` | | `top-only` | `top` | | `bottom-only` | `bottom` | | `center` | `center` | | `side-by-side` | `left`, `right` | ## Przykładowe żądanie {#example-request} Własny obraz z tekstem u góry i u dołu: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"textLayout": "top-bottom", "textBoxes": [{"id": "top", "text": "When the code works"}, {"id": "bottom", "text": "On the first try"}], "fontFamily": "anton", "allCaps": true}' ``` Z użyciem wbudowanego szablonu (treść JSON, bez przesyłania pliku): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"templateId": "drake", "textBoxes": [{"id": "top", "text": "Manual testing"}, {"id": "bottom", "text": "Automated tests"}]}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/meme-drake.png", "originalSize": 450000, "processedSize": 520000 } ``` ## Uwagi {#notes} * Wymagane jest podanie `templateId` albo przesłanego pliku obrazu. Podanie obu naraz spowoduje użycie szablonu. * Szablony definiują własne pozycje pól tekstowych; parametr `textLayout` jest ignorowany przy użyciu szablonów. * Tekst jest renderowany jako SVG z obrysem, aby uzyskać klasyczny wygląd memu. * Rozmiar czcionki jest obliczany automatycznie tak, aby zmieścić tekst w polu, jeśli nie został ustawiony jawnie. * Puste pola tekstowe są pomijane (renderowanie nie następuje, jeśli wszystkie pola są puste). * Nazwa pliku wynikowego zawiera ID szablonu przy jego użyciu (np. `meme-drake.png`). * Pliki wejściowe HEIC, RAW, PSD i SVG są automatycznie dekodowane przed przetwarzaniem. --- --- url: https://docs.snapotter.com/it/tools/image/barcode-generate.md description: >- Genera codici a barre nei formati Code 128, EAN-13, UPC-A, Code 39, ITF-14 e Data Matrix. --- # Generatore di codici a barre {#barcode-generator} Genera immagini di codici a barre da testo in input. Supporta i formati Code 128, EAN-13, UPC-A, Code 39, ITF-14 e Data Matrix. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Accetta un corpo `application/json` (non multipart). Il codice a barre viene generato dal testo fornito, non da un file caricato. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | text | string | Sì | - | Testo da codificare nel codice a barre (1-256 caratteri) | | type | string | No | `"code128"` | Formato del codice a barre: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | No | `3` | Fattore di scala dell'immagine (1-8) | | includeText | boolean | No | `true` | Se rendere il testo sotto il codice a barre | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Esempio di risposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Note {#notes} * A differenza della maggior parte degli strumenti, questo endpoint accetta un corpo JSON, non dati di form multipart, poiché i codici a barre vengono generati da testo anziché da un file caricato. * EAN-13 richiede esattamente 12 o 13 cifre. UPC-A richiede esattamente 11 o 12 cifre. Se una cifra di controllo viene omessa, viene calcolata automaticamente. * Code 128 è il formato più flessibile e supporta l'intero set di caratteri ASCII. * Data Matrix produce un codice a barre 2D adatto a codificare stringhe più lunghe in un quadrato compatto. --- --- url: https://docs.snapotter.com/it/tools/image/favicon.md description: >- Genera tutte le dimensioni standard di favicon e icone app da un'immagine sorgente. --- # Generatore di Favicon {#favicon-generator} Genera un set completo di file favicon e icone app da un'immagine sorgente. Produce tutte le dimensioni standard necessarie per browser, dispositivi Apple e Android, insieme a un web manifest e a uno snippet HTML. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/favicon` Accetta dati di form multipart con uno o più file immagine e un campo JSON `settings` opzionale. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | background | string | No | - | Colore di sfondo esadecimale (es. `"#ffffff"`). Quando impostato, l'icona viene appiattita su questo colore. | | padding | integer | No | `0` | Percentuale di padding attorno al contenuto dell'icona (da 0 a 40) | | radius | integer | No | `0` | Percentuale del raggio degli angoli per icone arrotondate (da 0 a 50) | | sizes | integer\[] | No | - | Limita l'output a dimensioni specifiche in pixel (es. `[16, 32, 180]`). Ometti per generare tutte le dimensioni standard. | | themeColor | string | No | `"#ffffff"` | Colore del tema esadecimale per il web manifest | ## File Generati {#generated-files} Per ogni immagine di input vengono prodotti i seguenti file: | File | Dimensione | Scopo | |------|------|---------| | `favicon-16x16.png` | 16x16 | Icona della scheda del browser | | `favicon-32x32.png` | 32x32 | Icona della scheda del browser (HiDPI) | | `favicon-48x48.png` | 48x48 | Scorciatoia desktop | | `apple-touch-icon.png` | 180x180 | Schermata home iOS | | `android-chrome-192x192.png` | 192x192 | Schermata home Android | | `android-chrome-512x512.png` | 512x512 | Schermata di avvio Android | | `favicon.ico` | 32x32 | Formato ICO legacy | | `manifest.json` | - | Web app manifest con riferimenti alle icone | | `favicon-snippet.html` | - | Tag link HTML pronti all'uso | ## Richiesta di Esempio {#example-request} Singola immagine sorgente con angoli arrotondati e padding: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Più immagini sorgente (ognuna ottiene il proprio set in una sottocartella): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Risposta di Esempio {#example-response} La risposta è un file ZIP trasmesso direttamente in streaming. Gli header della risposta sono: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Snippet HTML Incluso {#html-snippet-included} Lo ZIP include un file `favicon-snippet.html` che puoi incollare nell'`` del tuo HTML: ```html ``` ## Note {#notes} * Le immagini sorgente vengono ridimensionate usando la modalità di adattamento `cover`, il che significa che vengono ritagliate per riempire ogni dimensione quadrata. Per risultati ottimali, usa un'immagine sorgente quadrata. * Quando vengono caricati più file, ognuno ottiene la propria sottocartella nello ZIP (nominata in base al file sorgente). * Per il caricamento di un singolo file, tutti gli output si trovano nella radice dello ZIP senza sottocartella. * I file che non superano la validazione o la decodifica vengono saltati, e un `skipped-files.txt` viene incluso nello ZIP per spiegare i problemi. * Formati di input supportati: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD e altri. * L'orientamento EXIF viene applicato automaticamente prima del ridimensionamento. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/barcode-generate.md description: >- Gere códigos de barras nos formatos Code 128, EAN-13, UPC-A, Code 39, ITF-14 e Data Matrix. --- # Gerador de Código de Barras {#barcode-generator} Gere imagens de código de barras a partir de texto. Suporta os formatos Code 128, EAN-13, UPC-A, Code 39, ITF-14 e Data Matrix. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/barcode-generate` Aceita um corpo `application/json` (não multipart). O código de barras é gerado a partir do texto fornecido, não de um arquivo enviado. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | text | string | Sim | - | Texto a codificar no código de barras (1-256 caracteres) | | type | string | Não | `"code128"` | Formato do código de barras: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | | scale | integer | Não | `3` | Fator de escala da imagem (1-8) | | includeText | boolean | Não | `true` | Se o texto deve ser renderizado abaixo do código de barras | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/barcode-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Observações {#notes} * Diferente da maioria das ferramentas, este endpoint aceita um corpo JSON, não dados de formulário multipart, já que os códigos de barras são gerados a partir de texto e não de um arquivo enviado. * O EAN-13 requer exatamente 12 ou 13 dígitos. O UPC-A requer exatamente 11 ou 12 dígitos. Se um dígito verificador for omitido, ele é calculado automaticamente. * O Code 128 é o formato mais flexível e suporta todo o conjunto de caracteres ASCII. * O Data Matrix produz um código de barras 2D adequado para codificar strings mais longas em um quadrado compacto. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/favicon.md description: >- Gere todos os tamanhos padrão de favicon e ícones de aplicativo a partir de uma imagem de origem. --- # Gerador de Favicon {#favicon-generator} Gere um conjunto completo de arquivos de favicon e ícones de aplicativo a partir de uma imagem de origem. Produz todos os tamanhos padrão necessários para navegadores, dispositivos Apple e Android, junto com um manifesto web e um trecho de HTML. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/favicon` Aceita dados de formulário multipart com um ou mais arquivos de imagem e um campo JSON `settings` opcional. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | background | string | Não | - | Cor hexadecimal de fundo (ex.: `"#ffffff"`). Quando definida, o ícone é achatado sobre essa cor. | | padding | integer | Não | `0` | Percentual de preenchimento ao redor do conteúdo do ícone (0 a 40) | | radius | integer | Não | `0` | Percentual de raio de canto para ícones arredondados (0 a 50) | | sizes | integer\[] | Não | - | Restringe a saída a tamanhos específicos em pixels (ex.: `[16, 32, 180]`). Omita para gerar todos os tamanhos padrão. | | themeColor | string | Não | `"#ffffff"` | Cor de tema hexadecimal para o manifesto web | ## Arquivos Gerados {#generated-files} Para cada imagem de entrada, os seguintes arquivos são produzidos: | Arquivo | Tamanho | Finalidade | |------|------|---------| | `favicon-16x16.png` | 16x16 | Ícone da aba do navegador | | `favicon-32x32.png` | 32x32 | Ícone da aba do navegador (HiDPI) | | `favicon-48x48.png` | 48x48 | Atalho de desktop | | `apple-touch-icon.png` | 180x180 | Tela inicial do iOS | | `android-chrome-192x192.png` | 192x192 | Tela inicial do Android | | `android-chrome-512x512.png` | 512x512 | Tela de splash do Android | | `favicon.ico` | 32x32 | Formato ICO legado | | `manifest.json` | - | Manifesto de aplicativo web com referências de ícones | | `favicon-snippet.html` | - | Tags de link HTML prontas para uso | ## Exemplo de Requisição {#example-request} Imagem de origem única com cantos arredondados e preenchimento: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo.png" \ -F 'settings={"padding": 10, "radius": 20, "themeColor": "#0a0a0a"}' ``` Várias imagens de origem (cada uma recebe seu próprio conjunto em uma subpasta): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/favicon \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@logo-light.png" \ -F "file=@logo-dark.png" ``` ## Exemplo de Resposta {#example-response} A resposta é um arquivo ZIP transmitido diretamente. Os cabeçalhos da resposta são: ``` Content-Type: application/zip Content-Disposition: attachment; filename="favicons-a1b2c3d4.zip" ``` ## Trecho de HTML Incluído {#html-snippet-included} O ZIP inclui um arquivo `favicon-snippet.html` que você pode colar no `` do seu HTML: ```html ``` ## Observações {#notes} * As imagens de origem são redimensionadas usando o modo de ajuste `cover`, ou seja, são recortadas para preencher cada tamanho quadrado. Para melhores resultados, use uma imagem de origem quadrada. * Quando vários arquivos são enviados, cada um recebe sua própria subpasta no ZIP (nomeada de acordo com o arquivo de origem). * Para o envio de um único arquivo, todas as saídas ficam na raiz do ZIP sem subpasta. * Arquivos que falham na validação ou na decodificação são ignorados, e um `skipped-files.txt` é incluído no ZIP explicando os problemas. * Formatos de entrada suportados: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, SVG, RAW, PSD e outros. * A orientação EXIF é aplicada automaticamente antes do redimensionamento. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/meme-generator.md description: >- Crie memes com templates ou imagens personalizadas, caixas de texto estilizadas e opções de fonte. --- # Gerador de Memes {#meme-generator} Crie memes usando templates integrados ou imagens personalizadas. Adicione texto com o estilo clássico de meme (texto em negrito e contornado), vários presets de layout e opções de fonte. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/meme-generator` Aceita: * **Dados de formulário multipart** com um arquivo de imagem e um campo JSON `settings` (modo de imagem personalizada) * **Corpo JSON** com um `templateId` (modo de template, sem necessidade de upload de arquivo) ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | templateId | string | Não | - | ID do template de meme integrado. Se fornecido, não é necessário upload de imagem | | textLayout | string | Não | `"top-bottom"` | Layout da caixa de texto: `top-bottom`, `top-only`, `bottom-only`, `center`, `side-by-side` | | textBoxes | array | Não | `[]` | Array de objetos de caixa de texto com os campos `id` e `text` | | fontFamily | string | Não | `"anton"` | Fonte: `anton`, `arial-black`, `comic-sans`, `montserrat`, `bebas-neue`, `permanent-marker`, `roboto` | | fontSize | number | Não | auto | Tamanho da fonte em pixels (8 a 200). Calculado automaticamente se omitido | | textColor | string | Não | `"#ffffff"` | Cor de preenchimento do texto | | strokeColor | string | Não | `"#000000"` | Cor do traço/contorno do texto | | textAlign | string | Não | `"center"` | Alinhamento do texto: `left`, `center`, `right` | | allCaps | boolean | Não | `true` | Converter texto para maiúsculas | ### Caixas de Texto {#text-boxes} Cada entrada no array `textBoxes` deve ter: | Campo | Tipo | Descrição | |-------|------|-------------| | id | string | Identificador da caixa correspondente ao layout (por exemplo, `"top"`, `"bottom"`, `"left"`, `"right"`, `"center"`) | | text | string | O texto do meme a ser exibido | ### IDs das Caixas por Layout de Texto {#text-layout-box-ids} | Layout | IDs de Caixa Disponíveis | |--------|-------------------| | `top-bottom` | `top`, `bottom` | | `top-only` | `top` | | `bottom-only` | `bottom` | | `center` | `center` | | `side-by-side` | `left`, `right` | ## Exemplo de Requisição {#example-request} Imagem personalizada com texto superior e inferior: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"textLayout": "top-bottom", "textBoxes": [{"id": "top", "text": "When the code works"}, {"id": "bottom", "text": "On the first try"}], "fontFamily": "anton", "allCaps": true}' ``` Usando um template integrado (corpo JSON, sem upload de arquivo): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/meme-generator \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"templateId": "drake", "textBoxes": [{"id": "top", "text": "Manual testing"}, {"id": "bottom", "text": "Automated tests"}]}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/meme-drake.png", "originalSize": 450000, "processedSize": 520000 } ``` ## Notas {#notes} * É necessário fornecer `templateId` ou um arquivo de imagem enviado. Se ambos forem fornecidos, o template é usado. * Os templates definem suas próprias posições de caixa de texto; o parâmetro `textLayout` é ignorado ao usar templates. * O texto é renderizado como SVG com contornos de traço para o visual clássico de meme. * O tamanho da fonte é calculado automaticamente para caber na caixa de texto se não for definido explicitamente. * Caixas de texto vazias são ignoradas (nenhuma renderização ocorre se todas as caixas estiverem vazias). * O nome do arquivo de saída inclui o ID do template ao usar templates (por exemplo, `meme-drake.png`). * Entradas HEIC, RAW, PSD e SVG são decodificadas automaticamente antes do processamento. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/qr-generate.md description: Gere QR codes com cores personalizadas e níveis de correção de erros. --- # Gerador de QR Code {#qr-code-generator} Gere imagens de QR code a partir de texto ou URLs com tamanho configurável, nível de correção de erros e cores personalizadas de primeiro plano/fundo. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/qr-generate` Aceita um **corpo JSON** (não multipart). Nenhum upload de arquivo é necessário. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | text | string | Sim | - | Conteúdo a codificar no QR code (1 a 2000 caracteres) | | size | number | Não | `400` | Largura/altura da imagem de saída em pixels (100 a 10000) | | errorCorrection | string | Não | `"M"` | Nível de correção de erros: `L` (7%), `M` (15%), `Q` (25%), `H` (30%) | | foreground | string | Não | `"#000000"` | Cor de primeiro plano/módulo do QR code em hexadecimal (`#RRGGBB`) | | background | string | Não | `"#FFFFFF"` | Cor de fundo do QR code em hexadecimal (`#RRGGBB`) | | logoDataUri | string | Não | - | Imagem do logo como um data URI (`data:image/png;base64,...` ou `data:image/jpeg;base64,...`, máximo de 700 KB). Centralizado no QR code a 22% do tamanho do QR. Força a correção de erros para `H` | ### Níveis de Correção de Erros {#error-correction-levels} | Nível | Recuperação | Caso de Uso | |-------|----------|----------| | `L` | ~7% | Densidade máxima de dados | | `M` | ~15% | Equilibrado (padrão) | | `Q` | ~25% | Bom para códigos impressos | | `H` | ~30% | Melhor para códigos com logos sobrepostos | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "https://snapotter.com", "size": 500, "errorCorrection": "H"}' ``` QR code com marca e cores personalizadas: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/qr-generate \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"text": "Hello World", "size": 300, "foreground": "#1a365d", "background": "#f7fafc"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/qrcode.png", "originalSize": 0, "processedSize": 4520 } ``` ## Notas {#notes} * Este endpoint aceita JSON, e não dados de formulário multipart, pois nenhum upload de imagem é necessário. * A saída é sempre uma imagem PNG. * O nome do arquivo de saída é sempre `qrcode.png`. * `originalSize` é sempre 0, já que esta ferramenta gera imagens do zero. * Uma zona de silêncio (margem) de 2 módulos é incluída ao redor do QR code. * O comprimento máximo do texto é 2000 caracteres. A capacidade real depende do nível de correção de erros e da codificação de caracteres. * Níveis mais altos de correção de erros permitem que o QR code permaneça legível mesmo se parcialmente obscurecido, mas reduzem a capacidade de dados. * Quando um `logoDataUri` é fornecido, a correção de erros é forçada automaticamente para `H` (30%), de modo que o QR code permaneça legível apesar do logo ocultar o centro. --- --- url: https://docs.snapotter.com/de/tools/image/blur-faces.md description: >- Gesichter in Bildern per KI-Gesichtserkennung automatisch erkennen und weichzeichnen, für Datenschutz und DSGVO-konforme Anonymisierung. --- # Gesichter & PII weichzeichnen {#face-pii-blur} Erkennt und zeichnet Gesichter in Bildern automatisch mithilfe KI-gestützter Gesichtserkennung (MediaPipe) weich. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Verarbeitung:** Asynchron (gibt 202 zurück, `/api/v1/jobs/{jobId}/progress` per SSE nach dem Status abfragen) **Modellpaket:** `face-detection` (200-300 MB) ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bilddatei (multipart) | | blurRadius | number | Nein | `30` | Auf erkannte Gesichter angewendeter Weichzeichnungsradius (1-100) | | sensitivity | number | Nein | `0.5` | Empfindlichkeit der Gesichtserkennung (0-1). Niedrigere Werte erkennen weniger Gesichter mit höherer Zuversicht | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Antwort {#response} ### Erste Antwort (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Fortschritt (SSE unter `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Endergebnis (per SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### Keine Gesichter erkannt {#no-faces-detected} Werden keine Gesichter gefunden, enthält das Ergebnis eine Warnung: ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Hinweise {#notes} * Erfordert die Installation des Modellpakets `face-detection` (200-300 MB). * Das Ausgabeformat entspricht automatisch dem Eingabeformat. * Das Array `faces` enthält die Koordinaten des Begrenzungsrahmens (x, y, width, height) für jedes erkannte Gesicht. * Erhöhen Sie `sensitivity` (näher an 1.0), um mehr Gesichter zu erkennen, einschließlich teilweise verdeckter. * Unterstützt die Eingabeformate HEIC/HEIF, RAW, TGA, PSD, EXR und HDR über automatische Dekodierung. --- --- url: https://docs.snapotter.com/de/tools/image/enhance-faces.md description: >- Stellt unscharfe oder minderwertige Gesichter in Bildern mit den KI-Modellen GFPGAN und CodeFormer wieder her und schärft sie nach. --- # Gesichtsverbesserung {#face-enhancement} Stellt Gesichter in Bildern mit KI-Modellen (GFPGAN/CodeFormer) wieder her und verbessert sie. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Verarbeitung:** Asynchron (gibt 202 zurück, Status per SSE über `/api/v1/jobs/{jobId}/progress` abfragen) **Modell-Bundles:** `upscale-enhance` (5-6 GB) und `face-detection` (200-300 MB) ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bilddatei (Multipart) | | model | string | Nein | `"auto"` | Zu verwendendes Modell: `auto`, `gfpgan`, `codeformer` | | strength | number | Nein | `0.8` | Verbesserungsstärke (0-1). Höhere Werte erzeugen eine stärkere Verbesserung | | onlyCenterFace | boolean | Nein | `false` | Nur das zentralste/auffälligste Gesicht verbessern | | sensitivity | number | Nein | `0.5` | Empfindlichkeit der Gesichtserkennung (0-1) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Antwort {#response} ### Erste Antwort (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Fortschritt (SSE unter `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Endergebnis (per SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Hinweise {#notes} * Erfordert sowohl das Modell-Bundle `upscale-enhance` (5-6 GB) als auch das Modell-Bundle `face-detection` (200-300 MB). * GFPGAN erzeugt eine aggressivere Verbesserung; CodeFormer bewahrt die Identität besser. `auto` wählt das für die Eingabe beste Modell aus. * Die Ausgabe ist für maximale Qualität immer im PNG-Format. * Neben der Ausgabe in voller Auflösung wird für eine schnellere Anzeige im Frontend eine WebP-Vorschau erzeugt. * Der Parameter `strength` mischt das verbesserte Gesicht mit dem Original. Verwenden Sie niedrigere Werte (0.3-0.5) für dezente Verbesserungen, höhere Werte (0.7-1.0) für eine stärkere Wiederherstellung. * Unterstützt die Eingabeformate HEIC/HEIF, RAW, TGA, PSD, EXR und HDR durch automatische Dekodierung. --- --- url: https://docs.snapotter.com/hi/guide/getting-started.md description: >- SnapOtter को एक ही कमांड में Docker के साथ इंस्टॉल करें। इसमें Docker Compose सेटअप, सोर्स से बिल्ड करना, और एक पूर्ण फ़ीचर अवलोकन शामिल है। --- # Getting Started {#getting-started} ::: tip इंस्टॉल करने से पहले आज़माएँ [demo.snapotter.com](https://demo.snapotter.com) पर पूरा UI एक्सप्लोर करें, कोई साइनअप या इंस्टॉल आवश्यक नहीं। ::: ## Quick Start {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` यह एकल कंटेनर वह सब कुछ चलाता है जिसकी उसे आवश्यकता होती है: बिना किसी `DATABASE_URL` सेट के, यह लूपबैक इंटरफ़ेस (एम्बेडेड मोड) पर अपना स्वयं का PostgreSQL और Redis शुरू करता है और सभी डेटा को `SnapOtter-data` वॉल्यूम में रखता है। यह होमलैब पर SnapOtter या सेल्फ-होस्ट आज़माने का सबसे तेज़ तरीका है। उत्पादन के लिए, [कैनोनिकल डॉकर कंपोज़ स्टैक](#docker-compose) का उपयोग करें, जो PostgreSQL और Redis को अपने कंटेनर में रखता है। एंबेडेड मोड रूट (डिफ़ॉल्ट) के रूप में चलता है और जैसे ही आप `DATABASE_URL` सेट करते हैं तो स्वचालित रूप से बंद हो जाता है। Raspberry Pi, किसी पुराने लैपटॉप, या छोटे VPS पर इंस्टॉल कर रहे हैं? ट्यून की गई वॉकथ्रू और सीमित हार्डवेयर से क्या अपेक्षा करें, इसके लिए [कम संसाधन वाले सेटअप](/hi/guide/low-resource) देखें। पहले लॉगिन पर आपसे अपना पासवर्ड बदलने को कहा जाएगा। ::: tip अनाम उत्पाद एनालिटिक्स SnapOtter में डिफ़ॉल्ट रूप से अनाम उत्पाद एनालिटिक्स शामिल है। इसे बंद करने के लिए, **Settings → System → Privacy** खोलें और **Anonymous Product Analytics** को बंद कर दें। यह पूरे इंस्टेंस के लिए तुरंत रुक जाता है। आप किसी रीबिल्ड के बिना इंस्टेंस के लिए सभी टेलीमेट्री अक्षम करने के लिए एनवायरनमेंट वेरिएबल `SNAPOTTER_TELEMETRY=0` भी सेट कर सकते हैं (`false` और `off` भी काम करते हैं)। त्रुटि मॉनिटरिंग [Sentry](https://sentry.io) द्वारा संचालित है, जो अपने ओपन-सोर्स प्रोग्राम के माध्यम से SnapOtter को प्रायोजित करता है। क्या संग्रहीत किया जाता है इसके विवरण के लिए, [SnapOtter क्या संग्रहीत करता है](/hi/guide/telemetry) देखें। ::: ::: tip NVIDIA CUDA त्वरण NVIDIA CUDA-त्वरित पृष्ठभूमि हटाने, अपस्केलिंग, चेहरा निखारने और बहाली के लिए `--gpus all` जोड़ें। OCR सीपीयू-आधारित रहता है और GPU एक्सेस के साथ या उसके बिना एक ही छवि में काम करता है: ```bash docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest ``` [NVIDIA कंटेनर टूलकिट](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) की आवश्यकता है। CUDA अनुपलब्ध होने पर स्वचालित रूप से CPU पर वापस आ जाता है। वीए-एपीआई, क्विक सिंक या ओपनसीएल के माध्यम से इंटेल/एएमडी आईजीपीयू त्वरण आज एआई अनुमान के लिए समर्थित नहीं है। बेंचमार्क के लिए [डॉकर टैग](/hi/guide/docker-tags) देखें। यदि `--gpus all` के बावजूद AI उपकरण CPU पर चलते हैं, तो [GPU त्वरण सत्यापित करें](/hi/guide/deployment#verify-gpu-acceleration) देखें। ::: ::: details GHCR पर भी ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snapotter-hq/snapotter:latest ``` दोनों रजिस्ट्री हर रिलीज़ पर वही इमेज प्रकाशित करती हैं। ::: ## डॉकर कंपोज़ {#docker-compose} इस पृष्ठ से संक्षिप्त कंपोज़ उदाहरण की प्रतिलिपि बनाने के बजाय प्रत्येक रिलीज़ के साथ बनाए और परीक्षण की गई उत्पादन फ़ाइल का उपयोग करें: ```bash install -d -m 700 snapotter && cd snapotter curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \ https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.2.0/docker/docker-compose.yml # Keep generated service credentials out of shell history and world-readable files. umask 077 POSTGRES_PASSWORD="$(openssl rand -hex 32)" REDIS_PASSWORD="$(openssl rand -hex 32)" printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \ "$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --no-build ``` कैनोनिकल [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.2.0/docker/docker-compose.yml) में सभी चार रनटाइम वॉल्यूम, स्वास्थ्य जांच, संसाधन सीमाएं, टिकाऊ रेडिस कॉन्फ़िगरेशन, पिन किए गए डेटाबेस/कैश छवियां और वर्तमान कंटेनर हार्डनिंग शामिल हैं। प्रथम लॉगिन के तुरंत बाद डिफ़ॉल्ट एडमिन पासवर्ड बदलें। प्रतिलिपि प्रस्तुत करने योग्य परिनियोजन के लिए, `latest` का अनुसरण करने के बजाय SnapOtter एप्लिकेशन छवि को रिलीज़ टैग पर पिन करें या आपके द्वारा सत्यापित डाइजेस्ट करें। सभी पर्यावरण चर के लिए [कॉन्फ़िगरेशन](/hi/guide/configuration) और रहस्यों, नेटवर्क नीति और बैकअप मार्गदर्शन के लिए [सुरक्षा और हार्डनिंग](/hi/guide/security) देखें। ## Build from Source {#build-from-source} **पूर्वापेक्षाएँ:** Node.js 22.22+, pnpm 9+, Docker (Postgres + Redis के लिए), Python 3.11+ (AI फ़ीचर के लिए), Git। ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` * फ़्रंटएंड: * बैकएंड: ## What You Can Do {#what-you-can-do} ### File Processing (200+ Tools) {#file-processing-200-tools} | मोडैलिटी | संख्या | उदाहरण टूल | |----------|-------|---------------| | **Image** | 107 | Resize, Crop, Compress, Convert, Remove Background, Upscale, OCR, Watermark, Collage, Colorize, GIF Tools, format presets | | **Video** | 57 | Trim, Crop, Compress, Convert, Merge, Extract Audio, Auto Subtitles, Video to GIF, Resize, Stabilize, format presets | | **Audio** | 27 | Trim, Merge, Convert, Normalize, Noise Reduction, Transcribe, Pitch Shift, Fade, Ringtone Maker, format presets | | **PDF / Document** | 29 | Merge, Split, Compress, OCR, Watermark, Redact, Word to PDF, Excel to PDF, Rotate, Protect, Repair | | **Files** | 23 | CSV to JSON, JSON to XML, Merge CSVs, Split CSV, Create ZIP, Extract ZIP, Chart Maker, YAML/JSON | ### Pipelines {#pipelines} टूलों को बहु-चरणीय वर्कफ़्लो में जोड़ें और उन्हें एक इमेज या पूरे बैच पर लागू करें: 1. साइडबार में **Pipelines** खोलें। 2. चरण जोड़ें (कोई भी टूल, कोई भी सेटिंग)। 3. एक अकेली फ़ाइल पर चलाएँ, या एक साथ पूरे बैच पर। 4. बाद में पुनः उपयोग के लिए पाइपलाइन सहेजें। पाइपलाइन डिफ़ॉल्ट रूप से 20 चरणों की अनुमति देती हैं। सीमा को असीमित करने के लिए `MAX_PIPELINE_STEPS=0` सेट करें। ### File Library {#file-library} आप जो भी फ़ाइल प्रोसेस करते हैं उसे अपनी **Files** लाइब्रेरी में सहेजा जा सकता है। SnapOtter पूरा वर्शन इतिहास ट्रैक करता है ताकि आप मूल अपलोड से अंतिम आउटपुट तक हर प्रोसेसिंग चरण का पता लगा सकें। सहेजना स्पष्ट है: लाइब्रेरी में सहेजे गए परिणाम तब तक रखे जाते हैं जब तक आप उन्हें हटा नहीं देते, जबकि आप जिन परिणामों को प्रोसेस करते हैं और असहेजे छोड़ देते हैं वे 72 घंटे बाद स्वचालित रूप से साफ़ कर दिए जाते हैं (`FILE_MAX_AGE_HOURS` के माध्यम से कॉन्फ़िगर करने योग्य)। ### REST API & API Keys {#rest-api-api-keys} हर टूल HTTP के माध्यम से सुलभ है: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800,"height":600,"fit":"cover"}' ``` **Settings → API Keys** के अंतर्गत API कुंजियाँ उत्पन्न करें। सभी एंडपॉइंट के लिए [REST API reference](/hi/api/rest) देखें, या इंटरैक्टिव संदर्भ के लिए पर जाएँ। ### Multi-User & Teams {#multi-user-teams} रोल-आधारित एक्सेस नियंत्रण के साथ अनेक उपयोगकर्ता सक्षम करें: * **Admin**: पूर्ण एक्सेस, उपयोगकर्ता, टीम, सेटिंग्स, सभी फ़ाइलें/पाइपलाइन/API कुंजियाँ प्रबंधित करें * **User**: टूल उपयोग करें, अपनी फ़ाइलें/पाइपलाइन/API कुंजियाँ प्रबंधित करें उपयोगकर्ताओं को समूहित करने के लिए **Settings → Teams** के अंतर्गत टीम बनाएँ। `AUTH_ENABLED=true` सेट करें (या बिना लॉगिन के एकल-उपयोगकर्ता/स्व-उपयोग के लिए `false`)। ## अपने फ़ोन से इस्तेमाल करें {#use-it-from-your-phone} SnapOtter मोबाइल ब्राउज़र में चलता है, और आप इसे ऐप की तरह इंस्टॉल कर सकते हैं। फ़ोन पर अपना इंस्टेंस खोलें, फिर: * **iPhone / iPad (Safari)**: शेयर बटन पर टैप करें, फिर **होम स्क्रीन में जोड़ें** पर टैप करें। * **Android (Chrome)**: ब्राउज़र मेनू खोलें और **ऐप इंस्टॉल करें** पर टैप करें। इंस्टॉल किया गया ऐप अपनी अलग विंडो में खुलता है, सीधे आपके इंस्टेंस पर। एक बात ध्यान रखें: ब्राउज़र इंस्टॉल का विकल्प केवल HTTPS पर ही दिखाते हैं। आपके LAN पर सादा HTTP पता ब्राउज़र टैब में ठीक चलता है; असली इंस्टॉल के लिए इंस्टेंस को सर्टिफ़िकेट वाले रिवर्स प्रॉक्सी के पीछे रखें ([डिप्लॉयमेंट गाइड](/hi/guide/deployment) देखें)। फ़ोन और टैबलेट पर, इमेज टूल अपलोड बटन के बगल में **फ़ोटो लें** बटन दिखाते हैं। कोई रसीद या व्हाइटबोर्ड की फ़ोटो खींचें, और वह सीधे टूल में पहुँच जाती है। --- --- url: https://docs.snapotter.com/th/guide/getting-started.md description: >- ติดตั้ง SnapOtter ด้วย Docker ในคำสั่งเดียว รวมถึงการตั้งค่า Docker Compose การ build จากซอร์ส และภาพรวมฟีเจอร์ทั้งหมด --- # Getting Started {#getting-started} ::: tip ลองก่อนติดตั้ง สำรวจ UI แบบเต็มที่ [demo.snapotter.com](https://demo.snapotter.com) โดยไม่ต้องสมัครหรือติดตั้ง ::: ## Quick Start {#quick-start} ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest ``` คอนเทนเนอร์เดียวนี้รันทุกสิ่งที่ต้องการ: โดยไม่ต้องตั้งค่า `DATABASE_URL` คอนเทนเนอร์จะเริ่มต้น PostgreSQL และ Redis ของตัวเองบนอินเทอร์เฟซแบบย้อนกลับ (โหมดฝังตัว) และเก็บข้อมูลทั้งหมดไว้ในโวลุ่ม `SnapOtter-data` นี่เป็นวิธีที่เร็วที่สุดในการลองใช้ SnapOtter หรือโฮสต์เองบนโฮมแล็บ สำหรับการใช้งานจริง ให้ใช้ [canonical Docker Compose stack](#docker-compose) ซึ่งจะเก็บ PostgreSQL และ Redis ไว้ในคอนเทนเนอร์ของตัวเอง โหมดฝังตัวจะทำงานในฐานะรูท (ค่าเริ่มต้น) และปิดโดยอัตโนมัติทันทีที่คุณตั้งค่า `DATABASE_URL` หากกำลังติดตั้งบน Raspberry Pi แล็ปท็อปเครื่องเก่า หรือ VPS ขนาดเล็ก ดู [Low-Resource Setups](/th/guide/low-resource) สำหรับคู่มือทีละขั้นที่ปรับจูนมาแล้ว และสิ่งที่ควรคาดหวังจากฮาร์ดแวร์ที่จำกัด คุณจะถูกขอให้เปลี่ยนรหัสผ่านตอนล็อกอินครั้งแรก ::: tip การวิเคราะห์ผลิตภัณฑ์แบบไม่ระบุตัวตน SnapOtter มีการวิเคราะห์ผลิตภัณฑ์แบบไม่ระบุตัวตนโดยค่าเริ่มต้น หากต้องการปิด ให้เปิด **Settings → System → Privacy** แล้วปิด **Anonymous Product Analytics** มันจะหยุดทันทีสำหรับทั้งอินสแตนซ์ คุณยังสามารถตั้งค่าตัวแปรสภาพแวดล้อม `SNAPOTTER_TELEMETRY=0` (`false` และ `off` ก็ใช้ได้) เพื่อปิด telemetry ทั้งหมดสำหรับอินสแตนซ์โดยไม่ต้อง build ใหม่ การตรวจสอบข้อผิดพลาดขับเคลื่อนโดย [Sentry](https://sentry.io) ซึ่งสนับสนุน SnapOtter ผ่านโปรแกรมโอเพนซอร์สของตน สำหรับรายละเอียดเกี่ยวกับสิ่งที่ถูกเก็บ ดู [สิ่งที่ SnapOtter เก็บ](/th/guide/telemetry) ::: ::: tip การเร่งความเร็วด้วย NVIDIA CUDA เพิ่ม `--gpus all` สำหรับการลบพื้นหลังที่เร่งด้วย NVIDIA CUDA การลดขนาด การปรับปรุงใบหน้า และการฟื้นฟู OCR ยังคงใช้ CPU และทำงานในอิมเมจเดียวกันโดยมีหรือไม่มีการเข้าถึง GPU: ```bash docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest ``` ต้องใช้ [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) ถอยกลับไปที่ CPU โดยอัตโนมัติเมื่อ CUDA ไม่พร้อมใช้งาน การเร่งความเร็ว Intel/AMD iGPU ผ่าน VA-API, Quick Sync หรือ OpenCL ไม่รองรับการอนุมาน AI ในปัจจุบัน ดู [แท็กนักเทียบท่า](/th/guide/docker-tags) สำหรับการวัดประสิทธิภาพ หากเครื่องมือ AI ทำงานบน CPU แม้ว่าจะเป็น `--gpus all` โปรดดู [ตรวจสอบการเร่งความเร็ว GPU](/th/guide/deployment#verify-gpu-acceleration) ::: ::: details มีบน GHCR ด้วย ```bash docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snapotter-hq/snapotter:latest ``` ทั้งสอง registry เผยแพร่อิมเมจเดียวกันในทุกรีลีส ::: ## นักเทียบท่าเขียน {#docker-compose} ใช้ไฟล์ที่ใช้งานจริงที่ได้รับการดูแลและทดสอบกับแต่ละรีลีส แทนที่จะคัดลอกตัวอย่างการเขียนแบบย่อจากหน้านี้: ```bash install -d -m 700 snapotter && cd snapotter curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \ https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.2.0/docker/docker-compose.yml # Keep generated service credentials out of shell history and world-readable files. umask 077 POSTGRES_PASSWORD="$(openssl rand -hex 32)" REDIS_PASSWORD="$(openssl rand -hex 32)" printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \ "$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --no-build ``` Canonical [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.2.0/docker/docker-compose.yml) ประกอบด้วยรันไทม์วอลุ่มทั้งสี่ การตรวจสอบสภาพ ขีดจำกัดทรัพยากร การกำหนดค่า Redis ที่คงทน ฐานข้อมูล/อิมเมจแคชที่ปักหมุดไว้ และการทำให้คอนเทนเนอร์ปัจจุบันแข็งตัว เปลี่ยนรหัสผ่านผู้ดูแลระบบเริ่มต้นทันทีหลังจากเข้าสู่ระบบครั้งแรก สำหรับการปรับใช้ที่ทำซ้ำได้ ให้ปักหมุดอิมเมจแอปพลิเคชัน SnapOtter ไว้ที่แท็ก release หรือแยกย่อยที่คุณตรวจสอบแล้ว แทนที่จะติดตาม `latest` ดู [การกำหนดค่า](/th/guide/configuration) สำหรับตัวแปรสภาพแวดล้อมทั้งหมด และ [ความปลอดภัยและการป้องกัน](/th/guide/security) สำหรับความลับ นโยบายเครือข่าย และคำแนะนำในการสำรองข้อมูล ## Build from Source {#build-from-source} **ข้อกำหนดเบื้องต้น:** Node.js 22.22+, pnpm 9+, Docker (สำหรับ Postgres + Redis), Python 3.11+ (สำหรับฟีเจอร์ AI), Git ```bash git clone https://github.com/snapotter-hq/SnapOtter.git cd SnapOtter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` * Frontend: * Backend: ## What You Can Do {#what-you-can-do} ### File Processing (200+ Tools) {#file-processing-200-tools} | โมดัลลิตี | จำนวน | เครื่องมือตัวอย่าง | |----------|-------|---------------| | **รูปภาพ** | 107 | ปรับขนาด, ครอป, บีบอัด, แปลง, ลบพื้นหลัง, ขยายภาพ, OCR, ลายน้ำ, คอลลาจ, ลงสี, เครื่องมือ GIF, พรีเซ็ตรูปแบบ | | **วิดีโอ** | 57 | ตัด, ครอป, บีบอัด, แปลง, รวม, แยกเสียง, คำบรรยายอัตโนมัติ, วิดีโอเป็น GIF, ปรับขนาด, ทำให้ภาพนิ่ง, พรีเซ็ตรูปแบบ | | **เสียง** | 27 | ตัด, รวม, แปลง, นอร์มัลไลซ์, ลดสัญญาณรบกวน, ถอดเสียง, ปรับระดับเสียง, เฟด, สร้างริงโทน, พรีเซ็ตรูปแบบ | | **PDF / เอกสาร** | 29 | รวม, แยก, บีบอัด, OCR, ลายน้ำ, ปกปิดข้อมูล, Word เป็น PDF, Excel เป็น PDF, หมุน, ป้องกัน, ซ่อมแซม | | **ไฟล์** | 23 | CSV เป็น JSON, JSON เป็น XML, รวม CSV, แยก CSV, สร้าง ZIP, แตก ZIP, สร้างแผนภูมิ, YAML/JSON | ### Pipelines {#pipelines} ร้อยเครื่องมือเข้าเป็นเวิร์กโฟลว์หลายขั้นตอน แล้วนำไปใช้กับรูปภาพเดียวหรือทั้งชุด: 1. เปิด **Pipelines** ในแถบด้านข้าง 2. เพิ่มขั้นตอน (เครื่องมือใดก็ได้ การตั้งค่าใดก็ได้) 3. รันบนไฟล์เดียว หรือทั้งชุดในคราวเดียว 4. บันทึกไปป์ไลน์ไว้ใช้ซ้ำภายหลัง ไปป์ไลน์อนุญาต 20 ขั้นตอนโดยค่าเริ่มต้น ตั้งค่า `MAX_PIPELINE_STEPS=0` เพื่อทำให้ขีดจำกัดไม่จำกัด ### File Library {#file-library} ทุกไฟล์ที่คุณประมวลผลสามารถบันทึกไปยังไลบรารี **Files** ของคุณได้ SnapOtter ติดตามประวัติเวอร์ชันทั้งหมด เพื่อให้คุณย้อนรอยทุกขั้นตอนการประมวลผลตั้งแต่การอัปโหลดต้นฉบับจนถึงเอาต์พุตสุดท้าย การบันทึกเป็นการกระทำที่ชัดเจน: ผลลัพธ์ที่คุณบันทึกไปยังไลบรารีจะถูกเก็บไว้จนกว่าคุณจะลบ ในขณะที่ผลลัพธ์ที่คุณประมวลผลและปล่อยไว้โดยไม่บันทึกจะถูกล้างโดยอัตโนมัติหลังจาก 72 ชั่วโมง (กำหนดค่าได้ผ่าน `FILE_MAX_AGE_HOURS`) ### REST API & API Keys {#rest-api-api-keys} ทุกเครื่องมือเข้าถึงได้ผ่าน HTTP: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_" \ -F "file=@photo.jpg" \ -F 'settings={"width":800,"height":600,"fit":"cover"}' ``` สร้าง API key ภายใต้ **Settings → API Keys** ดู [REST API reference](/th/api/rest) สำหรับ endpoint ทั้งหมด หรือไปที่ สำหรับเอกสารอ้างอิงแบบโต้ตอบ ### Multi-User & Teams {#multi-user-teams} เปิดใช้ผู้ใช้หลายคนด้วยการควบคุมการเข้าถึงตามบทบาท: * **แอดมิน**: เข้าถึงเต็มรูปแบบ จัดการผู้ใช้, ทีม, การตั้งค่า, ไฟล์/ไปป์ไลน์/API key ทั้งหมด * **ผู้ใช้**: ใช้เครื่องมือ, จัดการไฟล์/ไปป์ไลน์/API key ของตัวเอง สร้างทีมภายใต้ **Settings → Teams** เพื่อจัดกลุ่มผู้ใช้ ตั้งค่า `AUTH_ENABLED=true` (หรือ `false` สำหรับการใช้งานคนเดียว/ใช้เองโดยไม่ต้องล็อกอิน) ## ใช้งานจากโทรศัพท์ {#use-it-from-your-phone} SnapOtter ใช้งานได้ในเบราว์เซอร์บนมือถือ และยังติดตั้งเป็นแอปได้ด้วย เปิดอินสแตนซ์ของคุณบนโทรศัพท์ แล้วทำตามนี้: * **iPhone / iPad (Safari):** แตะปุ่มแชร์ แล้วแตะ **เพิ่มลงในหน้าจอโฮม** * **Android (Chrome):** เปิดเมนูเบราว์เซอร์แล้วแตะ **ติดตั้งแอป** แอปที่ติดตั้งแล้วจะเปิดในหน้าต่างของตัวเอง ตรงเข้าอินสแตนซ์ของคุณทันที มีข้อควรรู้อย่างหนึ่ง: เบราว์เซอร์จะเสนอตัวเลือกติดตั้งผ่าน HTTPS เท่านั้น ที่อยู่ HTTP ธรรมดาในเครือข่าย LAN ยังใช้ในแท็บเบราว์เซอร์ได้ตามปกติ แต่ถ้าต้องการติดตั้งจริง ให้วางอินสแตนซ์ไว้หลัง reverse proxy ที่มีใบรับรอง (ดู[คู่มือการนำไปใช้งาน](/th/guide/deployment)) บนโทรศัพท์และแท็บเล็ต เครื่องมือรูปภาพจะแสดงปุ่ม **ถ่ายภาพ** ข้างปุ่มอัปโหลด ถ่ายรูปใบเสร็จหรือกระดานไวท์บอร์ด แล้วรูปจะเข้าไปอยู่ในเครื่องมือทันที --- --- url: https://docs.snapotter.com/nl/tools/image/blur-faces.md description: >- Detecteer en vervaag gezichten in afbeeldingen automatisch met AI-gezichtsdetectie voor privacy en AVG-conforme anonimisering. --- # Gezichten & PII vervagen {#face-pii-blur} Detecteer en vervaag gezichten in afbeeldingen automatisch met AI-gestuurde gezichtsdetectie (MediaPipe). ## API-endpoint {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Verwerking:** Asynchroon (retourneert 202, poll `/api/v1/jobs/{jobId}/progress` voor de status via SSE) **Modelbundel:** `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Afbeeldingsbestand (multipart) | | blurRadius | number | Nee | `30` | Vervagingsstraal toegepast op gedetecteerde gezichten (1-100) | | sensitivity | number | Nee | `0.5` | Gevoeligheid van gezichtsdetectie (0-1). Lagere waarden detecteren minder gezichten met hogere betrouwbaarheid | ## Voorbeeldaanvraag {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Antwoord {#response} ### Initieel antwoord (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Voortgang (SSE op `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Eindresultaat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### Geen gezichten gedetecteerd {#no-faces-detected} Als er geen gezichten worden gevonden, bevat het resultaat een waarschuwing: ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Opmerkingen {#notes} * Vereist dat de modelbundel `face-detection` is geïnstalleerd (200-300 MB). * Het uitvoerformaat komt automatisch overeen met het invoerformaat. * De array `faces` bevat de coördinaten van de omkadering (x, y, breedte, hoogte) voor elk gedetecteerd gezicht. * Verhoog `sensitivity` (dichter bij 1.0) om meer gezichten te detecteren, waaronder gedeeltelijk bedekte. * Ondersteunt de invoerformaten HEIC/HEIF, RAW, TGA, PSD, EXR en HDR via automatische decodering. --- --- url: https://docs.snapotter.com/nl/tools/image/enhance-faces.md description: >- Herstel en verscherp wazige of gezichten van lage kwaliteit in afbeeldingen met de AI-modellen GFPGAN en CodeFormer. --- # Gezichtsverbetering {#face-enhancement} Herstel en verbeter gezichten in afbeeldingen met AI-modellen (GFPGAN/CodeFormer). ## API-eindpunt {#api-endpoint} `POST /api/v1/tools/image/enhance-faces` **Verwerking:** Asynchroon (geeft 202 terug, poll `/api/v1/jobs/{jobId}/progress` voor de status via SSE) **Modelbundels:** `upscale-enhance` (5-6 GB) en `face-detection` (200-300 MB) ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Afbeeldingsbestand (multipart) | | model | string | Nee | `"auto"` | Te gebruiken model: `auto`, `gfpgan`, `codeformer` | | strength | number | Nee | `0.8` | Verbeteringssterkte (0-1). Hogere waarden geven een sterkere verbetering | | onlyCenterFace | boolean | Nee | `false` | Verbeter alleen het meest centrale/prominente gezicht | | sensitivity | number | Nee | `0.5` | Gevoeligheid van de gezichtsdetectie (0-1) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/enhance-faces \ -F "file=@portrait.jpg" \ -F 'settings={"model":"codeformer","strength":0.7,"onlyCenterFace":false}' ``` ## Antwoord {#response} ### Eerste antwoord (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Voortgang (SSE op `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Enhancing faces...","percent":60} ``` ### Eindresultaat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/portrait_enhanced.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 350000, "processedSize": 600000, "facesDetected": 2, "faces": [ {"x": 120, "y": 80, "w": 100, "h": 100}, {"x": 350, "y": 90, "w": 95, "h": 95} ], "model": "codeformer" } } ``` ## Opmerkingen {#notes} * Vereist zowel de modelbundel `upscale-enhance` (5-6 GB) als de modelbundel `face-detection` (200-300 MB). * GFPGAN produceert een agressievere verbetering; CodeFormer behoudt de identiteit beter. `auto` selecteert het beste model voor de invoer. * De uitvoer is altijd in PNG-formaat voor maximale kwaliteit. * Naast de uitvoer met volledige resolutie wordt een WebP-voorbeeld gegenereerd voor een snellere weergave in de frontend. * De parameter `strength` mengt het verbeterde gezicht met het origineel. Gebruik lagere waarden (0.3-0.5) voor subtiele verbeteringen en hogere waarden (0.7-1.0) voor een sterker herstel. * Ondersteunt de invoerformaten HEIC/HEIF, RAW, TGA, PSD, EXR en HDR via automatische decodering. --- --- url: https://docs.snapotter.com/vi/tools/image/compose.md description: Xếp lớp ảnh với vị trí, độ mờ và chế độ hòa trộn để ghép ảnh. --- # Ghép lớp ảnh {#image-composition} Xếp một ảnh phủ lên trên một ảnh nền với vị trí, độ mờ và chế độ hòa trộn cấu hình được. Hữu ích để ghép logo, đồ họa hoặc kết hợp nhiều ảnh. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/compose` Chấp nhận dữ liệu form multipart với **hai** tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | x | number | Không | `0` | Độ lệch ngang của ảnh phủ so với góc trên bên trái tính bằng pixel (tối thiểu 0) | | y | number | Không | `0` | Độ lệch dọc của ảnh phủ so với góc trên bên trái tính bằng pixel (tối thiểu 0) | | opacity | number | Không | `100` | Phần trăm độ mờ của ảnh phủ (0 đến 100) | | blendMode | string | Không | `"over"` | Chế độ hòa trộn khi ghép | ### Các chế độ hòa trộn {#blend-modes} | Giá trị | Mô tả | |-------|-------------| | `over` | Phủ thông thường (mặc định) | | `multiply` | Làm tối bằng cách nhân giá trị pixel | | `screen` | Làm sáng bằng cách đảo, nhân rồi đảo lại | | `overlay` | Kết hợp multiply và screen dựa trên độ sáng của ảnh nền | | `darken` | Giữ pixel tối hơn từ mỗi lớp | | `lighten` | Giữ pixel sáng hơn từ mỗi lớp | | `hard-light` | Phủ tương phản mạnh | | `soft-light` | Phủ tương phản nhẹ | | `difference` | Chênh lệch tuyệt đối giữa các lớp | | `exclusion` | Tương tự difference nhưng tương phản thấp hơn | ### Các trường tệp {#file-fields} | Tên trường | Bắt buộc | Mô tả | |------------|----------|-------------| | file | Có | Ảnh nền/hậu cảnh | | overlay | Có | Ảnh phủ/tiền cảnh | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Sử dụng chế độ hòa trộn multiply: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Ghi chú {#notes} * Cả hai ảnh được xác thực và giải mã (hỗ trợ HEIC, RAW, PSD, SVG) trước khi ghép. * Ảnh phủ được đặt tại đúng tọa độ pixel chỉ định bởi `x` và `y`. Nó không được thay đổi kích thước để vừa khít. * Nếu độ mờ nhỏ hơn 100, một mặt nạ alpha được áp dụng cho ảnh phủ trước khi hòa trộn. * Ảnh phủ có thể vượt ra ngoài ranh giới ảnh nền (phần vượt sẽ bị cắt). * Định hướng EXIF được áp dụng tự động cho cả hai ảnh trước khi xử lý. * Kích thước đầu ra khớp với kích thước ảnh nền. --- --- url: https://docs.snapotter.com/vi/tools/image/stitch.md description: >- Ghép ảnh cạnh nhau, xếp chồng, hoặc theo lưới với kiểm soát căn chỉnh, khoảng cách, viền, và chế độ đổi kích thước. --- # Ghép nối ảnh {#stitch-combine} Ghép nhiều ảnh cạnh nhau, xếp chồng theo chiều dọc, hoặc sắp xếp theo lưới. Hỗ trợ căn chỉnh, khoảng cách, viền, bo góc, và nhiều chế độ đổi kích thước. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/stitch` ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | direction | string | Không | `"horizontal"` | Hướng bố cục: `horizontal`, `vertical`, `grid` | | gridColumns | integer | Không | 2 | Số cột khi direction là `grid` (2 đến 100) | | resizeMode | string | Không | `"fit"` | Cách đổi kích thước ảnh: `fit`, `original`, `stretch`, `crop` | | alignment | string | Không | `"center"` | Căn chỉnh theo trục chéo: `start`, `center`, `end` | | gap | number | Không | 0 | Khoảng cách giữa các ảnh tính bằng pixel (0 đến 1000) | | border | number | Không | 0 | Độ rộng viền ngoài tính bằng pixel (0 đến 500) | | cornerRadius | number | Không | 0 | Bán kính bo góc áp dụng cho đầu ra cuối (0 đến 500) | | backgroundColor | string | Không | `"#FFFFFF"` | Màu nền/viền dạng hex (ví dụ `#FF0000`) | | format | string | Không | `"png"` | Định dạng đầu ra: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Không | 90 | Chất lượng đầu ra (1 đến 100) | ## Ví dụ Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/stitch \ -F "file=@image1.png" \ -F "file=@image2.png" \ -F "file=@image3.png" \ -F 'settings={"direction":"horizontal","resizeMode":"fit","gap":10,"backgroundColor":"#FFFFFF","format":"png"}' ``` ## Ví dụ Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stitch.png", "originalSize": 1234567, "processedSize": 987654 } ``` ## Ghi chú {#notes} * Yêu cầu ít nhất 2 ảnh. Tải lên nhiều tệp ảnh trong request multipart. * Hỗ trợ các định dạng đầu vào HEIC, RAW, PSD, và SVG (tự động giải mã). * Các chế độ đổi kích thước: * `fit` - Chia tỷ lệ ảnh để khớp với kích thước nhỏ nhất dọc theo trục ghép. * `original` - Giữ nguyên kích thước gốc (có thể tạo ra cạnh không đều). * `stretch` - Buộc ảnh khớp với kích thước nhỏ nhất mà không giữ tỷ lệ khung hình. * `crop` - Cắt kiểu cover để ảnh khớp với kích thước nhỏ nhất. * Ở chế độ `grid`, các ô được đặt kích thước theo kích thước trung vị của tất cả ảnh. * `cornerRadius` được áp dụng cho toàn bộ đầu ra cuối cùng, không phải từng ảnh riêng lẻ. * Kích thước canvas bị giới hạn bởi cấu hình máy chủ `MAX_CANVAS_PIXELS` để ngăn cạn kiệt bộ nhớ. --- --- url: https://docs.snapotter.com/vi/tools/audio/noise-reduction.md description: Giảm tạp âm nền khỏi âm thanh bằng khử nhiễu dựa trên FFT. --- # Giảm nhiễu {#noise-reduction} Giảm tạp âm nền trong một tệp âm thanh bằng cách khử nhiễu dựa trên FFT với cường độ có thể chọn. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/noise-reduction` Chấp nhận dữ liệu form multipart với một tệp âm thanh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | strength | string | Không | `"medium"` | Cường độ khử nhiễu: `light`, `medium`, `strong` | ## Yêu cầu ví dụ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/noise-reduction \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@audio.mp3" \ -F 'settings={"strength": "strong"}' ``` ## Phản hồi ví dụ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", "originalSize": 4500000, "processedSize": 4500000 } ``` ## Ghi chú {#notes} * `light` giữ lại nhiều chi tiết hơn nhưng loại bỏ ít nhiễu hơn. `strong` loại bỏ nhiều nhiễu hơn nhưng có thể tạo ra các nhiễu ảo (artifact) nhỏ. * Kết quả tốt nhất với các bản ghi có tạp âm nền ổn định (tiếng quạt kêu, điều hòa, tiếng rè tĩnh). * Đầu ra thường giữ container đầu vào. Đầu vào AAC được ghi thành M4A, và các đầu vào chỉ giải mã không được hỗ trợ sẽ chuyển về MP3. --- --- url: https://docs.snapotter.com/tr/tools/image/gif-tools.md description: >- Animasyonlu GIF'leri tek bir araçta yeniden boyutlandırın, optimize edin, hızını değiştirin, tersine çevirin, döndürün ve karelerini çıkarın. --- # GIF Araçları {#gif-tools} Animasyonlu GIF'leri yeniden boyutlandırın, optimize edin, hızını değiştirin, tersine çevirin, karelerini çıkarın ve döndürün. Tek bir araçta birden fazla işlem modu sunar. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parametreler {#parameters} ### Ortak Parametreler {#common-parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | mode | string | Hayır | `"resize"` | İşlem modu: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | Hayır | 0 | Çıktı GIF'i için döngü sayısı (0 = sonsuz, 1-100 = sonlu döngüler) | ### Yeniden Boyutlandırma Modu Parametreleri {#resize-mode-parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | width | integer | Hayır | - | Piksel cinsinden hedef genişlik (1 ile 16384 arası) | | height | integer | Hayır | - | Piksel cinsinden hedef yükseklik (1 ile 16384 arası) | | percentage | number | Hayır | - | Yüzdeye göre ölçeklendirme (1 ile 500 arası). Ayarlanırsa width/height değerlerini geçersiz kılar. | ### Optimizasyon Modu Parametreleri {#optimize-mode-parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | colors | number | Hayır | 256 | Palette bulunan maksimum renk sayısı (2 ile 256 arası) | | dither | number | Hayır | 1.0 | Titreme (dithering) gücü (0 ile 1 arası; 0 titremeyi devre dışı bırakır) | | effort | number | Hayır | 7 | Optimizasyon çaba düzeyi (1 ile 10 arası; daha yüksek = daha yavaş ama daha küçük) | ### Hız Modu Parametreleri {#speed-mode-parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | speedFactor | number | Hayır | 1.0 | Hız çarpanı (0.1 ile 10 arası). 1'den büyük değerler hızlandırır, 1'den küçük değerler yavaşlatır. | ### Çıkarma Modu Parametreleri {#extract-mode-parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | extractMode | string | Hayır | `"single"` | Çıkarma modu: `single`, `range`, `all` | | frameNumber | number | Hayır | 0 | `single` modunda çıkarılacak kare dizini (0 tabanlı) | | frameStart | number | Hayır | 0 | `range` modu için başlangıç kare dizini (0 tabanlı) | | frameEnd | number | Hayır | - | `range` modu için bitiş kare dizini (0 tabanlı, dahil) | | extractFormat | string | Hayır | `"png"` | Çıkarılan kareler için biçim: `png`, `webp` | ### Döndürme Modu Parametreleri {#rotate-mode-parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | angle | number | Hayır | - | Döndürme açısı: `90`, `180` veya `270` derece | | flipH | boolean | Hayır | `false` | Yatay olarak çevir | | flipV | boolean | Hayır | `false` | Dikey olarak çevir | ## Örnek İstekler {#example-requests} ### Yeniden Boyutlandırma {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimizasyon {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Hızlandırma {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Tek Kare Çıkarma {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Bilgi Alt Rotası {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Bir animasyonlu GIF'i işlemeden onun hakkında meta veri döndürür. ### Bilgi İsteği {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Bilgi Yanıtı {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Notlar {#notes} * Ana işleme uç noktası için standart `createToolRoute` fabrikasını kullanır. * Bilgi uç noktası yalnızca bir dosya yüklemesi gerektirir (ayara gerek yoktur). * `resize` modunda, `percentage` sağlanırsa `width`/`height` üzerinde önceliğe sahip olur. Yeniden boyutlandırma, en boy oranını korumak için `fit: inside` kullanır. * `speed` modunda, kare gecikmeleri hız faktörüne bölünür. Kare başına minimum gecikme 20ms'dir (GIF spesifikasyon sınırlaması). * `reverse` modunda, tersine çevirirken hızı aynı anda ayarlamak için `speedFactor` parametresi de kullanılabilir. * `range` veya `all` ile `extract` modunda çıktı, tekil kareleri içeren bir ZIP dosyasıdır. * `rotate` modunda, her kare ayrı ayrı işlenir ve bir animasyona yeniden birleştirilir. * `loop` parametresi, çıktı GIF'inin kaç kez döngü yapacağını kontrol eder. Sonsuz döngü için 0 kullanın. * Bilgi yanıtındaki `duration` alanı, milisaniye cinsinden toplam animasyon süresidir. --- --- url: https://docs.snapotter.com/sv/tools/video/gif-to-video.md description: Konvertera en animerad GIF till en MP4-, WebM- eller MOV-video. --- # GIF till video {#gif-to-video} Konvertera en animerad GIF till en kompakt MP4-, WebM- eller MOV-videofil. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Tar emot multipart-formulärdata med en GIF-fil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | format | string | Nej | `"mp4"` | Utdataformat: `mp4`, `webm`, `mov` | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Anteckningar {#notes} * Att konvertera GIF till video minskar vanligtvis filstorleken med 80-90 % samtidigt som samma visuella kvalitet bibehålls. * Endast animerade GIF-filer accepteras. Statiska bilder bör använda bildverktyget Konvertera. * MP4 och MOV använder H.264-kodning, WebM använder VP9. --- --- url: https://docs.snapotter.com/ar/tools/video/gif-to-video.md description: تحويل صورة GIF متحركة إلى فيديو MP4 أو WebM أو MOV. --- # GIF to Video {#gif-to-video} تحويل صورة GIF متحركة إلى ملف فيديو MP4 أو WebM أو MOV مضغوط. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` يقبل بيانات نموذج متعدد الأجزاء تحتوي على ملف GIF وحقل JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | صيغة الإخراج: `mp4` أو `webm` أو `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * عادةً ما يقلل تحويل GIF إلى فيديو حجم الملف بنسبة 80-90% مع الحفاظ على نفس جودة الصورة. * تُقبَل ملفات GIF المتحركة فقط. يجب أن تستخدم الصور الثابتة أداة Convert للصور. * يستخدم MP4 وMOV ترميز H.264، ويستخدم WebM ترميز VP9. --- --- url: https://docs.snapotter.com/de/tools/video/gif-to-video.md description: Ein animiertes GIF in ein MP4-, WebM- oder MOV-Video konvertieren. --- # GIF to Video {#gif-to-video} Ein animiertes GIF in eine kompakte MP4-, WebM- oder MOV-Videodatei konvertieren. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Nimmt Multipart-Formulardaten mit einer GIF-Datei und einem JSON-Feld `settings` entgegen. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Ausgabeformat: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Die Konvertierung von GIF zu Video verringert die Dateigröße typischerweise um 80-90 %, während dieselbe visuelle Qualität erhalten bleibt. * Es werden nur animierte GIF-Dateien akzeptiert. Für statische Bilder sollte das Bild-Tool Convert verwendet werden. * MP4 und MOV verwenden H.264-Kodierung, WebM verwendet VP9. --- --- url: https://docs.snapotter.com/es/tools/video/gif-to-video.md description: Convierte un GIF animado en un vídeo MP4, WebM o MOV. --- # GIF to Video {#gif-to-video} Convierte un GIF animado en un archivo de vídeo compacto MP4, WebM o MOV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Acepta datos de formulario multipart con un archivo GIF y un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Formato de salida: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Convertir un GIF en vídeo normalmente reduce el tamaño de archivo entre un 80 y un 90 % manteniendo la misma calidad visual. * Solo se aceptan archivos GIF animados. Las imágenes estáticas deben usar la herramienta Convert de imagen. * MP4 y MOV usan codificación H.264, WebM usa VP9. --- --- url: https://docs.snapotter.com/fr/tools/video/gif-to-video.md description: Convertit un GIF animé en vidéo MP4, WebM ou MOV. --- # GIF to Video {#gif-to-video} Convertit un GIF animé en un fichier vidéo compact MP4, WebM ou MOV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Accepte des données de formulaire multipart avec un fichier GIF et un champ JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Format de sortie : `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Convertir un GIF en vidéo réduit généralement la taille du fichier de 80 à 90 % tout en conservant la même qualité visuelle. * Seuls les fichiers GIF animés sont acceptés. Les images statiques doivent utiliser l'outil image Convert. * MP4 et MOV utilisent l'encodage H.264, WebM utilise VP9. --- --- url: https://docs.snapotter.com/hi/tools/video/gif-to-video.md description: किसी एनिमेटेड GIF को MP4, WebM, या MOV वीडियो में कन्वर्ट करें। --- # GIF to Video {#gif-to-video} किसी एनिमेटेड GIF को एक सुगठित MP4, WebM, या MOV वीडियो फ़ाइल में कन्वर्ट करें। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` एक GIF फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | आउटपुट फ़ॉर्मैट: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * GIF को वीडियो में कन्वर्ट करने से आम तौर पर वही दृश्य गुणवत्ता बनाए रखते हुए फ़ाइल आकार 80-90% तक घट जाता है। * केवल एनिमेटेड GIF फ़ाइलें स्वीकार की जाती हैं। स्थिर छवियों के लिए image Convert टूल का उपयोग करें। * MP4 और MOV H.264 encoding का उपयोग करते हैं, WebM VP9 का उपयोग करता है। --- --- url: https://docs.snapotter.com/id/tools/video/gif-to-video.md description: Mengonversi GIF animasi menjadi video MP4, WebM, atau MOV. --- # GIF to Video {#gif-to-video} Mengonversi GIF animasi menjadi file video MP4, WebM, atau MOV yang ringkas. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Menerima multipart form data dengan file GIF dan field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Format keluaran: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Mengonversi GIF ke video biasanya mengurangi ukuran file sebesar 80-90% sambil mempertahankan kualitas visual yang sama. * Hanya file GIF animasi yang diterima. Gambar statis sebaiknya menggunakan alat Convert gambar. * MP4 dan MOV menggunakan enkoding H.264, WebM menggunakan VP9. --- --- url: https://docs.snapotter.com/it/tools/video/gif-to-video.md description: Converti una GIF animata in un video MP4, WebM o MOV. --- # GIF to Video {#gif-to-video} Converti una GIF animata in un file video compatto MP4, WebM o MOV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Accetta dati form multipart con un file GIF e un campo JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Formato di output: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Convertire una GIF in video riduce tipicamente la dimensione del file dell'80-90% mantenendo la stessa qualità visiva. * Sono accettati solo file GIF animati. Le immagini statiche dovrebbero usare lo strumento Convert delle immagini. * MP4 e MOV usano la codifica H.264, WebM usa VP9. --- --- url: https://docs.snapotter.com/ja/tools/video/gif-to-video.md description: アニメーション GIF を MP4、WebM、または MOV 動画に変換します。 --- # GIF to Video {#gif-to-video} アニメーション GIF をコンパクトな MP4、WebM、または MOV 動画ファイルに変換します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` GIF ファイルと JSON の `settings` フィールドを含む multipart フォームデータを受け付けます。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 出力フォーマット: `mp4`、`webm`、`mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * GIF から動画への変換は、同じ視覚品質を保ちながら通常はファイルサイズを 80〜90% 削減します。 * 受け付けるのはアニメーション GIF ファイルのみです。静止画像には画像の Convert ツールを使用してください。 * MP4 と MOV は H.264 エンコードを、WebM は VP9 を使用します。 --- --- url: https://docs.snapotter.com/ko/tools/video/gif-to-video.md description: 애니메이션 GIF를 MP4, WebM 또는 MOV 비디오로 변환합니다. --- # GIF to Video {#gif-to-video} 애니메이션 GIF를 용량이 작은 MP4, WebM 또는 MOV 비디오 파일로 변환합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` GIF 파일과 JSON `settings` 필드가 담긴 multipart form data를 받습니다. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 출력 형식: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * GIF를 비디오로 변환하면 동일한 시각적 품질을 유지하면서 일반적으로 파일 크기가 80-90% 줄어듭니다. * 애니메이션 GIF 파일만 허용됩니다. 정적 이미지는 이미지 Convert 도구를 사용하세요. * MP4와 MOV는 H.264 인코딩을 사용하고 WebM은 VP9를 사용합니다. --- --- url: https://docs.snapotter.com/nl/tools/video/gif-to-video.md description: Een geanimeerde GIF omzetten naar een MP4-, WebM- of MOV-video. --- # GIF to Video {#gif-to-video} Zet een geanimeerde GIF om naar een compact MP4-, WebM- of MOV-videobestand. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Accepteert multipart form data met een GIF-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | format | string | Nee | `"mp4"` | Uitvoerformaat: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Het omzetten van GIF naar video verkleint de bestandsgrootte doorgaans met 80-90% terwijl dezelfde visuele kwaliteit behouden blijft. * Alleen geanimeerde GIF-bestanden worden geaccepteerd. Voor statische afbeeldingen gebruik je de image Convert-tool. * MP4 en MOV gebruiken H.264-encoding, WebM gebruikt VP9. --- --- url: https://docs.snapotter.com/pl/tools/video/gif-to-video.md description: Konwersja animowanego GIF na wideo MP4, WebM lub MOV. --- # GIF to Video {#gif-to-video} Konwertuje animowany GIF na kompaktowy plik wideo MP4, WebM lub MOV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Przyjmuje dane formularza multipart z plikiem GIF i polem JSON `settings`. ## Parameters {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | format | string | Nie | `"mp4"` | Format wyjściowy: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Konwersja GIF na wideo zazwyczaj zmniejsza rozmiar pliku o 80-90%, zachowując tę samą jakość wizualną. * Przyjmowane są tylko animowane pliki GIF. Obrazy statyczne powinny korzystać z narzędzia Convert dla obrazów. * MP4 i MOV używają kodowania H.264, WebM używa VP9. --- --- url: https://docs.snapotter.com/pt-BR/tools/video/gif-to-video.md description: Converte um GIF animado em um vídeo MP4, WebM ou MOV. --- # GIF to Video {#gif-to-video} Converte um GIF animado em um arquivo de vídeo MP4, WebM ou MOV compacto. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Aceita dados de formulário multipart com um arquivo GIF e um campo JSON `settings`. ## Parameters {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | format | string | Não | `"mp4"` | Formato de saída: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Converter GIF para vídeo normalmente reduz o tamanho do arquivo em 80-90% mantendo a mesma qualidade visual. * Apenas arquivos GIF animados são aceitos. Imagens estáticas devem usar a ferramenta Convert de imagem. * MP4 e MOV usam codificação H.264, WebM usa VP9. --- --- url: https://docs.snapotter.com/ru/tools/video/gif-to-video.md description: Конвертация анимированного GIF в видео MP4, WebM или MOV. --- # GIF to Video {#gif-to-video} Конвертация анимированного GIF в компактный видеофайл MP4, WebM или MOV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Принимает multipart form data с файлом GIF и полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Выходной формат: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Конвертация GIF в видео обычно уменьшает размер файла на 80-90 %, сохраняя при этом то же визуальное качество. * Принимаются только анимированные файлы GIF. Для статичных изображений следует использовать инструмент Convert из раздела изображений. * MP4 и MOV используют кодирование H.264, WebM использует VP9. --- --- url: https://docs.snapotter.com/th/tools/video/gif-to-video.md description: แปลง GIF แบบเคลื่อนไหวเป็นวิดีโอ MP4, WebM หรือ MOV --- # GIF to Video {#gif-to-video} แปลง GIF แบบเคลื่อนไหวเป็นไฟล์วิดีโอ MP4, WebM หรือ MOV ที่กะทัดรัด ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` รับข้อมูลแบบ multipart form พร้อมไฟล์ GIF และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | รูปแบบเอาต์พุต: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * การแปลง GIF เป็นวิดีโอโดยทั่วไปจะลดขนาดไฟล์ลง 80-90% ในขณะที่คงคุณภาพของภาพไว้เท่าเดิม * รับเฉพาะไฟล์ GIF แบบเคลื่อนไหว ภาพนิ่งควรใช้เครื่องมือ Convert สำหรับรูปภาพ * MP4 และ MOV ใช้การเข้ารหัส H.264 ส่วน WebM ใช้ VP9 --- --- url: https://docs.snapotter.com/tr/tools/video/gif-to-video.md description: Animasyonlu bir GIF'i MP4, WebM veya MOV videoya dönüştürün. --- # GIF to Video {#gif-to-video} Animasyonlu bir GIF'i kompakt bir MP4, WebM veya MOV video dosyasına dönüştürün. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Bir GIF dosyası ve bir JSON `settings` alanı içeren multipart form data kabul eder. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Çıktı formatı: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * GIF'i videoya dönüştürmek, aynı görsel kaliteyi korurken dosya boyutunu genellikle %80-90 azaltır. * Yalnızca animasyonlu GIF dosyaları kabul edilir. Statik görüntüler image Convert aracını kullanmalıdır. * MP4 ve MOV, H.264 kodlaması kullanır; WebM, VP9 kullanır. --- --- url: https://docs.snapotter.com/uk/tools/video/gif-to-video.md description: Конвертує анімований GIF у відео MP4, WebM або MOV. --- # GIF to Video {#gif-to-video} Конвертує анімований GIF у компактний відеофайл MP4, WebM або MOV. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Приймає дані форми multipart із файлом GIF і полем JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Вихідний формат: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Конвертація GIF у відео зазвичай зменшує розмір файлу на 80-90%, зберігаючи ту саму візуальну якість. * Приймаються лише анімовані файли GIF. Для статичних зображень слід використовувати інструмент Convert для зображень. * MP4 і MOV використовують кодування H.264, WebM використовує VP9. --- --- url: https://docs.snapotter.com/vi/tools/video/gif-to-video.md description: Chuyển đổi ảnh GIF động thành video MP4, WebM hoặc MOV. --- # GIF to Video {#gif-to-video} Chuyển đổi ảnh GIF động thành file video MP4, WebM hoặc MOV gọn nhẹ. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` Nhận multipart form data gồm một file GIF và một trường JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | Định dạng đầu ra: `mp4`, `webm`, `mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * Chuyển đổi GIF sang video thường giảm kích thước file 80-90% trong khi vẫn giữ nguyên chất lượng hình ảnh. * Chỉ chấp nhận file GIF động. Ảnh tĩnh nên dùng công cụ Convert của hình ảnh. * MP4 và MOV dùng mã hóa H.264, WebM dùng VP9. --- --- url: https://docs.snapotter.com/zh-CN/tools/video/gif-to-video.md description: 将动画 GIF 转换为 MP4、WebM 或 MOV 视频。 --- # GIF to Video {#gif-to-video} 将动画 GIF 转换为紧凑的 MP4、WebM 或 MOV 视频文件。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` 接受包含 GIF 文件和 JSON `settings` 字段的 multipart 表单数据。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 输出格式:`mp4`、`webm`、`mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * 将 GIF 转换为视频通常可在保持相同视觉质量的同时将文件大小减小 80-90%。 * 仅接受动画 GIF 文件。静态图像应使用图像 Convert 工具。 * MP4 和 MOV 使用 H.264 编码,WebM 使用 VP9。 --- --- url: https://docs.snapotter.com/zh-TW/tools/video/gif-to-video.md description: 將動畫 GIF 轉換為 MP4、WebM 或 MOV 影片。 --- # GIF to Video {#gif-to-video} 將動畫 GIF 轉換為精簡的 MP4、WebM 或 MOV 影片檔案。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/video/gif-to-video` 接受包含一個 GIF 檔案和一個 JSON `settings` 欄位的 multipart form data。 ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | format | string | No | `"mp4"` | 輸出格式:`mp4`、`webm`、`mov` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/video/gif-to-video \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"format": "mp4"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", "originalSize": 8500000, "processedSize": 950000 } ``` ## Notes {#notes} * 將 GIF 轉換為影片通常可縮小 80-90% 的檔案大小,同時維持相同的視覺品質。 * 只接受動畫 GIF 檔案。靜態圖片應使用圖片 Convert 工具。 * MP4 和 MOV 使用 H.264 編碼,WebM 使用 VP9。 --- --- url: https://docs.snapotter.com/hi/tools/image/gif-tools.md description: >- एक ही टूल में animated GIFs का आकार बदलें, अनुकूलित करें, गति बदलें, उलटें, घुमाएँ और फ़्रेम निकालें। --- # GIF Tools {#gif-tools} animated GIFs का आकार बदलें, अनुकूलित करें, गति बदलें, उलटें, फ़्रेम निकालें और घुमाएँ। एक ही टूल में कई ऑपरेशन मोड प्रदान करता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parameters {#parameters} ### Common Parameters {#common-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | नहीं | `"resize"` | ऑपरेशन मोड: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | नहीं | 0 | आउटपुट GIF के लिए Loop गणना (0 = अनंत, 1-100 = परिमित लूप) | ### Resize Mode Parameters {#resize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | नहीं | - | लक्ष्य चौड़ाई पिक्सेल में (1 से 16384) | | height | integer | नहीं | - | लक्ष्य ऊँचाई पिक्सेल में (1 से 16384) | | percentage | number | नहीं | - | प्रतिशत के अनुसार स्केल करें (1 से 500)। सेट होने पर width/height को ओवरराइड करता है। | ### Optimize Mode Parameters {#optimize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | colors | number | नहीं | 256 | पैलेट में रंगों की अधिकतम संख्या (2 से 256) | | dither | number | नहीं | 1.0 | Dithering ताकत (0 से 1, जहाँ 0 dithering को अक्षम करता है) | | effort | number | नहीं | 7 | अनुकूलन प्रयास स्तर (1 से 10, अधिक = धीमा लेकिन छोटा) | ### Speed Mode Parameters {#speed-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | speedFactor | number | नहीं | 1.0 | गति गुणक (0.1 से 10)। 1 से अधिक मान गति बढ़ाते हैं, 1 से कम गति घटाते हैं। | ### Extract Mode Parameters {#extract-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | extractMode | string | नहीं | `"single"` | निष्कर्षण मोड: `single`, `range`, `all` | | frameNumber | number | नहीं | 0 | `single` मोड में निकालने के लिए फ़्रेम अनुक्रमणिका (0-आधारित) | | frameStart | number | नहीं | 0 | `range` मोड के लिए प्रारंभ फ़्रेम अनुक्रमणिका (0-आधारित) | | frameEnd | number | नहीं | - | `range` मोड के लिए अंतिम फ़्रेम अनुक्रमणिका (0-आधारित, समावेशी) | | extractFormat | string | नहीं | `"png"` | निकाले गए फ़्रेमों के लिए प्रारूप: `png`, `webp` | ### Rotate Mode Parameters {#rotate-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | angle | number | नहीं | - | घूर्णन कोण: `90`, `180`, या `270` डिग्री | | flipH | boolean | नहीं | `false` | क्षैतिज रूप से फ़्लिप करें | | flipV | boolean | नहीं | `false` | लंबवत रूप से फ़्लिप करें | ## Example Requests {#example-requests} ### Resize {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimize {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Speed Up {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Extract Single Frame {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info Sub-Route {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` संसाधित किए बिना किसी animated GIF के बारे में मेटाडेटा लौटाता है। ### Info Request {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info Response {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Notes {#notes} * मुख्य प्रसंस्करण endpoint के लिए मानक `createToolRoute` factory का उपयोग करता है। * info endpoint को केवल एक फ़ाइल अपलोड की आवश्यकता होती है (किसी सेटिंग की ज़रूरत नहीं)। * `resize` मोड में, यदि `percentage` प्रदान किया जाता है तो यह `width`/`height` पर प्राथमिकता लेता है। आकार बदलने के लिए aspect ratio बनाए रखने हेतु `fit: inside` का उपयोग किया जाता है। * `speed` मोड में, फ़्रेम विलंब को speed factor से विभाजित किया जाता है। प्रति फ़्रेम न्यूनतम विलंब 20ms है (GIF स्पेक सीमा)। * `reverse` मोड में, उलटते समय गति को एक साथ समायोजित करने के लिए `speedFactor` parameter भी उपलब्ध है। * `extract` मोड में `range` या `all` के साथ, आउटपुट एक ZIP फ़ाइल होती है जिसमें अलग-अलग फ़्रेम होते हैं। * `rotate` मोड में, प्रत्येक फ़्रेम को अलग से संसाधित किया जाता है और एक एनिमेशन में पुनः जोड़ा जाता है। * `loop` parameter नियंत्रित करता है कि आउटपुट GIF कितनी बार लूप करता है। अनंत लूपिंग के लिए 0 का उपयोग करें। * info प्रतिक्रिया में `duration` फ़ील्ड मिलीसेकंड में कुल एनिमेशन अवधि है। --- --- url: https://docs.snapotter.com/id/tools/image/gif-tools.md description: >- Ubah ukuran, optimalkan, ubah kecepatan, balik, putar, dan ekstrak frame dari GIF beranimasi dalam satu alat. --- # GIF Tools {#gif-tools} Ubah ukuran, optimalkan, ubah kecepatan, balik, ekstrak frame, dan putar GIF beranimasi. Menyediakan beberapa mode operasi dalam satu alat. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parameters {#parameters} ### Common Parameters {#common-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"resize"` | Mode operasi: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | No | 0 | Jumlah loop untuk GIF output (0 = tak terbatas, 1-100 = loop terbatas) | ### Resize Mode Parameters {#resize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | - | Lebar target dalam piksel (1 hingga 16384) | | height | integer | No | - | Tinggi target dalam piksel (1 hingga 16384) | | percentage | number | No | - | Skala berdasarkan persentase (1 hingga 500). Mengesampingkan width/height bila diatur. | ### Optimize Mode Parameters {#optimize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | colors | number | No | 256 | Jumlah warna maksimum dalam palet (2 hingga 256) | | dither | number | No | 1.0 | Kekuatan dithering (0 hingga 1, di mana 0 menonaktifkan dithering) | | effort | number | No | 7 | Tingkat upaya optimasi (1 hingga 10, lebih tinggi = lebih lambat tetapi lebih kecil) | ### Speed Mode Parameters {#speed-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | speedFactor | number | No | 1.0 | Pengali kecepatan (0.1 hingga 10). Nilai > 1 mempercepat, < 1 memperlambat. | ### Extract Mode Parameters {#extract-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | extractMode | string | No | `"single"` | Mode ekstraksi: `single`, `range`, `all` | | frameNumber | number | No | 0 | Indeks frame yang akan diekstrak dalam mode `single` (berbasis 0) | | frameStart | number | No | 0 | Indeks frame awal untuk mode `range` (berbasis 0) | | frameEnd | number | No | - | Indeks frame akhir untuk mode `range` (berbasis 0, inklusif) | | extractFormat | string | No | `"png"` | Format untuk frame yang diekstrak: `png`, `webp` | ### Rotate Mode Parameters {#rotate-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | angle | number | No | - | Sudut rotasi: `90`, `180`, atau `270` derajat | | flipH | boolean | No | `false` | Balik horizontal | | flipV | boolean | No | `false` | Balik vertikal | ## Example Requests {#example-requests} ### Resize {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimize {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Speed Up {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Extract Single Frame {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info Sub-Route {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Mengembalikan metadata tentang GIF beranimasi tanpa memprosesnya. ### Info Request {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info Response {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Notes {#notes} * Menggunakan factory `createToolRoute` standar untuk endpoint pemrosesan utama. * Endpoint info hanya memerlukan unggahan file (tidak perlu pengaturan). * Dalam mode `resize`, bila `percentage` disediakan, ia diprioritaskan di atas `width`/`height`. Pengubahan ukuran menggunakan `fit: inside` untuk mempertahankan rasio aspek. * Dalam mode `speed`, delay frame dibagi dengan faktor kecepatan. Delay minimum per frame adalah 20ms (batasan spesifikasi GIF). * Dalam mode `reverse`, parameter `speedFactor` juga tersedia untuk menyesuaikan kecepatan sekaligus membalik. * Dalam mode `extract` dengan `range` atau `all`, output berupa file ZIP yang berisi frame-frame individual. * Dalam mode `rotate`, setiap frame diproses secara individual dan dirakit ulang menjadi animasi. * Parameter `loop` mengontrol berapa kali GIF output berputar. Gunakan 0 untuk perulangan tak terbatas. * Field `duration` dalam respons info adalah total durasi animasi dalam milidetik. --- --- url: https://docs.snapotter.com/th/tools/image/gif-tools.md description: >- ปรับขนาด ปรับให้เหมาะสม เปลี่ยนความเร็ว ย้อนกลับ หมุน และแยกเฟรมจาก GIF เคลื่อนไหวในเครื่องมือเดียว --- # GIF Tools {#gif-tools} ปรับขนาด ปรับให้เหมาะสม เปลี่ยนความเร็ว ย้อนกลับ แยกเฟรม และหมุน GIF เคลื่อนไหว มีโหมดการทำงานหลายแบบในเครื่องมือเดียว ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parameters {#parameters} ### Common Parameters {#common-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | mode | string | No | `"resize"` | โหมดการทำงาน: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | No | 0 | จำนวนรอบการวนซ้ำสำหรับ GIF ที่ได้ (0 = ไม่จำกัด, 1-100 = จำนวนรอบที่จำกัด) | ### Resize Mode Parameters {#resize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | width | integer | No | - | ความกว้างเป้าหมายเป็นพิกเซล (1 ถึง 16384) | | height | integer | No | - | ความสูงเป้าหมายเป็นพิกเซล (1 ถึง 16384) | | percentage | number | No | - | ปรับสัดส่วนตามเปอร์เซ็นต์ (1 ถึง 500) แทนที่ width/height หากตั้งค่า | ### Optimize Mode Parameters {#optimize-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | colors | number | No | 256 | จำนวนสีสูงสุดในจานสี (2 ถึง 256) | | dither | number | No | 1.0 | ความเข้มของ dithering (0 ถึง 1 โดย 0 ปิดการใช้งาน dithering) | | effort | number | No | 7 | ระดับความพยายามในการปรับให้เหมาะสม (1 ถึง 10 ยิ่งสูง = ช้าลงแต่เล็กลง) | ### Speed Mode Parameters {#speed-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | speedFactor | number | No | 1.0 | ตัวคูณความเร็ว (0.1 ถึง 10) ค่า > 1 เร่งความเร็ว, < 1 ทำให้ช้าลง | ### Extract Mode Parameters {#extract-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | extractMode | string | No | `"single"` | โหมดการแยก: `single`, `range`, `all` | | frameNumber | number | No | 0 | ดัชนีเฟรมที่จะแยกในโหมด `single` (เริ่มจาก 0) | | frameStart | number | No | 0 | ดัชนีเฟรมเริ่มต้นสำหรับโหมด `range` (เริ่มจาก 0) | | frameEnd | number | No | - | ดัชนีเฟรมสิ้นสุดสำหรับโหมด `range` (เริ่มจาก 0, รวมค่านี้ด้วย) | | extractFormat | string | No | `"png"` | รูปแบบสำหรับเฟรมที่แยก: `png`, `webp` | ### Rotate Mode Parameters {#rotate-mode-parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | angle | number | No | - | มุมการหมุน: `90`, `180`, หรือ `270` องศา | | flipH | boolean | No | `false` | พลิกแนวนอน | | flipV | boolean | No | `false` | พลิกแนวตั้ง | ## Example Requests {#example-requests} ### Resize {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimize {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Speed Up {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Extract Single Frame {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info Sub-Route {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` คืนค่าเมทาดาทาเกี่ยวกับ GIF เคลื่อนไหวโดยไม่ประมวลผล ### Info Request {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info Response {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Notes {#notes} * ใช้ factory `createToolRoute` มาตรฐานสำหรับ endpoint การประมวลผลหลัก * endpoint ข้อมูลต้องการเพียงการอัปโหลดไฟล์เท่านั้น (ไม่ต้องมีการตั้งค่า) * ในโหมด `resize` หากมีการระบุ `percentage` จะมีความสำคัญเหนือ `width`/`height` การปรับขนาดใช้ `fit: inside` เพื่อรักษาสัดส่วนภาพ * ในโหมด `speed` ความล่าช้าของเฟรมจะถูกหารด้วย speed factor ความล่าช้าต่ำสุดต่อเฟรมคือ 20ms (ข้อจำกัดของ GIF spec) * ในโหมด `reverse` พารามิเตอร์ `speedFactor` ก็ใช้ได้เช่นกันเพื่อปรับความเร็วพร้อมกับการย้อนกลับ * ในโหมด `extract` ที่มี `range` หรือ `all` ผลลัพธ์จะเป็นไฟล์ ZIP ที่มีเฟรมแต่ละเฟรม * ในโหมด `rotate` แต่ละเฟรมจะถูกประมวลผลทีละเฟรมและประกอบกลับเป็นภาพเคลื่อนไหว * พารามิเตอร์ `loop` ควบคุมว่า GIF ที่ได้จะวนซ้ำกี่ครั้ง ใช้ 0 สำหรับการวนซ้ำไม่จำกัด * ฟิลด์ `duration` ในการตอบกลับข้อมูลคือระยะเวลาภาพเคลื่อนไหวทั้งหมดในหน่วยมิลลิวินาที --- --- url: https://docs.snapotter.com/uk/tools/image/gif-tools.md description: >- Змінюйте розмір, оптимізуйте, змінюйте швидкість, реверсуйте, обертайте та витягуйте кадри з анімованих GIF в одному інструменті. --- # GIF Tools {#gif-tools} Змінюйте розмір, оптимізуйте, змінюйте швидкість, реверсуйте, витягуйте кадри та обертайте анімовані GIF. Надає кілька режимів роботи в одному інструменті. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Параметри {#parameters} ### Загальні параметри {#common-parameters} | Параметр | Тип | Обовʼязковий | За замовчуванням | Опис | |-----------|------|----------|---------|-------------| | mode | string | Ні | `"resize"` | Режим роботи: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | Ні | 0 | Кількість повторів вихідного GIF (0 = нескінченно, 1-100 = скінченна кількість повторів) | ### Параметри режиму зміни розміру {#resize-mode-parameters} | Параметр | Тип | Обовʼязковий | За замовчуванням | Опис | |-----------|------|----------|---------|-------------| | width | integer | Ні | - | Цільова ширина в пікселях (від 1 до 16384) | | height | integer | Ні | - | Цільова висота в пікселях (від 1 до 16384) | | percentage | number | Ні | - | Масштабувати у відсотках (від 1 до 500). Замінює width/height, якщо задано. | ### Параметри режиму оптимізації {#optimize-mode-parameters} | Параметр | Тип | Обовʼязковий | За замовчуванням | Опис | |-----------|------|----------|---------|-------------| | colors | number | Ні | 256 | Максимальна кількість кольорів у палітрі (від 2 до 256) | | dither | number | Ні | 1.0 | Сила дизерингу (від 0 до 1, де 0 вимикає дизеринг) | | effort | number | Ні | 7 | Рівень зусиль оптимізації (від 1 до 10, вище = повільніше, але менше) | ### Параметри режиму швидкості {#speed-mode-parameters} | Параметр | Тип | Обовʼязковий | За замовчуванням | Опис | |-----------|------|----------|---------|-------------| | speedFactor | number | Ні | 1.0 | Множник швидкості (від 0.1 до 10). Значення > 1 прискорюють, < 1 сповільнюють. | ### Параметри режиму витягування {#extract-mode-parameters} | Параметр | Тип | Обовʼязковий | За замовчуванням | Опис | |-----------|------|----------|---------|-------------| | extractMode | string | Ні | `"single"` | Режим витягування: `single`, `range`, `all` | | frameNumber | number | Ні | 0 | Індекс кадру для витягування в режимі `single` (з нуля) | | frameStart | number | Ні | 0 | Індекс початкового кадру для режиму `range` (з нуля) | | frameEnd | number | Ні | - | Індекс кінцевого кадру для режиму `range` (з нуля, включно) | | extractFormat | string | Ні | `"png"` | Формат витягнутих кадрів: `png`, `webp` | ### Параметри режиму обертання {#rotate-mode-parameters} | Параметр | Тип | Обовʼязковий | За замовчуванням | Опис | |-----------|------|----------|---------|-------------| | angle | number | Ні | - | Кут обертання: `90`, `180` або `270` градусів | | flipH | boolean | Ні | `false` | Віддзеркалити по горизонталі | | flipV | boolean | Ні | `false` | Віддзеркалити по вертикалі | ## Приклади запитів {#example-requests} ### Зміна розміру {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Оптимізація {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Прискорення {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Витягування одного кадру {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Приклад відповіді {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Підмаршрут Info {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Повертає метадані про анімований GIF без його обробки. ### Запит Info {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Відповідь Info {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Примітки {#notes} * Для основного кінцевого пункту обробки використовує стандартну фабрику `createToolRoute`. * Кінцевий пункт info вимагає лише завантаження файлу (налаштування не потрібні). * У режимі `resize`, якщо задано `percentage`, воно має пріоритет над `width`/`height`. Зміна розміру використовує `fit: inside` для збереження співвідношення сторін. * У режимі `speed` затримки кадрів діляться на коефіцієнт швидкості. Мінімальна затримка на кадр — 20ms (обмеження специфікації GIF). * У режимі `reverse` також доступний параметр `speedFactor` для одночасного регулювання швидкості під час реверсування. * У режимі `extract` з `range` або `all` вивід — це ZIP-файл, що містить окремі кадри. * У режимі `rotate` кожен кадр обробляється окремо та знову складається в анімацію. * Параметр `loop` контролює, скільки разів повторюється вихідний GIF. Використовуйте 0 для нескінченного повторення. * Поле `duration` у відповіді info — це загальна тривалість анімації в мілісекундах. --- --- url: https://docs.snapotter.com/ko/tools/image/gif-tools.md description: 애니메이션 GIF의 크기 조정, 최적화, 속도 변경, 반전, 회전, 프레임 추출을 하나의 도구에서 처리합니다. --- # GIF 도구 {#gif-tools} 애니메이션 GIF의 크기를 조정하고, 최적화하고, 속도를 변경하고, 반전하고, 프레임을 추출하고, 회전합니다. 하나의 도구에서 여러 작업 모드를 제공합니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## 파라미터 {#parameters} ### 공통 파라미터 {#common-parameters} | 파라미터 | 타입 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | mode | string | 아니오 | `"resize"` | 작업 모드: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | 아니오 | 0 | 출력 GIF의 반복 횟수(0 = 무한, 1-100 = 유한 반복) | ### 크기 조정 모드 파라미터 {#resize-mode-parameters} | 파라미터 | 타입 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | width | integer | 아니오 | - | 목표 너비(픽셀, 1에서 16384) | | height | integer | 아니오 | - | 목표 높이(픽셀, 1에서 16384) | | percentage | number | 아니오 | - | 비율로 조정(1에서 500). 설정하면 width/height를 무시합니다. | ### 최적화 모드 파라미터 {#optimize-mode-parameters} | 파라미터 | 타입 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | colors | number | 아니오 | 256 | 팔레트의 최대 색상 수(2에서 256) | | dither | number | 아니오 | 1.0 | 디더링 강도(0에서 1, 0이면 디더링 비활성화) | | effort | number | 아니오 | 7 | 최적화 노력 수준(1에서 10, 높을수록 느리지만 더 작음) | ### 속도 모드 파라미터 {#speed-mode-parameters} | 파라미터 | 타입 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | speedFactor | number | 아니오 | 1.0 | 속도 배수(0.1에서 10). 1보다 크면 빨라지고, 1보다 작으면 느려집니다. | ### 추출 모드 파라미터 {#extract-mode-parameters} | 파라미터 | 타입 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | extractMode | string | 아니오 | `"single"` | 추출 모드: `single`, `range`, `all` | | frameNumber | number | 아니오 | 0 | `single` 모드에서 추출할 프레임 인덱스(0부터 시작) | | frameStart | number | 아니오 | 0 | `range` 모드의 시작 프레임 인덱스(0부터 시작) | | frameEnd | number | 아니오 | - | `range` 모드의 끝 프레임 인덱스(0부터 시작, 포함) | | extractFormat | string | 아니오 | `"png"` | 추출 프레임 형식: `png`, `webp` | ### 회전 모드 파라미터 {#rotate-mode-parameters} | 파라미터 | 타입 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | angle | number | 아니오 | - | 회전 각도: `90`, `180`, 또는 `270` 도 | | flipH | boolean | 아니오 | `false` | 좌우 반전 | | flipV | boolean | 아니오 | `false` | 상하 반전 | ## 예제 요청 {#example-requests} ### 크기 조정 {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### 최적화 {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### 속도 높이기 {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### 단일 프레임 추출 {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## 예제 응답 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## 정보 하위 라우트 {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` 애니메이션 GIF를 처리하지 않고 그에 대한 메타데이터를 반환합니다. ### 정보 요청 {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### 정보 응답 {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## 참고 {#notes} * 메인 처리 엔드포인트에는 표준 `createToolRoute` 팩토리를 사용합니다. * 정보 엔드포인트는 파일 업로드만 필요합니다(설정 불필요). * `resize` 모드에서 `percentage`이 제공되면 `width`/`height`보다 우선합니다. 크기 조정은 종횡비를 유지하기 위해 `fit: inside`을 사용합니다. * `speed` 모드에서는 프레임 지연이 속도 배수로 나누어집니다. 프레임당 최소 지연은 20ms입니다(GIF 사양 제한). * `reverse` 모드에서는 반전하면서 동시에 속도를 조정할 수 있도록 `speedFactor` 파라미터도 사용할 수 있습니다. * `extract` 모드에서 `range` 또는 `all`를 사용하면 출력은 개별 프레임이 담긴 ZIP 파일입니다. * `rotate` 모드에서는 각 프레임이 개별적으로 처리된 후 애니메이션으로 다시 조립됩니다. * `loop` 파라미터는 출력 GIF가 몇 번 반복되는지를 제어합니다. 무한 반복에는 0을 사용하세요. * 정보 응답의 `duration` 필드는 총 애니메이션 재생 시간(밀리초)입니다. --- --- url: https://docs.snapotter.com/ja/tools/image/gif-tools.md description: アニメーション GIF のリサイズ、最適化、速度変更、逆再生、回転、フレーム抽出を 1 つのツールで行います。 --- # GIF ツール {#gif-tools} アニメーション GIF のリサイズ、最適化、速度変更、逆再生、フレーム抽出、回転を行います。1 つのツールで複数の操作モードを提供します。 ## API エンドポイント {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## パラメーター {#parameters} ### 共通パラメーター {#common-parameters} | パラメーター | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | mode | string | いいえ | `"resize"` | 操作モード: `resize`、`optimize`、`speed`、`reverse`、`extract`、`rotate` | | loop | number | いいえ | 0 | 出力 GIF のループ回数(0 = 無限、1〜100 = 有限ループ) | ### リサイズモードのパラメーター {#resize-mode-parameters} | パラメーター | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | width | integer | いいえ | - | 目標の幅(ピクセル、1 から 16384) | | height | integer | いいえ | - | 目標の高さ(ピクセル、1 から 16384) | | percentage | number | いいえ | - | パーセンテージでスケール(1 から 500)。設定すると width/height を上書きします。 | ### 最適化モードのパラメーター {#optimize-mode-parameters} | パラメーター | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | colors | number | いいえ | 256 | パレット内の最大色数(2 から 256) | | dither | number | いいえ | 1.0 | ディザリングの強度(0 から 1、0 でディザリングを無効化) | | effort | number | いいえ | 7 | 最適化の労力レベル(1 から 10、高いほど遅いが小さくなる) | ### 速度モードのパラメーター {#speed-mode-parameters} | パラメーター | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | speedFactor | number | いいえ | 1.0 | 速度倍率(0.1 から 10)。1 より大きい値で高速化、1 未満で低速化します。 | ### 抽出モードのパラメーター {#extract-mode-parameters} | パラメーター | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | extractMode | string | いいえ | `"single"` | 抽出モード: `single`、`range`、`all` | | frameNumber | number | いいえ | 0 | `single` モードで抽出するフレームのインデックス(0 始まり) | | frameStart | number | いいえ | 0 | `range` モードの開始フレームインデックス(0 始まり) | | frameEnd | number | いいえ | - | `range` モードの終了フレームインデックス(0 始まり、含む) | | extractFormat | string | いいえ | `"png"` | 抽出フレームの形式: `png`、`webp` | ### 回転モードのパラメーター {#rotate-mode-parameters} | パラメーター | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | angle | number | いいえ | - | 回転角度: `90`、`180`、または `270` 度 | | flipH | boolean | いいえ | `false` | 水平方向に反転 | | flipV | boolean | いいえ | `false` | 垂直方向に反転 | ## リクエスト例 {#example-requests} ### リサイズ {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### 最適化 {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### 高速化 {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### 単一フレームの抽出 {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## レスポンス例 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info サブルート {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` アニメーション GIF を処理せずにそのメタデータを返します。 ### Info リクエスト {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info レスポンス {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## 注記 {#notes} * メイン処理エンドポイントには標準の `createToolRoute` ファクトリを使用します。 * info エンドポイントはファイルのアップロードのみを必要とします(設定は不要)。 * `resize` モードでは、`percentage` が指定されている場合、`width`/`height` より優先されます。リサイズはアスペクト比を維持するために `fit: inside` を使用します。 * `speed` モードでは、フレームの遅延が速度係数で除算されます。フレームあたりの最小遅延は 20ms です(GIF 仕様の制限)。 * `reverse` モードでは、逆再生しながら同時に速度を調整するために `speedFactor` パラメーターも使用できます。 * `range` または `all` を指定した `extract` モードでは、出力は個々のフレームを含む ZIP ファイルになります。 * `rotate` モードでは、各フレームが個別に処理され、アニメーションに再構成されます。 * `loop` パラメーターは、出力 GIF がループする回数を制御します。無限ループには 0 を使用します。 * info レスポンスの `duration` フィールドは、アニメーション全体の再生時間(ミリ秒)です。 --- --- url: https://docs.snapotter.com/zh-CN/tools/image/gif-tools.md description: 在单个工具中对动画 GIF 进行调整大小、优化、变速、反转、旋转和提取帧。 --- # GIF 工具 {#gif-tools} 对动画 GIF 进行调整大小、优化、变速、反转、提取帧和旋转。在单个工具中提供多种操作模式。 ## API 端点 {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## 参数 {#parameters} ### 通用参数 {#common-parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | mode | string | 否 | `"resize"` | 操作模式:`resize`、`optimize`、`speed`、`reverse`、`extract`、`rotate` | | loop | number | 否 | 0 | 输出 GIF 的循环次数(0 = 无限,1-100 = 有限次循环) | ### 调整大小模式参数 {#resize-mode-parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | width | integer | 否 | - | 目标宽度(像素,1 到 16384) | | height | integer | 否 | - | 目标高度(像素,1 到 16384) | | percentage | number | 否 | - | 按百分比缩放(1 到 500)。设置后会覆盖 width/height。 | ### 优化模式参数 {#optimize-mode-parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | colors | number | 否 | 256 | 调色板中的最大颜色数(2 到 256) | | dither | number | 否 | 1.0 | 抖动强度(0 到 1,0 表示禁用抖动) | | effort | number | 否 | 7 | 优化投入级别(1 到 10,越高越慢但文件越小) | ### 变速模式参数 {#speed-mode-parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | speedFactor | number | 否 | 1.0 | 速度倍数(0.1 到 10)。值 > 1 加速,< 1 减速。 | ### 提取模式参数 {#extract-mode-parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | extractMode | string | 否 | `"single"` | 提取模式:`single`、`range`、`all` | | frameNumber | number | 否 | 0 | 在 `single` 模式下要提取的帧索引(从 0 开始) | | frameStart | number | 否 | 0 | `range` 模式下的起始帧索引(从 0 开始) | | frameEnd | number | 否 | - | `range` 模式下的结束帧索引(从 0 开始,含此帧) | | extractFormat | string | 否 | `"png"` | 提取帧的格式:`png`、`webp` | ### 旋转模式参数 {#rotate-mode-parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | angle | number | 否 | - | 旋转角度:`90`、`180` 或 `270` 度 | | flipH | boolean | 否 | `false` | 水平翻转 | | flipV | boolean | 否 | `false` | 垂直翻转 | ## 请求示例 {#example-requests} ### 调整大小 {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### 优化 {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### 加速 {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### 提取单帧 {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## 响应示例 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info 子路由 {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` 返回动画 GIF 的元数据而不对其进行处理。 ### Info 请求 {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info 响应 {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## 说明 {#notes} * 主处理端点使用标准的 `createToolRoute` 工厂。 * info 端点只需上传文件(无需设置)。 * 在 `resize` 模式下,如果提供了 `percentage`,它会优先于 `width`/`height`。调整大小使用 `fit: inside` 以保持宽高比。 * 在 `speed` 模式下,帧延迟会除以速度因子。每帧的最小延迟为 20ms(GIF 规范限制)。 * 在 `reverse` 模式下,还可使用 `speedFactor` 参数在反转的同时调整速度。 * 在 `extract` 模式且使用 `range` 或 `all` 时,输出是包含各个帧的 ZIP 文件。 * 在 `rotate` 模式下,会单独处理每一帧并重新组装成动画。 * `loop` 参数控制输出 GIF 的循环次数。使用 0 表示无限循环。 * info 响应中的 `duration` 字段是以毫秒为单位的动画总时长。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/gif-tools.md description: 在單一工具中對動態 GIF 進行縮放、最佳化、變速、反轉、旋轉並擷取影格。 --- # GIF 工具 {#gif-tools} 縮放、最佳化、變速、反轉、擷取影格並旋轉動態 GIF。在單一工具中提供多種操作模式。 ## API 端點 {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## 參數 {#parameters} ### 共用參數 {#common-parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | mode | string | 否 | `"resize"` | 操作模式:`resize`、`optimize`、`speed`、`reverse`、`extract`、`rotate` | | loop | number | 否 | 0 | 輸出 GIF 的循環次數(0 = 無限,1-100 = 有限循環) | ### 縮放模式參數 {#resize-mode-parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | width | integer | 否 | - | 目標寬度(像素,1 到 16384) | | height | integer | 否 | - | 目標高度(像素,1 到 16384) | | percentage | number | 否 | - | 依百分比縮放(1 到 500)。設定後會覆寫 width/height。 | ### 最佳化模式參數 {#optimize-mode-parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | colors | number | 否 | 256 | 調色盤中的最大顏色數(2 到 256) | | dither | number | 否 | 1.0 | 抖動強度(0 到 1,0 表示停用抖動) | | effort | number | 否 | 7 | 最佳化強度等級(1 到 10,越高越慢但檔案越小) | ### 變速模式參數 {#speed-mode-parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | speedFactor | number | 否 | 1.0 | 速度倍率(0.1 到 10)。大於 1 加速,小於 1 減速。 | ### 擷取模式參數 {#extract-mode-parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | extractMode | string | 否 | `"single"` | 擷取模式:`single`、`range`、`all` | | frameNumber | number | 否 | 0 | 在 `single` 模式下要擷取的影格索引(從 0 起算) | | frameStart | number | 否 | 0 | `range` 模式的起始影格索引(從 0 起算) | | frameEnd | number | 否 | - | `range` 模式的結束影格索引(從 0 起算,含此值) | | extractFormat | string | 否 | `"png"` | 擷取影格的格式:`png`、`webp` | ### 旋轉模式參數 {#rotate-mode-parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | angle | number | 否 | - | 旋轉角度:`90`、`180` 或 `270` 度 | | flipH | boolean | 否 | `false` | 水平翻轉 | | flipV | boolean | 否 | `false` | 垂直翻轉 | ## 範例請求 {#example-requests} ### 縮放 {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### 最佳化 {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### 加速 {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### 擷取單一影格 {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## 範例回應 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info 子路由 {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` 傳回動態 GIF 的中繼資料,而不對其進行處理。 ### Info 請求 {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info 回應 {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## 注意事項 {#notes} * 主處理端點使用標準的 `createToolRoute` factory。 * info 端點僅需上傳檔案(不需要設定)。 * 在 `resize` 模式下,若提供了 `percentage`,它會優先於 `width`/`height`。縮放時使用 `fit: inside` 以維持長寬比。 * 在 `speed` 模式下,影格延遲會除以速度係數。每影格最小延遲為 20ms(GIF 規格限制)。 * 在 `reverse` 模式下,也可使用 `speedFactor` 參數,在反轉的同時調整速度。 * 在 `extract` 模式下搭配 `range` 或 `all` 時,輸出為包含個別影格的 ZIP 檔案。 * 在 `rotate` 模式下,每個影格會被個別處理並重新組合為動畫。 * `loop` 參數控制輸出 GIF 循環的次數。使用 0 表示無限循環。 * info 回應中的 `duration` 欄位是動畫的總時長(毫秒)。 --- --- url: https://docs.snapotter.com/nl/tools/image/gif-tools.md description: >- Vergroot/verklein, optimaliseer, wijzig de snelheid, keer om, roteer en extraheer frames uit geanimeerde GIF's in één enkel hulpmiddel. --- # GIF-tools {#gif-tools} Vergroot/verklein, optimaliseer, wijzig de snelheid, keer om, extraheer frames en roteer geanimeerde GIF's. Biedt meerdere bewerkingsmodi in één enkel hulpmiddel. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parameters {#parameters} ### Algemene parameters {#common-parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | mode | string | Nee | `"resize"` | Bewerkingsmodus: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | Nee | 0 | Aantal herhalingen voor de uitvoer-GIF (0 = oneindig, 1-100 = eindig aantal herhalingen) | ### Parameters voor vergroten/verkleinen-modus {#resize-mode-parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | width | integer | Nee | - | Doelbreedte in pixels (1 tot 16384) | | height | integer | Nee | - | Doelhoogte in pixels (1 tot 16384) | | percentage | number | Nee | - | Schaal op percentage (1 tot 500). Overschrijft width/height indien ingesteld. | ### Parameters voor optimaliseren-modus {#optimize-mode-parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | colors | number | Nee | 256 | Maximaal aantal kleuren in het palet (2 tot 256) | | dither | number | Nee | 1.0 | Ditheringsterkte (0 tot 1, waarbij 0 dithering uitschakelt) | | effort | number | Nee | 7 | Optimalisatie-inspanningsniveau (1 tot 10, hoger = langzamer maar kleiner) | ### Parameters voor snelheidsmodus {#speed-mode-parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | speedFactor | number | Nee | 1.0 | Snelheidsvermenigvuldiger (0.1 tot 10). Waarden > 1 versnellen, < 1 vertragen. | ### Parameters voor extractiemodus {#extract-mode-parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | extractMode | string | Nee | `"single"` | Extractiemodus: `single`, `range`, `all` | | frameNumber | number | Nee | 0 | Frame-index om te extraheren in `single`-modus (0-gebaseerd) | | frameStart | number | Nee | 0 | Startframe-index voor `range`-modus (0-gebaseerd) | | frameEnd | number | Nee | - | Eindframe-index voor `range`-modus (0-gebaseerd, inclusief) | | extractFormat | string | Nee | `"png"` | Formaat voor geëxtraheerde frames: `png`, `webp` | ### Parameters voor rotatiemodus {#rotate-mode-parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | angle | number | Nee | - | Rotatiehoek: `90`, `180` of `270` graden | | flipH | boolean | Nee | `false` | Horizontaal spiegelen | | flipV | boolean | Nee | `false` | Verticaal spiegelen | ## Voorbeeldverzoeken {#example-requests} ### Vergroten/verkleinen {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimaliseren {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Versnellen {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Eén frame extraheren {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info-subroute {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Retourneert metadata over een geanimeerde GIF zonder deze te verwerken. ### Info-verzoek {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info-antwoord {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Opmerkingen {#notes} * Gebruikt de standaard `createToolRoute`-factory voor het hoofdverwerkingsendpoint. * Het info-endpoint vereist alleen een bestandsupload (geen instellingen nodig). * In `resize`-modus heeft `percentage` voorrang op `width`/`height` als het is opgegeven. Het vergroten/verkleinen gebruikt `fit: inside` om de beeldverhouding te behouden. * In `speed`-modus worden framevertragingen gedeeld door de snelheidsfactor. De minimale vertraging per frame is 20ms (beperking van de GIF-specificatie). * In `reverse`-modus is de parameter `speedFactor` ook beschikbaar om de snelheid gelijktijdig aan te passen tijdens het omkeren. * In `extract`-modus met `range` of `all` is de uitvoer een ZIP-bestand met de individuele frames. * In `rotate`-modus wordt elk frame afzonderlijk verwerkt en opnieuw samengevoegd tot een animatie. * De parameter `loop` bepaalt hoe vaak de uitvoer-GIF wordt herhaald. Gebruik 0 voor oneindig herhalen. * Het veld `duration` in het info-antwoord is de totale animatieduur in milliseconden. --- --- url: https://docs.snapotter.com/sv/tools/image/gif-tools.md description: >- Storleksändra, optimera, ändra hastighet, vänd, rotera och extrahera bildrutor från animerade GIF-filer i ett enda verktyg. --- # GIF-verktyg {#gif-tools} Storleksändra, optimera, ändra hastighet, vänd, extrahera bildrutor och rotera animerade GIF-filer. Erbjuder flera driftlägen i ett enda verktyg. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parametrar {#parameters} ### Gemensamma parametrar {#common-parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | mode | string | Nej | `"resize"` | Driftläge: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | Nej | 0 | Antal loopar för utdata-GIF (0 = oändligt, 1-100 = ändligt antal loopar) | ### Parametrar för storleksändringsläge {#resize-mode-parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | width | integer | Nej | - | Målbredd i pixlar (1 till 16384) | | height | integer | Nej | - | Målhöjd i pixlar (1 till 16384) | | percentage | number | Nej | - | Skala med procent (1 till 500). Åsidosätter width/height om den anges. | ### Parametrar för optimeringsläge {#optimize-mode-parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | colors | number | Nej | 256 | Maximalt antal färger i paletten (2 till 256) | | dither | number | Nej | 1.0 | Ditheringstyrka (0 till 1, där 0 inaktiverar dithering) | | effort | number | Nej | 7 | Optimeringsnivå (1 till 10, högre = långsammare men mindre) | ### Parametrar för hastighetsläge {#speed-mode-parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | speedFactor | number | Nej | 1.0 | Hastighetsmultiplikator (0.1 till 10). Värden > 1 snabbar upp, < 1 saktar ner. | ### Parametrar för extraheringsläge {#extract-mode-parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | extractMode | string | Nej | `"single"` | Extraheringsläge: `single`, `range`, `all` | | frameNumber | number | Nej | 0 | Bildruteindex att extrahera i läget `single` (0-baserat) | | frameStart | number | Nej | 0 | Startbildruteindex för läget `range` (0-baserat) | | frameEnd | number | Nej | - | Slutbildruteindex för läget `range` (0-baserat, inklusive) | | extractFormat | string | Nej | `"png"` | Format för extraherade bildrutor: `png`, `webp` | ### Parametrar för rotationsläge {#rotate-mode-parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | angle | number | Nej | - | Rotationsvinkel: `90`, `180` eller `270` grader | | flipH | boolean | Nej | `false` | Vänd horisontellt | | flipV | boolean | Nej | `false` | Vänd vertikalt | ## Exempelbegäranden {#example-requests} ### Storleksändra {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimera {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Snabba upp {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Extrahera enstaka bildruta {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info-underrutt {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Returnerar metadata om en animerad GIF utan att bearbeta den. ### Info-begäran {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info-svar {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Anmärkningar {#notes} * Använder standardfabriken `createToolRoute` för den huvudsakliga bearbetningsslutpunkten. * Info-slutpunkten kräver endast en filuppladdning (inga inställningar behövs). * I läget `resize`, om `percentage` anges har den prioritet över `width`/`height`. Storleksändringen använder `fit: inside` för att bibehålla bildförhållandet. * I läget `speed` divideras bildrutefördröjningarna med hastighetsfaktorn. Minsta fördröjning per bildruta är 20ms (begränsning i GIF-specifikationen). * I läget `reverse` är parametern `speedFactor` också tillgänglig för att samtidigt justera hastigheten medan vändningen sker. * I läget `extract` med `range` eller `all` är utdata en ZIP-fil som innehåller enskilda bildrutor. * I läget `rotate` bearbetas varje bildruta individuellt och sätts åter samman till en animation. * Parametern `loop` styr hur många gånger utdata-GIF:en loopar. Använd 0 för oändlig loopning. * Fältet `duration` i info-svaret är den totala animationslängden i millisekunder. --- --- url: https://docs.snapotter.com/de/tools/image/gif-tools.md description: >- Größe ändern, optimieren, Geschwindigkeit anpassen, umkehren, drehen und Frames aus animierten GIFs extrahieren, alles in einem Werkzeug. --- # GIF-Werkzeuge {#gif-tools} Größe ändern, optimieren, Geschwindigkeit anpassen, umkehren, Frames extrahieren und animierte GIFs drehen. Bietet mehrere Betriebsmodi in einem einzigen Werkzeug. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parameter {#parameters} ### Allgemeine Parameter {#common-parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | mode | string | Nein | `"resize"` | Betriebsmodus: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | Nein | 0 | Anzahl der Wiederholungen für die GIF-Ausgabe (0 = unendlich, 1-100 = endliche Wiederholungen) | ### Parameter für den Modus „Größe ändern“ {#resize-mode-parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | width | integer | Nein | - | Zielbreite in Pixeln (1 bis 16384) | | height | integer | Nein | - | Zielhöhe in Pixeln (1 bis 16384) | | percentage | number | Nein | - | Skalierung in Prozent (1 bis 500). Überschreibt width/height, wenn gesetzt. | ### Parameter für den Modus „Optimieren“ {#optimize-mode-parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | colors | number | Nein | 256 | Maximale Anzahl an Farben in der Palette (2 bis 256) | | dither | number | Nein | 1.0 | Dithering-Stärke (0 bis 1, wobei 0 das Dithering deaktiviert) | | effort | number | Nein | 7 | Optimierungsaufwand (1 bis 10, höher = langsamer, aber kleiner) | ### Parameter für den Modus „Geschwindigkeit“ {#speed-mode-parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | speedFactor | number | Nein | 1.0 | Geschwindigkeitsmultiplikator (0.1 bis 10). Werte > 1 beschleunigen, < 1 verlangsamen. | ### Parameter für den Modus „Extrahieren“ {#extract-mode-parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | extractMode | string | Nein | `"single"` | Extraktionsmodus: `single`, `range`, `all` | | frameNumber | number | Nein | 0 | Zu extrahierender Frame-Index im Modus `single` (0-basiert) | | frameStart | number | Nein | 0 | Start-Frame-Index für den Modus `range` (0-basiert) | | frameEnd | number | Nein | - | End-Frame-Index für den Modus `range` (0-basiert, einschließlich) | | extractFormat | string | Nein | `"png"` | Format für extrahierte Frames: `png`, `webp` | ### Parameter für den Modus „Drehen“ {#rotate-mode-parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | angle | number | Nein | - | Drehwinkel: `90`, `180` oder `270` Grad | | flipH | boolean | Nein | `false` | Horizontal spiegeln | | flipV | boolean | Nein | `false` | Vertikal spiegeln | ## Beispielanfragen {#example-requests} ### Größe ändern {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimieren {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Beschleunigen {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Einzelnen Frame extrahieren {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Info-Unterroute {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Gibt Metadaten zu einem animierten GIF zurück, ohne es zu verarbeiten. ### Info-Anfrage {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Info-Antwort {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Hinweise {#notes} * Verwendet die standardmäßige `createToolRoute`-Factory für den Haupt-Verarbeitungsendpunkt. * Der Info-Endpunkt erfordert nur einen Datei-Upload (keine Einstellungen erforderlich). * Im Modus `resize` hat `percentage`, falls angegeben, Vorrang vor `width`/`height`. Die Größenänderung verwendet `fit: inside`, um das Seitenverhältnis beizubehalten. * Im Modus `speed` werden die Frame-Verzögerungen durch den Geschwindigkeitsfaktor geteilt. Die minimale Verzögerung pro Frame beträgt 20 ms (Einschränkung der GIF-Spezifikation). * Im Modus `reverse` ist zusätzlich der Parameter `speedFactor` verfügbar, um die Geschwindigkeit gleichzeitig mit dem Umkehren anzupassen. * Im Modus `extract` mit `range` oder `all` ist die Ausgabe eine ZIP-Datei mit einzelnen Frames. * Im Modus `rotate` wird jeder Frame einzeln verarbeitet und wieder zu einer Animation zusammengesetzt. * Der Parameter `loop` steuert, wie oft die GIF-Ausgabe wiederholt wird. Verwenden Sie 0 für eine unendliche Wiederholung. * Das Feld `duration` in der Info-Antwort ist die Gesamtdauer der Animation in Millisekunden. --- --- url: https://docs.snapotter.com/hi/tools/image/gif-webp.md description: >- सभी फ़्रेमों को संरक्षित करते हुए animated GIF को WebP में और इसके विपरीत बदलें। --- # GIF/WebP Converter {#gif-webp-converter} सभी फ़्रेमों और एनिमेशन समय को संरक्षित करते हुए animated GIF फ़ाइलों को WebP में और इसके विपरीत बदलें। WebP एनिमेशन आमतौर पर समकक्ष GIFs की तुलना में 25-35% छोटे होते हैं। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-webp` GIF या WebP फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | integer | नहीं | `80` | WebP एन्कोडिंग के लिए आउटपुट गुणवत्ता (1-100) | | lossless | boolean | नहीं | `false` | lossless WebP संपीड़न का उपयोग करें | | resizePercent | integer | नहीं | `100` | आउटपुट को प्रतिशत के अनुसार स्केल करें (10-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Notes {#notes} * केवल `.gif` और `.webp` फ़ाइलें स्वीकार की जाती हैं। इस टूल द्वारा अन्य छवि प्रारूप समर्थित नहीं हैं। * रूपांतरण दिशा स्वचालित है: GIF इनपुट WebP आउटपुट उत्पन्न करता है, और WebP इनपुट GIF आउटपुट उत्पन्न करता है। * `quality` और `lossless` विकल्प केवल WebP में एन्कोड करते समय लागू होते हैं। GIF में बदलते समय, आउटपुट मानक GIF पैलेट का उपयोग करता है। * बड़े एनिमेशन के आयाम (और फ़ाइल आकार) कम करने के लिए `resizePercent` का उपयोग करें। --- --- url: https://docs.snapotter.com/id/tools/image/gif-webp.md description: Konversi GIF beranimasi ke WebP dan sebaliknya, mempertahankan semua frame. --- # GIF/WebP Converter {#gif-webp-converter} Konversi file GIF beranimasi ke WebP dan sebaliknya, mempertahankan semua frame dan timing animasi. Animasi WebP umumnya 25-35% lebih kecil daripada GIF yang setara. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Menerima multipart form data dengan file GIF atau WebP dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | integer | No | `80` | Kualitas output untuk encoding WebP (1-100) | | lossless | boolean | No | `false` | Gunakan kompresi WebP lossless | | resizePercent | integer | No | `100` | Skala output berdasarkan persentase (10-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Notes {#notes} * Hanya file `.gif` dan `.webp` yang diterima. Format gambar lain tidak didukung oleh alat ini. * Arah konversi bersifat otomatis: input GIF menghasilkan output WebP, dan input WebP menghasilkan output GIF. * Opsi `quality` dan `lossless` hanya berlaku saat encoding ke WebP. Saat mengonversi ke GIF, output menggunakan palet GIF standar. * Gunakan `resizePercent` untuk memperkecil dimensi (dan ukuran file) animasi berukuran besar. --- --- url: https://docs.snapotter.com/th/tools/image/gif-webp.md description: แปลง GIF เคลื่อนไหวเป็น WebP และในทางกลับกัน โดยรักษาทุกเฟรมไว้ --- # GIF/WebP Converter {#gif-webp-converter} แปลงไฟล์ GIF เคลื่อนไหวเป็น WebP และในทางกลับกัน โดยรักษาทุกเฟรมและจังหวะเวลาของภาพเคลื่อนไหว ภาพเคลื่อนไหว WebP โดยทั่วไปมีขนาดเล็กกว่า GIF ที่เทียบเท่ากันประมาณ 25-35% ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-webp` รับข้อมูลแบบ multipart form data ที่มีไฟล์ GIF หรือ WebP และฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | quality | integer | No | `80` | คุณภาพผลลัพธ์สำหรับการเข้ารหัส WebP (1-100) | | lossless | boolean | No | `false` | ใช้การบีบอัด WebP แบบ lossless | | resizePercent | integer | No | `100` | ปรับสัดส่วนผลลัพธ์ตามเปอร์เซ็นต์ (10-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Notes {#notes} * รับเฉพาะไฟล์ `.gif` และ `.webp` เท่านั้น เครื่องมือนี้ไม่รองรับรูปแบบภาพอื่นๆ * ทิศทางการแปลงเป็นแบบอัตโนมัติ: อินพุต GIF ผลิตเอาต์พุต WebP และอินพุต WebP ผลิตเอาต์พุต GIF * ตัวเลือก `quality` และ `lossless` ใช้ได้เฉพาะเมื่อเข้ารหัสเป็น WebP เมื่อแปลงเป็น GIF ผลลัพธ์จะใช้จานสี GIF มาตรฐาน * ใช้ `resizePercent` เพื่อลดขนาด (และขนาดไฟล์) ของภาพเคลื่อนไหวขนาดใหญ่ --- --- url: https://docs.snapotter.com/tr/tools/image/gif-webp.md description: Animasyonlu GIF'i WebP'ye ve tersine dönüştürün, tüm kareleri koruyun. --- # GIF/WebP Dönüştürücü {#gif-webp-converter} Animasyonlu GIF dosyalarını WebP'ye ve tersine dönüştürün; tüm kareleri ve animasyon zamanlamasını koruyun. WebP animasyonları genellikle eşdeğer GIF'lerden %25-35 daha küçüktür. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Bir GIF veya WebP dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | quality | integer | Hayır | `80` | WebP kodlaması için çıktı kalitesi (1-100) | | lossless | boolean | Hayır | `false` | Kayıpsız WebP sıkıştırması kullan | | resizePercent | integer | Hayır | `100` | Çıktıyı yüzdeye göre ölçeklendir (10-100) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Notlar {#notes} * Yalnızca `.gif` ve `.webp` dosyaları kabul edilir. Diğer görsel biçimleri bu araç tarafından desteklenmez. * Dönüştürme yönü otomatiktir: GIF girişi WebP çıktısı üretir, WebP girişi ise GIF çıktısı üretir. * `quality` ve `lossless` seçenekleri yalnızca WebP'ye kodlarken geçerlidir. GIF'e dönüştürürken çıktı, standart GIF paletini kullanır. * Büyük animasyonların boyutlarını (ve dosya boyutunu) azaltmak için `resizePercent` kullanın. --- --- url: https://docs.snapotter.com/ko/tools/image/gif-webp.md description: 모든 프레임을 보존하면서 애니메이션 GIF를 WebP로, 그리고 그 반대로 변환합니다. --- # GIF/WebP 변환기 {#gif-webp-converter} 애니메이션 GIF 파일을 WebP로, 그리고 그 반대로 변환하며 모든 프레임과 애니메이션 타이밍을 보존합니다. WebP 애니메이션은 일반적으로 동등한 GIF보다 25-35% 더 작습니다. ## API 엔드포인트 {#api-endpoint} `POST /api/v1/tools/image/gif-webp` GIF 또는 WebP 파일과 JSON `settings` 필드가 포함된 multipart 폼 데이터를 받습니다. ## 파라미터 {#parameters} | 파라미터 | 타입 | 필수 | 기본값 | 설명 | |-----------|------|----------|---------|-------------| | quality | integer | 아니오 | `80` | WebP 인코딩의 출력 품질(1-100) | | lossless | boolean | 아니오 | `false` | 무손실 WebP 압축 사용 | | resizePercent | integer | 아니오 | `100` | 출력을 비율로 조정(10-100) | ## 예제 요청 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## 예제 응답 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## 참고 {#notes} * `.gif` 및 `.webp` 파일만 허용됩니다. 다른 이미지 형식은 이 도구에서 지원되지 않습니다. * 변환 방향은 자동입니다: GIF 입력은 WebP 출력을, WebP 입력은 GIF 출력을 만들어 냅니다. * `quality` 및 `lossless` 옵션은 WebP로 인코딩할 때만 적용됩니다. GIF로 변환할 때 출력은 표준 GIF 팔레트를 사용합니다. * 큰 애니메이션의 치수(및 파일 크기)를 줄이려면 `resizePercent`을 사용하세요. --- --- url: https://docs.snapotter.com/ja/tools/image/gif-webp.md description: すべてのフレームを保持したまま、アニメーション GIF を WebP に、またはその逆に変換します。 --- # GIF/WebP コンバーター {#gif-webp-converter} すべてのフレームとアニメーションのタイミングを保持したまま、アニメーション GIF ファイルを WebP に、またはその逆に変換します。WebP アニメーションは、同等の GIF よりも通常 25〜35% 小さくなります。 ## API エンドポイント {#api-endpoint} `POST /api/v1/tools/image/gif-webp` GIF または WebP ファイルと JSON `settings` フィールドを含む multipart フォームデータを受け付けます。 ## パラメーター {#parameters} | パラメーター | 型 | 必須 | デフォルト | 説明 | |-----------|------|----------|---------|-------------| | quality | integer | いいえ | `80` | WebP エンコードの出力品質(1〜100) | | lossless | boolean | いいえ | `false` | ロスレス WebP 圧縮を使用 | | resizePercent | integer | いいえ | `100` | 出力をパーセンテージでスケール(10〜100) | ## リクエスト例 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## レスポンス例 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## 注記 {#notes} * `.gif` と `.webp` ファイルのみが受け付けられます。他の画像形式はこのツールではサポートされていません。 * 変換方向は自動です: GIF 入力は WebP 出力を生成し、WebP 入力は GIF 出力を生成します。 * `quality` と `lossless` オプションは、WebP へのエンコード時にのみ適用されます。GIF への変換時は、出力は標準の GIF パレットを使用します。 * 大きなアニメーションの寸法(およびファイルサイズ)を縮小するには `resizePercent` を使用します。 --- --- url: https://docs.snapotter.com/zh-CN/tools/image/gif-webp.md description: 在动画 GIF 与 WebP 之间互相转换,保留所有帧。 --- # GIF/WebP 转换器 {#gif-webp-converter} 在动画 GIF 文件与 WebP 之间互相转换,保留所有帧和动画时序。WebP 动画通常比等效的 GIF 小 25-35%。 ## API 端点 {#api-endpoint} `POST /api/v1/tools/image/gif-webp` 接受包含一个 GIF 或 WebP 文件的 multipart 表单数据,以及一个 JSON `settings` 字段。 ## 参数 {#parameters} | 参数 | 类型 | 是否必填 | 默认值 | 说明 | |-----------|------|----------|---------|-------------| | quality | integer | 否 | `80` | WebP 编码的输出质量(1-100) | | lossless | boolean | 否 | `false` | 使用无损 WebP 压缩 | | resizePercent | integer | 否 | `100` | 按百分比缩放输出(10-100) | ## 请求示例 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## 响应示例 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## 说明 {#notes} * 仅接受 `.gif` 和 `.webp` 文件。此工具不支持其他图像格式。 * 转换方向是自动的:GIF 输入生成 WebP 输出,WebP 输入生成 GIF 输出。 * `quality` 和 `lossless` 选项仅在编码为 WebP 时适用。转换为 GIF 时,输出使用标准 GIF 调色板。 * 使用 `resizePercent` 来缩小大型动画的尺寸(以及文件大小)。 --- --- url: https://docs.snapotter.com/zh-TW/tools/image/gif-webp.md description: 在動態 GIF 與 WebP 之間互相轉換,並保留所有影格。 --- # GIF/WebP 轉換器 {#gif-webp-converter} 在動態 GIF 檔案與 WebP 之間互相轉換,保留所有影格與動畫時序。WebP 動畫通常比同等的 GIF 小 25-35%。 ## API 端點 {#api-endpoint} `POST /api/v1/tools/image/gif-webp` 接受包含一個 GIF 或 WebP 檔案的 multipart 表單資料,以及一個 JSON `settings` 欄位。 ## 參數 {#parameters} | 參數 | 型別 | 必填 | 預設值 | 說明 | |-----------|------|----------|---------|-------------| | quality | integer | 否 | `80` | WebP 編碼的輸出品質(1-100) | | lossless | boolean | 否 | `false` | 使用無損 WebP 壓縮 | | resizePercent | integer | 否 | `100` | 依百分比縮放輸出(10-100) | ## 範例請求 {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## 範例回應 {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## 注意事項 {#notes} * 僅接受 `.gif` 與 `.webp` 檔案。此工具不支援其他圖片格式。 * 轉換方向會自動判定:GIF 輸入產生 WebP 輸出,WebP 輸入產生 GIF 輸出。 * `quality` 與 `lossless` 選項僅在編碼為 WebP 時適用。轉換為 GIF 時,輸出會使用標準的 GIF 調色盤。 * 使用 `resizePercent` 縮小大型動畫的尺寸(與檔案大小)。 --- --- url: https://docs.snapotter.com/nl/tools/image/gif-webp.md description: Converteer geanimeerde GIF naar WebP en omgekeerd, met behoud van alle frames. --- # GIF/WebP-converter {#gif-webp-converter} Converteer geanimeerde GIF-bestanden naar WebP en omgekeerd, met behoud van alle frames en de animatietiming. WebP-animaties zijn doorgaans 25-35% kleiner dan gelijkwaardige GIF's. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Accepteert multipart-formuliergegevens met een GIF- of WebP-bestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | quality | integer | Nee | `80` | Uitvoerkwaliteit voor WebP-codering (1-100) | | lossless | boolean | Nee | `false` | Gebruik lossless WebP-compressie | | resizePercent | integer | Nee | `100` | Schaal de uitvoer op percentage (10-100) | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Opmerkingen {#notes} * Alleen `.gif`- en `.webp`-bestanden worden geaccepteerd. Andere afbeeldingsformaten worden door dit hulpmiddel niet ondersteund. * De conversierichting is automatisch: GIF-invoer produceert WebP-uitvoer, en WebP-invoer produceert GIF-uitvoer. * De opties `quality` en `lossless` zijn alleen van toepassing bij codering naar WebP. Bij conversie naar GIF gebruikt de uitvoer het standaard GIF-palet. * Gebruik `resizePercent` om de afmetingen (en bestandsgrootte) van grote animaties te verkleinen. --- --- url: https://docs.snapotter.com/de/tools/image/gif-webp.md description: >- Konvertiert animierte GIFs in WebP und umgekehrt und behält dabei alle Frames bei. --- # GIF/WebP-Konverter {#gif-webp-converter} Konvertiert animierte GIF-Dateien in WebP und umgekehrt und behält dabei alle Frames und das Animations-Timing bei. WebP-Animationen sind typischerweise 25-35 % kleiner als vergleichbare GIFs. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Akzeptiert Multipart-Formulardaten mit einer GIF- oder WebP-Datei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | quality | integer | Nein | `80` | Ausgabequalität für die WebP-Codierung (1-100) | | lossless | boolean | Nein | `false` | Verlustfreie WebP-Kompression verwenden | | resizePercent | integer | Nein | `100` | Ausgabe in Prozent skalieren (10-100) | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Hinweise {#notes} * Es werden nur `.gif`- und `.webp`-Dateien akzeptiert. Andere Bildformate werden von diesem Werkzeug nicht unterstützt. * Die Konvertierungsrichtung erfolgt automatisch: GIF-Eingabe erzeugt WebP-Ausgabe, und WebP-Eingabe erzeugt GIF-Ausgabe. * Die Optionen `quality` und `lossless` gelten nur beim Codieren in WebP. Bei der Konvertierung in GIF verwendet die Ausgabe die standardmäßige GIF-Palette. * Verwenden Sie `resizePercent`, um die Abmessungen (und die Dateigröße) großer Animationen zu reduzieren. --- --- url: https://docs.snapotter.com/sv/tools/image/gif-webp.md description: >- Konvertera animerad GIF till WebP och vice versa, med bevarande av alla bildrutor. --- # GIF/WebP-konverterare {#gif-webp-converter} Konvertera animerade GIF-filer till WebP och vice versa, med bevarande av alla bildrutor och animationstiming. WebP-animationer är vanligtvis 25-35% mindre än motsvarande GIF-filer. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/gif-webp` Tar emot multipart-formulärdata med en GIF- eller WebP-fil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | quality | integer | Nej | `80` | Utdatakvalitet för WebP-kodning (1-100) | | lossless | boolean | Nej | `false` | Använd förlustfri WebP-komprimering | | resizePercent | integer | Nej | `100` | Skala utdata med procent (10-100) | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-webp \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@animation.gif" \ -F 'settings={"quality": 85, "resizePercent": 50}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", "originalSize": 3500000, "processedSize": 2200000 } ``` ## Anmärkningar {#notes} * Endast `.gif`- och `.webp`-filer accepteras. Andra bildformat stöds inte av detta verktyg. * Konverteringsriktningen är automatisk: GIF-inmatning ger WebP-utdata, och WebP-inmatning ger GIF-utdata. * Alternativen `quality` och `lossless` gäller endast vid kodning till WebP. Vid konvertering till GIF använder utdata standard-GIF-paletten. * Använd `resizePercent` för att minska dimensionerna (och filstorleken) på stora animationer. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/rotate.md description: Gire imagens em qualquer ângulo e espelhe na horizontal ou na vertical. --- # Girar e Espelhar Imagem {#rotate-flip} Gire imagens em um ângulo arbitrário e/ou espelhe-as na horizontal ou na vertical. As operações de rotação e espelhamento podem ser combinadas em uma única requisição. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/rotate` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | angle | number | Não | `0` | Ângulo de rotação em graus (sentido horário). Aceita qualquer valor numérico. | | horizontal | boolean | Não | `false` | Espelhar a imagem na horizontal (espelho) | | vertical | boolean | Não | `false` | Espelhar a imagem na vertical | ## Exemplo de Requisição {#example-request} Girar 90 graus no sentido horário: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 90}' ``` Espelhar na horizontal: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"horizontal": true}' ``` Girar e espelhar juntos: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 45, "vertical": true}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Notas {#notes} * A rotação é aplicada primeiro, depois as operações de espelhamento. * Rotações que não são de 90 graus (por exemplo, 45 graus) ampliarão a tela para acomodar a imagem girada, com preenchimento transparente ou preto dependendo do formato de saída. * Valores comuns: 90, 180, 270 para rotações de um quarto de volta. * A orientação EXIF é aplicada automaticamente antes do processamento, então a rotação é relativa à orientação visual. --- --- url: https://docs.snapotter.com/es/tools/pdf/rotate-pdf.md description: Gira las páginas de un PDF 90, 180 o 270 grados. --- # Girar PDF {#rotate-pdf} Gira todas las páginas de un PDF, o las seleccionadas, en un ángulo determinado. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/rotate-pdf` Acepta datos de formulario multipart con un archivo PDF y un campo JSON `settings`. ## Parameters {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | angle | integer | No | `90` | Ángulo de rotación: `90`, `180` o `270` | | range | string | No | `"1-z"` | Rango de páginas en sintaxis qpdf, p. ej. `"1-5,8"` (`"1-z"` = todas las páginas) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/rotate-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"angle": 90, "range": "1-3"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2450000 } ``` ## Notes {#notes} * La rotación es en el sentido de las agujas del reloj. * Los rangos de páginas usan la sintaxis de qpdf: `1-5` para las páginas 1 a 5, `z` para la última página y comas para combinar rangos. * El rango predeterminado `"1-z"` gira todas las páginas. --- --- url: https://docs.snapotter.com/it/tools/image/erase-object.md description: >- Rimuovi oggetti indesiderati dalle immagini con l'inpainting IA (LaMa), guidato da una maschera della regione da cancellare. --- # Gomma per oggetti {#object-eraser} Rimuovi oggetti indesiderati dalle immagini usando l'inpainting IA (modello LaMa). Accetta un'immagine e una maschera che indica la regione da cancellare. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/erase-object` **Elaborazione:** Asincrona (restituisce 202, esegui il polling di `/api/v1/jobs/{jobId}/progress` per lo stato tramite SSE) **Bundle del modello:** `object-eraser-colorize` (1-2 GB) ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | file | file | Sì | - | File immagine di origine (multipart) | | mask | file | Sì | - | Immagine maschera (bianco = area da cancellare, nero = mantieni). Deve essere caricata con il fieldname `mask` | | format | string | No | `"auto"` | Formato di output: `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | No | `95` | Qualità di output (1-100) | ## Esempio di richiesta {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/erase-object \ -F "file=@photo.jpg" \ -F "mask=@mask.png" \ -F "format=png" \ -F "quality=95" ``` ## Risposta {#response} ### Risposta iniziale (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Avanzamento (SSE su `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Inpainting...","percent":70} ``` ### Risultato finale (tramite SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_erased.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 245000, "processedSize": 230000 } } ``` ## Note {#notes} * Richiede l'installazione del bundle del modello `object-eraser-colorize` (1-2 GB). * La maschera deve avere le stesse dimensioni dell'immagine di origine. I pixel bianchi indicano le aree da cancellare; l'IA le riempie con contenuto plausibile. * Usa LaMa (Large Mask Inpainting) per una rimozione degli oggetti di alta qualità. * Per i formati di output non visualizzabili in anteprima nel browser, viene generata un'anteprima WebP insieme all'output principale. * Supporta i formati di input HEIC/HEIF, RAW, TGA, PSD, EXR e HDR tramite decodifica automatica. --- --- url: https://docs.snapotter.com/fr/tools/image/erase-object.md description: >- Retirez les objets indésirables des images avec l'inpainting par IA (LaMa), guidé par un masque de la région à effacer. --- # Gomme d'objets {#object-eraser} Retirez les objets indésirables des images à l'aide de l'inpainting par IA (modèle LaMa). Accepte une image et un masque indiquant la région à effacer. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/erase-object` **Traitement :** asynchrone (renvoie 202, interrogez `/api/v1/jobs/{jobId}/progress` pour le statut via SSE) **Bundle de modèle :** `object-eraser-colorize` (1-2 Go) ## Parameters {#parameters} | Paramètre | Type | Requis | Défaut | Description | |-----------|------|----------|---------|-------------| | file | file | Oui | - | Fichier image source (multipart) | | mask | file | Oui | - | Image de masque (blanc = zone à effacer, noir = à conserver). Doit être téléversée avec le nom de champ `mask` | | format | string | Non | `"auto"` | Format de sortie : `auto`, `png`, `jpg`, `jpeg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | integer | Non | `95` | Qualité de sortie (1-100) | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/erase-object \ -F "file=@photo.jpg" \ -F "mask=@mask.png" \ -F "format=png" \ -F "quality=95" ``` ## Response {#response} ### Initial Response (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Progress (SSE at `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Inpainting...","percent":70} ``` ### Final Result (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_erased.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 245000, "processedSize": 230000 } } ``` ## Notes {#notes} * Nécessite l'installation du bundle de modèle `object-eraser-colorize` (1-2 Go). * Le masque doit avoir les mêmes dimensions que l'image source. Les pixels blancs indiquent les zones à effacer ; l'IA les remplit avec un contenu plausible. * Utilise LaMa (Large Mask Inpainting) pour une suppression d'objets de haute qualité. * Pour les formats de sortie non prévisualisables dans le navigateur, un aperçu WebP est généré en parallèle de la sortie principale. * Prend en charge les formats d'entrée HEIC/HEIF, RAW, TGA, PSD, EXR et HDR par décodage automatique. --- --- url: https://docs.snapotter.com/vi/tools/audio/merge-audio.md description: Kết hợp nhiều tệp âm thanh thành một bản tuần tự. --- # Gộp âm thanh {#merge-audio} Kết hợp hai hoặc nhiều tệp âm thanh thành một bản tuần tự duy nhất, được nối theo thứ tự chúng được tải lên. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/audio/merge-audio` Chấp nhận dữ liệu form multipart với nhiều tệp âm thanh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | format | string | Không | `"mp3"` | Định dạng đầu ra: `mp3`, `wav`, `flac`, `m4a` | ## Yêu cầu ví dụ {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/audio/merge-audio \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@intro.mp3" \ -F "file=@main.mp3" \ -F "file=@outro.mp3" \ -F 'settings={"format": "mp3"}' ``` ## Phản hồi ví dụ {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.mp3", "originalSize": 9500000, "processedSize": 9200000 } ``` ## Ghi chú {#notes} * Chấp nhận 2 đến 10 tệp âm thanh mỗi yêu cầu. * Các tệp được nối theo thứ tự tải lên. * Tất cả tệp đầu vào được mã hóa lại về định dạng đầu ra và tần số lấy mẫu đã chọn để nối liền mạch. * Định dạng đầu vào hỗn hợp được hỗ trợ (ví dụ một tệp WAV và một tệp MP3). --- --- url: https://docs.snapotter.com/sv/tools/image/blur-faces.md description: >- Upptäck och gör ansikten suddiga automatiskt i bilder med AI-ansiktsigenkänning för integritet och GDPR-kompatibel anonymisering. --- # Gör ansikten & PII oskarpa {#face-pii-blur} Upptäck och gör ansikten suddiga automatiskt i bilder med AI-driven ansiktsigenkänning (MediaPipe). ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/blur-faces` **Bearbetning:** Asynkron (returnerar 202, hämta status genom att polla `/api/v1/jobs/{jobId}/progress` via SSE) **Modellpaket:** `face-detection` (200-300 MB) ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | file | fil | Ja | - | Bildfil (multipart) | | blurRadius | tal | Nej | `30` | Oskärperadie som tillämpas på upptäckta ansikten (1-100) | | sensitivity | tal | Nej | `0.5` | Känslighet för ansiktsigenkänning (0-1). Lägre värden upptäcker färre ansikten med högre säkerhet | ## Exempelförfrågan {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-faces \ -F "file=@group-photo.jpg" \ -F 'settings={"blurRadius":40,"sensitivity":0.3}' ``` ## Svar {#response} ### Första svaret (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Förlopp (SSE på `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Detecting faces...","percent":40} ``` ### Slutresultat (via SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/group-photo_blurred.jpg", "originalSize": 450000, "processedSize": 420000, "facesDetected": 3, "faces": [ {"x": 100, "y": 50, "w": 80, "h": 80}, {"x": 300, "y": 60, "w": 75, "h": 75}, {"x": 500, "y": 55, "w": 85, "h": 85} ] } } ``` ### Inga ansikten upptäckta {#no-faces-detected} Om inga ansikten hittas innehåller resultatet en varning: ```json { "phase": "complete", "percent": 100, "result": { "facesDetected": 0, "warning": "No faces detected in this image. Try increasing detection sensitivity." } } ``` ## Anteckningar {#notes} * Kräver att modellpaketet `face-detection` är installerat (200-300 MB). * Utdataformatet matchar indataformatet automatiskt. * Arrayen `faces` innehåller begränsningsrutans koordinater (x, y, bredd, höjd) för varje upptäckt ansikte. * Öka `sensitivity` (närmare 1,0) för att upptäcka fler ansikten, inklusive delvis skymda. * Stöder indataformaten HEIC/HEIF, RAW, TGA, PSD, EXR och HDR via automatisk avkodning. --- --- url: https://docs.snapotter.com/tr/tools/image/info.md description: >- Ayrıntılı görsel meta verilerini, özelliklerini ve kanal başına histogram istatistiklerini görüntüleyin. --- # Görsel Bilgisi {#image-info} Boyutlar, biçim, renk uzayı, EXIF/ICC/XMP varlığı ve kanal başına histogram istatistikleri dahil kapsamlı görsel meta verilerini döndüren salt okunur analiz aracı. İşlenmiş bir çıktı dosyası üretmez. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/info` Bir görsel dosyası içeren multipart form verisini kabul eder. Ayar alanı gerekmez. ## Parametreler {#parameters} Bu aracın yapılandırılabilir parametresi yoktur. Sadece görsel dosyasını yükleyin. | Alan | Tür | Zorunlu | Açıklama | |-------|------|----------|-------------| | file | file | Evet | Analiz edilecek görsel | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/info \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Örnek Yanıt {#example-response} ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "orientation": 1, "hasProfile": true, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` ## Yanıt Alanları {#response-fields} | Alan | Tür | Açıklama | |-------|------|-------------| | filename | string | Temizlenmiş dosya adı | | fileSize | number | Bayt cinsinden dosya boyutu | | width | number | Piksel cinsinden görsel genişliği | | height | number | Piksel cinsinden görsel yüksekliği | | format | string | Algılanan biçim (jpeg, png, webp vb.) | | channels | number | Renk kanallarının sayısı | | hasAlpha | boolean | Görselin bir alfa kanalı olup olmadığı | | colorSpace | string | Renk uzayı (srgb, cmyk vb.) | | density | number veya null | DPI/PPI çözünürlüğü | | isProgressive | boolean | JPEG'in progresif kodlama kullanıp kullanmadığı | | orientation | number veya null | EXIF yönlendirme değeri (1-8) | | hasProfile | boolean | Gömülü bir ICC profilinin olup olmadığı | | hasExif | boolean | EXIF meta verisinin mevcut olup olmadığı | | hasIcc | boolean | Bir ICC renk profilinin mevcut olup olmadığı | | hasXmp | boolean | XMP meta verisinin mevcut olup olmadığı | | bitDepth | string veya null | Örnek başına bit | | pages | number | Sayfa sayısı (TIFF, GIF gibi çok sayfalı biçimler için) | | histogram | array | Kanal başına istatistikler (min, maks, ortalama, standart sapma) | ## Notlar {#notes} * Bu, salt okunur bir uç noktadır. İndirilebilir bir çıktı dosyası veya bir `jobId` üretmez. * RAW biçimli görseller (DNG, CR2, NEF, ARW vb.) için, Sharp'ın doğrudan okuyamadığı gerçek sensör boyutlarını ve meta veri bayraklarını çıkarmak amacıyla ExifTool kullanılır. * HEIC/HEIF dosyaları, Sharp HEVC pikselleri çözümleyemediği için piksel istatistiklerini çıkarmak amacıyla dahili olarak PNG'ye çözümlenir. * Histogram, tam bir 256 bölmeli dağılım değil, kanal başına min/maks/ortalama/standart sapma sağlar. * `density` alanı, varsa gömülü DPI meta verisini yansıtır. --- --- url: https://docs.snapotter.com/tr/tools/image/image-pad.md description: >- Bir görseli düz renk, saydam veya bulanık arka planla hedef en boy oranına dolgulayın. --- # Görsel Dolgusu {#image-pad} Bir görselin çevresine düz renk, saydam veya bulanık bir arka plan ekleyerek onu hedef en boy oranına dolgulayın. Görselleri kırpmadan sosyal medya veya baskı için sabit en boy oranlarına sığdırmak için kullanışlıdır. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/image-pad` Bir görsel dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | target | string | Hayır | `"1:1"` | Hedef en boy oranı: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` veya `custom` | | ratioW | integer | Hayır | `1` | Özel oran genişliği (1-100, target `custom` olduğunda kullanılır) | | ratioH | integer | Hayır | `1` | Özel oran yüksekliği (1-100, target `custom` olduğunda kullanılır) | | background | string | Hayır | `"color"` | Arka plan modu: `color`, `transparent` veya `blur` | | color | string | Hayır | `"#ffffff"` | Arka plan hex rengi (background `color` olduğunda) | | padding | integer | Hayır | `0` | Tuval yüzdesi olarak ekstra dolgu (0-50) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-pad \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 3100000 } ``` ## Notlar {#notes} * `blur` arka plan modu, dolgu doldurması olarak orijinal görselin bulanık bir kopyasını oluşturarak görsel açıdan tutarlı bir sonuç üretir. * `transparent` arka plan kullanılırken, alfayı korumak için çıktı PNG'ye dönüştürülür. * Saydamlık söz konusu olmadıkça çıktı biçimi giriş biçimiyle eşleşir. HEIC, RAW, PSD ve SVG girişleri işlemeden önce otomatik olarak çözümlenir. * Rastgele en boy oranları için `target` değerini `custom` olarak ayarlayın ve `ratioW` ile `ratioH` değerlerini sağlayın (örn. 3:2 için `ratioW: 3, ratioH: 2`). --- --- url: https://docs.snapotter.com/tr/tools/image/image-enhancement.md description: >- Bir görseli analiz eden ve pozlamayı, kontrastı, beyaz dengesini, doygunluğu ve keskinliği düzelten tek tıkla otomatik geliştirme. --- # Görsel Geliştirme {#image-enhancement} Akıllı analizle tek tıkla otomatik iyileştirme. Görseli analiz eder ve pozlama, kontrast, beyaz dengesi, doygunluk, keskinlik ve gürültü azaltma düzeltmelerini uygular. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/image-enhancement` **İşleme:** Eşzamanlı (`createToolRoute` fabrikasını kullanır, sonucu doğrudan döndürür) **Model paketi:** Temel geliştirme için hiçbiri gerekmez. `upscale-enhance` paketi (5-6 GB) yalnızca `deepEnhance` etkinleştirildiğinde kullanılır (SCUNet aracılığıyla yapay zeka gürültü giderme için). ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | file | Evet | - | Görsel dosyası (multipart) | | mode | string | Hayır | `"auto"` | Geliştirme modu: `auto`, `portrait`, `landscape`, `low-light`, `food`, `document` | | intensity | number | Hayır | `50` | Genel geliştirme yoğunluğu (0-100) | | corrections | object | Hayır | tümü `true` | Uygulanacak seçmeli düzeltmeler (aşağıya bakın) | | deepEnhance | boolean | Hayır | `false` | Yapay zeka destekli gürültü gidermeyi etkinleştir (`noise-removal` aracının kurulu olmasını gerektirir) | ### Düzeltmeler Nesnesi {#corrections-object} | Alan | Tür | Varsayılan | Açıklama | |-------|------|---------|-------------| | exposure | boolean | `true` | Pozlamayı otomatik düzelt | | contrast | boolean | `true` | Kontrastı otomatik düzelt | | whiteBalance | boolean | `true` | Beyaz dengesini otomatik düzelt | | saturation | boolean | `true` | Doygunluğu otomatik düzelt | | sharpness | boolean | `true` | Otomatik keskinleştir | | denoise | boolean | `true` | Hafif gürültü giderme | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement \ -F "file=@photo.jpg" \ -F 'settings={"mode":"portrait","intensity":70,"corrections":{"exposure":true,"contrast":true,"sharpness":false}}' ``` ## Yanıt (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo.jpg", "originalSize": 300000, "processedSize": 310000 } ``` ## Analiz Uç Noktası {#analyze-endpoint} `POST /api/v1/tools/image/image-enhancement/analyze` Bir görseli analiz eder ve düzeltmeleri uygulamadan düzeltme önerileri döndürür. ### Parametreler {#parameters-1} | Parametre | Tür | Zorunlu | Açıklama | |-----------|------|----------|-------------| | file | file | Evet | Görsel dosyası (multipart) | ### Örnek İstek {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-enhancement/analyze \ -F "file=@photo.jpg" ``` ### Yanıt (200 OK) {#response-200-ok-1} ```json { "corrections": { "exposure": { "value": 0.3, "direction": "brighten" }, "contrast": { "value": 0.2, "direction": "increase" }, "whiteBalance": { "value": 200, "direction": "warmer" }, "saturation": { "value": 0.1, "direction": "increase" }, "sharpness": { "value": 0.4, "direction": "sharpen" } } } ``` ## Notlar {#notes} * Bu araç eşzamanlı `createToolRoute` fabrikasını kullanır, bu nedenle standart bir yanıt döndürür (202 async değil). * `mode` parametresi, düzeltmelerin nasıl ağırlıklandırılacağını ayarlar (örn. portre modu ten tonlarına daha yumuşak davranır, manzara modu doygunluğu artırır). * `deepEnhance` etkinleştirildiğinde ve `noise-removal` aracı (SCUNet) kurulu olduğunda, standart düzeltmelerden sonra ek bir yapay zeka gürültü giderme geçişi uygulanır. * Analiz uç noktası, uygulanmadan önce hangi düzeltmelerin uygulanacağını önizlemek için kullanışlıdır. * HEIC/HEIF, RAW, TGA, PSD, EXR ve HDR giriş biçimlerini otomatik çözümleme yoluyla destekler. --- --- url: https://docs.snapotter.com/tr/tools/image/image-to-base64.md description: >- HTML, CSS ve daha fazlasına gömmek için görselleri base64 veri URI'lerine dönüştürün. --- # Görselden Base64'e {#image-to-base64} Bir veya daha fazla görseli base64 kodlu dizelere ve veri URI'lerine dönüştürün. İsteğe bağlı biçim dönüştürme, kalite kontrolü ve yeniden boyutlandırmayı destekler. Görselleri doğrudan HTML, CSS, JSON veya e-posta şablonlarına gömmek için kullanışlıdır. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/image-to-base64` Bir veya daha fazla görsel dosyası ve isteğe bağlı bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | outputFormat | string | Hayır | `"original"` | Kodlamadan önce dönüştür: `original`, `jpeg`, `png`, `webp`, `avif`, `jxl` | | quality | number | Hayır | `80` | Kayıplı biçimler için çıktı kalitesi (1 ile 100 arası) | | maxWidth | number | Hayır | `0` | Piksel cinsinden maksimum genişlik (0 = yeniden boyutlandırma yok, büyütmez) | | maxHeight | number | Hayır | `0` | Piksel cinsinden maksimum yükseklik (0 = yeniden boyutlandırma yok, büyütmez) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon.png" \ -F 'settings={"outputFormat": "webp", "quality": 80, "maxWidth": 200}' ``` Birden fazla dosya: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-base64 \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@icon1.png" \ -F "file=@icon2.png" \ -F "file=@icon3.png" \ -F 'settings={"outputFormat": "original"}' ``` ## Örnek Yanıt {#example-response} ```json { "results": [ { "filename": "icon.png", "mimeType": "image/webp", "width": 200, "height": 200, "originalSize": 45000, "encodedSize": 28800, "overheadPercent": -36.0, "base64": "UklGRlYAAABXRUJQ...", "dataUri": "data:image/webp;base64,UklGRlYAAABXRUJQ..." } ], "errors": [] } ``` ## Yanıt Alanları {#response-fields} | Alan | Tür | Açıklama | |-------|------|-------------| | results | array | Başarıyla dönüştürülen görseller | | errors | array | İşlenemeyen görseller (dosya adı ve hata mesajıyla birlikte) | ### Sonuç Nesnesi {#result-object} | Alan | Tür | Açıklama | |-------|------|-------------| | filename | string | Orijinal dosya adı | | mimeType | string | Kodlanmış çıktının MIME türü | | width | number | Piksel cinsinden nihai genişlik (herhangi bir yeniden boyutlandırma sonrası) | | height | number | Piksel cinsinden nihai yükseklik (herhangi bir yeniden boyutlandırma sonrası) | | originalSize | number | Bayt cinsinden orijinal dosya boyutu | | encodedSize | number | Bayt cinsinden base64 dizesinin boyutu | | overheadPercent | number | Orijinale kıyasla yüzde boyut farkı (pozitif = daha büyük, negatif = daha küçük) | | base64 | string | Ham base64 kodlu görsel verisi | | dataUri | string | `src` özniteliklerinde kullanıma hazır tam veri URI'si | ## Notlar {#notes} * Base64 kodlama tipik olarak ikili dosyaya kıyasla boyutu yaklaşık %33 artırır. `overheadPercent` alanı gerçek farkı gösterir. * `outputFormat` değeri `"original"` olduğunda, HEIC/HEIF dosyaları JPEG'e dönüştürülür (tarayıcılar HEIC'i veri URI'lerinde gösteremediği için). * `maxWidth` ve `maxHeight` seçenekleri, `withoutEnlargement` ile `fit: inside` kullanarak yeniden boyutlandırır; bu nedenle belirtilen boyutlardan küçük görseller büyütülmez. * Tek bir istekte birden fazla dosya işlenebilir. Her dosya bağımsız olarak işlenir ve başarısızlıklar diğer dosyaların başarılı olmasını engellemez. * SVG dosyaları, yeniden kodlanmadan `image/svg+xml` olarak aktarılır (bir biçim dönüştürmesi istenmediği sürece). * Bu, salt okunur bir uç noktadır. İndirilebilir bir dosya veya bir `jobId` üretmez. Base64 verisi doğrudan yanıt gövdesinde döndürülür. --- --- url: https://docs.snapotter.com/tr/tools/image/image-to-pdf.md description: >- Bir veya daha fazla görseli sayfa boyutu, yönlendirme ve hedef dosya boyutu seçenekleriyle bir PDF belgesinde birleştirin. --- # Görselden PDF'e {#image-to-pdf} Bir veya daha fazla görseli bir PDF belgesinde birleştirin. Birden fazla sayfa boyutunu, yönlendirmeyi, kenar boşluklarını ve kalite ayarı yoluyla isteğe bağlı dosya boyutu hedeflemeyi destekler. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/image-to-pdf` Bir veya daha fazla görsel dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | pageSize | string | Hayır | `"A4"` | Sayfa boyutu: `A4`, `Letter`, `A3`, `A5` | | orientation | string | Hayır | `"portrait"` | Sayfa yönlendirmesi: `portrait` veya `landscape` | | margin | number | Hayır | `20` | Punto cinsinden sayfa kenar boşluğu (0-500) | | targetSize | object | Hayır | - | Hedef dosya boyutu kısıtlaması (aşağıya bakın) | | collate | boolean | Hayır | `true` | Tüm görselleri tek bir PDF'te birleştir. `false` ise görsel başına bir PDF oluşturur. | ### Hedef Boyut Nesnesi {#target-size-object} | Alan | Tür | Zorunlu | Açıklama | |-------|------|----------|-------------| | value | number | Evet | Hedef boyut değeri | | unit | string | Evet | Birim: `KB` veya `MB` | Minimum hedef boyut 50 KB'dir. ## Örnek İstek {#example-request} Temel çok görselli PDF: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page1.jpg" \ -F "file=@page2.jpg" \ -F "file=@page3.jpg" \ -F 'settings={"pageSize": "A4", "orientation": "portrait", "margin": 20}' ``` Dosya boyutu hedefiyle: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@scan1.jpg" \ -F "file=@scan2.jpg" \ -F 'settings={"pageSize": "Letter", "targetSize": {"value": 2, "unit": "MB"}}' ``` Görsel başına bir PDF: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/image-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F 'settings={"collate": false}' ``` ## Örnek Yanıt (Harmanlanmış) {#example-response-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 5000000, "processedSize": 1200000, "pages": 3 } ``` ## Örnek Yanıt (Harmanlanmamış) {#example-response-non-collated} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.zip", "originalSize": 5000000, "processedSize": 2400000, "pages": 2, "collated": false } ``` ## Örnek Yanıt (Hedef Boyutla) {#example-response-with-target-size} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/images.pdf", "originalSize": 10000000, "processedSize": 2000000, "pages": 5, "compression": { "targetRequested": 2097152, "targetMet": true, "jpegQuality": 72 } } ``` ## Notlar {#notes} * Görseller sayfada ortalanır ve en boy oranı korunurken kenar boşluklarına sığacak şekilde ölçeklendirilir. Görseller asla büyütülmez. * `collate` değeri `false` olduğunda, her görsel ayrı bir PDF dosyası olur ve indirme, tüm PDF'leri içeren bir ZIP arşividir. * Hedef boyut özelliği, bütçeye sığan en iyi kaliteyi bulmak için JPEG kalite düzeyleri (10-95) üzerinde yinelemeli ikili arama kullanır. * Saydam görseller, PDF'e gömülmeden önce beyaza düzleştirilir. * Desteklenen giriş biçimleri: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW, PSD, SVG ve daha fazlası. * EXIF yönlendirmesi gömülmeden önce otomatik olarak uygulanır. --- --- url: https://docs.snapotter.com/tr/tools/image/split.md description: >- Bir görüntüyü satır ve sütuna göre veya piksel boyutuna göre ızgara döşemelerine bölün, ZIP arşivi olarak döndürülür. --- # Görüntü Böl {#image-splitting} Tek bir görüntüyü sütun/satır sayısına göre veya belirli piksel boyutlarına göre ızgara döşemelerine bölün. Tüm döşemeleri içeren bir ZIP arşivi döndürür. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/split` ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | columns | integer | Hayır | 3 | Bölünecek sütun sayısı (1 ile 100 arası) | | rows | integer | Hayır | 3 | Bölünecek satır sayısı (1 ile 100 arası) | | tileWidth | integer | Hayır | - | Piksel cinsinden döşeme genişliği (min 10). Hem `tileWidth` hem `tileHeight` ayarlandığında `columns` değerini geçersiz kılar. | | tileHeight | integer | Hayır | - | Piksel cinsinden döşeme yüksekliği (min 10). Hem `tileWidth` hem `tileHeight` ayarlandığında `rows` değerini geçersiz kılar. | | outputFormat | string | Hayır | `"original"` | Döşemeler için çıktı biçimi: `original`, `png`, `jpg`, `webp`, `avif`, `jxl` | | quality | number | Hayır | 90 | Kayıplı biçimler için çıktı kalitesi (1 ile 100 arası) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/split \ -F "file=@large-image.png" \ -F 'settings={"columns":3,"rows":3,"outputFormat":"png"}' \ --output split-tiles.zip ``` ## Örnek Yanıt {#example-response} Yanıt, `Content-Type: application/zip` ile doğrudan bir ZIP dosyası olarak aktarılır. Dosya adı `split-.zip` desenini izler. ZIP içindeki her döşeme `_r_c.` olarak adlandırılır (örn. `photo_r1_c1.png`, `photo_r2_c3.webp`). ## Notlar {#notes} * Tek bir görüntü dosyası kabul eder. * HEIC, RAW, PSD ve SVG giriş biçimlerini destekler (otomatik olarak çözülür). * Hem `tileWidth` hem `tileHeight` sağlandığında, bunlar `columns`/`rows` üzerinde önceliğe sahiptir. Izgara boyutları `ceil(imageWidth / tileWidth)` ve `ceil(imageHeight / tileHeight)` olarak hesaplanır. * Kenar döşemeleri (en sağdaki sütun, alt satır), görüntü boyutları eşit olarak bölünemiyorsa belirtilen döşeme boyutundan daha küçük olabilir. * Maksimum ızgara boyutu 100x100 (10.000 döşeme) ile sınırlandırılmıştır. * Yanıt ZIP'i doğrudan aktarır, bu nedenle JSON yanıt gövdesi yoktur. Dosyayı kaydetmek için curl ile `--output` kullanın. --- --- url: https://docs.snapotter.com/tr/tools/image/resize.md description: Görselleri piksel, yüzde veya sığdırma modlarıyla yeniden boyutlandırın. --- # Görüntü Boyutlandır {#resize} Görselleri tam piksel boyutları, bir yüzde ölçek katsayısı veya görselin hedef boyutlara nasıl uyum sağlayacağını denetleyen bir sığdırma modu belirterek yeniden boyutlandırın. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/resize` Bir görsel dosyası ve bir JSON `settings` alanı içeren çok parçalı form verisi kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | width | integer | Hayır | - | Piksel cinsinden hedef genişlik (en fazla 16383) | | height | integer | Hayır | - | Piksel cinsinden hedef yükseklik (en fazla 16383) | | fit | string | Hayır | `"contain"` | Görselin boyutlara nasıl sığdığı: `contain`, `cover`, `fill`, `inside`, `outside` | | withoutEnlargement | boolean | Hayır | `false` | Görsel hedeften küçükse büyütmeyi önle | | percentage | number | Hayır | - | Yüzdeye göre ölçekle (örn. yarı boyut için 50) | `width`, `height` veya `percentage` değerlerinden en az biri sağlanmalıdır. ### Sığdırma Modları {#fit-modes} * **contain** - En boy oranını koruyarak boyutlara sığacak şekilde yeniden boyutlandırır (boş alan bırakabilir) * **cover** - En boy oranını koruyarak boyutları kaplayacak şekilde yeniden boyutlandırır (kırpabilir) * **fill** - Boyutlara tam olarak eşleşecek şekilde uzatır (en boy oranını göz ardı eder) * **inside** - `contain` gibidir, ancak yalnızca küçültür, asla büyütmez * **outside** - `cover` gibidir, ancak yalnızca küçültür, asla büyütmez ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"width": 800, "height": 600, "fit": "contain"}' ``` Yüzdeye göre yeniden boyutlandır: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/resize \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"percentage": 50}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 980000 } ``` ## Notlar {#notes} * Her iki eksende de maksimum boyut 16383 pikseldir (Sharp/libvips sınırı). * Çıktı biçimi girdi biçimiyle eşleşir. HEIC, RAW, PSD ve SVG girdileri işlemden önce otomatik olarak çözülür. * Yeniden boyutlandırmadan önce EXIF yönlendirmesi otomatik olarak uygulanır. * `withoutEnlargement` bayrağı, bazı görsellerin zaten hedeften küçük olabileceği toplu işleme için kullanışlıdır. --- --- url: https://docs.snapotter.com/tr/tools/image/upscale.md description: >- İnce ayrıntıyı korurken Real-ESRGAN AI süper çözünürlüğü ile görüntüleri 2x'ten 4x'e büyütün. --- # Görüntü Büyütme {#image-upscaling} Real-ESRGAN kullanarak AI süper çözünürlük geliştirmesi. Ayrıntıyı korurken görüntüleri 2x-4x büyütür. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/upscale` **İşleme:** Eşzamansız (202 döner, durum için SSE aracılığıyla `/api/v1/jobs/{jobId}/progress` üzerinden sorgulanır) **Model paketi:** `upscale-enhance` (5-6 GB) ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | file | Evet | - | Görüntü dosyası (multipart) | | scale | number | Hayır | `2` | Büyütme faktörü (örn. 2, 3, 4) | | model | string | Hayır | `"auto"` | Kullanılacak model (örn. `auto`, belirli model adları) | | faceEnhance | boolean | Hayır | `false` | Büyütme sırasında yüz geliştirme uygula | | denoise | number | Hayır | `0` | Gürültü azaltma gücü (0 = kapalı) | | format | string | Hayır | `"auto"` | Çıktı biçimi: `auto`, `png`, `jpg`, `webp`, `tiff`, `gif`, `avif`, `heic`, `heif`, `jxl` | | quality | number | Hayır | `95` | Çıktı kalitesi (1-100) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/upscale \ -F "file=@photo.jpg" \ -F 'settings={"scale":4,"model":"auto","faceEnhance":true,"format":"png"}' ``` ## Yanıt {#response} ### İlk Yanıt (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### İlerleme (`/api/v1/jobs/{jobId}/progress` üzerinde SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Upscaling...","percent":60} ``` ### Nihai Sonuç (SSE aracılığıyla) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_4x.png", "previewUrl": "/api/v1/download/{jobId}/preview.webp", "originalSize": 120000, "processedSize": 2400000, "width": 4096, "height": 4096, "method": "realesrgan-x4plus" } } ``` ## Notlar {#notes} * `upscale-enhance` model paketinin kurulmuş olmasını gerektirir (5-6 GB). * Mevcut olduğunda Real-ESRGAN kullanır; AI modeli kullanılamıyorsa Lanczos interpolasyonuna geri döner. * `faceEnhance` seçeneği, daha iyi yüz kalitesi için büyütme sırasında GFPGAN yüz onarımı uygular. * Tarayıcıda önizlenemeyen çıktı biçimleri (HEIC, JXL, TIFF) için ana çıktının yanında bir WebP önizlemesi oluşturulur. * HEIC/HEIF, RAW, TGA, PSD, EXR ve HDR giriş biçimlerini otomatik çözme yoluyla destekler. --- --- url: https://docs.snapotter.com/tr/tools/image/rotate.md description: Görselleri herhangi bir açıyla döndürün ve yatay veya dikey olarak çevirin. --- # Görüntü Döndür ve Çevir {#rotate-flip} Görselleri isteğe bağlı bir açıyla döndürün ve/veya yatay ya da dikey olarak çevirin. Döndürme ve çevirme işlemleri tek bir istekte birleştirilebilir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/rotate` Bir görsel dosyası ve bir JSON `settings` alanı içeren çok parçalı form verisi kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | angle | number | Hayır | `0` | Derece cinsinden döndürme açısı (saat yönünde). Herhangi bir sayısal değeri kabul eder. | | horizontal | boolean | Hayır | `false` | Görseli yatay olarak çevir (ayna) | | vertical | boolean | Hayır | `false` | Görseli dikey olarak çevir | ## Örnek İstek {#example-request} Saat yönünde 90 derece döndür: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 90}' ``` Yatay olarak çevir: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"horizontal": true}' ``` Birlikte döndür ve çevir: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/rotate \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"angle": 45, "vertical": true}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2480000 } ``` ## Notlar {#notes} * Önce döndürme, ardından çevirme işlemleri uygulanır. * 90 dereceden farklı döndürmeler (örn. 45 derece), çıktı biçimine bağlı olarak saydam veya siyah dolguyla döndürülen görsele sığacak şekilde tuvali büyütür. * Yaygın değerler: çeyrek tur döndürmeler için 90, 180, 270. * İşlemden önce EXIF yönlendirmesi otomatik olarak uygulanır; bu nedenle döndürme, görsel yönlendirmeye görelidir. --- --- url: https://docs.snapotter.com/tr/tools/image/convert.md description: >- AVIF, JXL ve HEIC gibi modern biçimler dahil olmak üzere görüntüleri biçimler arasında dönüştürün. --- # Görüntü Dönüştür {#convert} Görüntüleri biçimler arasında dönüştürün. HEIC, JXL, BMP, ICO, JP2, QOI ve PSD gibi özel biçimlerin yanı sıra yaygın web biçimlerini de destekler. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/convert` Bir görüntü dosyası ve bir JSON `settings` alanı ile çok parçalı form verilerini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | format | string | Evet | - | Hedef biçim: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `heic`, `heif`, `jxl`, `bmp`, `ico`, `jp2`, `qoi`, `psd`, `ppm`, `eps`, `tga` | | quality | number | Hayır | - | Çıktı kalitesi (1-100). jpg, webp, avif, heic gibi kayıplı biçimlere uygulanır. | ## Desteklenen Çıktı Biçimleri {#supported-output-formats} | Biçim | Tür | Notlar | |--------|------|-------| | jpg | Kayıplı | JPEG, en iyi uyumluluk | | png | Kayıpsız | Saydamlığı destekler | | webp | Her ikisi | Modern web biçimi, iyi sıkıştırma | | avif | Kayıplı | Yeni nesil biçim, mükemmel sıkıştırma | | tiff | Her ikisi | Baskı/yayın iş akışları | | gif | Kayıpsız | 256 renkle sınırlı | | heic / heif | Kayıplı | Apple ekosistemi biçimi | | jxl | Her ikisi | JPEG XL, yeni nesil biçim | | bmp | Kayıpsız | Sıkıştırılmamış bit eşlem | | ico | Kayıpsız | Windows simge biçimi | | jp2 | Kayıplı | JPEG 2000 | | qoi | Kayıpsız | Quite OK Image biçimi | | psd | Katmanlı | Adobe Photoshop (ImageMagick gerektirir) | | ppm | Kayıpsız | Portable Pixmap (PPM/PGM/PBM) | | eps | Vektör | Encapsulated PostScript | | tga | Kayıpsız | Targa görüntü biçimi | ## Örnek İstek {#example-request} WebP'ye dönüştür: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "webp", "quality": 85}' ``` PNG'ye dönüştür (kayıpsız): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/convert \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"format": "png"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", "originalSize": 2450000, "processedSize": 680000 } ``` ## Notlar {#notes} * Çıktı dosya adı uzantısı, hedef biçimle eşleşecek şekilde otomatik olarak güncellenir. * SVG girişleri, dönüştürmeden önce 300 DPI'de rasterleştirilir. * PSD dönüştürme, sunucuda ImageMagick'in kurulu olmasını gerektirir. * BMP, EPS, ICO, JP2, JXL, PPM, QOI ve TGA, özel CLI kodlayıcıları kullanır ve Sharp işlemesini atlar. * HEIC/HEIF kodlaması, sistem HEIC kodlayıcı kitaplığını kullanır. * Giriş biçimleri geniştir: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC, RAW (CR2, NEF, ARW, vb.), PSD, SVG, BMP ve daha fazlası. --- --- url: https://docs.snapotter.com/tr/tools/image/watermark-image.md description: >- Yapılandırılabilir konum, opaklık ve ölçekle bir logo veya görüntüyü filigran olarak yerleştirin. --- # Görüntü Filigranı {#image-watermark} Bir logo veya ikincil görüntüyü bir temel görüntü üzerinde filigran olarak yerleştirin. Filigran, temel görüntü genişliğine göre ölçeklenir ve bir köşede veya merkezde konumlandırılır. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/watermark-image` **İki** görüntü dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | position | string | Hayır | `"bottom-right"` | Filigran yerleşimi: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` | | opacity | number | Hayır | `50` | Filigran opaklık yüzdesi (0 ile 100 arası) | | scale | number | Hayır | `25` | Ana görüntü genişliğinin yüzdesi olarak filigran genişliği (1 ile 100 arası) | ### Dosya Alanları {#file-fields} | Alan Adı | Zorunlu | Açıklama | |------------|----------|-------------| | file | Evet | Ana/temel görüntü | | watermark | Evet | Filigran/logo görüntüsü | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/watermark-image \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "watermark=@logo.png" \ -F 'settings={"position": "bottom-right", "opacity": 60, "scale": 20}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2520000 } ``` ## Notlar {#notes} * Her iki görüntü de doğrulanır ve çözülür (HEIC, RAW, PSD, SVG desteklenir). * Filigran, genişliği ana görüntü genişliğinin %`scale`'sine eşit olacak şekilde orantılı olarak yeniden boyutlandırılır. * Opaklık, `dest-in` harmanlamayla birleştirilen bir alfa maskesi aracılığıyla uygulanır. * Köşe konumları görüntü kenarından 20px dolgu kullanır. * Filigran görüntüsünde saydamlık varsa (örn. bir PNG logosu), birleştirme sırasında korunur. * İşlemeden önce her iki görüntüde de EXIF yönü otomatik olarak uygulanır. --- --- url: https://docs.snapotter.com/tr/tools/image/compare.md description: >- İki görüntüyü piksel düzeyinde fark görselleştirmesi ve benzerlik puanıyla yan yana karşılaştırın. --- # Görüntü Karşılaştırma {#image-compare} Piksel düzeyinde bir fark haritası ve sayısal bir benzerlik yüzdesi hesaplamak için iki görüntü yükleyin. Çıktı, değişen bölgeleri kırmızıyla vurgulayan bir fark görüntüsüdür. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/compare` **İki** görüntü dosyasıyla çok parçalı form verilerini kabul eder. Ayarlar alanı gerekmez. ## Parametreler {#parameters} Bu aracın yapılandırılabilir parametresi yoktur. Tam olarak iki görüntü dosyası yükleyin. | Alan | Tür | Zorunlu | Açıklama | |-------|------|----------|-------------| | file (ilk) | file | Evet | İlk görüntü | | file (ikinci) | file | Evet | İkinci görüntü | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compare \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@original.jpg" \ -F "file=@modified.jpg" ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "similarity": 94.52, "dimensions": { "width": 1920, "height": 1080 }, "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/diff.png", "originalSize": 4900000, "processedSize": 280000 } ``` ## Yanıt Alanları {#response-fields} | Alan | Tür | Açıklama | |-------|------|-------------| | jobId | string | Fark görüntüsünü indirmek için iş tanımlayıcısı | | similarity | number | İki görüntü arasındaki yüzde benzerlik (0 ile 100 arası) | | dimensions | object | Karşılaştırma için kullanılan genişlik ve yükseklik | | downloadUrl | string | Oluşturulan fark görüntüsünü indirme URL'si | | originalSize | number | Her iki giriş görüntüsünün bayt cinsinden birleşik boyutu | | processedSize | number | Fark çıktısı görüntüsünün bayt cinsinden boyutu | ## Notlar {#notes} * Her iki görüntü de karşılaştırmadan önce aynı boyutlara (her eksenin maksimumu) yeniden boyutlandırılır. * Fark görüntüsü, değişim büyüklüğüyle orantılı opaklıkla farkları kırmızıyla vurgular. Aynı veya neredeyse aynı pikseller (fark < 10) orijinalin yarı saydam versiyonları olarak gösterilir. * Benzerlik, tüm pikseller boyunca ortalama piksel farkının tersi olarak hesaplanır ve yüzde olarak ifade edilir. * %100 benzerlik, görüntülerin (karşılaştırma çözünürlüğünde) piksel düzeyinde aynı olduğu anlamına gelir. * Fark çıktısı, giriş biçimlerinden bağımsız olarak her zaman PNG biçimindedir. * Her iki görüntü de karşılaştırmadan önce doğrulanır ve çözülür (HEIC, RAW, PSD, SVG desteklenir). * İşlemeden önce her iki görüntüde EXIF yönlendirmesi otomatik olarak uygulanır. --- --- url: https://docs.snapotter.com/tr/tools/image/sharpening.md description: >- İsteğe bağlı gürültü azaltma ile uyarlanabilir, unsharp mask veya high-pass yöntemlerini kullanarak görüntüleri keskinleştirin. --- # Görüntü Keskinleştir {#sharpening} Üç yöntemli gelişmiş keskinleştirme aracı: uyarlanabilir (akıllı kenar farkındalıklı), unsharp mask (klasik yarıçap/miktar) ve high-pass (doku vurgusu). Keskinleştirme artefaktlarını önlemek için yerleşik gürültü azaltma içerir. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/sharpening` Bir görüntü dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | method | string | Hayır | `"adaptive"` | Keskinleştirme algoritması: `adaptive`, `unsharp-mask`, `high-pass` | | sigma | number | Hayır | `1.0` | Uyarlanabilir: Gauss sigma (0.5 ile 10 arası) | | m1 | number | Hayır | `1.0` | Uyarlanabilir: düz alan keskinleştirme (0 ile 10 arası) | | m2 | number | Hayır | `3.0` | Uyarlanabilir: pürüzlü alan keskinleştirme (0 ile 20 arası) | | x1 | number | Hayır | `2.0` | Uyarlanabilir: düz/pürüzlü eşiği (0 ile 10 arası) | | y2 | number | Hayır | `12` | Uyarlanabilir: maksimum düz keskinleştirme (0 ile 50 arası) | | y3 | number | Hayır | `20` | Uyarlanabilir: maksimum pürüzlü keskinleştirme (0 ile 50 arası) | | amount | number | Hayır | `100` | Unsharp mask: keskinleştirme miktarı (0 ile 1000 arası) | | radius | number | Hayır | `1.0` | Unsharp mask: piksel cinsinden bulanıklık yarıçapı (0.1 ile 5 arası) | | threshold | number | Hayır | `0` | Unsharp mask: keskinleştirmek için minimum parlaklık farkı (0 ile 255 arası) | | strength | number | Hayır | `50` | High-pass: filtre gücü (0 ile 100 arası) | | kernelSize | number | Hayır | `3` | High-pass: konvolüsyon çekirdek boyutu (3 veya 5) | | denoise | string | Hayır | `"off"` | Keskinleştirme öncesi gürültü azaltma: `off`, `light`, `medium`, `strong` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "adaptive", "sigma": 1.5}' ``` Düz alanları korumak için eşikli unsharp mask: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sharpening \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"method": "unsharp-mask", "amount": 150, "radius": 1.5, "threshold": 10}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2510000 } ``` ## Notlar {#notes} * Yalnızca seçilen yöntemle ilgili parametreler kullanılır. Örneğin, `method` değeri `adaptive` olduğunda `amount`, `radius` ve `threshold` yok sayılır. * Uyarlanabilir yöntem, yapılandırılabilir düz/pürüzlü bölge davranışıyla Sharp'ın yerleşik uyarlanabilir keskinleştirmesini kullanır. * `denoise` seçeneği, gürültü/tanenin yükseltilmesini önlemek için keskinleştirme öncesinde gürültü azaltma uygular. * High-pass keskinleştirme, orijinalden bulanıklaştırılmış bir sürümü çıkararak ince ayrıntıyı ayıklar, ardından geri harmanlar. * Çıktı biçimi giriş biçimiyle eşleşir. HEIC, RAW, PSD ve SVG girdileri işlenmeden önce otomatik olarak çözülür. --- --- url: https://docs.snapotter.com/tr/tools/image/crop.md description: Konum ve boyutlarla bir bölge belirterek görüntüleri kırpın. --- # Görüntü Kırp {#crop} Konum ve boyut kullanarak dikdörtgen bir bölge tanımlayarak görüntüleri kırpın. Hem piksel hem de yüzde birimlerini destekler. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/crop` Bir görüntü dosyası ve bir JSON `settings` alanı ile çok parçalı form verilerini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | left | number | Evet | - | Kırpma bölgesinin X ofseti (sol kenardan) | | top | number | Evet | - | Kırpma bölgesinin Y ofseti (üst kenardan) | | width | number | Evet | - | Kırpma bölgesinin genişliği | | height | number | Evet | - | Kırpma bölgesinin yüksekliği | | unit | string | Hayır | `"px"` | Değerler için birim: `px` veya `percent` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 100, "top": 50, "width": 800, "height": 600}' ``` Yüzde değerlerini kullanarak kırpma: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/crop \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"left": 10, "top": 10, "width": 80, "height": 80, "unit": "percent"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 1200000 } ``` ## Notlar {#notes} * Kırpma bölgesi görüntü sınırları içine sığmalıdır. Bölge görüntünün ötesine uzanırsa, istek başarısız olur. * `percent` birimi kullanıldığında, değerler görüntü boyutlarının yüzdelerini temsil eder (örn. `left: 10`, sol kenardan %10 anlamına gelir). * Çıktı biçimi giriş biçimiyle eşleşir. * Kırpmadan önce EXIF yönlendirmesi otomatik olarak uygulanır, bu nedenle koordinatlar görsel olarak doğru yönlendirmeye karşılık gelir. --- --- url: https://docs.snapotter.com/tr/tools/image/compose.md description: Kompozit için görüntüleri konum, opaklık ve harmanlama modlarıyla katmanlayın. --- # Görüntü Kompozisyonu {#image-composition} Yapılandırılabilir konum, opaklık ve harmanlama moduyla bir temel görüntünün üzerine bir yer paylaşım görüntüsü katmanlayın. Logoları, grafikleri kompozit etmek veya birden fazla görüntüyü birleştirmek için kullanışlıdır. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/compose` **İki** görüntü dosyası ve bir JSON `settings` alanı ile çok parçalı form verilerini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | x | number | Hayır | `0` | Yer paylaşımının sol üst köşeden yatay ofseti, piksel cinsinden (min 0) | | y | number | Hayır | `0` | Yer paylaşımının sol üst köşeden dikey ofseti, piksel cinsinden (min 0) | | opacity | number | Hayır | `100` | Yer paylaşımı opaklık yüzdesi (0 ile 100 arası) | | blendMode | string | Hayır | `"over"` | Kompozit harmanlama modu | ### Harmanlama Modları {#blend-modes} | Değer | Açıklama | |-------|-------------| | `over` | Normal yer paylaşımı (varsayılan) | | `multiply` | Piksel değerlerini çarparak koyulaştırma | | `screen` | Tersine çevirerek, çarparak ve tekrar tersine çevirerek açma | | `overlay` | Temel parlaklığa göre çarpma ve ekranı birleştirir | | `darken` | Her katmandan daha koyu pikseli korur | | `lighten` | Her katmandan daha açık pikseli korur | | `hard-light` | Güçlü kontrast yer paylaşımı | | `soft-light` | İnce kontrast yer paylaşımı | | `difference` | Katmanlar arasındaki mutlak fark | | `exclusion` | Farka benzer ancak daha düşük kontrast | ### Dosya Alanları {#file-fields} | Alan Adı | Zorunlu | Açıklama | |------------|----------|-------------| | file | Evet | Temel/arka plan görüntüsü | | overlay | Evet | Yer paylaşımı/ön plan görüntüsü | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@background.jpg" \ -F "overlay=@graphic.png" \ -F 'settings={"x": 100, "y": 50, "opacity": 80, "blendMode": "over"}' ``` Çarpma harmanlama modunu kullanma: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compose \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F "overlay=@texture.jpg" \ -F 'settings={"x": 0, "y": 0, "opacity": 50, "blendMode": "multiply"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/background.jpg", "originalSize": 3200000, "processedSize": 3450000 } ``` ## Notlar {#notes} * Her iki görüntü de kompozit etmeden önce doğrulanır ve çözülür (HEIC, RAW, PSD, SVG desteklenir). * Yer paylaşımı, `x` ve `y` tarafından belirtilen tam piksel koordinatlarına yerleştirilir. Sığdırmak için yeniden boyutlandırılmaz. * Opaklık 100'den azsa, harmanlamadan önce yer paylaşımına bir alfa maskesi uygulanır. * Yer paylaşımı, temel görüntü sınırlarının ötesine uzanabilir (kırpılır). * İşlemeden önce her iki görüntüde EXIF yönlendirmesi otomatik olarak uygulanır. * Çıktı boyutları, temel görüntü boyutlarıyla eşleşir. --- --- url: https://docs.snapotter.com/tr/tools/image/edit-metadata.md description: >- Görüntülerde EXIF, IPTC, GPS ve XMP meta veri alanlarını piksel yeniden kodlaması olmadan düzenleyin. --- # Görüntü Meta Verisi Düzenle {#edit-metadata} EXIF, IPTC, GPS koordinatları, tarihler ve anahtar kelimeler dahil olmak üzere görüntü meta veri alanlarını düzenleyin. Arka planda ExifTool kullanır, bu nedenle meta veriler pikselleri yeniden kodlamadan yerinde yazılır ve tam görüntü kalitesi korunur. ## API Uç Noktaları {#api-endpoints} ### Meta Veri Düzenle {#edit-metadata-1} `POST /api/v1/tools/image/edit-metadata` Meta veri alanlarını görüntüye yazar ve değiştirilen dosyayı döndürür. ### Meta Veriyi İncele {#inspect-metadata} `POST /api/v1/tools/image/edit-metadata/inspect` Görüntüden tam meta veriyi ExifTool aracılığıyla JSON olarak döndürür. Görüntüyü değiştirmez. ## Parametreler (Düzenle) {#parameters-edit} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | title | string | Hayır | - | Görüntü başlığı (XMP/EXIF) | | author | string | Hayır | - | Yazar adı | | artist | string | Hayır | - | Sanatçı adı (EXIF Artist etiketi) | | copyright | string | Hayır | - | Telif hakkı bildirimi | | imageDescription | string | Hayır | - | Görüntü açıklaması (EXIF) | | software | string | Hayır | - | Yazılım etiketi | | dateTime | string | Hayır | - | EXIF DateTime değeri | | dateTimeOriginal | string | Hayır | - | EXIF DateTimeOriginal değeri | | setAllDates | string | Hayır | - | Tüm tarih alanlarını bir kerede ayarla | | dateShift | string | Hayır | - | Tüm tarihleri ofset kadar kaydır (biçim: `+HH:MM` veya `-HH:MM`) | | clearGps | boolean | Hayır | `false` | Tüm GPS verilerini kaldır | | gpsLatitude | number | Hayır | - | GPS enlemini ayarla (-90 ile 90 arası) | | gpsLongitude | number | Hayır | - | GPS boylamını ayarla (-180 ile 180 arası) | | gpsAltitude | number | Hayır | - | GPS yüksekliğini metre cinsinden ayarla | | keywords | string\[] | Hayır | - | Eklenecek veya ayarlanacak anahtar kelimeler/etiketler | | keywordsMode | string | Hayır | `"add"` | Anahtar kelimelerin nasıl işleneceği: `add` (ekle) veya `set` (değiştir) | | fieldsToRemove | string\[] | Hayır | `[]` | Kaldırılacak belirli meta veri alanı adlarının listesi | | iptcTitle | string | Hayır | - | IPTC Object Name | | iptcHeadline | string | Hayır | - | IPTC Headline | | iptcCity | string | Hayır | - | IPTC City | | iptcState | string | Hayır | - | IPTC Province/State | | iptcCountry | string | Hayır | - | IPTC Country | ## Örnek İstek {#example-request} Yazar ve telif hakkını ayarla: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"author": "Jane Smith", "copyright": "2024 Jane Smith"}' ``` GPS koordinatlarını ayarla: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"gpsLatitude": 48.8566, "gpsLongitude": 2.3522, "gpsAltitude": 35}' ``` GPS'i kaldır ve anahtar kelimeler ekle: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"clearGps": true, "keywords": ["landscape", "sunset"], "keywordsMode": "add"}' ``` Meta veriyi incele: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/edit-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Örnek Yanıt (Düzenle) {#example-response-edit} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2452000 } ``` ## Notlar {#notes} * Bu araç, sunucuda ExifTool'un kurulu olmasını gerektirir. Docker imajına dahildir. * Meta veriler yerinde yazılır, bu nedenle piksel yeniden kodlaması gerçekleşmez. Dosya boyutu değişikliği minimaldir (yalnızca meta veri baytları). * `dateShift` parametresi, tüm tarih alanlarını belirtilen ofset kadar kaydırır ve saat dilimi hatalarını düzeltmek için kullanışlıdır (örn. `+02:00` veya `-05:30`). * Hiçbir değişiklik istenmezse (tüm parametreler atlanmış veya boşsa), orijinal dosya değiştirilmeden döndürülür. * Desteklenen biçimler: JPEG, PNG, WebP, AVIF, TIFF, GIF, HEIC/HEIF. * Tarayıcıda önizlenemeyen biçimler (HEIF, TIFF) için yanıt, WebP önizlemesi içeren bir `previewUrl` alanı içerir. --- --- url: https://docs.snapotter.com/tr/tools/image/strip-metadata.md description: >- Gizlilik ve daha küçük dosya boyutları için görüntülerden EXIF, GPS, ICC ve XMP meta verilerini kaldırın. --- # Görüntü Meta Verisi Kaldır {#remove-metadata} Görüntülerden EXIF, GPS, ICC renk profilleri ve XMP meta verilerini kaldırın. Gizlilik (GPS koordinatlarını, kamera bilgilerini kaldırma) ve dosya boyutunu küçültme için kullanışlıdır. ## API Uç Noktaları {#api-endpoints} ### Meta Verileri Kaldır {#strip-metadata} `POST /api/v1/tools/image/strip-metadata` Görüntüyü işler ve seçilen meta verileri kaldırılmış temizlenmiş bir sürüm döndürür. ### Meta Verileri İncele {#inspect-metadata} `POST /api/v1/tools/image/strip-metadata/inspect` Görüntüyü değiştirmeden ayrıştırılmış meta verileri JSON olarak döndürür. Kaldırmadan önce hangi meta verinin var olduğunu önizlemek için kullanışlıdır. ## Parametreler (Kaldırma) {#parameters-strip} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | stripExif | boolean | Hayır | `false` | EXIF verilerini kaldır (kamera ayarları, tarihler vb.) | | stripGps | boolean | Hayır | `false` | Yalnızca GPS/konum verilerini kaldır | | stripIcc | boolean | Hayır | `false` | ICC renk profilini kaldır | | stripXmp | boolean | Hayır | `false` | XMP meta verilerini kaldır (Adobe, IPTC) | | stripAll | boolean | Hayır | `true` | Tüm meta verileri tek seferde kaldır | `stripAll` değeri `true` olduğunda, tek tek bayrakları geçersiz kılar ve her şeyi kaldırır. ## Örnek İstek {#example-request} Tüm meta verileri kaldır: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": true}' ``` Yalnızca GPS verilerini kaldır (kamera bilgilerini ve renk profilini koru): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": false, "stripGps": true}' ``` Değiştirmeden meta verileri incele: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Örnek Yanıt (Kaldırma) {#example-response-strip} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Örnek Yanıt (İnceleme) {#example-response-inspect} ```json { "filename": "photo.jpg", "fileSize": 2450000, "exif": { "Make": "Canon", "Model": "EOS R5", "DateTimeOriginal": "2024:03:15 14:30:00", "ExposureTime": "1/250", "FNumber": 2.8, "ISO": 400 }, "gps": { "GPSLatitudeRef": "N", "GPSLatitude": [37, 46, 30], "_latitude": 37.775, "_longitude": -122.4183 }, "icc": { "Profile Size": "3144 bytes", "Color Space": "RGB", "Description": "sRGB IEC61966-2.1" }, "xmp": { "CreatorTool": "Adobe Photoshop 25.0" } } ``` ## Notlar {#notes} * Görüntü, kaldırma işleminden sonra orijinal biçiminde yeniden kodlanır. JPEG, 90 kalitede mozjpeg kullanır; PNG, 9 sıkıştırma düzeyi kullanır; WebP, 85 kalite kullanır. * ICC profillerinin kaldırılması, görüntü sRGB olmayan bir profille etiketlenmişse ince renk kaymalarına neden olabilir. Renk doğruluğu önemliyse `stripIcc: false` kullanın. * İnceleme uç noktası, kolaylık için GPS koordinatlarını ondalık enlem/boylam değerlerine (alt çizgi ön ekli) ayrıştırır. * Desteklenen giriş biçimleri: JPEG, PNG, WebP, AVIF, TIFF, GIF. --- --- url: https://docs.snapotter.com/tr/api/image-engine.md description: >- Görüntü motoru işlemleri referansı. Tüm Sharp tabanlı görüntü işleme işlemleri ve parametreleri. --- # Görüntü motoru {#image-engine} `@snapotter/image-engine` paketi, AI olmayan tüm görüntü işlemlerini yönetir. [Sharp](https://sharp.pixelplumbing.com/) kitaplığını sarmalar ve harici bağımlılık olmadan tamamen işlem içinde çalışır. ## İşlemler {#operations} ### resize {#resize} Bir görüntüyü belirli boyutlara veya yüzdeye göre ölçekler. | Parametre | Tür | Açıklama | |---|---|---| | `width` | number | Piksel cinsinden hedef genişlik | | `height` | number | Piksel cinsinden hedef yükseklik | | `fit` | string | `cover`, `contain`, `fill`, `inside` veya `outside` | | `withoutEnlargement` | boolean | Doğruysa, daha küçük görüntüleri büyütmez | | `percentage` | number | Mutlak boyutlar yerine yüzdeye göre ölçekle | `width`, `height` değerlerini veya ikisini birden ayarlayabilirsiniz. Yalnızca birini ayarlarsanız, en boy oranını korumak için diğeri hesaplanır. ### crop {#crop} Görüntüden dikdörtgen bir bölge keser. | Parametre | Tür | Açıklama | |---|---|---| | `left` | number | Sol kenardan X ofseti | | `top` | number | Üst kenardan Y ofseti | | `width` | number | Kırpma alanının genişliği | | `height` | number | Kırpma alanının yüksekliği | | `unit` | string | `px` (varsayılan) veya `percent` | ### rotate {#rotate} Görüntüyü belirli bir açıyla döndürür. | Parametre | Tür | Açıklama | |---|---|---| | `angle` | number | Derece cinsinden döndürme açısı (0-360) | | `background` | string | Açığa çıkan alan için dolgu rengi (varsayılan: `#000000`). Yalnızca 90 derece olmayan açılara uygulanır. | ### flip {#flip} Görüntüyü yatay, dikey veya her ikisinde aynalar. En az biri doğru olmalıdır. | Parametre | Tür | Açıklama | |---|---|---| | `horizontal` | boolean | Soldan sağa aynala | | `vertical` | boolean | Yukarıdan aşağıya aynala | ### convert {#convert} Görüntü biçimini değiştirir. | Parametre | Tür | Açıklama | |---|---|---| | `format` | string | Hedef biçim: `jpg`, `png`, `webp`, `avif`, `tiff`, `gif`, `jxl`, `heic`, `heif`, `bmp`, `ico`, `jp2`, `qoi` | | `quality` | number | Sıkıştırma kalitesi (1-100, kayıplı biçimlere uygulanır) | İlk yedi biçim (`jpg` ile `jxl` arası) Sharp tarafından işlem içinde kodlanır. Kalan biçimler API katmanında harici kodlayıcılar kullanır: `heic`/`heif` heif-enc aracılığıyla, `bmp`/`ico` ImageMagick aracılığıyla, `jp2` opj\_compress aracılığıyla ve `qoi` satır içi bir TypeScript codec aracılığıyla. ### compress {#compress} Aynı biçimi koruyarak dosya boyutunu azaltır. | Parametre | Tür | Açıklama | |---|---|---| | `quality` | number | Hedef kalite (1-100) | | `targetSizeBytes` | number | Bayt cinsinden isteğe bağlı hedef dosya boyutu | | `format` | string | İsteğe bağlı biçim geçersiz kılma | ### strip-metadata {#strip-metadata} Görüntüden EXIF, IPTC, XMP ve ICC meta verilerini kaldırır. Parametre olmadan (veya `stripAll: true` ile) her şeyi kaldırır. Seçici kaldırma için ayrı bayraklar geçirin. | Parametre | Tür | Açıklama | |---|---|---| | `stripAll` | boolean | Tüm meta verileri kaldır (bayrak ayarlanmadığında varsayılan) | | `stripExif` | boolean | EXIF verilerini kaldır (`stripGps` ayrıca ayarlanmamışsa GPS dahil) | | `stripGps` | boolean | GPS konum verilerini kaldır | | `stripIcc` | boolean | ICC renk profilini kaldır | | `stripXmp` | boolean | XMP meta verilerini kaldır | ### Renk ayarlamaları {#color-adjustments} Bu işlemler bir görüntünün renk özelliklerini değiştirir. Her biri tek bir sayısal değer alır. | İşlem | Parametre | Aralık | Açıklama | |---|---|---|---| | `brightness` | `value` | -100 ile 100 | Parlaklığı ayarla | | `contrast` | `value` | -100 ile 100 | Kontrastı ayarla | | `saturation` | `value` | -100 ile 100 | Renk doygunluğunu ayarla | ### Renk filtreleri {#color-filters} Bunlar sabit bir renk dönüşümü uygular. Parametre almazlar. | İşlem | Açıklama | |---|---| | `grayscale` | Gri tonlamaya dönüştür | | `sepia` | Sepya ton uygula | | `invert` | Tüm renkleri tersine çevir | ### Renk kanalları {#color-channels} Bireysel RGB renk kanallarını ayarlar. Değerler, 100 = değişiklik yok olan çarpanlardır. | Parametre | Tür | Açıklama | |---|---|---| | `red` | number | Kırmızı kanal çarpanı (0 ile 200, 100 = değişmemiş) | | `green` | number | Yeşil kanal çarpanı (0 ile 200, 100 = değişmemiş) | | `blue` | number | Mavi kanal çarpanı (0 ile 200, 100 = değişmemiş) | ### sharpen {#sharpen} Tek bir değerle kontrol edilen basit keskinleştirme. | Parametre | Tür | Açıklama | |---|---|---| | `value` | number | Keskinleştirme yoğunluğu (0 ile 100). 0,5-10 arası bir Gauss sigma değerine eşlenir. | ### sharpen-advanced {#sharpen-advanced} Üç seçilebilir yöntem ve isteğe bağlı bir gürültü azaltma ön geçişi ile gelişmiş keskinleştirme. | Parametre | Tür | Açıklama | |---|---|---| | `method` | string | `adaptive`, `unsharp-mask` veya `high-pass` | | `sigma` | number | Gauss bulanıklık yarıçapı, 0,5-10 (uyarlamalı) | | `m1` | number | Düz alan keskinleştirme, 0-10 (uyarlamalı) | | `m2` | number | Dokulu alan keskinleştirme, 0-20 (uyarlamalı) | | `x1` | number | Düz/tırtıklı eşiği, 0-10 (uyarlamalı) | | `y2` | number | Maksimum aydınlatma (halo kelepçesi), 0-50 (uyarlamalı) | | `y3` | number | Maksimum karartma (halo kelepçesi), 0-50 (uyarlamalı) | | `amount` | number | Yoğunluk yüzdesi, 0-500 (unsharp-mask) | | `radius` | number | Bulanıklık yarıçapı, 0,1-5,0 (unsharp-mask) | | `threshold` | number | Minimum kenar parlaklığı, 0-255 (unsharp-mask) | | `strength` | number | Karıştırma gücü, 0-100 (high-pass) | | `kernelSize` | number | 3x3 / 5x5 çekirdek için `3` veya `5` (high-pass) | | `denoise` | string | Gürültü azaltma ön geçişi: `off`, `light`, `medium` veya `strong` | Parametreler yönteme özgüdür. Yalnızca seçilen yöntemle ilgili olanları sağlayın. ### color-blindness {#color-blindness} 3x3 renk yeniden birleştirme matrisi kullanarak bir renk görme eksikliğini simüle eder. | Parametre | Tür | Açıklama | |---|---|---| | `type` | string | Şunlardan biri: `protanopia`, `deuteranopia`, `tritanopia`, `protanomaly`, `deuteranomaly`, `tritanomaly`, `achromatopsia`, `blueConeMonochromacy` | ### edit-metadata {#edit-metadata} Tüm bloğu kaldırmadan bireysel EXIF/IPTC meta veri alanlarını yazar veya kaldırır. | Parametre | Tür | Açıklama | |---|---|---| | `artist` | string | EXIF Artist etiketi | | `copyright` | string | EXIF Copyright etiketi | | `imageDescription` | string | EXIF ImageDescription etiketi | | `software` | string | EXIF Software etiketi | | `dateTime` | string | EXIF DateTime etiketi | | `dateTimeOriginal` | string | EXIF DateTimeOriginal etiketi | | `clearGps` | boolean | Tüm GPS etiketlerini kaldır | | `fieldsToRemove` | string\[] | Silinecek EXIF alan adlarının listesi | Tüm parametreler isteğe bağlıdır. `fieldsToRemove` içinde listelenen alanlar mevcut EXIF bloğundan silinir. Adlandırılmış parametreler aracılığıyla ayarlanan alanlar yazılır (veya üzerine yazılır). MakerNote gibi ikili/güvenli olmayan anahtarlar sessizce yok sayılır. ## Biçim algılama {#format-detection} Motor, giriş biçimlerini yalnızca dosya uzantılarından değil, dosya başlıklarından otomatik olarak algılar. Bu, aslında bir PNG olan bir `.jpg` dosyasının doğru şekilde işleneceği anlamına gelir. Algılama çok katmanlı bir yaklaşım kullanır: önce sihirli baytlar, ardından yedek olarak dosya uzantısı. SnapOtter, 20+ markadan 23 kamera RAW biçimi, profesyonel biçimler (PSD, EPS, OpenEXR, HDR), modern codec'ler (JPEG XL, AVIF, HEIC, QOI, JPEG 2000) ve bilimsel/oyun biçimleri (FITS, DDS) dahil olmak üzere **55+ giriş biçimi** ve **13 çıkış biçimi** destekler. Kod çözme, mümkün olduğunda Sharp tarafından yerel olarak, ImageMagick, LibRaw ve özel CLI kod çözücülerine otomatik yedeklemeyle yönetilir. Tam liste için [Desteklenen Biçimler](/tr/guide/supported-formats) sayfasına bakın. ## Meta veri çıkarma {#metadata-extraction} `info` aracı görüntü meta verilerini döndürür. Tam alan referansı için [Görüntü Bilgisi](/tr/tools/image/info) sayfasına bakın. ```json { "filename": "photo.jpg", "fileSize": 2450000, "width": 4032, "height": 3024, "format": "jpeg", "channels": 3, "hasAlpha": false, "colorSpace": "srgb", "density": 72, "isProgressive": false, "hasExif": true, "hasIcc": true, "hasXmp": false, "bitDepth": "8", "pages": 1, "histogram": [ { "channel": "red", "min": 0, "max": 255, "mean": 128.45, "stdev": 52.31 }, { "channel": "green", "min": 2, "max": 253, "mean": 115.22, "stdev": 48.76 }, { "channel": "blue", "min": 0, "max": 250, "mean": 102.89, "stdev": 55.14 } ] } ``` --- --- url: https://docs.snapotter.com/tr/tools/image/compress.md description: >- Görüntü dosyası boyutunu kalite düzeyine göre veya hedef dosya boyutuna göre azaltın. --- # Görüntü Sıkıştır {#compress} Bir kalite düzeyi veya kilobayt cinsinden hedef bir dosya boyutu belirterek görüntü dosyası boyutunu azaltın. Araç, boyut hedeflerine doğru bir şekilde ulaşmak için yinelemeli ikili arama kullanır. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/compress` Bir görüntü dosyası ve bir JSON `settings` alanı ile çok parçalı form verilerini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | mode | string | Hayır | `"quality"` | Sıkıştırma modu: `quality` veya `targetSize` | | quality | number | Hayır | `80` | Kalite düzeyi (1-100). Mod `quality` olduğunda kullanılır. | | targetSizeKb | number | Hayır | - | Kilobayt cinsinden hedef dosya boyutu. Mod `targetSize` olduğunda kullanılır. | ## Örnek İstek {#example-request} Kalite 60'a sıkıştır: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "quality", "quality": 60}' ``` 200 KB hedef boyutuna sıkıştır: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/compress \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"mode": "targetSize", "targetSizeKb": 200}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 204800 } ``` ## Notlar {#notes} * `quality` modunda, daha düşük değerler daha fazla sıkıştırma bozulmasıyla daha küçük dosyalar üretir. 80 değeri, web kullanımı için iyi bir varsayılandır. * `targetSize` modunda, motor hedefi aşmadan mümkün olduğunca yaklaşmak için yinelemeli sıkıştırma gerçekleştirir. * Çıktı biçimi giriş biçimiyle eşleşir. Sıkıştırma, biçimin yerel kodlamasına uygulanır (örn. JPEG dosyaları için JPEG kalitesi, WebP dosyaları için WebP kalitesi). * Varsayılan kalite (80) kabul edilebilirse, `quality` parametresini tamamen atlayabilirsiniz. --- --- url: https://docs.snapotter.com/tr/tools/image/vectorize.md description: >- Raster görüntüleri siyah-beyaz (potrace) ve tam renkli çok katmanlı vektörleştirme ile SVG'ye dönüştürün. --- # Görüntüden SVG'ye {#image-to-svg} İzleme algoritmaları kullanarak raster görüntüleri SVG'ye vektörleştirin. Siyah-beyaz izlemeyi (potrace) ve tam renkli çok katmanlı vektörleştirmeyi destekler. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/vectorize` ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | colorMode | string | Hayır | `"bw"` | İzleme modu: `bw` (siyah ve beyaz) veya `color` (çok renkli katmanlar) | | threshold | number | Hayır | 128 | S\&B modu için parlaklık eşiği (0 ile 255 arası). Altındaki pikseller siyah olur. | | colorPrecision | number | Hayır | 6 | Renk modu için renk niceleme hassasiyeti (1 ile 16 arası). Daha yüksek değerler daha belirgin renk katmanları üretir. | | layerDifference | number | Hayır | 6 | Renk modunda katmanlar arası minimum renk farkı (1 ile 128 arası) | | filterSpeckle | number | Hayır | 4 | Piksel cinsinden izlenen şekiller için minimum alan (1 ile 256 arası). Gürültü/lekeleri kaldırır. | | pathMode | string | Hayır | `"spline"` | Yol yumuşatma: `none` (pürüzlü), `polygon` (düz segmentler), `spline` (yumuşak eğriler) | | cornerThreshold | number | Hayır | 60 | Renk modunda köşe algılama için açı eşiği (0 ile 180 derece arası) | | invert | boolean | Hayır | `false` | İzlemeden önce görüntüyü tersine çevir (siyah/beyazı değiştir) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@logo.png" \ -F 'settings={"colorMode":"bw","threshold":128,"filterSpeckle":4,"pathMode":"spline"}' ``` ### Renkli Vektörleştirme {#color-vectorization} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/vectorize \ -F "file=@illustration.png" \ -F 'settings={"colorMode":"color","colorPrecision":8,"layerDifference":6,"filterSpeckle":4}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logo.svg", "originalSize": 45678, "processedSize": 12345 } ``` ## Notlar {#notes} * Giriş biçiminden bağımsız olarak çıktı her zaman bir SVG dosyasıdır. * HEIC, RAW, PSD ve SVG giriş biçimlerini destekler (izlemeden önce otomatik olarak raster'a çözülür). * S\&B modu potrace algoritmasını kullanır. Görüntü önce gri tonlamaya dönüştürülür, ardından izlemeden önce saf siyah/beyaza eşiklenir. * Renk modu çok katmanlı bir yaklaşım kullanır: görüntü renk katmanlarına nicelenir, her biri ayrı ayrı izlenir ve SVG çıktısında üst üste yığılır. * Daha düşük `filterSpeckle` değerleri daha fazla ayrıntıyı korur ancak daha fazla yollu daha büyük SVG dosyaları üretir. * `pathMode` ayarı dosya boyutunu önemli ölçüde etkiler: `none` en fazla yolu üretir, `spline` en yumuşak (ve genellikle en küçük) çıktıyı üretir. * Logolar ve simgeler için en iyi sonuçlar için, temiz ve yüksek kontrastlı bir girdiyle S\&B modunu kullanın. Fotoğraflar veya illüstrasyonlar için daha yüksek `colorPrecision` ile renk modunu kullanın. --- --- url: https://docs.snapotter.com/tr/tools/image/stitch.md description: >- Hizalama, boşluk, kenarlık ve yeniden boyutlandırma modu üzerinde denetimle görüntüleri yan yana, üst üste veya bir ızgarada birleştirin. --- # Görüntüleri Birleştir {#stitch-combine} Birden fazla görüntüyü yan yana, dikey olarak üst üste veya bir ızgara halinde birleştirin. Hizalama, boşluk, kenarlık, köşe yarıçapı ve birden fazla yeniden boyutlandırma modunu destekler. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/stitch` ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | direction | string | Hayır | `"horizontal"` | Yerleşim yönü: `horizontal`, `vertical`, `grid` | | gridColumns | integer | Hayır | 2 | Yön `grid` olduğunda sütun sayısı (2 ile 100 arası) | | resizeMode | string | Hayır | `"fit"` | Görüntülerin nasıl yeniden boyutlandırılacağı: `fit`, `original`, `stretch`, `crop` | | alignment | string | Hayır | `"center"` | Çapraz eksen hizalaması: `start`, `center`, `end` | | gap | number | Hayır | 0 | Piksel cinsinden görüntüler arası boşluk (0 ile 1000 arası) | | border | number | Hayır | 0 | Piksel cinsinden dış kenarlık genişliği (0 ile 500 arası) | | cornerRadius | number | Hayır | 0 | Nihai çıktıya uygulanan köşe yarıçapı (0 ile 500 arası) | | backgroundColor | string | Hayır | `"#FFFFFF"` | Hex olarak arka plan/kenarlık rengi (örn. `#FF0000`) | | format | string | Hayır | `"png"` | Çıktı biçimi: `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Hayır | 90 | Çıktı kalitesi (1 ile 100 arası) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/stitch \ -F "file=@image1.png" \ -F "file=@image2.png" \ -F "file=@image3.png" \ -F 'settings={"direction":"horizontal","resizeMode":"fit","gap":10,"backgroundColor":"#FFFFFF","format":"png"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stitch.png", "originalSize": 1234567, "processedSize": 987654 } ``` ## Notlar {#notes} * En az 2 görüntü gerektirir. Multipart isteğinde birden fazla görüntü dosyası yükleyin. * HEIC, RAW, PSD ve SVG giriş biçimlerini destekler (otomatik olarak çözülür). * Yeniden boyutlandırma modları: * `fit` - Görüntüleri birleştirme ekseni boyunca en küçük boyuta uyacak şekilde ölçekler. * `original` - Orijinal boyutları korur (düzensiz kenarlar oluşturabilir). * `stretch` - En-boy oranını korumadan görüntüleri en küçük boyuta uymaya zorlar. * `crop` - En küçük boyuta uyacak şekilde görüntüleri kaplama-kırpma yapar. * `grid` modunda hücreler, tüm görüntülerin medyan boyutlarına göre boyutlandırılır. * `cornerRadius`, tek tek görüntülere değil, tüm nihai çıktıya uygulanır. * Bellek tükenmesini önlemek için tuval boyutu `MAX_CANVAS_PIXELS` sunucu yapılandırmasıyla sınırlandırılır. --- --- url: https://docs.snapotter.com/ar/tools/pdf/grayscale-pdf.md description: تحويل جميع الألوان في ملف PDF إلى تدرّج رمادي. --- # Grayscale PDF {#grayscale-pdf} حوّل جميع الألوان في ملف PDF إلى تدرّج رمادي، مُنتِجاً نسخة بالأبيض والأسود من المستند. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` يقبل بيانات نموذج multipart تحتوي على ملف PDF. لا حاجة إلى حقل `settings`. ## Parameters {#parameters} ليس لهذه الأداة أي معاملات إعدادات. ارفع ملف PDF مباشرة. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * تُحوَّل جميع مساحات الألوان (RGB وCMYK) إلى تدرّج رمادي، بما في ذلك الصور المضمّنة والرسوميات المتّجهة والنص. * غالباً ما يكون ملف المخرجات أصغر من الأصلي لأن بيانات التدرّج الرمادي تتطلّب وحدات بايت أقل لكل بكسل. --- --- url: https://docs.snapotter.com/hi/tools/pdf/grayscale-pdf.md description: PDF के सभी रंगों को ग्रेस्केल में बदलें। --- # Grayscale PDF {#grayscale-pdf} PDF के सभी रंगों को ग्रेस्केल में बदलें, जिससे दस्तावेज़ का एक श्वेत-श्याम संस्करण बने। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` एक PDF फ़ाइल के साथ multipart form data स्वीकार करता है। कोई `settings` फ़ील्ड आवश्यक नहीं है। ## Parameters {#parameters} इस टूल में कोई सेटिंग्स पैरामीटर नहीं हैं। PDF फ़ाइल सीधे अपलोड करें। ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * सभी कलर स्पेस (RGB, CMYK) को ग्रेस्केल में बदला जाता है, जिसमें एम्बेडेड इमेज, वेक्टर ग्राफ़िक्स और टेक्स्ट शामिल हैं। * आउटपुट फ़ाइल अक्सर मूल से छोटी होती है क्योंकि ग्रेस्केल डेटा को प्रति पिक्सेल कम बाइट्स की आवश्यकता होती है। --- --- url: https://docs.snapotter.com/id/tools/pdf/grayscale-pdf.md description: Konversi semua warna dalam PDF menjadi skala abu-abu. --- # Grayscale PDF {#grayscale-pdf} Konversi semua warna dalam PDF menjadi skala abu-abu, menghasilkan versi hitam-putih dari dokumen. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Menerima data form multipart berisi file PDF. Tidak diperlukan field `settings`. ## Parameters {#parameters} Alat ini tidak memiliki parameter pengaturan. Unggah file PDF secara langsung. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Semua ruang warna (RGB, CMYK) dikonversi menjadi skala abu-abu, termasuk gambar yang tertanam, grafik vektor, dan teks. * File output sering kali lebih kecil dari aslinya karena data skala abu-abu membutuhkan lebih sedikit byte per piksel. --- --- url: https://docs.snapotter.com/ja/tools/pdf/grayscale-pdf.md description: PDF 内のすべての色をグレースケールに変換します。 --- # Grayscale PDF {#grayscale-pdf} PDF 内のすべての色をグレースケールに変換し、ドキュメントの白黒バージョンを生成します。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` PDF ファイルを含む multipart フォームデータを受け付けます。`settings` フィールドは不要です。 ## Parameters {#parameters} このツールに設定パラメータはありません。PDF ファイルをそのままアップロードしてください。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * すべての色空間(RGB、CMYK)が、埋め込み画像、ベクターグラフィック、テキストを含めてグレースケールに変換されます。 * グレースケールデータは 1 ピクセルあたりのバイト数が少なくて済むため、出力ファイルは元よりも小さくなることが多いです。 --- --- url: https://docs.snapotter.com/ko/tools/pdf/grayscale-pdf.md description: PDF의 모든 색상을 회색조로 변환합니다. --- # Grayscale PDF {#grayscale-pdf} PDF의 모든 색상을 회색조로 변환하여 문서의 흑백 버전을 생성합니다. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` PDF 파일이 포함된 multipart form data를 받습니다. `settings` 필드는 필요하지 않습니다. ## Parameters {#parameters} 이 도구에는 설정 매개변수가 없습니다. PDF 파일을 직접 업로드하세요. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * 모든 색 공간(RGB, CMYK)이 회색조로 변환되며, 여기에는 내장된 이미지, 벡터 그래픽, 텍스트가 포함됩니다. * 회색조 데이터는 픽셀당 더 적은 바이트를 필요로 하므로 출력 파일은 원본보다 작은 경우가 많습니다. --- --- url: https://docs.snapotter.com/nl/tools/pdf/grayscale-pdf.md description: Zet alle kleuren in een PDF om naar grijstinten. --- # Grayscale PDF {#grayscale-pdf} Zet alle kleuren in een PDF om naar grijstinten en produceer een zwart-witversie van het document. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Accepteert multipart-formuliergegevens met een PDF-bestand. Er is geen veld `settings` vereist. ## Parameters {#parameters} Dit hulpmiddel heeft geen instellingsparameters. Upload het PDF-bestand direct. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Alle kleurruimten (RGB, CMYK) worden omgezet naar grijstinten, inclusief ingebedde afbeeldingen, vectorafbeeldingen en tekst. * Het uitvoerbestand is vaak kleiner dan het origineel omdat grijstintgegevens minder bytes per pixel vereisen. --- --- url: https://docs.snapotter.com/pl/tools/pdf/grayscale-pdf.md description: Przekształć wszystkie kolory w pliku PDF na odcienie szarości. --- # Grayscale PDF {#grayscale-pdf} Przekształć wszystkie kolory w pliku PDF na odcienie szarości, tworząc czarno-białą wersję dokumentu. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Przyjmuje dane formularza multipart z plikiem PDF. Pole `settings` nie jest wymagane. ## Parameters {#parameters} To narzędzie nie ma parametrów ustawień. Prześlij plik PDF bezpośrednio. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Wszystkie przestrzenie barw (RGB, CMYK) są konwertowane na odcienie szarości, w tym osadzone obrazy, grafika wektorowa i tekst. * Plik wynikowy jest często mniejszy niż oryginał, ponieważ dane w skali szarości wymagają mniej bajtów na piksel. --- --- url: https://docs.snapotter.com/pt-BR/tools/pdf/grayscale-pdf.md description: Converta todas as cores de um PDF para escala de cinza. --- # Grayscale PDF {#grayscale-pdf} Converta todas as cores de um PDF para escala de cinza, produzindo uma versão em preto e branco do documento. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Aceita dados de formulário multipart com um arquivo PDF. Nenhum campo `settings` é necessário. ## Parameters {#parameters} Esta ferramenta não tem parâmetros de configuração. Envie o arquivo PDF diretamente. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Todos os espaços de cor (RGB, CMYK) são convertidos para escala de cinza, incluindo imagens incorporadas, gráficos vetoriais e texto. * O arquivo de saída costuma ser menor que o original, pois os dados em escala de cinza exigem menos bytes por pixel. --- --- url: https://docs.snapotter.com/ru/tools/pdf/grayscale-pdf.md description: Преобразование всех цветов в PDF в оттенки серого. --- # Grayscale PDF {#grayscale-pdf} Преобразуйте все цвета в PDF в оттенки серого, получив чёрно-белую версию документа. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Принимает данные multipart form с PDF-файлом. Поле `settings` не требуется. ## Parameters {#parameters} У этого инструмента нет параметров настроек. Загрузите PDF-файл напрямую. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Все цветовые пространства (RGB, CMYK) преобразуются в оттенки серого, включая встроенные изображения, векторную графику и текст. * Выходной файл часто меньше исходного, поскольку данные в оттенках серого требуют меньше байтов на пиксель. --- --- url: https://docs.snapotter.com/sv/tools/pdf/grayscale-pdf.md description: Konvertera alla färger i en PDF till gråskala. --- # Grayscale PDF {#grayscale-pdf} Konvertera alla färger i en PDF till gråskala och skapa en svartvit version av dokumentet. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Tar emot multipart-formulärdata med en PDF-fil. Inget fält `settings` krävs. ## Parameters {#parameters} Detta verktyg har inga inställningsparametrar. Ladda upp PDF-filen direkt. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Alla färgrymder (RGB, CMYK) konverteras till gråskala, inklusive inbäddade bilder, vektorgrafik och text. * Utdatafilen är ofta mindre än originalet eftersom gråskaledata kräver färre byte per pixel. --- --- url: https://docs.snapotter.com/th/tools/pdf/grayscale-pdf.md description: แปลงสีทั้งหมดใน PDF ให้เป็นโทนสีเทา --- # Grayscale PDF {#grayscale-pdf} แปลงสีทั้งหมดใน PDF ให้เป็นโทนสีเทา สร้างเอกสารเวอร์ชันขาวดำ ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` รับข้อมูลแบบ multipart form data พร้อมไฟล์ PDF ไม่จำเป็นต้องมีฟิลด์ `settings` ## Parameters {#parameters} เครื่องมือนี้ไม่มีพารามิเตอร์การตั้งค่า อัปโหลดไฟล์ PDF ได้โดยตรง ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * พื้นที่สีทั้งหมด (RGB, CMYK) จะถูกแปลงเป็นโทนสีเทา รวมถึงรูปภาพที่ฝังอยู่ กราฟิกเวกเตอร์ และข้อความ * ไฟล์ผลลัพธ์มักจะเล็กกว่าต้นฉบับ เนื่องจากข้อมูลโทนสีเทาต้องการจำนวนไบต์ต่อพิกเซลน้อยกว่า --- --- url: https://docs.snapotter.com/uk/tools/pdf/grayscale-pdf.md description: Перетворення всіх кольорів у PDF на відтінки сірого. --- # Grayscale PDF {#grayscale-pdf} Перетворюйте всі кольори в PDF на відтінки сірого, отримуючи чорно-білу версію документа. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Приймає багаточастинні (multipart) дані форми з файлом PDF. Поле `settings` не потрібне. ## Parameters {#parameters} Цей інструмент не має параметрів налаштувань. Завантажте файл PDF напряму. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Усі колірні простори (RGB, CMYK) перетворюються на відтінки сірого, включно з вбудованими зображеннями, векторною графікою та текстом. * Вихідний файл часто менший за оригінал, оскільки дані у відтінках сірого потребують менше байтів на піксель. --- --- url: https://docs.snapotter.com/vi/tools/pdf/grayscale-pdf.md description: Chuyển đổi tất cả màu sắc trong một PDF sang thang xám. --- # Grayscale PDF {#grayscale-pdf} Chuyển đổi tất cả màu sắc trong một PDF sang thang xám, tạo ra một phiên bản đen trắng của tài liệu. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` Chấp nhận dữ liệu biểu mẫu multipart với một tệp PDF. Không cần trường `settings`. ## Parameters {#parameters} Công cụ này không có tham số cài đặt. Tải trực tiếp tệp PDF lên. ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * Tất cả các không gian màu (RGB, CMYK) được chuyển đổi sang thang xám, bao gồm hình ảnh nhúng, đồ họa vector và văn bản. * Tệp đầu ra thường nhỏ hơn tệp gốc vì dữ liệu thang xám cần ít byte hơn cho mỗi pixel. --- --- url: https://docs.snapotter.com/zh-CN/tools/pdf/grayscale-pdf.md description: 将 PDF 中的所有颜色转换为灰度。 --- # Grayscale PDF {#grayscale-pdf} 将 PDF 中的所有颜色转换为灰度,生成文档的黑白版本。 ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/grayscale-pdf` 接受包含一个 PDF 文件的 multipart 表单数据。无需 `settings` 字段。 ## Parameters {#parameters} 此工具没有设置参数。直接上传 PDF 文件即可。 ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/grayscale-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 3200000, "processedSize": 2800000 } ``` ## Notes {#notes} * 所有色彩空间(RGB、CMYK)都会转换为灰度,包括嵌入的图像、矢量图形和文本。 * 输出文件通常比原始文件更小,因为灰度数据每像素所需的字节更少。 --- --- url: https://docs.snapotter.com/pt-BR/guide/translations.md description: >- 21 idiomas suportados e como criar ou aprimorar traduções para o SnapOtter usando o sistema de i18n reforçado por TypeScript. --- # Guia de tradução {#translation-guide} O SnapOtter já vem com 21 idiomas prontos para uso. O sistema de i18n usa um runtime próprio e leve, com completude de locale garantida pelo TypeScript e code-splitting dinâmico. ## Idiomas suportados {#supported-languages} | Code | Language | Native Name | Direction | |------|----------|-------------|-----------| | `en` | Inglês | English | LTR | | `zh-CN` | Chinês (Simplificado) | 简体中文 | LTR | | `zh-TW` | Chinês (Tradicional) | 繁體中文 | LTR | | `ja` | Japonês | 日本語 | LTR | | `ko` | Coreano | 한국어 | LTR | | `es` | Espanhol | Español | LTR | | `fr` | Francês | Français | LTR | | `it` | Italiano | Italiano | LTR | | `pt-BR` | Português (Brasil) | Português (Brasil) | LTR | | `de` | Alemão | Deutsch | LTR | | `nl` | Holandês | Nederlands | LTR | | `sv` | Sueco | Svenska | LTR | | `ru` | Russo | Русский | LTR | | `pl` | Polonês | Polski | LTR | | `uk` | Ucraniano | Українська | LTR | | `ar` | Árabe | العربية | RTL | | `tr` | Turco | Türkçe | LTR | | `hi` | Híndi | हिन्दी | LTR | | `vi` | Vietnamita | Tiếng Việt | LTR | | `id` | Indonésio | Bahasa Indonesia | LTR | | `th` | Tailandês | ไทย | LTR | ## Como funciona a detecção de idioma {#how-language-detection-works} O SnapOtter usa uma ordem de resolução em três camadas: 1. **Preferência do usuário** - armazenada em `localStorage("snapotter-locale")` e sincronizada com as configurações do usuário quando autenticado 2. **Detecção automática do navegador** - percorre o array `navigator.languages` com correspondência de prefixo BCP 47 3. **Padrão da instância** - a variável de ambiente `DEFAULT_LOCALE` do administrador (obtida de `GET /api/v1/config/locale`) 4. **Fallback para inglês** - sempre disponível Os usuários podem alterar o idioma a partir de: * O **seletor Globo no rodapé** (desktop, sempre visível) * O seletor de idioma da **página de login** (pré-autenticação) * A seção **Configurações > Geral** (preferência por usuário) * O menu suspenso de idioma da **barra lateral móvel** * A seção **Configurações > Sistema** define o padrão para toda a instância (somente administrador) ## Como funcionam as traduções {#how-translations-work} Todas as strings da interface ficam em `packages/shared/src/i18n/`. O arquivo de referência é `en.ts`, que exporta um objeto tipado com todas as strings que o app usa (~1500 chaves). Os demais idiomas são arquivos separados (por exemplo, `de.ts`, `fr.ts`) que exportam a mesma estrutura. O tipo `TranslationKeys` usa `DeepStringRecord` para aceitar qualquer valor de string enquanto impõe a estrutura das chaves. O TypeScript detecta chaves faltantes em qualquer arquivo de tradução em tempo de compilação. Apenas o locale ativo é carregado em runtime via `import()` dinâmico, mantendo o bundle principal pequeno. ## Usando traduções em componentes {#using-translations-in-components} ```tsx import { useTranslation } from "@/contexts/i18n-context"; import { format, plural } from "@/lib/format"; function MyComponent() { const { t, locale, setLocale } = useTranslation(); return (

{t.common.settings}

{format(t.settings.people.deleteConfirm, { username: "admin" })}

{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}

); } ``` ## Contribuindo com uma tradução {#contributing-a-translation} Aceitamos PRs de tradução diretamente. Você pode aprimorar um locale existente ou adicionar um novo. Para relatar uma tradução incorreta sem enviar código, abra uma [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) com o idioma, a string incorreta e a correção sugerida. ::: tip PRs de tradução não exigem aprovação prévia. Faça um fork do repositório, faça suas alterações e abra um PR. Consulte o [Guia de Contribuição](/pt-BR/guide/contributing) para o processo completo de PR e o requisito de CLA. ::: ## Como criar ou atualizar uma tradução {#how-to-create-or-update-a-translation} ### 1. Faça o fork e clone {#\_1-fork-and-clone} ```bash git clone https://github.com//snapotter.git cd snapotter pnpm install ``` ### 2. Copie o arquivo de referência (apenas novo idioma) {#\_2-copy-the-reference-file-new-language-only} Pule esta etapa se você estiver aprimorando uma tradução existente. ```bash cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts ``` ### 3. Traduza as strings {#\_3-translate-the-strings} Abra seu novo arquivo e traduza cada valor de string. Mantenha a estrutura do objeto e as chaves exatamente iguais. ```ts import type { TranslationKeys } from "./en.js"; export const xx: TranslationKeys = { common: { upload: "Your translation here", // ... translate all entries }, // ... translate all sections } as const; ``` Regras: * Não traduza as chaves do objeto, apenas os valores de string * Mantenha `as const` no final * Importe `TranslationKeys` de `./en.js` e tipe sua exportação * Mantenha os placeholders `{variable}` exatamente como estão * Os arrays (`rotatingPhrases`, `progressMessages`) devem ter o mesmo número de entradas * Não traduza: SnapOtter, JPEG, PNG, WebP, EXIF, API e outros termos técnicos ### 4. Registre o locale (apenas novo idioma) {#\_4-register-the-locale-new-language-only} Adicione seu locale a `SUPPORTED_LOCALES` em `packages/shared/src/i18n/index.ts`: ```ts { code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" }, ``` ### 5. Verifique {#\_5-verify} ```bash pnpm typecheck # catches missing or mistyped keys pnpm lint # formatting check pnpm dev # manually verify strings appear correctly ``` ### 6. Envie {#\_6-submit} Abra um PR contra `main` com um título como `feat(i18n): add Swedish translation` ou `fix(i18n): correct German typos`. O bot do CLA pedirá que você assine na sua primeira contribuição. ## Adicionando novas chaves de tradução {#adding-new-translation-keys} Ao adicionar um novo recurso que precise de novas strings de interface: 1. Adicione as novas chaves a `en.ts` primeiro (o arquivo de referência) 2. Execute `pnpm typecheck` - cada arquivo de locale falhará se estiver sem a nova chave 3. Adicione a nova chave a todos os arquivos de locale (use o inglês como fallback temporário) ## Configuração {#configuration} Defina o idioma padrão da instância por meio de variável de ambiente: ```yaml DEFAULT_LOCALE: "de" # German as the default for all new users ``` ## Referência de arquivos {#file-reference} | File | Purpose | |------|---------| | `packages/shared/src/i18n/en.ts` | Strings em inglês (locale de referência, ~1500 chaves) | | `packages/shared/src/i18n/index.ts` | `SUPPORTED_LOCALES`, `loadTranslations()`, exportações de tipos | | `packages/shared/src/i18n/.ts` | Arquivos de tradução por idioma | | `apps/web/src/contexts/i18n-context.tsx` | `I18nProvider`, hook `useTranslation()` | | `apps/web/src/lib/format.ts` | Helpers `format()`, `plural()`, `formatFileSize()` | | `apps/api/src/routes/config.ts` | Endpoint público `GET /api/v1/config/locale` | ## Traduzindo o site, a documentação e a referência da API {#translating-the-web-surfaces} O suporte a 21 idiomas descrito acima cobre o **app**. O site público (snapotter.com), este site de documentação e a referência da API REST também são traduzidos para todos os 21 idiomas, por um pipeline separado protegido por hash que reutiliza os mesmos nomes e descrições de ferramentas de `packages/shared/src/i18n`, de modo que a terminologia permaneça consistente em toda parte. ### Traduzido por máquina por padrão {#machine-translated-by-default} Toda página que não seja em inglês no site e na documentação é **traduzida por máquina** na primeira passagem (por uma sessão do Claude Code, não por um serviço de terceiros) e traz um pequeno banner dispensável dizendo isso, com um link de volta para cá. Isso é deliberado: entrega todos os 21 idiomas com rapidez e honestidade e, então, convida a comunidade a refinar as páginas que mais importam. A tradução por máquina transmite o significado; a revisão humana faz o texto soar natural. ### Como o pipeline decide o que traduzir {#how-the-web-pipeline-decides} Cada unidade traduzível do texto-fonte em inglês é submetida a hash, e o hash é armazenado ao lado de sua tradução. A cada execução, o pipeline: * traduz qualquer unidade que ainda não tenha tradução, * pula qualquer unidade cujo hash armazenado ainda corresponda ao texto-fonte em inglês, * retraduz uma unidade de **máquina** quando seu texto-fonte em inglês muda, * e sinaliza uma unidade refinada por **humano** como `stale` (precisa de revisão) quando seu texto-fonte em inglês muda, em vez de sobrescrever seu trabalho. ### Refinando uma tradução da web por PR {#refining-a-web-translation-by-pr} Você aprimora uma tradução do site, da documentação ou da referência da API da mesma forma que aprimora um locale do app: editando o arquivo gerado e abrindo um PR. 1. Encontre a tradução gerada para o seu idioma: * strings de interface do site: `apps/landing/src/i18n/.json` * uma página da documentação: `apps/docs//**.md` * a referência da API: `apps/api/src/openapi..yaml` 2. Edite o texto. Mantenha código, links, `{placeholders}` e quaisquer marcadores `⸤I18N…⸥` exatamente como estão; o validador do pipeline rejeita uma tradução que remova ou reordene esses elementos. 3. Abra um PR. Editar uma unidade muda sua proveniência de `machine` para `human`, de modo que o pipeline **nunca a sobrescreverá** em uma execução posterior. Se o texto-fonte em inglês mudar depois, sua unidade é sinalizada como `stale` para revisão, em vez de ser substituída silenciosamente. Para relatar uma tradução incorreta sem enviar código, abra uma [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) com a URL da página, o idioma, o texto incorreto e sua correção sugerida. ::: tip Os mantenedores executam o pipeline de tradução; você não precisa de uma chave de API para contribuir. Basta editar o arquivo gerado e abrir um PR. Consulte [`scripts/i18n/README.md`](https://github.com/snapotter-hq/SnapOtter/blob/main/scripts/i18n/README.md) para saber como o pipeline funciona. ::: --- --- url: https://docs.snapotter.com/es/guide/translations.md description: >- 21 idiomas admitidos y cómo crear o mejorar traducciones para SnapOtter usando el sistema i18n reforzado con TypeScript. --- # Guía de traducción {#translation-guide} SnapOtter incluye 21 idiomas de fábrica. El sistema i18n usa un runtime propio y ligero, con integridad de locales reforzada por TypeScript y división dinámica del código. ## Idiomas admitidos {#supported-languages} | Code | Language | Native Name | Direction | |------|----------|-------------|-----------| | `en` | Inglés | English | LTR | | `zh-CN` | Chino (simplificado) | 简体中文 | LTR | | `zh-TW` | Chino (tradicional) | 繁體中文 | LTR | | `ja` | Japonés | 日本語 | LTR | | `ko` | Coreano | 한국어 | LTR | | `es` | Español | Español | LTR | | `fr` | Francés | Français | LTR | | `it` | Italiano | Italiano | LTR | | `pt-BR` | Portugués (Brasil) | Português (Brasil) | LTR | | `de` | Alemán | Deutsch | LTR | | `nl` | Neerlandés | Nederlands | LTR | | `sv` | Sueco | Svenska | LTR | | `ru` | Ruso | Русский | LTR | | `pl` | Polaco | Polski | LTR | | `uk` | Ucraniano | Українська | LTR | | `ar` | Árabe | العربية | RTL | | `tr` | Turco | Türkçe | LTR | | `hi` | Hindi | हिन्दी | LTR | | `vi` | Vietnamita | Tiếng Việt | LTR | | `id` | Indonesio | Bahasa Indonesia | LTR | | `th` | Tailandés | ไทย | LTR | ## Cómo funciona la detección de idioma {#how-language-detection-works} SnapOtter usa un orden de resolución de tres niveles: 1. **Preferencia del usuario**: almacenada en `localStorage("snapotter-locale")` y sincronizada con los ajustes del usuario cuando ha iniciado sesión 2. **Detección automática del navegador**: recorre el array `navigator.languages` con coincidencia de prefijos BCP 47 3. **Predeterminado de la instancia**: la variable de entorno `DEFAULT_LOCALE` del administrador (obtenida de `GET /api/v1/config/locale`) 4. **Respaldo en inglés**: siempre disponible Los usuarios pueden cambiar el idioma desde: * El **selector del globo terráqueo del pie de página** (escritorio, siempre visible) * El selector de idioma de la **página de inicio de sesión** (previo a la autenticación) * La sección **Ajustes > General** (preferencia por usuario) * El menú desplegable de idioma de la **barra lateral móvil** * La sección **Ajustes > Sistema**, que fija el idioma predeterminado de toda la instancia (solo administradores) ## Cómo funcionan las traducciones {#how-translations-work} Todas las cadenas de la interfaz viven en `packages/shared/src/i18n/`. El archivo de referencia es `en.ts`, que exporta un objeto tipado con todas las cadenas que usa la aplicación (~1500 claves). Los demás idiomas son archivos independientes (por ejemplo, `de.ts`, `fr.ts`) que exportan la misma forma. El tipo `TranslationKeys` usa `DeepStringRecord` para aceptar cualquier valor de cadena a la vez que refuerza la estructura de claves. TypeScript detecta las claves que falten en cualquier archivo de traducción en tiempo de compilación. En tiempo de ejecución solo se carga el locale activo mediante `import()` dinámico, lo que mantiene pequeño el bundle principal. ## Uso de traducciones en los componentes {#using-translations-in-components} ```tsx import { useTranslation } from "@/contexts/i18n-context"; import { format, plural } from "@/lib/format"; function MyComponent() { const { t, locale, setLocale } = useTranslation(); return (

{t.common.settings}

{format(t.settings.people.deleteConfirm, { username: "admin" })}

{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}

); } ``` ## Contribuir con una traducción {#contributing-a-translation} Recibimos con gusto PRs de traducción directamente. Puedes mejorar un locale existente o añadir uno nuevo. Para informar de una traducción incorrecta sin enviar código, abre un [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) con el idioma, la cadena incorrecta y la corrección sugerida. ::: tip Los PRs de traducción no requieren aprobación previa. Haz un fork del repositorio, realiza tus cambios y abre un PR. Consulta la [Guía de contribución](/es/guide/contributing) para conocer el proceso completo de PR y el requisito del CLA. ::: ## Cómo crear o actualizar una traducción {#how-to-create-or-update-a-translation} ### 1. Fork y clonado {#\_1-fork-and-clone} ```bash git clone https://github.com//snapotter.git cd snapotter pnpm install ``` ### 2. Copiar el archivo de referencia (solo para un idioma nuevo) {#\_2-copy-the-reference-file-new-language-only} Omite este paso si estás mejorando una traducción existente. ```bash cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts ``` ### 3. Traducir las cadenas {#\_3-translate-the-strings} Abre tu nuevo archivo y traduce cada valor de cadena. Mantén exactamente igual la estructura del objeto y las claves. ```ts import type { TranslationKeys } from "./en.js"; export const xx: TranslationKeys = { common: { upload: "Your translation here", // ... translate all entries }, // ... translate all sections } as const; ``` Reglas: * No traduzcas las claves del objeto, solo los valores de cadena * Mantén `as const` al final * Importa `TranslationKeys` desde `./en.js` y tipa tu exportación * Mantén los marcadores `{variable}` exactamente como están * Los arrays (`rotatingPhrases`, `progressMessages`) deben tener el mismo número de entradas * No traduzcas: SnapOtter, JPEG, PNG, WebP, EXIF, API y otros términos técnicos ### 4. Registrar el locale (solo para un idioma nuevo) {#\_4-register-the-locale-new-language-only} Añade tu locale a `SUPPORTED_LOCALES` en `packages/shared/src/i18n/index.ts`: ```ts { code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" }, ``` ### 5. Verificar {#\_5-verify} ```bash pnpm typecheck # catches missing or mistyped keys pnpm lint # formatting check pnpm dev # manually verify strings appear correctly ``` ### 6. Enviar {#\_6-submit} Abre un PR contra `main` con un título como `feat(i18n): add Swedish translation` o `fix(i18n): correct German typos`. El bot del CLA te pedirá que firmes en tu primera contribución. ## Añadir nuevas claves de traducción {#adding-new-translation-keys} Al añadir una nueva función que necesita cadenas nuevas en la interfaz: 1. Añade primero las nuevas claves a `en.ts` (el archivo de referencia) 2. Ejecuta `pnpm typecheck`: cada archivo de locale fallará si le falta la nueva clave 3. Añade la nueva clave a todos los archivos de locale (usa el inglés como respaldo temporal) ## Configuración {#configuration} Establece el idioma predeterminado de la instancia mediante una variable de entorno: ```yaml DEFAULT_LOCALE: "de" # German as the default for all new users ``` ## Referencia de archivos {#file-reference} | File | Purpose | |------|---------| | `packages/shared/src/i18n/en.ts` | Cadenas en inglés (locale de referencia, ~1500 claves) | | `packages/shared/src/i18n/index.ts` | `SUPPORTED_LOCALES`, `loadTranslations()`, exportaciones de tipos | | `packages/shared/src/i18n/.ts` | Archivos de traducción por idioma | | `apps/web/src/contexts/i18n-context.tsx` | `I18nProvider`, hook `useTranslation()` | | `apps/web/src/lib/format.ts` | Helpers `format()`, `plural()`, `formatFileSize()` | | `apps/api/src/routes/config.ts` | Endpoint público `GET /api/v1/config/locale` | ## Traducir el sitio web, la documentación y la referencia de la API {#translating-the-web-surfaces} El soporte de 21 idiomas descrito arriba cubre la **aplicación**. El sitio web público (snapotter.com), este sitio de documentación y la referencia de la API REST también se traducen a los 21 idiomas, mediante una canalización independiente controlada por hash que reutiliza los mismos nombres y descripciones de herramientas de `packages/shared/src/i18n`, de modo que la terminología se mantenga coherente en todas partes. ### Traducción automática de forma predeterminada {#machine-translated-by-default} Cada página que no está en inglés del sitio web y de la documentación se **traduce automáticamente** en la primera pasada (por una sesión de Claude Code, no por un servicio de terceros) y lleva un banner pequeño y descartable que así lo indica, con un enlace de vuelta aquí. Es intencional: así se publican los 21 idiomas de forma rápida y honesta, y luego se invita a la comunidad a refinar las páginas más importantes. La traducción automática transmite el significado; la revisión humana hace que se lea con naturalidad. ### Cómo decide la canalización qué traducir {#how-the-web-pipeline-decides} Cada unidad traducible del texto original en inglés se somete a hash, y ese hash se almacena junto a su traducción. En cada ejecución, la canalización: * traduce cualquier unidad que todavía no tenga traducción, * omite cualquier unidad cuyo hash almacenado siga coincidiendo con el texto original en inglés, * vuelve a traducir una unidad **automática** cuando su texto original en inglés cambia, * y marca una unidad refinada por un **humano** como `stale` (necesita revisión) cuando su texto original en inglés cambia, en lugar de sobrescribir tu trabajo. ### Refinar una traducción del sitio web mediante un PR {#refining-a-web-translation-by-pr} Mejoras una traducción del sitio web, de la documentación o de la referencia de la API igual que mejoras un locale de la aplicación: editando el archivo generado y abriendo un PR. 1. Encuentra la traducción generada para tu idioma: * cadenas de la interfaz del sitio web: `apps/landing/src/i18n/.json` * una página de documentación: `apps/docs//**.md` * la referencia de la API: `apps/api/src/openapi..yaml` 2. Edita el texto. Mantén el código, los enlaces, `{placeholders}` y cualquier marcador `⸤I18N…⸥` exactamente como están; el validador de la canalización rechaza una traducción que los omita o reordene. 3. Abre un PR. Editar una unidad cambia su procedencia de `machine` a `human`, de modo que la canalización **nunca la sobrescribirá** en una ejecución posterior. Si el texto original en inglés cambia después, tu unidad se marca como `stale` para revisión en lugar de reemplazarse en silencio. Para informar de una traducción incorrecta sin enviar código, abre un [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) con la URL de la página, el idioma, el texto incorrecto y tu corrección sugerida. ::: tip Los mantenedores ejecutan la canalización de traducción; no necesitas una clave de API para contribuir. Solo edita el archivo generado y abre un PR. Consulta [`scripts/i18n/README.md`](https://github.com/snapotter-hq/SnapOtter/blob/main/scripts/i18n/README.md) para saber cómo se ejecuta la canalización. ::: --- --- url: https://docs.snapotter.com/es/guide/developer.md description: >- Configuración del entorno de desarrollo local, comandos, convenciones de código y cómo añadir una nueva herramienta a SnapOtter. --- # Guía del desarrollador {#developer-guide} Cómo configurar un entorno de desarrollo local y contribuir con código a SnapOtter. ## Requisitos previos {#prerequisites} * [Node.js](https://nodejs.org/) 22.22+ * [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`) * [Docker](https://www.docker.com/) (requerido para Postgres + Redis locales, construcciones de contenedores y funciones de IA) * Git Python 3.11+ solo es necesario si trabajas en el sidecar de IA/ML (eliminación de fondo, escalado, OCR). ## Configuración {#setup} ```bash git clone https://github.com/snapotter-hq/snapotter.git cd snapotter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` Esto inicia dos servidores de desarrollo: | Servicio | URL | Notas | |----------|--------------------------|------------------------------------| | Frontend | http://localhost:1351 | Servidor de desarrollo Vite, hace proxy de /api | | Backend | http://localhost:13490 | API de Fastify (accedida vía proxy) | Abre http://localhost:1351 en tu navegador. Inicia sesión con `admin` / `admin`. Se te pedirá que cambies la contraseña en el primer inicio de sesión. ## Estructura del proyecto {#project-structure} ``` apps/ api/ Fastify backend web/ Vite + React frontend docs/ VitePress documentation (this site) packages/ shared/ Constants, types, i18n strings image-engine/ Sharp-based image operations media-engine/ FFmpeg spawn + progress parsing doc-engine/ qpdf, LibreOffice, ghostscript wrappers ai/ Python sidecar bridge for ML models tests/ unit/ Vitest unit tests integration/ Vitest integration tests (full API) e2e/ Playwright end-to-end specs fixtures/ Small test images ``` ## Comandos {#commands} ```bash pnpm dev # start frontend + backend pnpm build # build all workspaces pnpm typecheck # TypeScript check across monorepo pnpm lint # Biome lint + format check pnpm lint:fix # auto-fix lint + format pnpm test # unit + integration tests pnpm test:unit # unit tests only pnpm test:integration # integration tests only pnpm test:e2e # Playwright e2e tests pnpm test:coverage # tests with coverage report ``` ## Convenciones de código {#code-conventions} * Comillas dobles, punto y coma, indentación de 2 espacios (aplicado por Biome) * Módulos ES en todos los workspaces * [Conventional commits](https://www.conventionalcommits.org/) para semantic-release * Zod para toda la validación de entrada de la API * Sin modificaciones a los archivos de configuración de Biome, TypeScript o del editor. Corrige el código, no el linter. ## Base de datos {#database} PostgreSQL 17 mediante Drizzle ORM (pg-core). El desarrollo local requiere que Postgres y Redis estén en ejecución; inícialos con: ```bash docker compose -f docker-compose.dev.yml up -d ``` Esto te proporciona Postgres en el puerto 5432 y Redis en el puerto 6379. Luego genera y aplica las migraciones: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` El esquema se define en `apps/api/src/db/schema.ts`. Tablas: users, sessions, settings, jobs, apiKeys, pipelines, teams, userFiles, roles, auditLog. ## Añadir una nueva herramienta {#adding-a-new-tool} Cada herramienta sigue el mismo patrón. Aquí tienes un ejemplo mínimo. ### 1. Ruta del backend {#\_1-backend-route} Crea `apps/api/src/routes/tools/my-tool.ts`: ```ts import { z } from "zod"; import type { FastifyInstance } from "fastify"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ intensity: z.number().min(0).max(100).default(50), }); export function registerMyTool(app: FastifyInstance) { createToolRoute(app, { toolId: "my-tool", settingsSchema, async process(inputBuffer, settings, filename) { // Use sharp or other libraries to process the image const sharp = (await import("sharp")).default; const result = await sharp(inputBuffer) // ... your processing logic .toBuffer(); return { buffer: result, filename: filename.replace(/\.[^.]+$/, ".png"), contentType: "image/png", }; }, }); } ``` Luego regístrala en `apps/api/src/routes/tools/index.ts`. ### 2. Componente de ajustes del frontend {#\_2-frontend-settings-component} Crea `apps/web/src/components/tools/my-tool-settings.tsx`: ```tsx import { useState } from "react"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; export function MyToolSettings() { const { files } = useFileStore(); const { processFiles, processing, error, downloadUrl } = useToolProcessor("my-tool"); const [intensity, setIntensity] = useState(50); const handleProcess = () => { processFiles(files, { intensity }); }; return (
{/* your controls here */}
); } ``` Luego regístralo en el registro de herramientas del frontend en `apps/web/src/lib/tool-registry.tsx`: ```tsx // Add the lazy import const MyToolSettings = lazy(() => import("@/components/tools/my-tool-settings").then((m) => ({ default: m.MyToolSettings, })), ); // Add to the toolRegistry Map ["my-tool", { displayMode: "before-after", Settings: MyToolSettings }], ``` Modos de visualización: `"side-by-side"`, `"before-after"`, `"live-preview"`, `"no-comparison"`, `"interactive-crop"`, `"interactive-eraser"`, `"no-dropzone"`. ### 3. Entrada de i18n {#\_3-i18n-entry} Añade a `packages/shared/src/i18n/en.ts`: ```ts "my-tool": { name: "My Tool", description: "Short description of what this tool does", }, ``` ### 4. Pruebas {#\_4-tests} Añade un atributo `data-testid` a tu botón de acción (como se muestra arriba) para que las pruebas e2e puedan localizarlo de forma fiable. ## Construcciones de Docker {#docker-builds} Construye la imagen de producción completa localmente: ```bash docker build -f docker/Dockerfile -t snapotter:latest . ``` Usa las cache mounts de BuildKit para reconstrucciones más rápidas: ```bash DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest . ``` ## Dominios de versión de lanzamiento {#release-version-domains} SnapOtter tiene intencionalmente tres dominios de versión. No copie un dominio en otro durante un lanzamiento: * La versión de lanzamiento de la aplicación cubre el manifiesto raíz, todos los paquetes de espacios de trabajo privados y `APP_VERSION`. Semantic-release proporciona este valor y `pnpm version:sync ` actualiza cada espacio de trabajo antes del lanzamiento de una aplicación. * OpenAPI `info.version` es el contrato principal público estable API. Todas las especificaciones localizadas permanecen en `.0.0` para versiones de aplicaciones compatibles y cambian solo cuando el contrato API pasa a una nueva versión principal. * `docker/feature-manifest.json` mantiene a `imageVersion: 2.0.0` como la época de almacenamiento de paquetes de funciones heredadas e inmutables. Esas rutas de archivo v2 no son versiones de paquetes de aplicaciones. Accurate OCR utiliza el formato de tiempo de ejecución v3 y registra el origen de la versión de la aplicación por separado. `tests/unit/infra/release-version-policy.test.ts` impone estos límites. Una nueva versión de dominio o migración debe actualizar ese contrato y el diseño de migración de artefacto relevante juntos. Los valores independientes API y del paquete heredado se encuentran en `config/release-version-policy.json`; La sincronización de la versión de la aplicación nunca debe reescribir ese archivo de política implícitamente. ## Variables de entorno {#environment-variables} Consulta la [Guía de configuración](/es/guide/configuration) para la lista completa. Las clave para el desarrollo: | Variable | Por defecto | Descripción | |-----------------------------|-----------|------------------------------------------------| | `AUTH_ENABLED` | `true` | Habilitar/deshabilitar la autenticación | | `DEFAULT_USERNAME` | `admin` | Nombre de usuario del administrador por defecto | | `DEFAULT_PASSWORD` | `admin` | Contraseña del administrador por defecto | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Omitir el cambio de contraseña forzado (solo CI/dev) | | `RATE_LIMIT_PER_MIN` | `1000` | Límite de tasa de API por minuto (0 = deshabilitado) | | `MAX_UPLOAD_SIZE_MB` | `100` | Tamaño máximo de subida en MB (0 = ilimitado) | --- --- url: https://docs.snapotter.com/pt-BR/guide/developer.md description: >- Configuração de ambiente de desenvolvimento local, comandos, convenções de código e como adicionar uma nova ferramenta ao SnapOtter. --- # Guia do desenvolvedor {#developer-guide} Como configurar um ambiente de desenvolvimento local e contribuir com código para o SnapOtter. ## Pré-requisitos {#prerequisites} * [Node.js](https://nodejs.org/) 22.22+ * [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`) * [Docker](https://www.docker.com/) (necessário para Postgres + Redis locais, builds de contêiner e recursos de IA) * Git Python 3.11+ só é necessário se você estiver trabalhando no sidecar de IA/ML (remoção de fundo, upscaling, OCR). ## Configuração {#setup} ```bash git clone https://github.com/snapotter-hq/snapotter.git cd snapotter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` Isso inicia dois servidores de desenvolvimento: | Serviço | URL | Observações | |----------|--------------------------|------------------------------------| | Frontend | http://localhost:1351 | Servidor de dev Vite, faz proxy de /api | | Backend | http://localhost:13490 | API Fastify (acessada via proxy) | Abra http://localhost:1351 no seu navegador. Faça login com `admin` / `admin`. Você será solicitado a alterar a senha no primeiro login. ## Estrutura do projeto {#project-structure} ``` apps/ api/ Fastify backend web/ Vite + React frontend docs/ VitePress documentation (this site) packages/ shared/ Constants, types, i18n strings image-engine/ Sharp-based image operations media-engine/ FFmpeg spawn + progress parsing doc-engine/ qpdf, LibreOffice, ghostscript wrappers ai/ Python sidecar bridge for ML models tests/ unit/ Vitest unit tests integration/ Vitest integration tests (full API) e2e/ Playwright end-to-end specs fixtures/ Small test images ``` ## Comandos {#commands} ```bash pnpm dev # start frontend + backend pnpm build # build all workspaces pnpm typecheck # TypeScript check across monorepo pnpm lint # Biome lint + format check pnpm lint:fix # auto-fix lint + format pnpm test # unit + integration tests pnpm test:unit # unit tests only pnpm test:integration # integration tests only pnpm test:e2e # Playwright e2e tests pnpm test:coverage # tests with coverage report ``` ## Convenções de código {#code-conventions} * Aspas duplas, ponto e vírgula, indentação de 2 espaços (imposto pelo Biome) * Módulos ES em todos os workspaces * [Conventional commits](https://www.conventionalcommits.org/) para semantic-release * Zod para toda validação de entrada da API * Sem modificações nos arquivos de configuração do Biome, do TypeScript ou do editor. Corrija o código, não o linter. ## Banco de dados {#database} PostgreSQL 17 via Drizzle ORM (pg-core). O desenvolvimento local requer Postgres e Redis em execução - inicie-os com: ```bash docker compose -f docker-compose.dev.yml up -d ``` Isso lhe dá o Postgres na porta 5432 e o Redis na porta 6379. Depois gere e aplique as migrações: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` O esquema é definido em `apps/api/src/db/schema.ts`. Tabelas: users, sessions, settings, jobs, apiKeys, pipelines, teams, userFiles, roles, auditLog. ## Adicionando uma nova ferramenta {#adding-a-new-tool} Toda ferramenta segue o mesmo padrão. Aqui está um exemplo mínimo. ### 1. Rota do backend {#\_1-backend-route} Crie `apps/api/src/routes/tools/my-tool.ts`: ```ts import { z } from "zod"; import type { FastifyInstance } from "fastify"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ intensity: z.number().min(0).max(100).default(50), }); export function registerMyTool(app: FastifyInstance) { createToolRoute(app, { toolId: "my-tool", settingsSchema, async process(inputBuffer, settings, filename) { // Use sharp or other libraries to process the image const sharp = (await import("sharp")).default; const result = await sharp(inputBuffer) // ... your processing logic .toBuffer(); return { buffer: result, filename: filename.replace(/\.[^.]+$/, ".png"), contentType: "image/png", }; }, }); } ``` Então registre-a em `apps/api/src/routes/tools/index.ts`. ### 2. Componente de configurações do frontend {#\_2-frontend-settings-component} Crie `apps/web/src/components/tools/my-tool-settings.tsx`: ```tsx import { useState } from "react"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; export function MyToolSettings() { const { files } = useFileStore(); const { processFiles, processing, error, downloadUrl } = useToolProcessor("my-tool"); const [intensity, setIntensity] = useState(50); const handleProcess = () => { processFiles(files, { intensity }); }; return (
{/* your controls here */}
); } ``` Então registre-o no registro de ferramentas do frontend em `apps/web/src/lib/tool-registry.tsx`: ```tsx // Add the lazy import const MyToolSettings = lazy(() => import("@/components/tools/my-tool-settings").then((m) => ({ default: m.MyToolSettings, })), ); // Add to the toolRegistry Map ["my-tool", { displayMode: "before-after", Settings: MyToolSettings }], ``` Modos de exibição: `"side-by-side"`, `"before-after"`, `"live-preview"`, `"no-comparison"`, `"interactive-crop"`, `"interactive-eraser"`, `"no-dropzone"`. ### 3. Entrada de i18n {#\_3-i18n-entry} Adicione a `packages/shared/src/i18n/en.ts`: ```ts "my-tool": { name: "My Tool", description: "Short description of what this tool does", }, ``` ### 4. Testes {#\_4-tests} Adicione um atributo `data-testid` ao seu botão de ação (como mostrado acima) para que os testes e2e possam localizá-lo de forma confiável. ## Builds do Docker {#docker-builds} Construa a imagem de produção completa localmente: ```bash docker build -f docker/Dockerfile -t snapotter:latest . ``` Use cache mounts do BuildKit para rebuilds mais rápidos: ```bash DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest . ``` ## Domínios de versões de lançamento {#release-version-domains} SnapOtter possui intencionalmente três domínios de versão. Não copie um domínio para outro durante um lançamento: * A versão de lançamento do aplicativo abrange o manifesto raiz, todos os pacotes de espaço de trabalho privado e `APP_VERSION`. Semantic-release fornece esse valor e `pnpm version:sync ` atualiza cada espaço de trabalho antes do lançamento do aplicativo. * OpenAPI `info.version` é o contrato público estável API-major. Todas as especificações localizadas permanecem em `.0.0` para versões de aplicativos compatíveis e mudam somente quando o contrato API passa para uma nova versão principal. * `docker/feature-manifest.json` mantém `imageVersion: 2.0.0` como a época de armazenamento de pacote de recursos legado imutável. Esses caminhos de arquivo v2 não são versões de pacotes de aplicativos. O OCR preciso usa o formato de tempo de execução v3 e registra a origem da versão do aplicativo separadamente. `tests/unit/infra/release-version-policy.test.ts` impõe esses limites. Um novo domínio de versão ou migração deve atualizar esse contrato e o design de migração de artefato relevante juntos. Os valores independentes API e do pacote legado residem em `config/release-version-policy.json`; a sincronização de versão do aplicativo nunca deve reescrever esse arquivo de política implicitamente. ## Variáveis de ambiente {#environment-variables} Veja o [Guia de configuração](/pt-BR/guide/configuration) para a lista completa. As principais para desenvolvimento: | Variável | Padrão | Descrição | |-----------------------------|-----------|------------------------------------------------| | `AUTH_ENABLED` | `true` | Habilitar/desabilitar autenticação | | `DEFAULT_USERNAME` | `admin` | Nome de usuário admin padrão | | `DEFAULT_PASSWORD` | `admin` | Senha admin padrão | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Pular mudança de senha forçada (apenas CI/dev) | | `RATE_LIMIT_PER_MIN` | `1000` | Limite de taxa da API por minuto (0 = desabilitado) | | `MAX_UPLOAD_SIZE_MB` | `100` | Tamanho máximo de upload em MB (0 = ilimitado) | --- --- url: https://docs.snapotter.com/it/guide/translations.md description: >- 21 lingue supportate e come creare o migliorare le traduzioni di SnapOtter usando il sistema i18n con completezza garantita da TypeScript. --- # Guida alla traduzione {#translation-guide} SnapOtter include 21 lingue pronte all'uso. Il sistema i18n usa un runtime personalizzato leggero, con completezza dei locale garantita da TypeScript e code-splitting dinamico. ## Lingue supportate {#supported-languages} | Code | Language | Native Name | Direction | |------|----------|-------------|-----------| | `en` | Inglese | English | LTR | | `zh-CN` | Cinese (semplificato) | 简体中文 | LTR | | `zh-TW` | Cinese (tradizionale) | 繁體中文 | LTR | | `ja` | Giapponese | 日本語 | LTR | | `ko` | Coreano | 한국어 | LTR | | `es` | Spagnolo | Español | LTR | | `fr` | Francese | Français | LTR | | `it` | Italiano | Italiano | LTR | | `pt-BR` | Portoghese (Brasile) | Português (Brasil) | LTR | | `de` | Tedesco | Deutsch | LTR | | `nl` | Olandese | Nederlands | LTR | | `sv` | Svedese | Svenska | LTR | | `ru` | Russo | Русский | LTR | | `pl` | Polacco | Polski | LTR | | `uk` | Ucraino | Українська | LTR | | `ar` | Arabo | العربية | RTL | | `tr` | Turco | Türkçe | LTR | | `hi` | Hindi | हिन्दी | LTR | | `vi` | Vietnamita | Tiếng Việt | LTR | | `id` | Indonesiano | Bahasa Indonesia | LTR | | `th` | Thailandese | ไทย | LTR | ## Come funziona il rilevamento della lingua {#how-language-detection-works} SnapOtter usa un ordine di risoluzione a tre livelli: 1. **Preferenza dell'utente** - memorizzata in `localStorage("snapotter-locale")` e sincronizzata con le impostazioni utente quando si è autenticati 2. **Rilevamento automatico del browser** - scorre l'array `navigator.languages` con corrispondenza per prefisso BCP 47 3. **Impostazione predefinita dell'istanza** - la variabile d'ambiente `DEFAULT_LOCALE` dell'amministratore (recuperata da `GET /api/v1/config/locale`) 4. **Fallback all'inglese** - sempre disponibile Gli utenti possono cambiare lingua da: * Il **selettore Globo nel footer** (desktop, sempre visibile) * Il selettore di lingua della **pagina di login** (pre-autenticazione) * La sezione **Impostazioni > Generale** (preferenza per singolo utente) * Il menu a tendina della lingua nella **barra laterale mobile** * La sezione **Impostazioni > Sistema** imposta l'impostazione predefinita a livello di istanza (solo amministratore) ## Come funzionano le traduzioni {#how-translations-work} Tutte le stringhe dell'interfaccia si trovano in `packages/shared/src/i18n/`. Il file di riferimento è `en.ts`, che esporta un oggetto tipizzato con ogni stringa usata dall'app (~1500 chiavi). Le altre lingue sono file separati (ad esempio `de.ts`, `fr.ts`) che esportano la stessa struttura. Il tipo `TranslationKeys` usa `DeepStringRecord` per accettare qualsiasi valore stringa pur imponendo la struttura delle chiavi. TypeScript individua le chiavi mancanti in qualsiasi file di traduzione al momento della compilazione. Al runtime viene caricato solo il locale attivo tramite `import()` dinamico, mantenendo piccolo il bundle principale. ## Usare le traduzioni nei componenti {#using-translations-in-components} ```tsx import { useTranslation } from "@/contexts/i18n-context"; import { format, plural } from "@/lib/format"; function MyComponent() { const { t, locale, setLocale } = useTranslation(); return (

{t.common.settings}

{format(t.settings.people.deleteConfirm, { username: "admin" })}

{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}

); } ``` ## Contribuire con una traduzione {#contributing-a-translation} Accogliamo con favore le PR di traduzione dirette. Puoi migliorare un locale esistente o aggiungerne uno nuovo. Per segnalare una traduzione errata senza inviare codice, apri una [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) indicando la lingua, la stringa errata e la correzione suggerita. ::: tip Le PR di traduzione non richiedono un'approvazione preliminare. Fai il fork del repository, apporta le tue modifiche e apri una PR. Consulta la [Guida al contributo](/it/guide/contributing) per l'intero processo di PR e i requisiti CLA. ::: ## Come creare o aggiornare una traduzione {#how-to-create-or-update-a-translation} ### 1. Fai il fork e clona {#\_1-fork-and-clone} ```bash git clone https://github.com//snapotter.git cd snapotter pnpm install ``` ### 2. Copia il file di riferimento (solo per una nuova lingua) {#\_2-copy-the-reference-file-new-language-only} Salta questo passaggio se stai migliorando una traduzione esistente. ```bash cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts ``` ### 3. Traduci le stringhe {#\_3-translate-the-strings} Apri il tuo nuovo file e traduci ogni valore stringa. Mantieni identiche la struttura dell'oggetto e le chiavi. ```ts import type { TranslationKeys } from "./en.js"; export const xx: TranslationKeys = { common: { upload: "Your translation here", // ... translate all entries }, // ... translate all sections } as const; ``` Regole: * Non tradurre le chiavi dell'oggetto, solo i valori stringa * Mantieni `as const` alla fine * Importa `TranslationKeys` da `./en.js` e tipizza il tuo export * Mantieni i segnaposto `{variable}` esattamente come sono * Gli array (`rotatingPhrases`, `progressMessages`) devono avere lo stesso numero di voci * Non tradurre: SnapOtter, JPEG, PNG, WebP, EXIF, API e altri termini tecnici ### 4. Registra il locale (solo per una nuova lingua) {#\_4-register-the-locale-new-language-only} Aggiungi il tuo locale a `SUPPORTED_LOCALES` in `packages/shared/src/i18n/index.ts`: ```ts { code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" }, ``` ### 5. Verifica {#\_5-verify} ```bash pnpm typecheck # catches missing or mistyped keys pnpm lint # formatting check pnpm dev # manually verify strings appear correctly ``` ### 6. Invia {#\_6-submit} Apri una PR verso `main` con un titolo come `feat(i18n): add Swedish translation` o `fix(i18n): correct German typos`. Il bot CLA ti chiederà di firmare al tuo primo contributo. ## Aggiungere nuove chiavi di traduzione {#adding-new-translation-keys} Quando aggiungi una nuova funzionalità che necessita di nuove stringhe dell'interfaccia: 1. Aggiungi prima le nuove chiavi a `en.ts` (il file di riferimento) 2. Esegui `pnpm typecheck` - ogni file di locale fallirà se manca la nuova chiave 3. Aggiungi la nuova chiave a tutti i file di locale (usa l'inglese come fallback temporaneo) ## Configurazione {#configuration} Imposta la lingua predefinita dell'istanza tramite variabile d'ambiente: ```yaml DEFAULT_LOCALE: "de" # German as the default for all new users ``` ## Riferimento dei file {#file-reference} | File | Purpose | |------|---------| | `packages/shared/src/i18n/en.ts` | Stringhe in inglese (locale di riferimento, ~1500 chiavi) | | `packages/shared/src/i18n/index.ts` | `SUPPORTED_LOCALES`, `loadTranslations()`, export dei tipi | | `packages/shared/src/i18n/.ts` | File di traduzione per lingua | | `apps/web/src/contexts/i18n-context.tsx` | `I18nProvider`, hook `useTranslation()` | | `apps/web/src/lib/format.ts` | Helper `format()`, `plural()`, `formatFileSize()` | | `apps/api/src/routes/config.ts` | Endpoint pubblico `GET /api/v1/config/locale` | ## Tradurre il sito web, la documentazione e il riferimento API {#translating-the-web-surfaces} Il supporto per 21 lingue descritto sopra riguarda l'**app**. Anche il sito web pubblico (snapotter.com), questo sito di documentazione e il riferimento API REST sono tradotti in tutte le 21 lingue, tramite una pipeline separata regolata dagli hash che riutilizza gli stessi nomi e descrizioni dei tool da `packages/shared/src/i18n`, così che la terminologia resti coerente ovunque. ### Tradotto automaticamente per impostazione predefinita {#machine-translated-by-default} Ogni pagina non in inglese del sito web e della documentazione viene **tradotta automaticamente** al primo passaggio (da una sessione di Claude Code, non da un servizio di terze parti) e riporta un piccolo banner richiudibile che lo segnala, con un link di ritorno a questa pagina. È una scelta deliberata: consente di rilasciare tutte le 21 lingue rapidamente e onestamente, per poi invitare la community a perfezionare le pagine più importanti. La traduzione automatica trasmette il significato; la revisione umana la rende naturale da leggere. ### Come la pipeline decide cosa tradurre {#how-the-web-pipeline-decides} Ogni unità traducibile del testo sorgente in inglese viene sottoposta ad hashing, e l'hash viene memorizzato accanto alla sua traduzione. A ogni esecuzione la pipeline: * traduce qualsiasi unità che non ha ancora una traduzione, * salta qualsiasi unità il cui hash memorizzato corrisponde ancora al testo sorgente inglese, * ritraduce un'unità **machine** quando il suo testo sorgente inglese cambia, * e contrassegna un'unità perfezionata da un **human** come `stale` (da revisionare) quando il suo testo sorgente inglese cambia, invece di sovrascrivere il tuo lavoro. ### Perfezionare una traduzione web tramite PR {#refining-a-web-translation-by-pr} Migliori la traduzione di un sito web, della documentazione o del riferimento API nello stesso modo in cui migliori un locale dell'app: modificando il file generato e aprendo una PR. 1. Trova la traduzione generata per la tua lingua: * stringhe dell'interfaccia del sito web: `apps/landing/src/i18n/.json` * una pagina di documentazione: `apps/docs//**.md` * il riferimento API: `apps/api/src/openapi..yaml` 2. Modifica il testo. Mantieni il codice, i link, `{placeholders}` e qualsiasi marcatore `⸤I18N…⸥` esattamente come sono; il validatore della pipeline rifiuta una traduzione che li elimina o li riordina. 3. Apri una PR. La modifica di un'unità cambia la sua provenienza da `machine` a `human`, così che la pipeline **non la sovrascriverà mai** in un'esecuzione successiva. Se in seguito il testo sorgente inglese cambia, la tua unità viene contrassegnata come `stale` per la revisione anziché essere sostituita silenziosamente. Per segnalare una traduzione errata senza inviare codice, apri una [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) indicando l'URL della pagina, la lingua, il testo errato e la tua correzione suggerita. ::: tip I maintainer eseguono la pipeline di traduzione; non hai bisogno di una chiave API per contribuire. Basta modificare il file generato e aprire una PR. Consulta [`scripts/i18n/README.md`](https://github.com/snapotter-hq/SnapOtter/blob/main/scripts/i18n/README.md) per sapere come viene eseguita la pipeline. ::: --- --- url: https://docs.snapotter.com/it/guide/developer.md description: >- Configurazione dell'ambiente di sviluppo locale, comandi, convenzioni di codice e come aggiungere un nuovo strumento a SnapOtter. --- # Guida per sviluppatori {#developer-guide} Come configurare un ambiente di sviluppo locale e contribuire con codice a SnapOtter. ## Prerequisiti {#prerequisites} * [Node.js](https://nodejs.org/) 22.22+ * [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`) * [Docker](https://www.docker.com/) (richiesto per Postgres + Redis locali, build dei container e funzionalità AI) * Git Python 3.11+ è necessario solo se stai lavorando sul sidecar AI/ML (rimozione dello sfondo, upscaling, OCR). ## Configurazione {#setup} ```bash git clone https://github.com/snapotter-hq/snapotter.git cd snapotter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` Questo avvia due dev server: | Servizio | URL | Note | |----------|--------------------------|------------------------------------| | Frontend | http://localhost:1351 | Dev server Vite, fa da proxy a /api | | Backend | http://localhost:13490 | API Fastify (accessibile via proxy) | Apri http://localhost:1351 nel tuo browser. Accedi con `admin` / `admin`. Ti verrà chiesto di cambiare la password al primo login. ## Struttura del progetto {#project-structure} ``` apps/ api/ Fastify backend web/ Vite + React frontend docs/ VitePress documentation (this site) packages/ shared/ Constants, types, i18n strings image-engine/ Sharp-based image operations media-engine/ FFmpeg spawn + progress parsing doc-engine/ qpdf, LibreOffice, ghostscript wrappers ai/ Python sidecar bridge for ML models tests/ unit/ Vitest unit tests integration/ Vitest integration tests (full API) e2e/ Playwright end-to-end specs fixtures/ Small test images ``` ## Comandi {#commands} ```bash pnpm dev # start frontend + backend pnpm build # build all workspaces pnpm typecheck # TypeScript check across monorepo pnpm lint # Biome lint + format check pnpm lint:fix # auto-fix lint + format pnpm test # unit + integration tests pnpm test:unit # unit tests only pnpm test:integration # integration tests only pnpm test:e2e # Playwright e2e tests pnpm test:coverage # tests with coverage report ``` ## Convenzioni di codice {#code-conventions} * Virgolette doppie, punto e virgola, indentazione di 2 spazi (imposte da Biome) * Moduli ES in tutti i workspace * [Conventional commit](https://www.conventionalcommits.org/) per semantic-release * Zod per tutta la validazione degli input API * Nessuna modifica ai file di configurazione di Biome, TypeScript o dell'editor. Correggi il codice, non il linter. ## Database {#database} PostgreSQL 17 via Drizzle ORM (pg-core). Lo sviluppo locale richiede Postgres e Redis in esecuzione: avviali con: ```bash docker compose -f docker-compose.dev.yml up -d ``` Questo ti fornisce Postgres sulla porta 5432 e Redis sulla porta 6379. Poi genera e applica le migrazioni: ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Lo schema è definito in `apps/api/src/db/schema.ts`. Tabelle: users, sessions, settings, jobs, apiKeys, pipelines, teams, userFiles, roles, auditLog. ## Aggiungere un nuovo strumento {#adding-a-new-tool} Ogni strumento segue lo stesso pattern. Ecco un esempio minimo. ### 1. Route del backend {#\_1-backend-route} Crea `apps/api/src/routes/tools/my-tool.ts`: ```ts import { z } from "zod"; import type { FastifyInstance } from "fastify"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ intensity: z.number().min(0).max(100).default(50), }); export function registerMyTool(app: FastifyInstance) { createToolRoute(app, { toolId: "my-tool", settingsSchema, async process(inputBuffer, settings, filename) { // Use sharp or other libraries to process the image const sharp = (await import("sharp")).default; const result = await sharp(inputBuffer) // ... your processing logic .toBuffer(); return { buffer: result, filename: filename.replace(/\.[^.]+$/, ".png"), contentType: "image/png", }; }, }); } ``` Poi registralo in `apps/api/src/routes/tools/index.ts`. ### 2. Componente delle impostazioni del frontend {#\_2-frontend-settings-component} Crea `apps/web/src/components/tools/my-tool-settings.tsx`: ```tsx import { useState } from "react"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; export function MyToolSettings() { const { files } = useFileStore(); const { processFiles, processing, error, downloadUrl } = useToolProcessor("my-tool"); const [intensity, setIntensity] = useState(50); const handleProcess = () => { processFiles(files, { intensity }); }; return (
{/* your controls here */}
); } ``` Poi registralo nel registro degli strumenti del frontend in `apps/web/src/lib/tool-registry.tsx`: ```tsx // Add the lazy import const MyToolSettings = lazy(() => import("@/components/tools/my-tool-settings").then((m) => ({ default: m.MyToolSettings, })), ); // Add to the toolRegistry Map ["my-tool", { displayMode: "before-after", Settings: MyToolSettings }], ``` Modalità di visualizzazione: `"side-by-side"`, `"before-after"`, `"live-preview"`, `"no-comparison"`, `"interactive-crop"`, `"interactive-eraser"`, `"no-dropzone"`. ### 3. Voce i18n {#\_3-i18n-entry} Aggiungi a `packages/shared/src/i18n/en.ts`: ```ts "my-tool": { name: "My Tool", description: "Short description of what this tool does", }, ``` ### 4. Test {#\_4-tests} Aggiungi un attributo `data-testid` al tuo pulsante di azione (come mostrato sopra) così i test e2e possono individuarlo in modo affidabile. ## Build Docker {#docker-builds} Compila l'immagine di produzione completa localmente: ```bash docker build -f docker/Dockerfile -t snapotter:latest . ``` Usa le cache mount di BuildKit per rebuild più veloci: ```bash DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest . ``` ## Rilascia i domini della versione {#release-version-domains} SnapOtter ha intenzionalmente tre domini di versione. Non copiare un dominio in un altro durante un rilascio: * La versione di rilascio dell'applicazione copre il manifest root, tutti i pacchetti dell'area di lavoro privata e `APP_VERSION`. Semantic-release fornisce questo valore e `pnpm version:sync ` aggiorna ogni area di lavoro prima del rilascio dell'applicazione. * OpenAPI `info.version` è il contratto pubblico stabile API-major. Tutte le specifiche localizzate rimangono su `.0.0` per i rilasci di applicazioni compatibili e cambiano solo quando il contratto API passa a una nuova versione principale. * `docker/feature-manifest.json` mantiene `imageVersion: 2.0.0` come epoca di archiviazione del pacchetto di funzionalità legacy immutabile. Tali percorsi di archivio v2 non sono versioni del pacchetto dell'applicazione. L'OCR accurato utilizza il formato runtime v3 e registra separatamente la provenienza del rilascio dell'applicazione. `tests/unit/infra/release-version-policy.test.ts` rafforza questi limiti. Un nuovo dominio di versione o una migrazione deve aggiornare insieme il contratto e la progettazione di migrazione dell'artefatto pertinente. I valori API indipendenti e quelli del bundle legacy risiedono in `config/release-version-policy.json`; la sincronizzazione della versione dell'applicazione non deve mai riscrivere implicitamente il file della politica. ## Variabili d'ambiente {#environment-variables} Vedi la [Guida alla configurazione](/it/guide/configuration) per l'elenco completo. Quelle principali per lo sviluppo: | Variabile | Predefinito | Descrizione | |-----------------------------|-----------|------------------------------------------------| | `AUTH_ENABLED` | `true` | Abilita/disabilita l'autenticazione | | `DEFAULT_USERNAME` | `admin` | Nome utente amministratore predefinito | | `DEFAULT_PASSWORD` | `admin` | Password amministratore predefinita | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Salta il cambio forzato della password (solo CI/dev) | | `RATE_LIMIT_PER_MIN` | `1000` | Limite di rate delle API al minuto (0 = disabilitato) | | `MAX_UPLOAD_SIZE_MB` | `100` | Dimensione massima di caricamento in MB (0 = illimitata) | --- --- url: https://docs.snapotter.com/fr/guide/translations.md description: >- 21 langues prises en charge et comment créer ou améliorer les traductions de SnapOtter grâce au système i18n renforcé par TypeScript. --- # Guide de traduction {#translation-guide} SnapOtter est livré avec 21 langues prêtes à l'emploi. Le système i18n s'appuie sur un moteur d'exécution personnalisé et léger, avec une complétude des locales garantie par TypeScript et un découpage dynamique du code. ## Langues prises en charge {#supported-languages} | Code | Langue | Native Name | Direction | |------|----------|-------------|-----------| | `en` | Anglais | English | LTR | | `zh-CN` | Chinois (simplifié) | 简体中文 | LTR | | `zh-TW` | Chinois (traditionnel) | 繁體中文 | LTR | | `ja` | Japonais | 日本語 | LTR | | `ko` | Coréen | 한국어 | LTR | | `es` | Espagnol | Español | LTR | | `fr` | Français | Français | LTR | | `it` | Italien | Italiano | LTR | | `pt-BR` | Portugais (Brésil) | Português (Brasil) | LTR | | `de` | Allemand | Deutsch | LTR | | `nl` | Néerlandais | Nederlands | LTR | | `sv` | Suédois | Svenska | LTR | | `ru` | Russe | Русский | LTR | | `pl` | Polonais | Polski | LTR | | `uk` | Ukrainien | Українська | LTR | | `ar` | Arabe | العربية | RTL | | `tr` | Turc | Türkçe | LTR | | `hi` | Hindi | हिन्दी | LTR | | `vi` | Vietnamien | Tiếng Việt | LTR | | `id` | Indonésien | Bahasa Indonesia | LTR | | `th` | Thaï | ไทย | LTR | ## Fonctionnement de la détection de langue {#how-language-detection-works} SnapOtter utilise un ordre de résolution à trois niveaux : 1. **Préférence de l'utilisateur** - stockée dans `localStorage("snapotter-locale")` et synchronisée avec les paramètres de l'utilisateur une fois authentifié 2. **Détection automatique du navigateur** - parcourt le tableau `navigator.languages` avec une correspondance de préfixe BCP 47 3. **Valeur par défaut de l'instance** - la variable d'environnement `DEFAULT_LOCALE` de l'administrateur (récupérée depuis `GET /api/v1/config/locale`) 4. **Repli sur l'anglais** - toujours disponible Les utilisateurs peuvent changer de langue depuis : * Le **sélecteur Globe du pied de page** (bureau, toujours visible) * Le sélecteur de langue de la **page de connexion** (avant l'authentification) * La section **Paramètres > Général** (préférence par utilisateur) * La liste déroulante de langue de la **barre latérale mobile** * La section **Paramètres > Système** définit la valeur par défaut à l'échelle de l'instance (administrateur uniquement) ## Fonctionnement des traductions {#how-translations-work} Toutes les chaînes de l'interface se trouvent dans `packages/shared/src/i18n/`. Le fichier de référence est `en.ts`, qui exporte un objet typé contenant chaque chaîne utilisée par l'application (~1500 clés). Les autres langues sont des fichiers distincts (par ex. `de.ts`, `fr.ts`) qui exportent la même structure. Le type `TranslationKeys` utilise `DeepStringRecord` pour accepter n'importe quelle valeur de chaîne tout en imposant la structure des clés. TypeScript détecte les clés manquantes dans n'importe quel fichier de traduction au moment de la compilation. Seule la locale active est chargée à l'exécution via un `import()` dynamique, ce qui maintient le bundle principal petit. ## Utiliser les traductions dans les composants {#using-translations-in-components} ```tsx import { useTranslation } from "@/contexts/i18n-context"; import { format, plural } from "@/lib/format"; function MyComponent() { const { t, locale, setLocale } = useTranslation(); return (

{t.common.settings}

{format(t.settings.people.deleteConfirm, { username: "admin" })}

{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}

); } ``` ## Contribuer à une traduction {#contributing-a-translation} Nous accueillons directement les PR de traduction. Vous pouvez améliorer une locale existante ou en ajouter une nouvelle. Pour signaler une erreur de traduction sans soumettre de code, ouvrez une [issue GitHub](https://github.com/snapotter-hq/SnapOtter/issues) en indiquant la langue, la chaîne incorrecte et la correction suggérée. ::: tip Les PR de traduction ne nécessitent pas d'approbation préalable. Forkez le dépôt, apportez vos modifications et ouvrez une PR. Consultez le [guide de contribution](/fr/guide/contributing) pour le processus complet de PR et l'exigence de CLA. ::: ## Comment créer ou mettre à jour une traduction {#how-to-create-or-update-a-translation} ### 1. Forker et cloner {#\_1-fork-and-clone} ```bash git clone https://github.com//snapotter.git cd snapotter pnpm install ``` ### 2. Copier le fichier de référence (nouvelle langue uniquement) {#\_2-copy-the-reference-file-new-language-only} Ignorez cette étape si vous améliorez une traduction existante. ```bash cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts ``` ### 3. Traduire les chaînes {#\_3-translate-the-strings} Ouvrez votre nouveau fichier et traduisez chaque valeur de chaîne. Conservez exactement la même structure d'objet et les mêmes clés. ```ts import type { TranslationKeys } from "./en.js"; export const xx: TranslationKeys = { common: { upload: "Your translation here", // ... translate all entries }, // ... translate all sections } as const; ``` Règles : * Ne traduisez pas les clés d'objet, uniquement les valeurs de chaîne * Conservez `as const` à la fin * Importez `TranslationKeys` depuis `./en.js` et typez votre export * Conservez les espaces réservés `{variable}` exactement tels quels * Les tableaux (`rotatingPhrases`, `progressMessages`) doivent comporter le même nombre d'entrées * Ne traduisez pas : SnapOtter, JPEG, PNG, WebP, EXIF, API et autres termes techniques ### 4. Enregistrer la locale (nouvelle langue uniquement) {#\_4-register-the-locale-new-language-only} Ajoutez votre locale à `SUPPORTED_LOCALES` dans `packages/shared/src/i18n/index.ts` : ```ts { code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" }, ``` ### 5. Vérifier {#\_5-verify} ```bash pnpm typecheck # catches missing or mistyped keys pnpm lint # formatting check pnpm dev # manually verify strings appear correctly ``` ### 6. Soumettre {#\_6-submit} Ouvrez une PR sur `main` avec un titre du type `feat(i18n): add Swedish translation` ou `fix(i18n): correct German typos`. Le bot CLA vous demandera de signer lors de votre première contribution. ## Ajouter de nouvelles clés de traduction {#adding-new-translation-keys} Lorsque vous ajoutez une nouvelle fonctionnalité qui nécessite de nouvelles chaînes d'interface : 1. Ajoutez d'abord les nouvelles clés à `en.ts` (le fichier de référence) 2. Exécutez `pnpm typecheck` - chaque fichier de locale échouera s'il manque la nouvelle clé 3. Ajoutez la nouvelle clé à tous les fichiers de locale (utilisez l'anglais comme repli temporaire) ## Configuration {#configuration} Définissez la langue par défaut de l'instance via une variable d'environnement : ```yaml DEFAULT_LOCALE: "de" # German as the default for all new users ``` ## Référence des fichiers {#file-reference} | Fichier | Rôle | |------|---------| | `packages/shared/src/i18n/en.ts` | Chaînes anglaises (locale de référence, ~1500 clés) | | `packages/shared/src/i18n/index.ts` | `SUPPORTED_LOCALES`, `loadTranslations()`, exports de types | | `packages/shared/src/i18n/.ts` | Fichiers de traduction par langue | | `apps/web/src/contexts/i18n-context.tsx` | `I18nProvider`, hook `useTranslation()` | | `apps/web/src/lib/format.ts` | Fonctions utilitaires `format()`, `plural()`, `formatFileSize()` | | `apps/api/src/routes/config.ts` | Point de terminaison public `GET /api/v1/config/locale` | ## Traduire le site web, la documentation et la référence de l'API {#translating-the-web-surfaces} La prise en charge de 21 langues décrite ci-dessus couvre l'**application**. Le site web public (snapotter.com), ce site de documentation et la référence de l'API REST sont également traduits dans les 21 langues, par un pipeline distinct verrouillé par hachage qui réutilise les mêmes noms et descriptions d'outils issus de `packages/shared/src/i18n`, afin que la terminologie reste cohérente partout. ### Traduction automatique par défaut {#machine-translated-by-default} Chaque page non anglaise du site web et de la documentation est **traduite automatiquement** lors du premier passage (par une session Claude Code, et non un service tiers) et porte une petite bannière fermable qui l'indique, avec un lien renvoyant ici. C'est délibéré : cela permet de livrer les 21 langues rapidement et honnêtement, puis d'inviter la communauté à affiner les pages qui comptent le plus. La traduction automatique fait passer le sens ; la relecture humaine la rend naturelle à lire. ### Comment le pipeline décide de ce qu'il faut traduire {#how-the-web-pipeline-decides} Chaque unité traduisible de la source anglaise est hachée, et le hachage est stocké à côté de sa traduction. À chaque exécution, le pipeline : * traduit toute unité qui n'a pas encore de traduction, * ignore toute unité dont le hachage stocké correspond toujours à la source anglaise, * retraduit une unité **machine** lorsque sa source anglaise change, * et signale une unité affinée par un **humain** comme `stale` (à relire) lorsque sa source anglaise change, au lieu d'écraser votre travail. ### Affiner une traduction web par PR {#refining-a-web-translation-by-pr} Vous améliorez une traduction du site web, de la documentation ou de la référence de l'API de la même manière que vous améliorez une locale de l'application : en modifiant le fichier généré et en ouvrant une PR. 1. Trouvez la traduction générée pour votre langue : * chaînes d'interface du site web : `apps/landing/src/i18n/.json` * une page de documentation : `apps/docs//**.md` * la référence de l'API : `apps/api/src/openapi..yaml` 2. Modifiez le texte. Conservez le code, les liens, `{placeholders}` et tous les marqueurs `⸤I18N…⸥` exactement tels quels ; le validateur du pipeline rejette une traduction qui les supprime ou les réordonne. 3. Ouvrez une PR. La modification d'une unité fait passer sa provenance de `machine` à `human`, de sorte que le pipeline ne l'**écrasera jamais** lors d'une exécution ultérieure. Si la source anglaise change par la suite, votre unité est signalée `stale` pour relecture plutôt que remplacée silencieusement. Pour signaler une erreur de traduction sans soumettre de code, ouvrez une [issue GitHub](https://github.com/snapotter-hq/SnapOtter/issues) en indiquant l'URL de la page, la langue, le texte incorrect et votre correction suggérée. ::: tip Les mainteneurs exécutent le pipeline de traduction ; vous n'avez pas besoin de clé API pour contribuer. Modifiez simplement le fichier généré et ouvrez une PR. Consultez [`scripts/i18n/README.md`](https://github.com/snapotter-hq/SnapOtter/blob/main/scripts/i18n/README.md) pour savoir comment le pipeline s'exécute. ::: --- --- url: https://docs.snapotter.com/fr/guide/developer.md description: >- Configuration de l'environnement de développement local, commandes, conventions de code et comment ajouter un nouvel outil à SnapOtter. --- # Guide du développeur {#developer-guide} Comment configurer un environnement de développement local et contribuer au code de SnapOtter. ## Prérequis {#prerequisites} * [Node.js](https://nodejs.org/) 22.22+ * [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`) * [Docker](https://www.docker.com/) (requis pour Postgres + Redis en local, les builds de conteneur et les fonctionnalités d'IA) * Git Python 3.11+ n'est nécessaire que si vous travaillez sur le sidecar IA/ML (suppression d'arrière-plan, agrandissement, OCR). ## Configuration {#setup} ```bash git clone https://github.com/snapotter-hq/snapotter.git cd snapotter docker compose -f docker-compose.dev.yml up -d # start Postgres + Redis pnpm install pnpm dev ``` Cela démarre deux serveurs de développement : | Service | URL | Notes | |----------|--------------------------|------------------------------------| | Frontend | http://localhost:1351 | Serveur de développement Vite, proxifie /api | | Backend | http://localhost:13490 | API Fastify (accédée via le proxy) | Ouvrez http://localhost:1351 dans votre navigateur. Connectez-vous avec `admin` / `admin`. Il vous sera demandé de changer le mot de passe à la première connexion. ## Structure du projet {#project-structure} ``` apps/ api/ Fastify backend web/ Vite + React frontend docs/ VitePress documentation (this site) packages/ shared/ Constants, types, i18n strings image-engine/ Sharp-based image operations media-engine/ FFmpeg spawn + progress parsing doc-engine/ qpdf, LibreOffice, ghostscript wrappers ai/ Python sidecar bridge for ML models tests/ unit/ Vitest unit tests integration/ Vitest integration tests (full API) e2e/ Playwright end-to-end specs fixtures/ Small test images ``` ## Commandes {#commands} ```bash pnpm dev # start frontend + backend pnpm build # build all workspaces pnpm typecheck # TypeScript check across monorepo pnpm lint # Biome lint + format check pnpm lint:fix # auto-fix lint + format pnpm test # unit + integration tests pnpm test:unit # unit tests only pnpm test:integration # integration tests only pnpm test:e2e # Playwright e2e tests pnpm test:coverage # tests with coverage report ``` ## Conventions de code {#code-conventions} * Guillemets doubles, points-virgules, indentation de 2 espaces (imposés par Biome) * Modules ES dans tous les workspaces * [Commits conventionnels](https://www.conventionalcommits.org/) pour semantic-release * Zod pour toute validation d'entrée de l'API * Aucune modification des fichiers de configuration de Biome, TypeScript ou de l'éditeur. Corrigez le code, pas le linter. ## Base de données {#database} PostgreSQL 17 via Drizzle ORM (pg-core). Le développement local nécessite que Postgres et Redis soient en cours d'exécution - démarrez-les avec : ```bash docker compose -f docker-compose.dev.yml up -d ``` Cela vous donne Postgres sur le port 5432 et Redis sur le port 6379. Générez ensuite et appliquez les migrations : ```bash cd apps/api npx drizzle-kit generate # generate a migration from schema changes npx drizzle-kit migrate # apply pending migrations ``` Le schéma est défini dans `apps/api/src/db/schema.ts`. Tables : users, sessions, settings, jobs, apiKeys, pipelines, teams, userFiles, roles, auditLog. ## Ajouter un nouvel outil {#adding-a-new-tool} Chaque outil suit le même schéma. Voici un exemple minimal. ### 1. Route backend {#\_1-backend-route} Créez `apps/api/src/routes/tools/my-tool.ts` : ```ts import { z } from "zod"; import type { FastifyInstance } from "fastify"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ intensity: z.number().min(0).max(100).default(50), }); export function registerMyTool(app: FastifyInstance) { createToolRoute(app, { toolId: "my-tool", settingsSchema, async process(inputBuffer, settings, filename) { // Use sharp or other libraries to process the image const sharp = (await import("sharp")).default; const result = await sharp(inputBuffer) // ... your processing logic .toBuffer(); return { buffer: result, filename: filename.replace(/\.[^.]+$/, ".png"), contentType: "image/png", }; }, }); } ``` Puis enregistrez-la dans `apps/api/src/routes/tools/index.ts`. ### 2. Composant de paramètres frontend {#\_2-frontend-settings-component} Créez `apps/web/src/components/tools/my-tool-settings.tsx` : ```tsx import { useState } from "react"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; export function MyToolSettings() { const { files } = useFileStore(); const { processFiles, processing, error, downloadUrl } = useToolProcessor("my-tool"); const [intensity, setIntensity] = useState(50); const handleProcess = () => { processFiles(files, { intensity }); }; return (
{/* your controls here */}
); } ``` Puis enregistrez-le dans le registre d'outils frontend à `apps/web/src/lib/tool-registry.tsx` : ```tsx // Add the lazy import const MyToolSettings = lazy(() => import("@/components/tools/my-tool-settings").then((m) => ({ default: m.MyToolSettings, })), ); // Add to the toolRegistry Map ["my-tool", { displayMode: "before-after", Settings: MyToolSettings }], ``` Modes d'affichage : `"side-by-side"`, `"before-after"`, `"live-preview"`, `"no-comparison"`, `"interactive-crop"`, `"interactive-eraser"`, `"no-dropzone"`. ### 3. Entrée i18n {#\_3-i18n-entry} Ajoutez à `packages/shared/src/i18n/en.ts` : ```ts "my-tool": { name: "My Tool", description: "Short description of what this tool does", }, ``` ### 4. Tests {#\_4-tests} Ajoutez un attribut `data-testid` à votre bouton d'action (comme montré ci-dessus) afin que les tests e2e puissent le cibler de manière fiable. ## Builds Docker {#docker-builds} Construisez l'image de production complète en local : ```bash docker build -f docker/Dockerfile -t snapotter:latest . ``` Utilisez les cache mounts de BuildKit pour des reconstructions plus rapides : ```bash DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest . ``` ## Domaines de la version Release {#release-version-domains} SnapOtter possède intentionnellement trois domaines de version. Ne copiez pas un domaine dans un autre lors d'une version : * La version de l'application couvre le manifeste racine, tous les packages d'espace de travail privé et `APP_VERSION`. Semantic-release fournit cette valeur et `pnpm version:sync ` met à jour chaque espace de travail avant la version d'une application. * OpenAPI `info.version` est le contrat public stable majeur API. Toutes les spécifications localisées restent sur `.0.0` pour les versions d'applications compatibles et ne changent que lorsque le contrat API passe à une nouvelle version majeure. * `docker/feature-manifest.json` conserve `imageVersion: 2.0.0` comme époque de stockage immuable des ensembles de fonctionnalités héritées. Ces chemins d'archives v2 ne sont pas des versions de packages d'application. Accurate OCR utilise le format d'exécution v3 et enregistre séparément la provenance de la version de l'application. `tests/unit/infra/release-version-policy.test.ts` applique ces limites. Un nouveau domaine de version ou une nouvelle migration doit mettre à jour ce contrat et la conception de migration d'artefact pertinente ensemble. Les valeurs indépendantes API et du bundle hérité résident dans `config/release-version-policy.json` ; la synchronisation des versions d'application ne doit jamais réécrire implicitement ce fichier de stratégie. ## Variables d'environnement {#environment-variables} Consultez le [Guide de configuration](/fr/guide/configuration) pour la liste complète. Les principales pour le développement : | Variable | Par défaut | Description | |-----------------------------|-----------|------------------------------------------------| | `AUTH_ENABLED` | `true` | Activer/désactiver l'authentification | | `DEFAULT_USERNAME` | `admin` | Nom d'utilisateur admin par défaut | | `DEFAULT_PASSWORD` | `admin` | Mot de passe admin par défaut | | `SKIP_MUST_CHANGE_PASSWORD` | `false` | Ignorer le changement forcé de mot de passe (CI/dev uniquement) | | `RATE_LIMIT_PER_MIN` | `1000` | Limite de débit de l'API par minute (0 = désactivée) | | `MAX_UPLOAD_SIZE_MB` | `100` | Taille d'envoi maximale en Mo (0 = illimité) | --- --- url: https://docs.snapotter.com/tr/tools/image/noise-removal.md description: >- Çok kademeli kalite seçenekleriyle yapay zeka destekli gürültü ve grenlilik giderme. --- # Gürültü Giderme {#noise-removal} Python yardımcı bileşenini (SCUNet modeli) kullanan, çok kademeli kalite seçenekleriyle yapay zeka destekli gürültü ve grenlilik giderme. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/noise-removal` **İşleme:** Eşzamansız (202 döndürür, durum için SSE aracılığıyla `/api/v1/jobs/{jobId}/progress` sorgulayın) **Model paketi:** `upscale-enhance` (5-6 GB) ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | file | file | Evet | - | Görsel dosyası (çok parçalı) | | tier | string | Hayır | `"balanced"` | Kalite kademesi: `quick`, `balanced`, `quality`, `maximum` | | strength | number | Hayır | `50` | Gürültü giderme gücü (0-100) | | detailPreservation | number | Hayır | `50` | Ne kadar ayrıntının korunacağı (0-100). Daha yüksek değerler daha fazla doku korur | | colorNoise | number | Hayır | `30` | Renk gürültüsü azaltma gücü (0-100) | | format | string | Hayır | `"original"` | Çıktı biçimi: `original`, `png`, `jpeg`, `webp`, `avif`, `jxl` | | quality | number | Hayır | `90` | Çıktı kodlama kalitesi (1-100) | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/noise-removal \ -F "file=@noisy-photo.jpg" \ -F 'settings={"tier":"quality","strength":60,"detailPreservation":70,"colorNoise":40}' ``` ## Yanıt {#response} ### İlk Yanıt (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### İlerleme (`/api/v1/jobs/{jobId}/progress` konumunda SSE) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Denoising...","percent":65} ``` ### Nihai Sonuç (SSE aracılığıyla) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/noisy-photo_denoised.jpg", "originalSize": 500000, "processedSize": 380000 } } ``` ## Notlar {#notes} * `upscale-enhance` model paketinin kurulu olmasını gerektirir (5-6 GB). * Kalite kademeleri hız ile kaliteyi dengeler: `quick` temel gürültü gidermeyle en hızlısıdır, `maximum` en kapsamlı çok geçişli yaklaşımı kullanır. * `detailPreservation` parametresi dokulu özneler (kumaş, saç, yapraklar) için kritiktir. Daha yüksek değerler, gürültü gidericinin ince ayrıntıyı düzleştirip yok etmesini önler. * `format` değeri `"original"` olarak ayarlandığında çıktı biçimi girdi dosyası biçimiyle eşleşir. * HEIC/HEIF, RAW, TGA, PSD, EXR ve HDR girdi biçimlerini otomatik çözme yoluyla destekler. --- --- url: https://docs.snapotter.com/tr/guide/security.md description: >- SnapOtter için güvenlik sıkılaştırma kılavuzu. Konteyner güvenliği, ağ yalıtımı, Docker secrets, Kubernetes dağıtımı ve uyumluluk yapıtları. --- # Güvenlik ve Sıkılaştırma {#security-hardening} SnapOtter dosyaları tamamen kendi altyapınızda işler. Projeyi geliştirmeye yardımcı olmak için varsayılan olarak anonim, içerik içermeyen ürün analitiği ve çökme raporları gönderir. Dosyalarınızı, dosya adlarınızı, dosya içeriklerinizi, OCR çıktısını, görsel meta verilerini veya belge metnini asla göndermez. İsteğe bağlı geri bildirim yalnızca bir kullanıcı gönderdikten sonra, yalnızca analitik etkinken gönderilir ve iletişim alanları yalnızca açık iletişim onayıyla dahil edilir. Bir yönetici, Settings > System > Privacy altında tek tıklamayla analitik ve geri bildirim yakalamayı yeniden derleme gerekmeden kapatabilir. Dosya işleme her zaman konteynerinizin içinde kalır. Konteyner, gerekli minimum küme dışında tüm Linux yetenekleri düşürülmüş özel bir root olmayan kullanıcı (`snapotter`) olarak çalışır. Tam güvenlik açığı açıklama politikası ve güvenlik mimarisi için GitHub'daki [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) dosyasına bakın. ## Konteyner Sertleştirme {#container-hardening} Kurallı [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) ve [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml) Compose dosyaları gerçeğin kaynağıdır. Kısaltılmış bir örneği üretime kopyalamayın; dosyayı doğruladığınız sürüm etiketinden dağıtın. Her iki yığın da aşağıdaki kontrolleri uygular: * Bellek, takas, CPU ve PID sınırları kaçak yerel işleme içerir. * Her hizmet tüm Linux yeteneklerini düşürür. Uygulama, birim sahipliği, tek yönlü `gosu` kimlik düşüşü ve zarif sinyal iletimi için yalnızca `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL`'yi geri ekler. PostgreSQL ve Redis yalnızca resmi giriş noktalarının ihtiyaç duyduğu alt kümeyi alır. * `security_opt: [no-new-privileges:true]`, uygulamadaki, PostgreSQL ve Redis kapsayıcılarındaki işlemlerin ek ayrıcalıklar kazanmasını engeller. Bu, `gosu` ile uyumlu olmaya devam eder: giriş noktası kök olarak başlar, birimleri hazırlar ve yalnızca özel `snapotter` kullanıcısına düşer. * PostgreSQL ve Redis görüntü girişleri özet ile sabitlenir. Uygulama aynı şekilde `latest` yerine doğrulanmış bir sürüm etiketine veya özete sabitlenmelidir. * Durum denetimleri, sınırlı JSON günlük rotasyonu, dayanıklı Redis AOF ve yeniden başlatma politikası, standart dosyalarda merkezi olarak tanımlanır. İnternet'e yönelik bir dağıtım için, 1349 numaralı bağlantı noktasını geri döngüye bağlayın ve korunan bir ters proxy'de TLS'yi sonlandırın. Benzersiz PostgreSQL ve Redis kimlik bilgileri oluşturun, sırları korumalı dosyalarda veya gizli yöneticide saklayın ve ilk yönetici şifresini hemen değiştirin. ### `read_only` Neden Ayarlanmıyor {#why-read-only-is-not-set} PUID/PGID yeniden eşlemesi başlangıçta `/etc/passwd` ve `/etc/group`'ye yazdığı için `read_only: true` ayarlanmadı. PUID/PGID yerine Docker'ın `--user` bayrağını veya Kubernetes `runAsUser`'yi kullanırsanız salt okunur bir kök dosya sistemini güvenli bir şekilde etkinleştirebilirsiniz. ## Ağ Yalıtımı {#network-isolation} Dosya işleme yereldir ancak varsayılan kurulum **çıkışsız bir sistem değildir**. Anonim ürün analitiği PostHog'u kullanır ve telemetri etkinleştirildiğinde kilitlenme raporlaması Sentry'yi kullanır. Her ikisini de kapatmak için `SNAPOTTER_TELEMETRY=0`'yi ayarlayın (veya Ayarlar > Sistem > Gizlilik altında analitiği devre dışı bırakın). SnapOtter hiçbir zaman yüklenen dosyaları, dosya adlarını, OCR çıktısını, belge metnini veya diğer dosya içeriklerini bu etkinliklere dahil etmez. Diğer giden trafik ise özellik odaklıdır: AI paketi/model kurulumu, imzalı sürüm girişlerini indirir; URL içe aktarma, kullanıcı tarafından istenen genel bir URL'yi getirir; ve açıkça yapılandırılmış OIDC, SAML, OpenTelemetry, web kancaları, S3 uyumlu depolama veya benzer entegrasyonlar, yönetici tarafından seçilen hedeflerle iletişim kurar. Çalışma zamanı model indirmeleri varsayılan olarak devre dışıdır. Otomatik yedek indirmeleri açıkça etkinleştirmek için yalnızca `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` ayarını kullanın. [Çevrimdışı paket içe aktarma](/tr/guide/deployment), çalışma zamanı modeli çıkışı olmadan AI özelliklerini sağlayabilir. **Güvenlik duvarı önerileri:** |Senaryo|Giden kuralı| |---|---| |Hava boşluklu|`SNAPOTTER_TELEMETRY=0` ve `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0`'yi ayarlayın, çevrimdışı AI paketi içe aktarmayı kullanın, URL içe aktarmayı ve harici entegrasyonları devre dışı bırakın, ardından çıkışı engelleyin| |Varsayılan telemetri|Tarayıcınız/ağ günlükleriniz tarafından listelenen PostHog ve Sentry uç noktalarına izin verin; politika izin vermiyorsa telemetriyi devre dışı bırakın| |AI paketleri gerekli|Kurulum sırasında HTTPS'nin `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org`'ye izin vermesine izin verin; daha sonra bu ana bilgisayarları engelleyin| |Harici entegrasyonlar|Yalnızca yönetici tarafından yapılandırılan OIDC/SAML/OTLP/webhook/nesne depolama hedeflerine tam olarak izin verin| Paket arşivleri, `*.xethub.hf.co` uç noktaları üzerinden paralel olarak aktarım yapan Hugging Face'in Xet depolama alanından sunulur ve çoklu GB paket indirmelerini hızlı kılan da budur. Güvenlik duvarınız `huggingface.co`'ye izin veriyor ancak `*.xethub.hf.co`'yi engelliyorsa, yüklemeler yine de başarılı olur ancak daha yavaş tek akışlı indirmeye geri dönerse, hızlı yolda kalmak için Xet ana bilgisayarlarını izin verilenler listesine ekleyin. Tamamen çevrimdışı yüklemeler tüm bunları atlayabilir ve bunun yerine [Çevrimdışı Paket İçe Aktarma](/tr/guide/deployment) yöntemini kullanabilir. Ters proxy yapılandırması için (Nginx, Traefik, Caddy, Cloudflare Tünelleri), [Dağıtım kılavuzuna](/tr/guide/deployment#reverse-proxy) bakın. ## Docker Secrets {#docker-secrets} Üretim dağıtımları için, secret'ları düz metin ortam değişkenleri olarak geçirmekten kaçının. Giriş noktası Docker'ın `_FILE` kuralını destekler: bir secret'ı dosya olarak bağlayın ve karşılık gelen `_FILE` değişkenini yoluna ayarlayın. **Desteklenen secret'lar:** | Değişken | `_FILE` eşdeğeri | |---|---| | `DEFAULT_PASSWORD` | `DEFAULT_PASSWORD_FILE` | | `COOKIE_SECRET` | `COOKIE_SECRET_FILE` | | `OIDC_CLIENT_SECRET` | `OIDC_CLIENT_SECRET_FILE` | | `S3_ACCESS_KEY_ID` | `S3_ACCESS_KEY_ID_FILE` | | `S3_SECRET_ACCESS_KEY` | `S3_SECRET_ACCESS_KEY_FILE` | | `SNAPOTTER_LICENSE_KEY` | `SNAPOTTER_LICENSE_KEY_FILE` | **Docker Compose secrets ile örnek:** ```yaml services: SnapOtter: image: snapotter/snapotter:latest environment: - AUTH_ENABLED=true - DEFAULT_USERNAME=admin - DEFAULT_PASSWORD_FILE=/run/secrets/snapotter_password - COOKIE_SECRET_FILE=/run/secrets/cookie_secret secrets: - snapotter_password - cookie_secret secrets: snapotter_password: file: ./secrets/snapotter_password.txt cookie_secret: file: ./secrets/cookie_secret.txt ``` ::: tip Docker Compose secrets (Swarm olmadan) Compose v2.23 veya üstünü gerektirir. ::: ## Kubernetes Dağıtımı {#kubernetes-deployment} Giriş noktası, konteynerin zaten root olmayan olarak çalıştığını algılar (ör. Kubernetes `runAsUser` aracılığıyla) ve gosu ayrıcalık düşürmesini otomatik olarak atlar. Bu durumda bağlanan birimleri kendisi chown yapamaz, bu nedenle bunların yazılabilir olduğunu doğrular ve değilse eyleme geçirilebilir yönlendirmeyle erken çıkar - `fsGroup` ve yabancı-UID kurulumları (TrueNAS, OpenShift) için [Depolama izinleri](/tr/guide/deployment#storage-permissions) bölümüne bakın. **Önerilen Pod SecurityContext:** ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: snapotter spec: replicas: 1 selector: matchLabels: app: snapotter template: metadata: labels: app: snapotter spec: securityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 fsGroup: 999 containers: - name: snapotter image: snapotter/snapotter:latest ports: - containerPort: 1349 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] resources: requests: cpu: "1" memory: 2Gi limits: cpu: "4" memory: 6Gi livenessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readinessProbe: httpGet: path: /api/v1/health port: 1349 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - name: data mountPath: /data - name: workspace mountPath: /tmp/workspace volumes: - name: data persistentVolumeClaim: claimName: snapotter-data - name: workspace emptyDir: medium: Memory sizeLimit: 2Gi ``` `runAsUser: 999` pod düzeyinde ayarlandığından, giriş noktası gosu'yu tamamen atlar. Bu, `allowPrivilegeEscalation: false` ve `drop: [ALL]` yeteneklerine çakışma olmadan izin verir. Kaynak boyutlandırma için [Donanım Gereksinimleri](/tr/guide/deployment#hardware-requirements) bölümüne bakın. ## Yedekleme ve Kurtarma {#backup-and-recovery} Üretim Oluşturma yığını dört cilt tanımlar. PostgreSQL, Redis ve dosya durumunun zaman içinde aynı noktayı tanımlaması için, girişi durdurun ve koordineli bir yedekleme almadan önce etkin işlerin bitmesini bekleyin. |Hacim|İçindekiler|İyileşme tedavisi| |---|---|---| |`SnapOtter-pgdata`|PostgreSQL kullanıcıları, ayarlar, işlem hatları, işler, dosya meta verileri ve denetim günlüğü|Kritik; taşınabilir kurtarma için hızlı bir mantıksal döküm kullanın| |`SnapOtter-data`|Kaydedilen kitaplık nesneleri, günlükler ve AI durumu (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|Tüm birimi yedekleyin; yerden tasarruf etmek için tüm AI durumlarını kasıtlı olarak çıkarın ve paketlerini yeniden yükleyin| |`SnapOtter-redisdata`|Dayanıklı BullMQ kuyruk durumu için Redis AOF|Uygulamayı duraklatıp `SAVE`'yi zorladıktan sonra yedekleyin; sıraya alınmış çalışmayı tam olarak sürdürmek için gerekli| |`SnapOtter-workspace`|Geçici nesne depolama anahtarları (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|Tüm işler boşaltıldıktan veya iptal edildikten sonra yedekleme yapmayın; işler aktifken asla atmayın| Normalde birim adlarının ön ekini proje adıyla birlikte oluşturun. `SnapOtter-data` gibi bir görünen adın Docker birim adı olduğunu varsaymak yerine, gerçek kaynak birimini takılı kapsayıcıdan çözümleyin. ### Veritabanı yedeklemesi {#database-backup} PostgreSQL'in özel arşiv formatını kullanın ve yedeklemeyi tamamlanmış olarak değerlendirmeden önce arşivi doğrulayın: ```bash docker exec SnapOtter-postgres \ pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump test -s snapotter.dump docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null # Restore only into a fresh/disposable target first; any SQL error fails the command. docker exec -i SnapOtter-postgres \ pg_restore --exit-on-error --clean --if-exists --no-owner \ -U snapotter -d snapotter < snapotter.dump ``` Her yedeklemeyi yalıtılmış bir yığına geri yükleyerek, veritabanı kayıtlarını ve dosya sağlama toplamlarını kontrol ederek ve uygulamayı başlatarak test edin. Deponun `tests/qa/backup-restore-drill.sh`'si, açık bir `QA_IMAGE`'ye karşı bu serbest bırakma kapısını otomatikleştirir. Platformunuz bunun yerine kilitlenmeyle tutarlı birim anlık görüntüleri alıyorsa, önce tüm yığını durdurun ve tüm kritik birimlerin anlık görüntüsünü tek bir set olarak alın. Çalışan bir kapsayıcıdan alınan ham PostgreSQL veri dizini kopyası, desteklenen bir mantıksal yedekleme değildir. ### Dosya ve kuyruk yedeklemesi {#file-and-queue-backup} Dosya ve kuyruk birimlerini yakalamadan önce uygulamayı duraklatın. Gerçek birim adını çözümlemek, Redis'i mevcut durumunu sürdürmeye zorlamak ve sahiplik ve izinler korunarak arşivlemek için `docker inspect` kullanın: ```bash docker stop SnapOtter docker exec SnapOtter-redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning SAVE docker stop SnapOtter-redis DATA_VOLUME="$(docker inspect SnapOtter --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" REDIS_VOLUME="$(docker inspect SnapOtter-redis --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')" install -d -m 700 backup docker run --rm -v "$DATA_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-data.tar.gz -C /source . docker run --rm -v "$REDIS_VOLUME:/source:ro" -v "$PWD/backup:/backup" \ alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-redis.tar.gz -C /source . sha256sum backup/snapotter-*.tar.gz > backup/SHA256SUMS ``` Uygulamadan önce Redis'i yeniden başlatın. `/data/ai`'yi kasıtlı olarak hariç tutarsanız, bir `installed.json` kaydını modelleri veya sanal ortamı olmadan korumak yerine tüm AI alt ağacını kaldırın. Yedekleme dosyalarını şifrelenmiş, erişim kontrollü ve SnapOtter çalıştıran ana bilgisayardan ayrı tutun. ## Uyumluluk Eserleri {#compliance-artifacts} Her SnapOtter sürümü aşağıdaki güvenlik yapılarını içerir: | eser | Biçim | Nerede bulunur? | |---|---|---| | Konu bağlamayı serbest bırak | Kanonik JSON + GitHub onayı | [GitHub Sürümü](https://github.com/snapotter-hq/SnapOtter/releases) varlığı: `snapotter-v{version}-release-subjects.json` | | Arşiv SBOM | CycloneDX ve SPDX JSON | Varlıkları serbest bırakma: `snapotter-v{version}-archive-linux-{arch}-sbom.{cdx,spdx}.json` | | Resim SBOM | CycloneDX ve SPDX JSON | Varlıkları serbest bırakma: `snapotter-v{version}-image-linux-{arch}-sbom.{cdx,spdx}.json` | | Güvenlik açığı taramaları | Trivy JSON | Eşleşen `archive-linux-{arch}` veya `image-linux-{arch}` önekleriyle varlıkları serbest bırakın | | Güvenlik açığı taraması | SARIF | [GitHub Güvenlik](https://github.com/snapotter-hq/SnapOtter/security) sekmesi | | Statik analiz | CodeQL (JS/TS + Python) | [GitHub Güvenlik](https://github.com/snapotter-hq/SnapOtter/security) sekmesi, haftalık + PR başına çalışır | | Bağımlılık incelemesi | GitHub yerel | PR başına kontrol, yüksek önem derecesine sahip eklemelerde başarısız olur | | Python bağımlılık denetimi | pip-audit | Her basışta CI çalıştırma günlüğü | | Güvenlik politikası | Markdown | Depodaki [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) | | Bağımlılık güncellemeleri | Dependabot | Npm, pip, Docker, Eylemler için otomatik haftalık PR'ler | **Kendi taramanızı çalıştırma:** Yayın konusu bildirimini indirin ve yayın iş akışı tarafından onaylandığını doğrulayın: ```bash gh attestation verify snapotter-v2.2.0-release-subjects.json \ --repo snapotter-hq/SnapOtter \ --signer-workflow snapotter-hq/SnapOtter/.github/workflows/release.yml ``` Bildirim, `releaseTag`, `releaseCommit` ve `workflowTriggerCommit`'yi ayrı ayrı kaydeder. `releaseCommit`'nin değişmez etiketten çıkarılan kayıt olduğunu doğrulayın, ardından arşivin, görüntünün, SBOM'nin veya tükettiğiniz taramanın SHA-256 özetini `subjects`'deki girişine göre doğrulayın. Bu ayrım kasıtlıdır: yeni oluşturulan bir sürüm taahhüdünün kontrol edilmesi, iş akışının OIDC kimlik bilgisindeki taahhüt kimliğini değiştirmez. İndirilen bir SBOM'yi veya görüntüyü doğrudan da tarayabilirsiniz: ```bash # Scan with Grype using the CycloneDX SBOM grype sbom:snapotter-v2.2.0-image-linux-amd64-sbom.cdx.json # Scan with Trivy using the SPDX SBOM trivy sbom snapotter-v2.2.0-image-linux-amd64-sbom.spdx.json # Scan the Docker image directly trivy image snapotter/snapotter:2.2.0 ``` ::: info Görüntü SBOMs ve taramalar, söz konusu sürüm için yayınlanan mimariye özgü görüntüyü tam olarak yansıtır. Arşiv SBOMs ve taramalar, önceden oluşturulmuş arşivi ayrı ayrı açıklar. Dağıtımdan sonra yüklenen AI model paketleri, çalışma zamanında indirildikleri için bu SBOMs'ye dahil edilmez. ::: --- --- url: https://docs.snapotter.com/sv/tools/pdf/booklet-pdf.md description: Arrangera PDF-sidor för att vikas till ett häfte. --- # Häftes-PDF {#booklet-pdf} Montera sidor för dubbelsidig utskrift så att de utskrivna arken kan vikas till ett häfte. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/booklet-pdf` Tar emot multipart-formulärdata med en PDF-fil och ett JSON-fält `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | Sidor per ark: `2`, `4`, `6` eller `8` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/booklet-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 2}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2400000 } ``` ## Notes {#notes} * Standardvärdet `perSheet: 2` placerar två sidor sida vid sida på varje ark, vilket är standardlayouten för häften vid dubbelsidig utskrift. * Tomma sidor läggs till automatiskt om det totala sidantalet inte är en multipel av arkstorleken. * Skriv ut utdatan dubbelsidigt med bindning längs kortsidan, vik sedan och häfta. --- --- url: https://docs.snapotter.com/id/tools/pdf/nup-pdf.md description: Susun beberapa halaman PDF per lembar (2-up, 4-up, dll.). --- # Halaman Per Lembar (N-up) {#n-up-pdf} Susun beberapa halaman per lembar untuk menghemat kertas saat mencetak, seperti tata letak 2-up atau 4-up. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/pdf/nup-pdf` Menerima data form multipart berisi file PDF dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | perSheet | integer | No | `2` | Halaman per lembar: `2`, `3`, `4`, `8`, `9`, `12`, atau `16` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/pdf/nup-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@document.pdf" \ -F 'settings={"perSheet": 4}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", "originalSize": 2450000, "processedSize": 2300000 } ``` ## Notes {#notes} * Halaman disusun dalam urutan baca (kiri ke kanan, atas ke bawah). * Ukuran halaman output sama dengan aslinya; masing-masing halaman diperkecil agar pas dengan grid. * Dokumen 20 halaman dengan `perSheet: 4` menghasilkan output 5 halaman. --- --- url: https://docs.snapotter.com/id/tools/image/strip-metadata.md description: >- Menghapus metadata EXIF, GPS, ICC, dan XMP dari gambar untuk privasi dan ukuran file yang lebih kecil. --- # Hapus Metadata Gambar {#remove-metadata} Menghapus metadata EXIF, GPS, profil warna ICC, dan XMP dari gambar. Berguna untuk privasi (menghapus koordinat GPS, info kamera) dan mengurangi ukuran file. ## API Endpoints {#api-endpoints} ### Strip Metadata {#strip-metadata} `POST /api/v1/tools/image/strip-metadata` Memproses gambar dan mengembalikan versi bersih dengan metadata yang dipilih dihapus. ### Inspect Metadata {#inspect-metadata} `POST /api/v1/tools/image/strip-metadata/inspect` Mengembalikan metadata yang telah diurai sebagai JSON tanpa memodifikasi gambar. Berguna untuk melihat pratinjau metadata apa saja yang ada sebelum dihapus. ## Parameters (Strip) {#parameters-strip} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | stripExif | boolean | No | `false` | Menghapus data EXIF (pengaturan kamera, tanggal, dll.) | | stripGps | boolean | No | `false` | Menghapus data GPS/lokasi saja | | stripIcc | boolean | No | `false` | Menghapus profil warna ICC | | stripXmp | boolean | No | `false` | Menghapus metadata XMP (Adobe, IPTC) | | stripAll | boolean | No | `true` | Menghapus semua metadata sekaligus | Ketika `stripAll` bernilai `true`, itu menggantikan flag individual dan menghapus segalanya. ## Example Request {#example-request} Menghapus semua metadata: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": true}' ``` Menghapus hanya data GPS (mempertahankan info kamera dan profil warna): ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"stripAll": false, "stripGps": true}' ``` Memeriksa metadata tanpa memodifikasi: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/strip-metadata/inspect \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" ``` ## Example Response (Strip) {#example-response-strip} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", "originalSize": 2450000, "processedSize": 2380000 } ``` ## Example Response (Inspect) {#example-response-inspect} ```json { "filename": "photo.jpg", "fileSize": 2450000, "exif": { "Make": "Canon", "Model": "EOS R5", "DateTimeOriginal": "2024:03:15 14:30:00", "ExposureTime": "1/250", "FNumber": 2.8, "ISO": 400 }, "gps": { "GPSLatitudeRef": "N", "GPSLatitude": [37, 46, 30], "_latitude": 37.775, "_longitude": -122.4183 }, "icc": { "Profile Size": "3144 bytes", "Color Space": "RGB", "Description": "sRGB IEC61966-2.1" }, "xmp": { "CreatorTool": "Adobe Photoshop 25.0" } } ``` ## Notes {#notes} * Gambar dienkode ulang dalam format aslinya setelah dihapus. JPEG menggunakan mozjpeg pada kualitas 90, PNG menggunakan level kompresi 9, WebP menggunakan kualitas 85. * Menghapus profil ICC dapat menyebabkan pergeseran warna yang halus jika gambar ditandai dengan profil non-sRGB. Gunakan `stripIcc: false` jika akurasi warna penting. * Endpoint inspect mengurai koordinat GPS menjadi nilai lintang/bujur desimal (diawali dengan garis bawah) untuk kemudahan. * Format masukan yang didukung: JPEG, PNG, WebP, AVIF, TIFF, GIF. --- --- url: https://docs.snapotter.com/es/tools/image/gif-tools.md description: >- Redimensiona, optimiza, cambia la velocidad, invierte, gira y extrae fotogramas de GIF animados en una sola herramienta. --- # Herramientas de GIF {#gif-tools} Redimensiona, optimiza, cambia la velocidad, invierte, extrae fotogramas y gira GIF animados. Ofrece varios modos de operación en una sola herramienta. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/gif-tools` ## Parámetros {#parameters} ### Parámetros comunes {#common-parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | mode | string | No | `"resize"` | Modo de operación: `resize`, `optimize`, `speed`, `reverse`, `extract`, `rotate` | | loop | number | No | 0 | Número de repeticiones del GIF de salida (0 = infinito, 1-100 = repeticiones finitas) | ### Parámetros del modo Redimensionar {#resize-mode-parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | width | integer | No | - | Ancho objetivo en píxeles (1 a 16384) | | height | integer | No | - | Alto objetivo en píxeles (1 a 16384) | | percentage | number | No | - | Escalar por porcentaje (1 a 500). Anula width/height si se define. | ### Parámetros del modo Optimizar {#optimize-mode-parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | colors | number | No | 256 | Número máximo de colores en la paleta (2 a 256) | | dither | number | No | 1.0 | Intensidad del difuminado (0 a 1, donde 0 desactiva el difuminado) | | effort | number | No | 7 | Nivel de esfuerzo de optimización (1 a 10, mayor = más lento pero más pequeño) | ### Parámetros del modo Velocidad {#speed-mode-parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | speedFactor | number | No | 1.0 | Multiplicador de velocidad (0.1 a 10). Los valores > 1 aceleran, < 1 ralentizan. | ### Parámetros del modo Extraer {#extract-mode-parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | extractMode | string | No | `"single"` | Modo de extracción: `single`, `range`, `all` | | frameNumber | number | No | 0 | Índice del fotograma a extraer en el modo `single` (basado en 0) | | frameStart | number | No | 0 | Índice del fotograma inicial para el modo `range` (basado en 0) | | frameEnd | number | No | - | Índice del fotograma final para el modo `range` (basado en 0, inclusive) | | extractFormat | string | No | `"png"` | Formato de los fotogramas extraídos: `png`, `webp` | ### Parámetros del modo Girar {#rotate-mode-parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | angle | number | No | - | Ángulo de rotación: `90`, `180` o `270` grados | | flipH | boolean | No | `false` | Voltear horizontalmente | | flipV | boolean | No | `false` | Voltear verticalmente | ## Ejemplos de solicitud {#example-requests} ### Redimensionar {#resize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"resize","percentage":50}' ``` ### Optimizar {#optimize} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@large.gif" \ -F 'settings={"mode":"optimize","colors":128,"effort":9}' ``` ### Acelerar {#speed-up} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"speed","speedFactor":2.0}' ``` ### Extraer un solo fotograma {#extract-single-frame} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools \ -F "file=@animation.gif" \ -F 'settings={"mode":"extract","extractMode":"single","frameNumber":5,"extractFormat":"png"}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.gif", "originalSize": 2345678, "processedSize": 1234567 } ``` ## Subruta de información {#info-sub-route} `POST /api/v1/tools/image/gif-tools/info` Devuelve metadatos sobre un GIF animado sin procesarlo. ### Solicitud de información {#info-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/gif-tools/info \ -F "file=@animation.gif" ``` ### Respuesta de información {#info-response} ```json { "width": 480, "height": 320, "pages": 24, "delay": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], "loop": 0, "fileSize": 2345678, "duration": 2400 } ``` ## Notas {#notes} * Usa la fábrica estándar `createToolRoute` para el endpoint de procesamiento principal. * El endpoint de información solo requiere subir un archivo (no se necesita configuración). * En el modo `resize`, si se proporciona `percentage` tiene prioridad sobre `width`/`height`. El redimensionado usa `fit: inside` para mantener la relación de aspecto. * En el modo `speed`, los retardos de los fotogramas se dividen por el factor de velocidad. El retardo mínimo por fotograma es de 20 ms (limitación de la especificación GIF). * En el modo `reverse`, el parámetro `speedFactor` también está disponible para ajustar simultáneamente la velocidad mientras se invierte. * En el modo `extract` con `range` o `all`, la salida es un archivo ZIP que contiene fotogramas individuales. * En el modo `rotate`, cada fotograma se procesa individualmente y se vuelve a ensamblar en una animación. * El parámetro `loop` controla cuántas veces se repite el GIF de salida. Usa 0 para repetición infinita. * El campo `duration` de la respuesta de información es la duración total de la animación en milisegundos. --- --- url: https://docs.snapotter.com/de/tools/image/remove-background.md description: >- KI-gestützte Hintergrundentfernung mit optionalen Effekten (Weichzeichnen, Schatten, Verlauf, eigener Hintergrund). --- # Hintergrund entfernen {#remove-background} KI-gestützte Hintergrundentfernung mit optionalen Effekten (Weichzeichnen, Schatten, Verlauf, eigener Hintergrund). ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/remove-background` **Verarbeitung:** Asynchron (gibt 202 zurück, Status über SSE per `/api/v1/jobs/{jobId}/progress` abfragen) **Modell-Bundle:** `background-removal` (4-5 GB) ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | file | file | Ja | - | Bilddatei (multipart) | | model | string | Nein | - | Zu verwendende KI-Modellvariante | | backgroundType | string | Nein | `"transparent"` | Eines von: `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | Nein | - | Hex-Farbe für einfarbigen Hintergrund | | gradientColor1 | string | Nein | - | Erste Verlaufsfarbe | | gradientColor2 | string | Nein | - | Zweite Verlaufsfarbe | | gradientAngle | number | Nein | - | Verlaufswinkel in Grad | | blurEnabled | boolean | Nein | - | Hintergrund-Weichzeichnungseffekt aktivieren | | blurIntensity | number | Nein | - | Weichzeichnungsintensität (0-100) | | shadowEnabled | boolean | Nein | - | Schlagschatten auf dem Motiv aktivieren | | shadowOpacity | number | Nein | - | Deckkraft des Schattens (0-100) | | outputFormat | string | Nein | - | Ausgabeformat: `png`, `webp` oder `avif` | | edgeRefine | integer | Nein | - | Stufe der Kantenverfeinerung (0-3) | | decontaminate | boolean | Nein | - | Farbüberläufe an den Kanten entfernen | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType":"transparent","edgeRefine":2,"outputFormat":"png"}' ``` ## Antwort {#response} ### Erste Antwort (202 Accepted) {#initial-response-202-accepted} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ### Fortschritt (SSE unter `/api/v1/jobs/{jobId}/progress`) {#progress-sse-at-api-v1-jobs-jobid-progress} ``` event: progress data: {"phase":"processing","stage":"Removing background...","percent":50} ``` ### Endergebnis (über SSE) {#final-result-via-sse} ```json { "phase": "complete", "percent": 100, "result": { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_mask.png", "maskUrl": "/api/v1/download/{jobId}/photo_mask.png", "originalUrl": "/api/v1/download/{jobId}/photo_original.png", "originalSize": 245000, "processedSize": 180000, "filename": "photo.jpg", "model": "rembg" } } ``` ## Effekt-Endpunkt (Phase 2) {#effects-endpoint-phase-2} `POST /api/v1/tools/image/remove-background/effects` Wendet Hintergrundeffekte erneut an, ohne das KI-Modell neu auszuführen. Verwendet die zwischengespeicherte Maske und das Original aus Phase 1. ### Parameter {#parameters-1} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | settings | JSON | Ja | - | JSON mit Effekteinstellungen (siehe unten) | | backgroundImage | file | Nein | - | Eigenes Hintergrundbild (wenn backgroundType `image` ist) | #### JSON-Felder der Einstellungen {#settings-json-fields} | Feld | Typ | Erforderlich | Beschreibung | |-------|------|----------|-------------| | jobId | string | Ja | Job-ID aus Phase 1 | | filename | string | Ja | Ursprünglicher Dateiname aus Phase 1 | | backgroundType | string | Nein | `transparent`, `color`, `gradient`, `blur`, `image` | | backgroundColor | string | Nein | Hex-Farbe für einfarbigen Hintergrund | | gradientColor1 | string | Nein | Erste Verlaufsfarbe | | gradientColor2 | string | Nein | Zweite Verlaufsfarbe | | gradientAngle | number | Nein | Verlaufswinkel in Grad | | blurEnabled | boolean | Nein | Hintergrund-Weichzeichnung aktivieren | | blurIntensity | number | Nein | Weichzeichnungsintensität (0-100) | | shadowEnabled | boolean | Nein | Schlagschatten aktivieren | | shadowOpacity | number | Nein | Deckkraft des Schattens (0-100) | | outputFormat | string | Nein | `png`, `webp` oder `avif` | ### Beispielanfrage {#example-request-1} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/remove-background/effects \ -F 'settings={"jobId":"a1b2c3d4-...","filename":"photo.jpg","backgroundType":"color","backgroundColor":"#FF5500","outputFormat":"png"}' ``` ### Antwort (200 OK) {#response-200-ok} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/{jobId}/photo_nobg.png", "processedSize": 195000 } ``` ## Hinweise {#notes} * Erfordert das installierte Modell-Bundle `background-removal` (4-5 GB). * Phase 1 speichert die transparente Maske und das Originalbild zwischen, sodass Phase 2 (Effekte) verschiedene Hintergründe sofort erneut anwenden kann, ohne das KI-Modell neu auszuführen. * Unterstützt die Eingabeformate HEIC/HEIF, RAW, TGA, PSD, EXR und HDR durch automatische Dekodierung. * Die EXIF-Rotation wird vor der Verarbeitung automatisch korrigiert. --- --- url: https://docs.snapotter.com/de/tools/image/background-replace.md description: >- Den Bildhintergrund mit einer Volltonfarbe oder einem Farbverlauf per KI ersetzen. --- # Hintergrund ersetzen {#background-replace} Ersetzt den Hintergrund eines Bildes durch eine Volltonfarbe oder einen Farbverlauf. Das KI-Modell erkennt das Motiv, entfernt den ursprünglichen Hintergrund und setzt das Motiv auf den von Ihnen gewählten Hintergrund. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/background-replace` Nimmt Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | backgroundType | string | Nein | `"color"` | Hintergrundmodus: `color` oder `gradient` | | color | string | Nein | `"#ffffff"` | Hex-Farbe des Hintergrunds (wenn backgroundType `color` ist) | | gradientColor1 | string | Nein | - | Erste Hex-Farbe des Farbverlaufs | | gradientColor2 | string | Nein | - | Zweite Hex-Farbe des Farbverlaufs | | gradientAngle | integer | Nein | `180` | Winkel des Farbverlaufs in Grad (0-360) | | feather | integer | Nein | `0` | Radius der Kantenweichzeichnung (0-20) | | format | string | Nein | `"png"` | Ausgabeformat: `png` oder `webp` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/background-replace \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Verfolgen Sie den Fortschritt per SSE unter `GET /api/v1/jobs/{jobId}/progress`. Wenn der Auftrag abgeschlossen ist, gibt der SSE-Stream ein `completed`-Ereignis mit der Download-URL aus. ## Hinweise {#notes} * Dies ist ein KI-gestütztes Werkzeug, das `202 Accepted` zurückgibt und asynchron verarbeitet. Verbinden Sie sich mit dem SSE-Endpunkt, um Fortschrittsaktualisierungen und das Endergebnis zu erhalten. * Erfordert die Installation des Funktionspakets **background-removal**. Gibt `501` zurück, wenn das Paket nicht verfügbar ist. * Eingaben in HEIC, RAW, PSD und SVG werden vor der Verarbeitung automatisch dekodiert. * Die Ausgabe ist standardmäßig PNG, um die Transparenz um das Motiv herum zu erhalten. --- --- url: https://docs.snapotter.com/de/tools/image/blur-background.md description: Den Hintergrund weichzeichnen und dabei das Motiv per KI scharf halten. --- # Hintergrund weichzeichnen {#blur-background} Zeichnet den Hintergrund eines Bildes weich und hält dabei das Motiv scharf. Das KI-Modell isoliert das Motiv, wendet eine Weichzeichnung auf den ursprünglichen Hintergrund an und setzt das scharfe Motiv darüber. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/blur-background` Nimmt Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings` entgegen. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | intensity | integer | Nein | `50` | Weichzeichnungsintensität (1-100) | | feather | integer | Nein | `0` | Radius der Kantenweichzeichnung (0-20) | | format | string | Nein | `"png"` | Ausgabeformat: `png` oder `webp` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/blur-background \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"intensity": 75, "feather": 3}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` Verfolgen Sie den Fortschritt per SSE unter `GET /api/v1/jobs/{jobId}/progress`. Wenn der Auftrag abgeschlossen ist, gibt der SSE-Stream ein `completed`-Ereignis mit der Download-URL aus. ## Hinweise {#notes} * Dies ist ein KI-gestütztes Werkzeug, das `202 Accepted` zurückgibt und asynchron verarbeitet. Verbinden Sie sich mit dem SSE-Endpunkt, um Fortschrittsaktualisierungen und das Endergebnis zu erhalten. * Erfordert die Installation des Funktionspakets **background-removal**. Gibt `501` zurück, wenn das Paket nicht verfügbar ist. * Höhere Intensitätswerte erzeugen einen stärkeren Weichzeichnungseffekt. Werte über 80 erzeugen eine ausgeprägte bokeh-artige Trennung. * Eingaben in HEIC, RAW, PSD und SVG werden vor der Verarbeitung automatisch dekodiert. --- --- url: https://docs.snapotter.com/hi/tools/image/histogram.md description: किसी छवि से प्रति-चैनल आँकड़ों के साथ एक RGB histogram चार्ट जनरेट करें। --- # Histogram {#histogram} किसी छवि से एक RGB histogram चार्ट जनरेट करें। प्रतिक्रिया JSON में प्रति-चैनल आँकड़ों और कच्चे 256-bin histogram डेटा के साथ एक PNG histogram छवि लौटाता है। ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/histogram` एक image फ़ाइल और एक JSON `settings` फ़ील्ड के साथ multipart form data स्वीकार करता है। ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | scale | string | नहीं | `"linear"` | Y-axis स्केल: `linear` या `log` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Notes {#notes} * `downloadUrl` एक रेंडर किए गए PNG histogram चार्ट की ओर इंगित करता है जो R, G, B और luminance वितरण दिखाता है। * `bins` में प्रत्येक चैनल (red, green, blue, luminance) के लिए कच्चे 256-मान arrays होते हैं, जो कस्टम विज़ुअलाइज़ेशन रेंडर करने के लिए उपयुक्त हैं। * `stats` प्रति चैनल mean, median और मानक विचलन प्रदान करता है। * `mean` और `max` पश्च-संगत शॉर्टहैंड फ़ील्ड हैं। * जब histogram पर कुछ शिखर हावी हों और आप निचले bins में विवरण देखना चाहें तो `log` स्केल का उपयोग करें। * HEIC, RAW, PSD और SVG इनपुट विश्लेषण से पहले स्वचालित रूप से डिकोड किए जाते हैं। --- --- url: https://docs.snapotter.com/id/tools/image/histogram.md description: Hasilkan bagan histogram RGB dengan statistik per-channel dari sebuah gambar. --- # Histogram {#histogram} Hasilkan bagan histogram RGB dari sebuah gambar. Mengembalikan gambar histogram PNG beserta statistik per-channel dan data histogram 256-bin mentah dalam JSON respons. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/histogram` Menerima multipart form data dengan file gambar dan sebuah field JSON `settings`. ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | scale | string | No | `"linear"` | Skala sumbu Y: `linear` atau `log` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Notes {#notes} * `downloadUrl` menunjuk ke bagan histogram PNG yang telah dirender, menampilkan distribusi R, G, B, dan luminansi. * `bins` berisi array 256-nilai mentah untuk setiap channel (red, green, blue, luminance), cocok untuk merender visualisasi kustom. * `stats` menyediakan mean, median, dan deviasi standar per channel. * `mean` dan `max` adalah field ringkas yang kompatibel-mundur. * Gunakan skala `log` ketika histogram didominasi beberapa puncak dan Anda ingin melihat detail pada bin yang lebih rendah. * Input HEIC, RAW, PSD, dan SVG di-decode otomatis sebelum analisis. --- --- url: https://docs.snapotter.com/nl/tools/image/histogram.md description: >- Genereer een RGB-histogramgrafiek met statistieken per kanaal vanuit een afbeelding. --- # Histogram {#histogram} Genereer een RGB-histogramgrafiek vanuit een afbeelding. Retourneert een PNG-histogramafbeelding samen met statistieken per kanaal en ruwe histogramgegevens met 256 bins in de antwoord-JSON. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/histogram` Accepteert multipart-formuliergegevens met een afbeeldingsbestand en een JSON-veld `settings`. ## Parameters {#parameters} | Parameter | Type | Vereist | Standaard | Beschrijving | |-----------|------|----------|---------|-------------| | scale | string | Nee | `"linear"` | Schaal van de Y-as: `linear` of `log` | ## Voorbeeldverzoek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Voorbeeldantwoord {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Opmerkingen {#notes} * Het veld `downloadUrl` verwijst naar een gerenderde PNG-histogramgrafiek die de R-, G-, B- en luminantieverdelingen toont. * `bins` bevat ruwe arrays met 256 waarden voor elk kanaal (rood, groen, blauw, luminantie), geschikt voor het renderen van aangepaste visualisaties. * `stats` geeft het gemiddelde, de mediaan en de standaarddeviatie per kanaal. * `mean` en `max` zijn achterwaarts compatibele afkortingsvelden. * Gebruik de schaal `log` wanneer het histogram wordt gedomineerd door enkele pieken en je detail in de lagere bins wilt zien. * HEIC-, RAW-, PSD- en SVG-invoer wordt automatisch gedecodeerd vóór de analyse. --- --- url: https://docs.snapotter.com/pl/tools/image/histogram.md description: >- Generuj wykres histogramu RGB ze statystykami dla poszczególnych kanałów z obrazu. --- # Histogram {#histogram} Generuj wykres histogramu RGB z obrazu. Zwraca obraz histogramu w formacie PNG wraz ze statystykami dla poszczególnych kanałów oraz surowymi danymi histogramu z 256 przedziałami w odpowiedzi JSON. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/histogram` Przyjmuje dane formularza multipart z plikiem obrazu oraz polem JSON `settings`. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | scale | string | Nie | `"linear"` | Skala osi Y: `linear` lub `log` | ## Przykładowe żądanie {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Uwagi {#notes} * `downloadUrl` wskazuje na wyrenderowany wykres histogramu PNG pokazujący rozkłady R, G, B i luminancji. * `bins` zawiera surowe tablice 256 wartości dla każdego kanału (czerwony, zielony, niebieski, luminancja), przydatne do renderowania niestandardowych wizualizacji. * `stats` dostarcza średnią, medianę i odchylenie standardowe dla każdego kanału. * `mean` i `max` to zgodne wstecznie pola skrócone. * Użyj skali `log`, gdy histogram jest zdominowany przez kilka szczytów, a chcesz zobaczyć szczegóły w niższych przedziałach. * Wejścia HEIC, RAW, PSD i SVG są automatycznie dekodowane przed analizą. --- --- url: https://docs.snapotter.com/sv/tools/image/histogram.md description: Generera ett RGB-histogramdiagram med statistik per kanal från en bild. --- # Histogram {#histogram} Generera ett RGB-histogramdiagram från en bild. Returnerar en PNG-histogrambild tillsammans med statistik per kanal och rå 256-bins histogramdata i svars-JSON. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/histogram` Tar emot multipart-formulärdata med en bildfil och ett JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | scale | string | Nej | `"linear"` | Y-axelns skala: `linear` eller `log` | ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Exempelsvar {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Anmärkningar {#notes} * `downloadUrl` pekar på ett renderat PNG-histogramdiagram som visar fördelningarna för R, G, B och luminans. * `bins` innehåller råa 256-värdesmatriser för varje kanal (röd, grön, blå, luminans), lämpliga för att rendera anpassade visualiseringar. * `stats` tillhandahåller medelvärde, median och standardavvikelse per kanal. * `mean` och `max` är bakåtkompatibla förkortade fält. * Använd skalan `log` när histogrammet domineras av ett fåtal toppar och du vill se detaljer i de lägre binsen. * HEIC-, RAW-, PSD- och SVG-inmatningar avkodas automatiskt före analys. --- --- url: https://docs.snapotter.com/th/tools/image/histogram.md description: สร้างแผนภูมิ RGB histogram พร้อมสถิติต่อช่องสัญญาณจากภาพ --- # Histogram {#histogram} สร้างแผนภูมิ RGB histogram จากภาพ คืนค่าเป็นภาพ histogram แบบ PNG พร้อมกับสถิติต่อช่องสัญญาณและข้อมูล histogram ดิบแบบ 256 bin ในการตอบกลับ JSON ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/histogram` รับข้อมูลแบบ multipart form data ที่มีไฟล์ภาพและฟิลด์ JSON `settings` ## Parameters {#parameters} | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | scale | string | No | `"linear"` | สเกลแกน Y: `linear` หรือ `log` | ## Example Request {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Example Response {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Notes {#notes} * `downloadUrl` ชี้ไปยังแผนภูมิ PNG histogram ที่เรนเดอร์แล้ว แสดงการกระจายของ R, G, B และความสว่าง * `bins` มีอาร์เรย์ 256 ค่าดิบสำหรับแต่ละช่องสัญญาณ (แดง เขียว น้ำเงิน ความสว่าง) เหมาะสำหรับการเรนเดอร์การแสดงผลแบบกำหนดเอง * `stats` ให้ค่าเฉลี่ย ค่ามัธยฐาน และส่วนเบี่ยงเบนมาตรฐานต่อช่องสัญญาณ * `mean` และ `max` เป็นฟิลด์แบบย่อที่เข้ากันได้กับเวอร์ชันก่อนหน้า * ใช้สเกล `log` เมื่อ histogram ถูกครอบงำด้วยยอดไม่กี่จุด และคุณต้องการเห็นรายละเอียดใน bin ที่ต่ำกว่า * อินพุต HEIC, RAW, PSD และ SVG จะถูกถอดรหัสโดยอัตโนมัติก่อนการวิเคราะห์ --- --- url: https://docs.snapotter.com/tr/tools/image/histogram.md description: >- Bir görselden kanal başına istatistiklerle birlikte bir RGB histogram grafiği üretin. --- # Histogram {#histogram} Bir görselden bir RGB histogram grafiği üretin. Yanıt JSON'unda kanal başına istatistikler ve ham 256 bölmeli histogram verileriyle birlikte bir PNG histogram görseli döndürür. ## API Uç Noktası {#api-endpoint} `POST /api/v1/tools/image/histogram` Bir görsel dosyası ve bir JSON `settings` alanı içeren multipart form verisini kabul eder. ## Parametreler {#parameters} | Parametre | Tür | Zorunlu | Varsayılan | Açıklama | |-----------|------|----------|---------|-------------| | scale | string | Hayır | `"linear"` | Y ekseni ölçeği: `linear` veya `log` | ## Örnek İstek {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Örnek Yanıt {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Notlar {#notes} * `downloadUrl`, R, G, B ve parlaklık dağılımlarını gösteren, işlenmiş bir PNG histogram grafiğine işaret eder. * `bins`, her kanal (kırmızı, yeşil, mavi, parlaklık) için özel görselleştirmeler oluşturmaya uygun ham 256 değerli diziler içerir. * `stats`, kanal başına ortalama, medyan ve standart sapma sağlar. * `mean` ve `max`, geriye dönük uyumlu kısaltma alanlarıdır. * Histogram birkaç zirveyle domine edildiğinde ve alt bölmelerdeki ayrıntıyı görmek istediğinizde `log` ölçeğini kullanın. * HEIC, RAW, PSD ve SVG girişleri analizden önce otomatik olarak çözümlenir. --- --- url: https://docs.snapotter.com/vi/tools/image/histogram.md description: Tạo biểu đồ histogram RGB với thống kê theo từng kênh từ một ảnh. --- # Histogram {#histogram} Tạo biểu đồ histogram RGB từ một ảnh. Trả về một ảnh histogram PNG cùng với thống kê theo từng kênh và dữ liệu histogram thô 256 bin trong JSON phản hồi. ## Điểm cuối API {#api-endpoint} `POST /api/v1/tools/image/histogram` Chấp nhận dữ liệu biểu mẫu multipart với một tệp ảnh và một trường JSON `settings`. ## Tham số {#parameters} | Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả | |-----------|------|----------|---------|-------------| | scale | string | Không | `"linear"` | Thang trục Y: `linear` hoặc `log` | ## Ví dụ yêu cầu {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Ví dụ phản hồi {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Ghi chú {#notes} * `downloadUrl` trỏ tới một biểu đồ histogram PNG đã kết xuất cho thấy phân bố của R, G, B và độ sáng (luminance). * `bins` chứa các mảng thô 256 giá trị cho mỗi kênh (đỏ, lục, lam, độ sáng), phù hợp để kết xuất các biểu diễn tùy chỉnh. * `stats` cung cấp giá trị trung bình, trung vị và độ lệch chuẩn cho mỗi kênh. * `mean` và `max` là các trường viết tắt tương thích ngược. * Dùng thang `log` khi histogram bị chi phối bởi một vài đỉnh và bạn muốn thấy chi tiết ở các bin thấp hơn. * Đầu vào HEIC, RAW, PSD và SVG được giải mã tự động trước khi phân tích. --- --- url: https://docs.snapotter.com/es/tools/image/histogram.md description: >- Genera un gráfico de histograma RGB con estadísticas por canal a partir de una imagen. --- # Histograma {#histogram} Genera un gráfico de histograma RGB a partir de una imagen. Devuelve una imagen de histograma PNG junto con estadísticas por canal y datos de histograma sin procesar de 256 bins en el JSON de la respuesta. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/histogram` Acepta datos de formulario multipart con un archivo de imagen y un campo JSON `settings`. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | scale | string | No | `"linear"` | Escala del eje Y: `linear` o `log` | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Notas {#notes} * El `downloadUrl` apunta a un gráfico de histograma PNG renderizado que muestra las distribuciones de R, G, B y luminancia. * `bins` contiene matrices sin procesar de 256 valores por cada canal (rojo, verde, azul, luminancia), adecuadas para renderizar visualizaciones personalizadas. * `stats` proporciona la media, la mediana y la desviación estándar por canal. * `mean` y `max` son campos abreviados retrocompatibles. * Usa la escala `log` cuando el histograma está dominado por unos pocos picos y quieres ver el detalle en los bins más bajos. * Las entradas HEIC, RAW, PSD y SVG se decodifican automáticamente antes del análisis. --- --- url: https://docs.snapotter.com/pt-BR/tools/image/histogram.md description: >- Gere um gráfico de histograma RGB com estatísticas por canal a partir de uma imagem. --- # Histograma {#histogram} Gere um gráfico de histograma RGB a partir de uma imagem. Retorna uma imagem PNG do histograma junto com estatísticas por canal e dados brutos de histograma de 256 bins no JSON da resposta. ## Endpoint da API {#api-endpoint} `POST /api/v1/tools/image/histogram` Aceita dados de formulário multipart com um arquivo de imagem e um campo JSON `settings`. ## Parâmetros {#parameters} | Parâmetro | Tipo | Obrigatório | Padrão | Descrição | |-----------|------|----------|---------|-------------| | scale | string | Não | `"linear"` | Escala do eixo Y: `linear` ou `log` | ## Exemplo de Requisição {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Exemplo de Resposta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Observações {#notes} * O `downloadUrl` aponta para um gráfico de histograma PNG renderizado mostrando as distribuições de R, G, B e luminância. * `bins` contém arrays brutos de 256 valores para cada canal (vermelho, verde, azul, luminância), adequados para renderizar visualizações personalizadas. * `stats` fornece média, mediana e desvio padrão por canal. * `mean` e `max` são campos abreviados compatíveis com versões anteriores. * Use a escala `log` quando o histograma for dominado por alguns picos e você quiser ver detalhes nos bins mais baixos. * Entradas HEIC, RAW, PSD e SVG são decodificadas automaticamente antes da análise. --- --- url: https://docs.snapotter.com/de/tools/image/histogram.md description: Erzeugt ein RGB-Histogramm-Diagramm mit Statistiken pro Kanal aus einem Bild. --- # Histogramm {#histogram} Erzeugt ein RGB-Histogramm-Diagramm aus einem Bild. Gibt ein PNG-Histogrammbild zusammen mit Statistiken pro Kanal und rohen Histogrammdaten mit 256 Bins im Antwort-JSON zurück. ## API-Endpunkt {#api-endpoint} `POST /api/v1/tools/image/histogram` Akzeptiert Multipart-Formulardaten mit einer Bilddatei und einem JSON-Feld `settings`. ## Parameter {#parameters} | Parameter | Typ | Erforderlich | Standard | Beschreibung | |-----------|------|----------|---------|-------------| | scale | string | Nein | `"linear"` | Skala der Y-Achse: `linear` oder `log` | ## Beispielanfrage {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Beispielantwort {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Hinweise {#notes} * `downloadUrl` verweist auf ein gerendertes PNG-Histogramm-Diagramm, das die Verteilungen von R, G, B und Luminanz zeigt. * `bins` enthält rohe Arrays mit 256 Werten für jeden Kanal (Rot, Grün, Blau, Luminanz), geeignet für das Rendern eigener Visualisierungen. * `stats` liefert Mittelwert, Median und Standardabweichung pro Kanal. * `mean` und `max` sind abwärtskompatible Kurzform-Felder. * Verwenden Sie die Skala `log`, wenn das Histogramm von wenigen Spitzen dominiert wird und Sie Details in den unteren Bins sehen möchten. * HEIC-, RAW-, PSD- und SVG-Eingaben werden vor der Analyse automatisch decodiert. --- --- url: https://docs.snapotter.com/fr/tools/image/histogram.md description: >- Générez un graphique d'histogramme RVB avec des statistiques par canal à partir d'une image. --- # Histogramme {#histogram} Générez un graphique d'histogramme RVB à partir d'une image. Renvoie une image d'histogramme PNG accompagnée de statistiques par canal et des données brutes d'histogramme à 256 classes dans le JSON de réponse. ## Point de terminaison de l'API {#api-endpoint} `POST /api/v1/tools/image/histogram` Accepte des données de formulaire multipart avec une image et un champ JSON `settings`. ## Paramètres {#parameters} | Paramètre | Type | Requis | Par défaut | Description | |-----------|------|----------|---------|-------------| | scale | string | Non | `"linear"` | Échelle de l'axe Y : `linear` ou `log` | ## Exemple de requête {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/histogram \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo.jpg" \ -F 'settings={"scale": "linear"}' ``` ## Exemple de réponse {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", "originalSize": 2450000, "processedSize": 12000, "bins": { "r": [0, 12, 45, "... (256 values)"], "g": [0, 8, 38, "... (256 values)"], "b": [2, 15, 52, "... (256 values)"], "lum": [0, 10, 40, "... (256 values)"] }, "stats": { "r": { "mean": 128, "median": 132, "stdev": 48.5 }, "g": { "mean": 119, "median": 121, "stdev": 44.2 }, "b": { "mean": 105, "median": 108, "stdev": 51.3 }, "lum": { "mean": 118, "median": 120, "stdev": 45.1 } }, "mean": { "r": 128, "g": 119, "b": 105 }, "max": { "r": 4200, "g": 3800, "b": 4100 } } ``` ## Notes {#notes} * Le champ `downloadUrl` pointe vers un graphique d'histogramme PNG rendu montrant les distributions R, V, B et de luminance. * `bins` contient des tableaux bruts de 256 valeurs pour chaque canal (rouge, vert, bleu, luminance), adaptés au rendu de visualisations personnalisées. * `stats` fournit la moyenne, la médiane et l'écart type par canal. * `mean` et `max` sont des champs raccourcis rétrocompatibles. * Utilisez l'échelle `log` lorsque l'histogramme est dominé par quelques pics et que vous souhaitez voir les détails dans les classes inférieures. * Les entrées HEIC, RAW, PSD et SVG sont automatiquement décodées avant l'analyse. --- --- url: https://docs.snapotter.com/sv/tools/image/find-duplicates.md description: Upptäck dubbletter och nästan identiska bilder med perceptuell hashning. --- # Hitta dubbletter {#find-duplicates} Ladda upp flera bilder för att upptäcka dubbletter och nästan identiska bilder med perceptuell hashning (dHash). Grupperar liknande bilder tillsammans, identifierar versionen med bäst kvalitet i varje grupp och beräknar potentiella utrymmesbesparingar. ## API-slutpunkt {#api-endpoint} `POST /api/v1/tools/image/find-duplicates` Tar emot multipart-formulärdata med flera bildfiler och ett valfritt JSON-fält `settings`. ## Parametrar {#parameters} | Parameter | Typ | Obligatorisk | Standard | Beskrivning | |-----------|------|----------|---------|-------------| | threshold | number | Nej | `8` | Maximalt Hamming-avstånd för att betrakta bilder som dubbletter (0 till 20). Lägre = strängare matchning | ### Filfält {#file-fields} Ladda upp minst 2 bildfiler i multipart-begäran (alla med fältnamnet `file` eller vilket fältnamn som helst för fildelar). ## Exempelbegäran {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/find-duplicates \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@photo1.jpg" \ -F "file=@photo2.jpg" \ -F "file=@photo3.jpg" \ -F "file=@photo4.jpg" \ -F 'settings={"threshold": 8}' ``` ## Exempelsvar {#example-response} ```json { "totalImages": 4, "duplicateGroups": [ { "groupId": 1, "files": [ { "filename": "photo1.jpg", "similarity": 100, "width": 4032, "height": 3024, "fileSize": 2450000, "format": "jpeg", "isBest": true, "thumbnail": "data:image/jpeg;base64,/9j/..." }, { "filename": "photo2.jpg", "similarity": 96.88, "width": 1920, "height": 1440, "fileSize": 850000, "format": "jpeg", "isBest": false, "thumbnail": "data:image/jpeg;base64,/9j/..." } ] } ], "uniqueImages": 2, "spaceSaveable": 850000, "skippedFiles": [] } ``` ## Svarsfält {#response-fields} | Fält | Typ | Beskrivning | |-------|------|-------------| | totalImages | number | Antal bilder som analyserats framgångsrikt | | duplicateGroups | array | Grupper av dubblettbilder | | uniqueImages | number | Antal bilder som inte ingår i någon dubblettgrupp | | spaceSaveable | number | Totalt antal byte som kan sparas genom att ta bort dubbletter som inte är bäst | | skippedFiles | array | Filer som inte kunde bearbetas (med filnamn och orsak) | ### Objekt för dubblettgrupp {#duplicate-group-object} | Fält | Typ | Beskrivning | |-------|------|-------------| | groupId | number | Gruppidentifierare | | files | array | Bilder i denna dubblettgrupp | ### Filobjekt (inom en grupp) {#file-object-within-a-group} | Fält | Typ | Beskrivning | |-------|------|-------------| | filename | string | Ursprungligt filnamn | | similarity | number | Likhetsprocent i förhållande till referensbilden (den första i gruppen) | | width | number | Bildbredd i pixlar | | height | number | Bildhöjd i pixlar | | fileSize | number | Filstorlek i byte | | format | string | Bildformat | | isBest | boolean | Om detta är versionen med högst kvalitet (flest pixlar, störst fil) | | thumbnail | string eller null | Base64 JPEG-miniatyr (200px bred) för förhandsvisning | ## Anmärkningar {#notes} * Använder en 128-bitars dHash (64-bitars rad + 64-bitars kolumn) för perceptuell likhetsdetektering. Detta fångar dubbletter även vid storleksändringar, omkomprimering och mindre redigeringar. * Tröskelvärdet representerar det maximala Hamming-avståndet mellan hashvärden. Standardvärdet 8 fångar nästan identiska bilder samtidigt som falska positiva undviks. Använd 0 för endast pixelidentiska, eller 15-20 för mycket lös matchning. * Den "bästa" bilden i varje grupp är den med flest pixlar (bredd x höjd), med filstorlek som avgörande faktor vid lika resultat. * Minst 2 bilder krävs. Filer som misslyckas med validering eller avkodning rapporteras i `skippedFiles` i stället för att få hela begäran att misslyckas. * Miniatyrer är 200px breda JPEG-förhandsvisningar kodade som data-URI:er. * Alla vanliga format stöds (HEIC, RAW, PSD, SVG avkodas automatiskt). --- --- url: https://docs.snapotter.com/es/tools/image/sprite-sheet.md description: >- Combina varias imágenes en una sola hoja de sprites en cuadrícula con metadatos de fotogramas. --- # Hoja de sprites {#sprite-sheet} Combina varias imágenes en una sola hoja de sprites en cuadrícula. Cada imagen se redimensiona para coincidir con las dimensiones de la primera imagen y se coloca en la cuadrícula. Devuelve la imagen de la hoja de sprites junto con metadatos de coordenadas por fotograma. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/image/sprite-sheet` Acepta datos de formulario multipart con dos o más archivos de imagen y un campo `settings` en JSON. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | columns | integer | No | `4` | Número de columnas en la cuadrícula (1-16) | | padding | integer | No | `0` | Relleno entre celdas en píxeles (0-64) | | background | string | No | `"#ffffff"` | Color de fondo en hexadecimal | | format | string | No | `"png"` | Formato de salida: `png`, `webp` o `jpeg` | | quality | integer | No | `90` | Calidad de salida (1-100) | ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/image/sprite-sheet \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@frame1.png" \ -F "file=@frame2.png" \ -F "file=@frame3.png" \ -F "file=@frame4.png" \ -F 'settings={"columns": 2, "padding": 4, "format": "png"}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sprite-sheet.png", "originalSize": 120000, "processedSize": 95000, "frames": [ { "index": 0, "left": 0, "top": 0, "width": 128, "height": 128 }, { "index": 1, "left": 132, "top": 0, "width": 128, "height": 128 }, { "index": 2, "left": 0, "top": 132, "width": 128, "height": 128 }, { "index": 3, "left": 132, "top": 132, "width": 128, "height": 128 } ], "cols": 2, "rows": 2, "cellWidth": 128, "cellHeight": 128, "canvasWidth": 260, "canvasHeight": 260 } ``` ## Notas {#notes} * Acepta de 2 a 64 imágenes. Todas las imágenes se redimensionan para coincidir con las dimensiones de la primera imagen subida. * El arreglo `frames` proporciona las coordenadas exactas en píxeles de cada fotograma en la salida, aptas para definiciones de sprites CSS o mapas de fotogramas de motores de juegos. * El número de filas se calcula automáticamente a partir del recuento de imágenes y el valor de `columns`. * Usa el parámetro `padding` para agregar espacio entre celdas. El color `background` es visible en las áreas de relleno y en cualquier celda final vacía. * Las entradas HEIC, RAW, PSD y SVG se decodifican automáticamente antes del procesamiento. --- --- url: https://docs.snapotter.com/es/tools/image/html-to-image.md description: >- Captura páginas web o fragmentos de HTML como imágenes de alta calidad con emulación de dispositivos. --- # HTML a imagen {#html-to-image} Captura la URL de una página web o contenido HTML sin procesar como una imagen de captura de pantalla. Admite emulación de dispositivos (escritorio, tableta, móvil), captura de página completa y varios formatos de salida. ## Endpoint de la API {#api-endpoint} `POST /api/v1/tools/image/html-to-image` Acepta un **cuerpo JSON** (no multipart). No es necesario subir ningún archivo. ## Parámetros {#parameters} | Parámetro | Tipo | Obligatorio | Predeterminado | Descripción | |-----------|------|----------|---------|-------------| | url | string | Condicional | - | URL a capturar (debe ser una URL válida) | | html | string | Condicional | - | Contenido HTML sin procesar a renderizar (1 a 5.000.000 de caracteres) | | format | string | No | `"png"` | Formato de salida: `jpg`, `png`, `webp` | | quality | number | No | `90` | Calidad de salida para formatos con pérdidas (1 a 100) | | fullPage | boolean | No | `false` | Captura la página completa con desplazamiento, no solo la ventana visible | | devicePreset | string | No | `"desktop"` | Emulación de dispositivo: `desktop`, `tablet`, `mobile`, `custom` | | viewportWidth | number | No | `1280` | Ancho de la ventana visible personalizado en píxeles (320 a 3840, se usa cuando devicePreset es `custom`) | | viewportHeight | number | No | `720` | Alto de la ventana visible personalizado en píxeles (320 a 2160, se usa cuando devicePreset es `custom`) | Debe proporcionarse `url` o `html`, pero no ambos. ### Preajustes de dispositivo {#device-presets} | Preajuste | Ancho | Alto | UA móvil | |--------|-------|--------|-----------| | `desktop` | 1280 | 720 | No | | `tablet` | 768 | 1024 | No | | `mobile` | 375 | 812 | Sí | | `custom` | (especificado por el usuario) | (especificado por el usuario) | No | ## Ejemplo de solicitud {#example-request} Capturar una página web: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com", "format": "png", "fullPage": true, "devicePreset": "desktop"}' ``` Renderizar contenido HTML: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"html": "

Hello

", "format": "png"}' ``` ## Ejemplo de respuesta {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 0, "processedSize": 145000 } ``` ## Notas {#notes} * Requiere que Chromium esté instalado en el servidor. Devuelve HTTP 503 si el servicio del navegador no está disponible. * Las URL se validan contra ataques SSRF (las direcciones de red privadas/internas están bloqueadas). * Este endpoint tiene un límite de 120 solicitudes por hora. * `originalSize` siempre es 0 ya que esta herramienta genera imágenes a partir de URL/HTML. * El nombre del archivo de salida es `screenshot.`. * Si la página tarda demasiado en cargar, la solicitud devuelve HTTP 504 (tiempo de espera de la puerta de enlace agotado). * Si el servicio del navegador se bloquea repetidamente, se desactiva temporalmente y devuelve HTTP 503 con el código `BROWSER_CRASHED`. --- --- url: https://docs.snapotter.com/es/tools/files/html-to-pdf.md description: Convierte un archivo HTML a PDF. --- # HTML a PDF {#html-to-pdf} Convierte un archivo HTML en un documento PDF con estilos. Los recursos remotos (imágenes, hojas de estilo y scripts externos) están deshabilitados por privacidad. ## API Endpoint {#api-endpoint} `POST /api/v1/tools/files/html-to-pdf` Acepta datos de formulario multipart con un archivo HTML. ## Parámetros {#parameters} Esta herramienta no tiene parámetros configurables. Sube un archivo HTML y se convertirá a PDF. ## Ejemplo de solicitud {#example-request} ```bash curl -X POST http://localhost:1349/api/v1/tools/files/html-to-pdf \ -H "Authorization: Bearer si_your-api-key" \ -F "file=@page.html" ``` ## Ejemplo de respuesta {#example-response} Devuelve `202 Accepted`. Sigue el progreso mediante SSE en `/api/v1/jobs/{jobId}/progress`. ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "async": true } ``` ## Notas {#notes} * Formatos de entrada aceptados: `.html`, `.htm`. * Los recursos remotos (imágenes, hojas de estilo y scripts referenciados mediante URL) no se descargan por privacidad y seguridad. * Los estilos en línea y las imágenes incrustadas (data URI) se conservan. * La conversión la gestiona WeasyPrint en el servidor. --- --- url: https://docs.snapotter.com/it/tools/image/html-to-image.md description: >- Cattura pagine web o snippet HTML come immagini di alta qualità con emulazione dei dispositivi. --- # HTML in Immagine {#html-to-image} Cattura un URL di una pagina web o contenuto HTML grezzo come immagine screenshot. Supporta l'emulazione dei dispositivi (desktop, tablet, mobile), la cattura dell'intera pagina e più formati di output. ## Endpoint API {#api-endpoint} `POST /api/v1/tools/image/html-to-image` Accetta un **corpo JSON** (non multipart). Non è necessario alcun caricamento di file. ## Parametri {#parameters} | Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | |-----------|------|----------|---------|-------------| | url | string | Condizionale | - | URL da catturare (deve essere un URL valido) | | html | string | Condizionale | - | Contenuto HTML grezzo da renderizzare (da 1 a 5.000.000 caratteri) | | format | string | No | `"png"` | Formato di output: `jpg`, `png`, `webp` | | quality | number | No | `90` | Qualità dell'output per formati con perdita (da 1 a 100) | | fullPage | boolean | No | `false` | Cattura l'intera pagina scorrevole, non solo il viewport | | devicePreset | string | No | `"desktop"` | Emulazione del dispositivo: `desktop`, `tablet`, `mobile`, `custom` | | viewportWidth | number | No | `1280` | Larghezza personalizzata del viewport in pixel (da 320 a 3840, usata quando devicePreset è `custom`) | | viewportHeight | number | No | `720` | Altezza personalizzata del viewport in pixel (da 320 a 2160, usata quando devicePreset è `custom`) | Deve essere fornito `url` oppure `html`, ma non entrambi. ### Preset dei Dispositivi {#device-presets} | Preset | Larghezza | Altezza | UA Mobile | |--------|-------|--------|-----------| | `desktop` | 1280 | 720 | No | | `tablet` | 768 | 1024 | No | | `mobile` | 375 | 812 | Sì | | `custom` | (specificato dall'utente) | (specificato dall'utente) | No | ## Richiesta di Esempio {#example-request} Cattura una pagina web: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com", "format": "png", "fullPage": true, "devicePreset": "desktop"}' ``` Renderizza contenuto HTML: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"html": "

Hello

", "format": "png"}' ``` ## Risposta di Esempio {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 0, "processedSize": 145000 } ``` ## Note {#notes} * Richiede che Chromium sia installato sul server. Restituisce HTTP 503 se il servizio del browser non è disponibile. * Gli URL vengono validati contro attacchi SSRF (gli indirizzi di rete privati/interni sono bloccati). * Questo endpoint è soggetto a un limite di 120 richieste all'ora. * `originalSize` è sempre 0 poiché questo strumento genera immagini da URL/HTML. * Il nome file di output è `screenshot.`. * Se il caricamento della pagina richiede troppo tempo, la richiesta restituisce HTTP 504 (gateway timeout). * Se il servizio del browser va in crash ripetutamente, viene temporaneamente disabilitato e restituisce HTTP 503 con codice `BROWSER_CRASHED`. --- --- url: https://docs.snapotter.com/pl/tools/image/html-to-image.md description: >- Przechwytuj strony internetowe lub fragmenty HTML jako obrazy wysokiej jakości z emulacją urządzeń. --- # HTML na obraz {#html-to-image} Przechwyć adres URL strony internetowej lub surową zawartość HTML jako obraz zrzutu ekranu. Obsługuje emulację urządzeń (komputer stacjonarny, tablet, telefon), przechwytywanie całej strony i wiele formatów wyjściowych. ## Punkt końcowy API {#api-endpoint} `POST /api/v1/tools/image/html-to-image` Przyjmuje **treść JSON** (nie multipart). Nie jest wymagane przesyłanie pliku. ## Parametry {#parameters} | Parametr | Typ | Wymagany | Domyślnie | Opis | |-----------|------|----------|---------|-------------| | url | string | Warunkowo | - | Adres URL do przechwycenia (musi być prawidłowym adresem URL) | | html | string | Warunkowo | - | Surowa zawartość HTML do wyrenderowania (1 do 5 000 000 znaków) | | format | string | Nie | `"png"` | Format wyjściowy: `jpg`, `png`, `webp` | | quality | number | Nie | `90` | Jakość wyjściowa dla formatów stratnych (1 do 100) | | fullPage | boolean | Nie | `false` | Przechwyć całą przewijalną stronę, a nie tylko widoczny obszar | | devicePreset | string | Nie | `"desktop"` | Emulacja urządzenia: `desktop`, `tablet`, `mobile`, `custom` | | viewportWidth | number | Nie | `1280` | Niestandardowa szerokość widoku w pikselach (320 do 3840, używana gdy devicePreset to `custom`) | | viewportHeight | number | Nie | `720` | Niestandardowa wysokość widoku w pikselach (320 do 2160, używana gdy devicePreset to `custom`) | Należy podać albo `url`, albo `html`, ale nie oba naraz. ### Presety urządzeń {#device-presets} | Preset | Szerokość | Wysokość | Mobilny UA | |--------|-------|--------|-----------| | `desktop` | 1280 | 720 | Nie | | `tablet` | 768 | 1024 | Nie | | `mobile` | 375 | 812 | Tak | | `custom` | (określone przez użytkownika) | (określone przez użytkownika) | Nie | ## Przykładowe żądanie {#example-request} Przechwyć stronę internetową: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com", "format": "png", "fullPage": true, "devicePreset": "desktop"}' ``` Wyrenderuj zawartość HTML: ```bash curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \ -H "Authorization: Bearer si_your-api-key" \ -H "Content-Type: application/json" \ -d '{"html": "

Hello

", "format": "png"}' ``` ## Przykładowa odpowiedź {#example-response} ```json { "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/screenshot.png", "originalSize": 0, "processedSize": 145000 } ``` ## Uwagi {#notes} * Wymaga zainstalowania Chromium na serwerze. Zwraca HTTP 503, jeśli usługa przeglądarki jest niedostępna. * Adresy URL są walidowane pod kątem ataków SSRF (adresy sieci prywatnej/wewnętrznej są blokowane). * Ten punkt końcowy jest ograniczony do 120 żądań na godzinę. * `originalSize` zawsze wynosi 0, ponieważ to narzędzie generuje obrazy z adresów URL/HTML. * Nazwa pliku wyjściowego to `screenshot.`. * Jeśli wczytanie strony trwa zbyt długo, żądanie zwraca HTTP 504 (przekroczenie limitu czasu bramy). * Jeśli usługa przeglądarki wielokrotnie ulega awarii, jest tymczasowo wyłączana i zwraca HTTP 503 z kodem `BROWSER_CRASHED`. --- --- url: https://docs.snapotter.com/nl/tools/image/html-to-image.md description: >- Leg webpagina's of HTML-fragmenten vast als hoogwaardige afbeeldingen met apparaatemulatie. --- # HTML naar afbeelding {#html-to-image} Leg een webpagina-URL of ruwe HTML-inhoud vast als een schermafbeelding. Ondersteunt apparaatemulatie (desktop, tablet, mobiel), vas