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.
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.
| Parameter | Description |
|---|---|
formatquery | Output format. Default webp. One of: jpeg, png, webp, avif, gif, tiff. |
widthquery | Width in pixels, 1 to 8000. |
heightquery | Height in pixels, 1 to 8000. |
fitquery | How the picture fits width and height. Default inside. One of: inside, cover, fill. |
qualityquery | JPEG, 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.
| Parameter | Description |
|---|---|
formatquery | png (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.