India API

Docs › Files, documents and media

Image tools API

Resize and convert pictures, remove backgrounds, and compare pictures by how they look.

Upload a picture and get it back resized or in another format (WebP, AVIF, JPEG, PNG), with its background removed, or as a fingerprint for finding duplicates. HEIC photos from iPhones are read too. Metadata such as the GPS position is always removed. Pictures are processed and deleted; nothing is kept or logged.

Base URL https://api.dharun.devNo API key600 requests a minuteThis page as Markdown

Resize and convert a picture

POST/v1/image/convert

Returns the picture itself, turned upright from its EXIF orientation, without metadata. fit=inside keeps the whole picture within width and height and never enlarges it; cover fills the box and crops the middle; fill stretches. Options go in the query string, or as form fields when the file is sent as multipart/form-data.

Send: A picture: JPEG, PNG, WebP, HEIC, AVIF, GIF, BMP or TIFF, up to 10 MB. Post the file as the request body, or as multipart/form-data. Try it with this sample.

The answer returns the image itself; errors are JSON as everywhere else.

What you send here is never written to the log, and the answer is not cached.

ParameterDescription
formatqueryOutput format. Default webp. One of: jpeg, png, webp, avif, gif, tiff.
widthqueryWidth in pixels, 1 to 8000.
heightqueryHeight in pixels, 1 to 8000.
fitqueryHow the picture fits width and height. Default inside. One of: inside, cover, fill.
qualityqueryJPEG, WebP and AVIF quality, 1 to 100. Default 80.

curl

# a sample to try: https://api.dharun.dev/samples/photo.jpg
curl -F "[email protected]" -o out.webp "https://api.dharun.dev/v1/image/convert?format=webp&width=400"

JavaScript

// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/image/convert?format=webp&width=400", { method: "POST", body: form });
if (!response.ok) throw new Error((await response.json()).error.message);
const file = await response.blob();

Python

import requests

files = [("file", open("photo.jpg", "rb"))]
response = requests.post("https://api.dharun.dev/v1/image/convert?format=webp&width=400", files=files, timeout=90)
if not response.ok:
    raise RuntimeError(response.json()["error"]["message"])
open("out.webp", "wb").write(response.content)

Size, format and metadata of a picture

POST/v1/image/info

Format, size, colour space, pages, orientation, the camera, and whether the picture carries EXIF data or a GPS position.

Send: A picture: JPEG, PNG, WebP, HEIC, AVIF, GIF, BMP or TIFF, up to 10 MB. Post the file as the request body, or as multipart/form-data. Try it with this sample.

What you send here is never written to the log, and the answer is not cached.

curl

# a sample to try: https://api.dharun.dev/samples/photo.jpg
curl -F "[email protected]" "https://api.dharun.dev/v1/image/info"

JavaScript

// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/image/info", { method: "POST", body: form });
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);

Python

import requests

files = [("file", open("photo.jpg", "rb"))]
response = requests.post("https://api.dharun.dev/v1/image/info", files=files, timeout=90)
body = response.json()
if not response.ok:
    raise RuntimeError(body["error"]["message"])
print(body["data"])

Response

{
  "data": {
    "format": "jpeg",
    "width": 853,
    "height": 640,
    "bands": 3,
    "alpha": false,
    "colour_space": "srgb",
    "pages": 1,
    "orientation": 1,
    "has_exif": false,
    "has_location": false,
    "bytes": 16053
  },
  "meta": {}
}

Remove the background

POST/v1/image/remove-background

Returns the picture as a PNG with the background transparent, cut out by the IS-Net model. Works best on one clear subject: a product, a person, an animal. Takes a few seconds; pictures larger than 4096 pixels are made smaller. Options go in the query string, or as form fields when the file is sent as multipart/form-data.

Send: A picture: JPEG, PNG, WebP, HEIC, AVIF, GIF, BMP or TIFF, up to 10 MB. Post the file as the request body, or as multipart/form-data. Try it with this sample.

The answer returns the image itself; errors are JSON as everywhere else.

What you send here is never written to the log, and the answer is not cached.

