NAV
python shell

Introduction

Hi, developers, welcome to use Dewatermark's API. The following are some basic introductions to your access service. Hope you can find the AI ​​technology capabilities that are suitable for your business here. Thank you for using!

Authentication

To authorize, use this code:

import requests

API_KEY = "YOUR_API_KEY"
headers = {
    "X-API-KEY": API_KEY
}

# Make API request
response = requests.get(
    "https://platform.dewatermark.ai/api/object_removal/v1/erase_watermark",
    headers=headers
)
# With shell, you can just pass the correct header with each request
curl "https://platform.dewatermark.ai/api/object_removal/v1/erase_watermark" \
  -H "X-API-KEY: <API-KEY>"

Make sure to replace <API-KEY> with your API key.

Dewatermark uses API keys to allow access to the API. You can receive your unique API key by signing up and opening API managent page).

The API key must be included in all API requests to the server in a header that looks like the following:

X-API-KEY: API_KEY

Image Processing API

Remove Watermark

Remove Watermark

import requests
import base64
import uuid
import os
from io import BytesIO


def erase_watermark(original_preview_image=None, mask_base=None, mask_brush=None, session_id=None, remove_text="true"):
    API_KEY = "YOUR_API_KEY"
    erase_url = "https://platform.dewatermark.ai/api/object_removal/v1/erase_watermark"
    headers = {
        "X-API-KEY": API_KEY
    }
    erase_files = {}

    if original_preview_image is not None:
        if isinstance(original_preview_image, str) and os.path.isfile(original_preview_image):
            image_file = open(original_preview_image, "rb")
            file_original_preview_image = ("original_preview_image.jpeg", image_file)
        else:
            image_bytes = base64.b64decode(original_preview_image)
            image_file = BytesIO(image_bytes)
            file_original_preview_image = ("original_preview_image.jpeg", image_file)
        erase_files["original_preview_image"] = file_original_preview_image
    else:
        if session_id is not None:
            erase_files["session_id"] = (None, session_id)
        else:
            raise ValueError("Either original_preview_image or session_id must be provided.")


    if mask_base is not None:
        image_bytes = base64.b64decode(mask_base)
        image_file = BytesIO(image_bytes)
        file_mask_base = ("mask_base.jpeg", image_file)

    if mask_brush is not None:
        image_file = open(mask_brush, "rb")
        file_mask_brush = ("mask_brush.png", image_file)


    if original_preview_image is not None:
        erase_files["original_preview_image"] = file_original_preview_image

    if mask_base is not None:
        erase_files["mask_base"] = file_mask_base

    if mask_brush is not None:
        erase_files["mask_brush"] = file_mask_brush

    erase_files["remove_text"] = (None, remove_text)

    erase_response = requests.post(erase_url, headers=headers, files=erase_files)

    response_data = erase_response.json()
    return {
        "session_id": response_data["session_id"],
        "image_base64": response_data["edited_image"]["image"],
        "mask_base": response_data["edited_image"]["mask"]
    }

# Initial call: Automatically detect and remove visible watermarks using AI
auto_result = erase_watermark("input.jpeg")

# Optional: Uncomment this line to preview the auto-processed result (Base64-encoded image)
# print(auto_result["image_base64"])

# Manual refinement: If some watermarks remain, manually specify areas to remove using a brush mask
manual_result_step_1 = erase_watermark(
    original_preview_image=auto_result["image_base64"],
    mask_base=auto_result["mask_base"],
    mask_brush="mask_brush_manual_step_1.png"
)

# Optional: Uncomment this line to preview the result after first manual correction
# print(manual_result_step_1["image_base64"])

# Optimization: On subsequent calls, use session_id instead of re-uploading the original image
manual_result_step_2 = erase_watermark(
    session_id=manual_result_step_1["session_id"],
    mask_base=manual_result_step_1["mask_base"],
    mask_brush="mask_brush_manual_step_2.png"
)

# Output the final cleaned image (Base64 format)
print(manual_result_step_2["image_base64"])
curl -X POST "https://platform.dewatermark.ai/api/object_removal/v1/erase_watermark" \
  -H "X-API-KEY: API_KEY" \
  --form 'session_id="SESSION_ID"' \
  --form 'original_preview_image=@"IMAGE_FILE"' \
  --form 'mask_base=@"MASK_BASE_FILE"'\
  --form 'mask_brush=@"MASK_BRUSH_FILE"' \
  --form 'remove_text="true"'

