You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, minConfidence = 0.5, boxColor = '#ff0000', textColor = '#ffffff', fontSize = 16, lineWidth = 2) {
/**
* Dynamically loads a script and returns a promise that resolves when the script is loaded.
* @param {string} url - The URL of the script to load.
* @returns {Promise<void>}
*/
const loadScript = (url) => {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
};
/**
* Helper to create a fallback canvas with the original image in case of an error.
* @param {Image} img - The original image object.
* @returns {HTMLCanvasElement}
*/
const createFallbackCanvas = (img) => {
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth || img.width;
canvas.height = img.naturalHeight || img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
return canvas;
};
try {
// Load TensorFlow.js and the COCO-SSD model if they aren't already available.
if (!window.cocoSsd) {
// Load TensorFlow.js core
await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.11.0/dist/tf.min.js');
// Load the COCO-SSD model
await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@2.2.2/dist/coco-ssd.min.js');
}
// Create a canvas to draw on
const canvas = document.createElement('canvas');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
const ctx = canvas.getContext('2d');
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// Load the COCO-SSD model.
const model = await window.cocoSsd.load();
// Detect objects in the image.
const predictions = await model.detect(originalImg);
// Define a list of classes from the COCO dataset that are considered food or food-related.
const foodItems = [
'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog',
'pizza', 'donut', 'cake', 'bottle', 'wine glass', 'cup', 'fork', 'knife',
'spoon', 'bowl'
];
// Set up drawing styles
ctx.lineWidth = lineWidth;
ctx.strokeStyle = boxColor;
ctx.font = `${fontSize}px Arial`;
// Iterate through predictions and draw boxes/labels for detected food items
predictions.forEach(prediction => {
// Check if the detected object is a food item and meets the confidence threshold
if (prediction.score > minConfidence && foodItems.includes(prediction.class)) {
const [x, y, width, height] = prediction.bbox;
const label = `${prediction.class} (${Math.round(prediction.score * 100)}%)`;
// Draw the bounding box
ctx.beginPath();
ctx.rect(x, y, width, height);
ctx.stroke();
// Measure text to create a background for it
const textMetrics = ctx.measureText(label);
const textWidth = textMetrics.width;
const textHeight = fontSize;
const padding = 4;
// Draw background for the label
ctx.fillStyle = boxColor;
ctx.fillRect(x, y, textWidth + padding * 2, textHeight + padding * 2);
// Draw the label text
ctx.fillStyle = textColor;
ctx.fillText(label, x + padding, y + textHeight + padding / 2);
}
});
return canvas;
} catch (error) {
console.error("Image processing failed:", error);
// In case of an error, return the original image drawn on a canvas.
return createFallbackCanvas(originalImg);
}
}
Apply Changes