You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, topK = 3, minScore = 0.1, fontSize = 24, fontColor = 'white', boxColor = 'rgba(0, 0, 0, 0.6)') {
/**
* Helper function to dynamically load a script and return a promise.
* @param {string} src The script URL to load.
* @returns {Promise<void>} A promise that resolves when the script is loaded.
*/
const loadScript = (src) => {
// Check if the script is already loaded to avoid duplicates
if (document.querySelector(`script[src="${src}"]`)) {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = resolve;
script.onerror = () => reject(new Error(`Failed to load script: ${src}`));
document.head.appendChild(script);
});
};
// 1. Create a canvas and draw the original image on it.
const canvas = document.createElement('canvas');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0);
try {
// 2. Dynamically load TensorFlow.js and the MobileNet model libraries.
// These are loaded from a CDN. The function will only proceed once they are loaded.
await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.17.0/dist/tf.min.js');
await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@3.0.1/dist/mobilenet.min.js');
// Display a loading message on the canvas.
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.fillRect(0, canvas.height / 2 - 20, canvas.width, 40);
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.font = '20px "Segoe UI", "Roboto", sans-serif';
ctx.fillText('Analyzing image...', canvas.width / 2, canvas.height / 2 + 7);
// 3. Load the pre-trained MobileNet model.
const model = await mobilenet.load();
// 4. Classify the image to get predictions.
const predictions = await model.classify(originalImg, topK);
// 5. Clear the loading message before drawing the results.
ctx.drawImage(originalImg, 0, 0);
// 6. Filter predictions based on the minimum confidence score.
const filteredPredictions = predictions.filter(p => p.probability >= minScore);
if (filteredPredictions.length > 0) {
// 7. Prepare to draw the prediction text on the canvas.
const textLines = filteredPredictions.map(p => {
const probability = Math.round(p.probability * 100);
// Take the primary name, which is usually before the first comma.
const className = p.className.split(',')[0];
// Capitalize the first letter for better display.
const capitalizedName = className.charAt(0).toUpperCase() + className.slice(1);
return `${capitalizedName}: ${probability}%`;
});
ctx.font = `bold ${fontSize}px "Segoe UI", "Roboto", "Helvetica Neue", sans-serif`;
const textHeight = fontSize * 1.2;
const padding = 15;
const boxHeight = (textLines.length * textHeight) + (padding * 2);
const boxY = canvas.height - boxHeight;
// Draw a semi-transparent background box for the text.
ctx.fillStyle = boxColor;
ctx.fillRect(0, boxY, canvas.width, boxHeight);
// Draw each prediction line.
ctx.fillStyle = fontColor;
let currentY = boxY + textHeight - (textHeight - fontSize) / 2 + padding;
for (const line of textLines) {
ctx.fillText(line, padding, currentY);
currentY += textHeight;
}
} else {
// If no predictions meet the score threshold, display a message.
ctx.fillStyle = boxColor;
ctx.fillRect(0, canvas.height - 50, canvas.width, 50);
ctx.fillStyle = fontColor;
ctx.textAlign = 'center';
ctx.font = `${fontSize * 0.8}px "Segoe UI", "Roboto", "Helvetica Neue", sans-serif`;
ctx.fillText("Could not identify a specific object.", canvas.width / 2, canvas.height - 20);
}
} catch (error) {
console.error("Error during image identification:", error);
// If an error occurs, draw an error message on the canvas.
ctx.drawImage(originalImg, 0, 0); // Redraw image to clear loading text
ctx.fillStyle = 'rgba(200, 0, 0, 0.8)';
ctx.fillRect(0, canvas.height - 60, canvas.width, 60);
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.font = '16px "Segoe UI", "Roboto", "Helvetica Neue", sans-serif';
ctx.fillText("An error occurred during identification.", canvas.width / 2, canvas.height - 35);
ctx.fillText("Please check the browser console for details.", canvas.width / 2, canvas.height - 15);
}
// 8. Return the final canvas element.
return canvas;
}
Apply Changes