This API allows you to remove watermark from an image and seamlessly inpaint the erased area to blend it naturally with the surrounding background. Each remove watermark image API call is counted as 1 credits.

The above command returns JSON structured like this:

{
  "edited_image": {
    "image": "BASE_64_IMAGE",
    "image_id": "image_id",
    "mask": "BASE64_MASK",
    "watermark_mask":"BASE64_MASK"
  },
  "event_id": "event_id",
  "session_id": "session_id"
}

HTTP Request

POST https://platform.dewatermark.ai/api/object_removal/v1/erase_watermark

Request body

Form Required Type Description
original_preview_image Optional binary The input image, it should be a JPEG image and the largest dimension is not greater than 1408 px.
session_id Optional text The session id, it represents the current image.
mask_base Optional text The masked image of the previously erased parts.
mask_brush Optional binary The mask image for the Remove Object API should include a binary representation of the unwanted object's outline, delineating the area to be removed and inpainted.
remove_text Optional text If set to 'true', enables the text removal feature for improved results when removing purely textual watermarks. Note that this may remove all text from your image.

In the request form data, while either original_preview_image or session_id parameter is required, it is recommended to include session_id if it's already available.

The inital request doesn't require mask_base and mask_brush.

Response

Property Description
edited_image.image The result after removing object, it it's a base64 encoded image.
edited_image.watermark_mask This is the masked image of all previously erased parts.

Continuing Watermark Removal with Manual Refinement

Here's a complete example that demonstrates the watermark removal process with automatic detection and manual refinement:

The process works as follows:

  1. Initial Input Image Input Image

  2. Automatic Watermark Detection and Removal Auto-processed Result

  3. First Manual Correction First Manual Mask After First Manual Correction

  4. Second Manual Correction Second Manual Mask Final Result

This example demonstrates the complete workflow for removing watermarks: 1. Start with automatic watermark detection and removal 2. If needed, perform manual corrections using brush masks 3. Use session_id for subsequent refinements to optimize the process

The images show the progression from the original image through each step of the watermark removal process, including the manual masks used for refinement.

Even after the initial API call, you can achieve even more precise results by manually specifying the remaining watermark area you want to erase. Here's the process:

Manual Selection: Define a mask that isolates the specific part of the image containing the remaining watermark or unwanted element. This mask acts as a guide for the API.

API Call with Session ID and Mask: Make a subsequent API call to remove the designated area. Remember to include these important parameters:

original_preview_image: The output image (edited_image.image) from the previous automatic Watermark removal. For the first manual refinement, you must send this output image from the initial API call. It should be a JPEG image, and the largest dimension is not greater than 1920.

session_id: This unique identifier is generated during the initial watermark removal process. It allows the API to link your refinement request to the specific image you're working on. In the second manual refinement, you must use this session_id instead of original_preview_image.

mask_brush: This parameter allows you to provide a new, more refined mask that focuses on the remaining watermark area you want to erase.

remove_text: If you want to enable the text removal feature, set remove_text to 'true' in the request body to remove text from the image. If the watermark is purely text, enable the text remover for improved results. Note that this may remove all text from your image.

By following these steps, you can iteratively remove watermarks and achieve a highly refined final image.

Save Image

import requests
import base64
import uuid
import os
from io import BytesIO


def erase_watermark(original_preview_image=None, remove_text="true"):
    API_KEY = "YOUR_API_KEY"
    erase_url = "https://platform.dewatermark.ai/api/object_removal/v1/erase_watermark"
    headers = {
        "X-API-KEY": API_KEY
    }
    erase_files = {}

    if original_preview_image is not None:
        if isinstance(original_preview_image, str) and os.path.isfile(original_preview_image):
            image_file = open(original_preview_image, "rb")
            file_original_preview_image = ("original_preview_image.jpeg", image_file)
        else:
            image_bytes = base64.b64decode(original_preview_image)
            image_file = BytesIO(image_bytes)
            file_original_preview_image = ("original_preview_image.jpeg", image_file)
        erase_files["original_preview_image"] = file_original_preview_image


    erase_files["remove_text"] = (None, remove_text)

    erase_response = requests.post(erase_url, headers=headers, files=erase_files)

    response_data = erase_response.json()
    return {
        "session_id": response_data["session_id"],
        "preview_image_to_save": response_data["edited_image"]["image"],
        "preview_mask_to_save": response_data["edited_image"]["watermark_mask"]
    }

