walidadebayo's picture
Enhance mask handling in image processing: resize and validate dimensions, update demo link, and correct copyright year in footer
311bfbf
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Magic Eraser API Documentation</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 1.6;
color: #333;
max-width: 1100px;
margin: 0 auto;
padding: 20px;
}
header {
border-bottom: 1px solid #eee;
padding-bottom: 20px;
margin-bottom: 30px;
}
h1 {
color: #2c3e50;
}
h2 {
color: #3498db;
margin-top: 40px;
}
h3 {
color: #2980b9;
}
pre {
background-color: #f5f7f9;
border-radius: 5px;
padding: 15px;
overflow-x: auto;
}
code {
font-family: 'Courier New', Courier, monospace;
}
.endpoint {
background-color: #f8f9fa;
border-left: 4px solid #3498db;
padding: 15px;
margin-bottom: 20px;
}
.method {
display: inline-block;
padding: 3px 6px;
border-radius: 4px;
color: white;
font-size: 14px;
margin-right: 10px;
}
.get {
background-color: #3498db;
}
.post {
background-color: #2ecc71;
}
table {
border-collapse: collapse;
width: 100%;
}
th, td {
text-align: left;
padding: 12px;
border-bottom: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
.container {
margin-top: 20px;
}
.demo-section {
margin-top: 40px;
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
}
.btn {
display: inline-block;
padding: 10px 15px;
background-color: #3498db;
color: white;
text-decoration: none;
border-radius: 4px;
border: none;
cursor: pointer;
}
.btn:hover {
background-color: #2980b9;
}
</style>
</head>
<body>
<header>
<h1>📷 Magic Eraser API</h1>
<p>An AI-powered REST API for removing unwanted objects from images and performing content-aware resizing.</p>
<p>Check out the InnoAI Space for the streamline demo frontend: <a href="https://huggingface.co/spaces/innoai/Magic-Eraser-Pub" target="_blank">Magic Eraser Demo</a></p>
</header>
<section>
<h2>Features</h2>
<ul>
<li><strong>Object Removal</strong>: Remove unwanted objects from images with advanced AI inpainting</li>
<li><strong>Seam Carving</strong>: Content-aware image resizing and object removal</li>
<li><strong>Simple Integration</strong>: Easy-to-use REST API endpoints</li>
</ul>
</section>
<section>
<h2>API Endpoints</h2>
<div class="endpoint">
<h3><span class="method get">GET</span> /</h3>
<p>Health check endpoint. Returns a status message if the API is running.</p>
<h4>Response</h4>
<pre><code>{
"status": "API is running"
}</code></pre>
</div>
<div class="endpoint">
<h3><span class="method post">POST</span> /api/inpaint</h3>
<p>Removes objects from images and fills in the background using AI.</p>
<h4>Request Body</h4>
<pre><code>{
"image": "data:image/png;base64,<base64-encoded-image>",
"mask": "data:image/png;base64,<base64-encoded-mask>"
}</code></pre>
<table>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>image</td>
<td>string</td>
<td>Base64-encoded image with data URL prefix</td>
</tr>
<tr>
<td>mask</td>
<td>string</td>
<td>Base64-encoded mask where transparent areas (alpha=0) indicate what to remove</td>
</tr>
</table>
<h4>Response</h4>
<pre><code>{
"result": "data:image/png;base64,<base64-encoded-result>"
}</code></pre>
</div>
<div class="endpoint">
<h3><span class="method post">POST</span> /api/seam-carve</h3>
<p>Content-aware resizing or object removal using the seam carving algorithm.</p>
<h4>Request Body</h4>
<pre><code>{
"image": "data:image/png;base64,<base64-encoded-image>",
"mask": "data:image/png;base64,<base64-encoded-mask>",
"vs": 50,
"hs": 30,
"mode": "resize"
}</code></pre>
<table>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>image</td>
<td>string</td>
<td>Base64-encoded image with data URL prefix</td>
</tr>
<tr>
<td>mask</td>
<td>string</td>
<td>Base64-encoded mask (optional for resize mode, required for remove mode)</td>
</tr>
<tr>
<td>vs</td>
<td>integer</td>
<td>Number of vertical seams to add/remove (positive = add, negative = remove)</td>
</tr>
<tr>
<td>hs</td>
<td>integer</td>
<td>Number of horizontal seams to add/remove (positive = add, negative = remove)</td>
</tr>
<tr>
<td>mode</td>
<td>string</td>
<td>Either "resize" (change dimensions) or "remove" (remove objects)</td>
</tr>
</table>
<h4>Response</h4>
<pre><code>{
"result": "data:image/png;base64,<base64-encoded-result>"
}</code></pre>
</div>
</section>
<section>
<h2>JavaScript Example</h2>
<p>Here's how to use the API in a JavaScript application:</p>
<h3>Inpainting Example</h3>
<pre><code>async function removeObject(imageBase64, maskBase64) {
const response = await fetch('{{ api_url }}/api/inpaint', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
image: imageBase64,
mask: maskBase64,
}),
});
const data = await response.json();
return data.result; // base64 encoded result image
}</code></pre>
<h3>Seam Carving Example</h3>
<pre><code>async function resizeImage(imageBase64, maskBase64) {
const response = await fetch('{{ api_url }}/api/seam-carve', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
image: imageBase64,
mask: maskBase64,
vs: -50, // Remove 50 vertical seams (make narrower)
hs: 30, // Add 30 horizontal seams (make taller)
mode: 'resize', // or 'remove' to remove objects
}),
});
const data = await response.json();
return data.result;
}</code></pre>
</section>
<section>
<h2>Setting Up a Drawing Canvas</h2>
<p>To integrate with our API, you'll need a way for users to draw masks over images. Here's a simple HTML5 Canvas example:</p>
<pre><code>function setupCanvas(imageUrl) {
// Create canvas elements
const imageCanvas = document.createElement('canvas');
const maskCanvas = document.createElement('canvas');
const container = document.getElementById('canvas-container');
container.appendChild(imageCanvas);
container.appendChild(maskCanvas);
// Load image
const img = new Image();
img.onload = function() {
// Set canvas dimensions
imageCanvas.width = maskCanvas.width = img.width;
imageCanvas.height = maskCanvas.height = img.height;
// Draw image on image canvas
const imgCtx = imageCanvas.getContext('2d');
imgCtx.drawImage(img, 0, 0);
// Setup mask canvas for drawing
const maskCtx = maskCanvas.getContext('2d');
maskCtx.fillStyle = 'rgba(255, 0, 0, 0.5)';
// Drawing state
let isDrawing = false;
// Mouse/touch event handlers
maskCanvas.addEventListener('mousedown', startDrawing);
maskCanvas.addEventListener('mousemove', draw);
maskCanvas.addEventListener('mouseup', stopDrawing);
maskCanvas.addEventListener('mouseleave', stopDrawing);
function startDrawing(e) {
isDrawing = true;
draw(e);
}
function draw(e) {
if (!isDrawing) return;
const rect = maskCanvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
maskCtx.beginPath();
maskCtx.arc(x, y, 15, 0, Math.PI * 2);
maskCtx.fill();
}
function stopDrawing() {
isDrawing = false;
}
};
img.src = imageUrl;
}</code></pre>
</section>
<section class="demo-section">
<h2>Try It Out</h2>
<p>Visit InnoAI interactive demo frontend:</p>
<a href="https://huggingface.co/spaces/innoai/Magic" class="btn" target="_blank">Open Demo Frontend</a>
<p><small>Demo frontend connects to this API for processing images.</small></p>
</section>
<footer>
<p><small>© 2025 Magic Eraser API. MIT License.</small></p>
</footer>
</body>
</html>