ParameterDescription
formatquerypng (default), webp, or mask: the cut-out mask alone, white where the subject is. One of: png, webp, mask.

curl

# a sample to try: https://api.dharun.dev/samples/photo.jpg
curl -F "[email protected]" -o out.png "https://api.dharun.dev/v1/image/remove-background"

JavaScript

// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/image/remove-background", { method: "POST", body: form });
if (!response.ok) throw new Error((await response.json()).error.message);
const file = await response.blob();

Python

import requests

files = [("file", open("photo.jpg", "rb"))]
response = requests.post("https://api.dharun.dev/v1/image/remove-background", files=files, timeout=90)
if not response.ok:
    raise RuntimeError(response.json()["error"]["message"])
open("out.png", "wb").write(response.content)

Perceptual hash of a picture

POST/v1/image/hash

Three 64-bit fingerprints (average, difference and DCT-based perceptual hashes) that stay nearly the same when a picture is resized, recompressed or slightly edited. Pictures whose perceptual hashes differ by 10 bits or fewer look alike.

Send: A picture: JPEG, PNG, WebP, HEIC, AVIF, GIF, BMP or TIFF, up to 10 MB. Post the file as the request body, or as multipart/form-data. Try it with this sample.

What you send here is never written to the log, and the answer is not cached.

curl

# a sample to try: https://api.dharun.dev/samples/photo.jpg
curl -F "[email protected]" "https://api.dharun.dev/v1/image/hash"

JavaScript

// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/image/hash", { method: "POST", body: form });
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);

Python

import requests

files = [("file", open("photo.jpg", "rb"))]
response = requests.post("https://api.dharun.dev/v1/image/hash", files=files, timeout=90)
body = response.json()
if not response.ok:
    raise RuntimeError(body["error"]["message"])
print(body["data"])

Response

{
  "data": {
    "average": "fff3e7c3c3c3c300",
    "difference": "16660c9696868e30",
    "perceptual": "e4cc9b3199939393",
    "width": 853,
    "height": 640
  },
  "meta": {
    "note": "Hex 64-bit hashes. Compare two pictures by counting the bits that differ: up to about 10 of 64 means they look alike."
  }
}

Compare two pictures

POST/v1/image/compare

Send two pictures as form fields. Returns the bits by which each hash differs, a score from 0 to 1, and whether they look like the same picture.

Send: Two pictures, as multipart/form-data, up to 10 MB each. Post the file as the request body, or as multipart/form-data with one field per file. Try it with this sample.

What you send here is never written to the log, and the answer is not cached.

curl

# a sample to try: https://api.dharun.dev/samples/photo.jpg
curl -F "[email protected]" -F "[email protected]" "https://api.dharun.dev/v1/image/compare"

JavaScript

// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
form.append("file", input.files[1]);
const response = await fetch("https://api.dharun.dev/v1/image/compare", { method: "POST", body: form });
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);

Python

import requests

files = [("file", open("photo-1.jpg", "rb")), ("file", open("photo-2.jpg", "rb"))]
response = requests.post("https://api.dharun.dev/v1/image/compare", files=files, timeout=90)
body = response.json()
if not response.ok:
    raise RuntimeError(body["error"]["message"])
print(body["data"])

Response

{
  "data": {
    "similar": true,
    "distance": {
      "average": 0,
      "difference": 0,
      "perceptual": 0
    },
    "score": 1,
    "pictures": [
      {
        "average": "fff3e7c3c3c3c300",
        "difference": "16660c9696868e30",
        "perceptual": "e4cc9b3199939393",
        "width": 853,
        "height": 640
      },
      {
        "average": "fff3e7c3c3c3c300",
        "difference": "16660c9696868e30",
        "perceptual": "e4cc9b3199939393",
        "width": 853,
        "height": 640
      }
    ]
  },
  "meta": {
    "note": "Distances are bits that differ, of 64. similar is true when the perceptual hashes differ by 10 bits or fewer. score is 1 for the same picture."
  }
}

Using an AI assistant? Connect the MCP server and it can call this API by itself.