def save_large_image(original_large_image=None, preview_image_to_save=None,preview_mask_to_save=None,session_id=None,remove_text="true"):
    API_KEY = "YOUR_API_KEY"
    erase_url = "https://platform.dewatermark.ai/api/object_removal/v1/save_large_image"
    headers = {
        "X-API-KEY": API_KEY
    }
    erase_files = {}

    if original_large_image is not None:
        if isinstance(original_large_image, str) and os.path.isfile(original_large_image):
            image_file = open(original_large_image, "rb")
            file_original_large_image = ("original_large_image.jpeg", image_file)
        else:
            image_bytes = base64.b64decode(original_large_image)
            image_file = BytesIO(image_bytes)
            file_original_large_image = ("original_large_image.jpeg", image_file)
        erase_files["original_large_image"] = file_original_large_image


    if preview_image_to_save is not None:
        image_bytes = base64.b64decode(preview_image_to_save)
        image_file = BytesIO(image_bytes)
        file_preview_image_to_save = ("preview_image_to_save.jpeg", image_file)
        erase_files["preview_image_to_save"] = file_preview_image_to_save 

    if preview_mask_to_save is not None:
        image_bytes = base64.b64decode(preview_mask_to_save)
        image_file = BytesIO(image_bytes)
        file_preview_mask_to_save = ("preview_mask_to_save.jpeg", image_file) 
        erase_files["preview_mask_to_save"] = file_preview_mask_to_save 

    erase_files["remove_text"] = (None, remove_text)
    erase_files["session_id"] = (None, session_id)


    erase_response = requests.post(erase_url, headers=headers, files=erase_files)

    response_data = erase_response.json()

    return {
        "large_image_to_save": response_data["large_image_to_save"]
    }


erase_watermark_result = erase_watermark("input.jpeg")

save_large_image_result = save_large_image(
    original_large_image="input.jpeg",
    session_id=erase_watermark_result["session_id"],
    preview_image_to_save=erase_watermark_result["preview_image_to_save"],
    preview_mask_to_save=erase_watermark_result["preview_mask_to_save"],
)

print(save_large_image_result['large_image_to_save'])
curl -X POST "https://platform.dewatermark.ai/api/object_removal/v1/save_large_image" \
  -H "X-API-KEY: API_KEY" \
  --form 'session_id="SESSION_ID"' \
  --form 'preview_image_to_save=@"IMAGE_FILE"' \
  --form 'preview_mask_to_save=@"MASK_BRUSH_FILE"' \
  --form 'original_large_image=@"ORIGINAL_IMAGE_FILE"' \
  --form 'remove_text="true"'

This API enables you to save the image from the remove watermark API with a higher resolution, up to 4000px. If your image is smaller than 1408, you don't need to utilize this API.

Each save image API call is counted as 2 credits.

Request body

Form Required Type Description
original_preview_image Optional binary The input image, it should be a JPEG image and the largest dimension is not greater than 1408px.
preview_mask_to_save Required text The masked image of the erased parts, you should use the edited_image.watermark_mask from the previous response.
preview_image_to_save Required binary The image was removed watermark, you should use the edited_image.image from the previous response, the largest dimension is not greater than 1920px
original_large_image Required text The original image, and the largest dimension is not greater than 4000px.

The above command returns JSON structured like this:

{
    "event_id": "event_id",
    "large_image_to_save": "BASE64_IMAGE",
    "session_id": "session_id"
}

large_image_to_save is the final output, it's a base64 image, you can encode it back to JPEG image.

Errors

The Kittn API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The kitten requested is hidden for administrators only.
404 Not Found -- The specified kitten could not be found.
405 Method Not Allowed -- You tried to access a kitten with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The kitten requested has been removed from our servers.
418 I'm a teapot.
429 Too Many Requests -- You're requesting too many kittens! Slow down!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.