{
  "openapi": "3.1.1",
  "info": {
    "title": "Image Upscaler API",
    "version": "1.0.0",
    "summary": "Enlarge images 2×, 3× or 4× with classic Lanczos/Mitchell filters and sharpening (no AI).",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://imageupscaler.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Enlarge images 2×, 3× or 4× with classic Lanczos/Mitchell filters and sharpening (no AI).",
        "description": "Enlarges a small image by 2, 3 or 4 times (up to 16 megapixels) with high-quality classic resampling filters, optional noise reduction before and unsharp-mask sharpening after. A side-by-side crop compares plain pixel enlargement with the result. This is classic interpolation, not an AI upscaler: it cannot invent detail that is not in the original.\n\nMethodology:\n- Classic (non-AI) upscaling: every new pixel is a weighted average of nearby original pixels. Lanczos, Mitchell and Catmull-Rom are separable windowed filters; \"EWA Lanczos Sharp\" uses a cylindrical (elliptical weighted average) filter that produces fewer staircase artefacts on diagonal edges.\n- Optional noise reduction runs before enlarging (so noise is not magnified): despeckle, enhance or a 3×3 median. Optional unsharp-mask sharpening runs after enlarging to counter the softness that interpolation causes.\n- The image is turned upright from its EXIF orientation, resized in linear light (to avoid darkened edges), converted back to sRGB and encoded. The output is limited to 16 megapixels.\n- What AI upscalers do differently: models such as Real-ESRGAN or SwinIR are neural networks trained on millions of image pairs. They hallucinate plausible texture (hair, foliage, text strokes) that is not in the original. That looks sharper, but it can invent wrong details, alter faces and change text. Classic filters never add information; they only interpolate it, so results look softer but stay faithful.\n\nEnlarging cannot recover detail that was never captured. For prints, prefer the original high-resolution file if you have it.",
        "tags": [
          "media"
        ],
        "x-mcp-tool": "image_upscaler",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageUpscalerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Small logo 4× with Lanczos and light sharpening",
                  "value": {
                    "file": {
                      "filename": "logo.png",
                      "contentType": "image/png",
                      "contentBase64": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQMAAAA26i3WAAAABlBMVEX4+PgWUvBKqxVnAAAAEklEQVQI12NgQAP8/z/gxWgAAPdHD/H1HpIcAAAAAElFTkSuQmCC"
                    },
                    "factor": "4",
                    "filter": "lanczos",
                    "sharpen": "light",
                    "format": "png"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageUpscalerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ImageUpscalerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "Image",
            "description": "JPG, PNG, WebP, AVIF, GIF, TIFF or HEIC, max 50 MB. The enlarged result may be at most 16 megapixels. Upload as {filename, contentType?, contentBase64}. Max 51200 KiB. Accepts .jpg,.jpeg,.png,.webp,.avif,.gif,.tif,.tiff,.heic,.heif,image/jpeg,image/png,image/webp,image/avif,image/gif,image/tiff,image/heic,image/heif.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "factor": {
            "title": "Scale factor",
            "type": "string",
            "enum": [
              "2",
              "3",
              "4"
            ],
            "default": "2"
          },
          "filter": {
            "title": "Resampling filter",
            "type": "string",
            "enum": [
              "lanczos",
              "mitchell",
              "catrom",
              "ewa"
            ],
            "default": "lanczos"
          },
          "sharpen": {
            "title": "Sharpening after enlarging",
            "type": "string",
            "enum": [
              "none",
              "light",
              "medium",
              "strong"
            ],
            "default": "light"
          },
          "denoise": {
            "title": "Noise reduction before enlarging",
            "type": "string",
            "enum": [
              "none",
              "despeckle",
              "enhance",
              "median"
            ],
            "default": "none"
          },
          "format": {
            "title": "Output format",
            "type": "string",
            "enum": [
              "png",
              "jpeg",
              "webp"
            ],
            "default": "png"
          },
          "quality": {
            "title": "Quality",
            "description": "For JPG and WebP.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 92
          }
        },
        "required": [
          "file"
        ]
      },
      "ImageUpscalerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "factor",
              "filter",
              "sharpen",
              "denoise",
              "originalWidth",
              "originalHeight",
              "width",
              "height",
              "megapixels",
              "originalBytes",
              "outputBytes",
              "outputFormat",
              "method",
              "artifact",
              "comparison"
            ],
            "properties": {
              "factor": {
                "type": "integer"
              },
              "filter": {
                "type": "string"
              },
              "sharpen": {
                "type": "string"
              },
              "denoise": {
                "type": "string"
              },
              "originalWidth": {
                "type": "integer"
              },
              "originalHeight": {
                "type": "integer"
              },
              "width": {
                "type": "integer"
              },
              "height": {
                "type": "integer"
              },
              "megapixels": {
                "type": "number"
              },
              "originalBytes": {
                "type": "integer"
              },
              "outputBytes": {
                "type": "integer"
              },
              "outputFormat": {
                "type": "string"
              },
              "method": {
                "type": "string",
                "enum": [
                  "classic-interpolation"
                ]
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "comparison": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                },
                "description": "PNG with a centre crop: left nearest-neighbour enlargement, right this result."
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}