You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, includeEngines = "All") {
// Create the main container UI
const container = document.createElement('div');
container.style.cssText = `
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
background: #ffffff;
border: 1px solid #eaeaea;
border-radius: 16px;
box-shadow: 0 10px 25px rgba(0,0,0,0.08);
max-width: 400px;
width: 100%;
margin: 20px auto;
padding: 30px 24px;
box-sizing: border-box;
`;
// Title
const title = document.createElement('h2');
title.textContent = 'Reverse Image Search';
title.style.cssText = `
margin: 0 0 24px 0;
font-size: 22px;
color: #202124;
text-align: center;
font-weight: 600;
`;
container.appendChild(title);
// Display scaled-down preview of the original image
const previewCanvas = document.createElement('canvas');
const previewCtx = previewCanvas.getContext('2d');
const MAX_PREVIEW = 280;
let previewScale = Math.min(MAX_PREVIEW / originalImg.width, MAX_PREVIEW / originalImg.height, 1);
previewCanvas.width = originalImg.width * previewScale;
previewCanvas.height = originalImg.height * previewScale;
previewCtx.drawImage(originalImg, 0, 0, previewCanvas.width, previewCanvas.height);
previewCanvas.style.cssText = `
border-radius: 8px;
margin-bottom: 24px;
border: 1px solid #f0f0f0;
max-width: 100%;
height: auto;
`;
container.appendChild(previewCanvas);
const buttonContainer = document.createElement('div');
buttonContainer.style.cssText = `
display: flex;
flex-direction: column;
gap: 12px;
width: 100%;
`;
container.appendChild(buttonContainer);
// Prepare a hidden canvas to extract a capped resolution version for search (max 1920x1920 to keep size reasonable)
const hiddenCanvas = document.createElement('canvas');
const ctxH = hiddenCanvas.getContext('2d');
let maxDim = Math.max(originalImg.width, originalImg.height);
let scaleH = maxDim > 1920 ? 1920 / maxDim : 1;
hiddenCanvas.width = originalImg.width * scaleH;
hiddenCanvas.height = originalImg.height * scaleH;
// Draw the image onto the hidden canvas (will catch CORS errors if cross-origin image cannot be extracted)
try {
ctxH.drawImage(originalImg, 0, 0, hiddenCanvas.width, hiddenCanvas.height);
} catch (e) {
buttonContainer.innerHTML = `<div style="color:#d32f2f; text-align:center; font-size:14px; padding:10px;">Security Error: Cross-origin image cannot be processed.</div>`;
return container;
}
// Convert to Blob asynchronously
const blob = await new Promise(resolve => {
try {
hiddenCanvas.toBlob(resolve, 'image/png');
} catch (e) {
resolve(null);
}
});
if (!blob) {
buttonContainer.innerHTML = `<div style="color:#d32f2f; text-align:center; font-size:14px; padding:10px;">Error: Failed to process image data.</div>`;
return container;
}
// Create a File from the Blob and add it to a DataTransfer object
let dt;
try {
dt = new DataTransfer();
const file = new File([blob], "image_search.png", { type: "image/png" });
dt.items.add(file);
} catch (e) {
buttonContainer.innerHTML = `<div style="color:#d32f2f; text-align:center; font-size:14px; padding:10px;">Error: Browser does not support programmatically setting files.</div>`;
return container;
}
// Define the available reverse image search engines and their form upload configs
const engines = [
{ name: 'Google Lens', url: 'https://images.google.com/searchbyimage/upload', fileParam: 'encoded_image', color: '#4285F4', hover: '#3367D6' },
{ name: 'Yandex', url: 'https://yandex.com/images/search?rpt=imageview', fileParam: 'upfile', color: '#FC3F1D', hover: '#D32F2F' },
{ name: 'TinEye', url: 'https://tineye.com/search', fileParam: 'image', color: '#11558C', hover: '#0D4069' },
{ name: 'Bing', url: 'https://www.bing.com/images/search?view=detailv2&iss=sbiupload', fileParam: 'imageBin', color: '#0078D7', hover: '#005A9E' }
];
const allowed = includeEngines.toLowerCase();
let addedCount = 0;
// Build functional buttons for each engine requested
engines.forEach(engine => {
if (allowed !== 'all' && !allowed.includes(engine.name.toLowerCase())) return;
addedCount++;
// Create a hidden form that targets a new tab
const form = document.createElement('form');
form.method = 'POST';
form.action = engine.url;
form.enctype = 'multipart/form-data';
form.target = '_blank';
form.style.display = 'none';
// Add the standard file input programmatically populated
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.name = engine.fileParam;
try {
fileInput.files = dt.files;
} catch (e) {
// Older browsers might fail here, skip silently
}
form.appendChild(fileInput);
container.appendChild(form);
// UI Button
const btn = document.createElement('button');
btn.innerHTML = `<span style="margin-right: 8px;">🔍</span> Search on ${engine.name}`;
btn.style.cssText = `
display: flex;
align-items: center;
justify-content: center;
padding: 12px 20px;
background-color: ${engine.color};
color: #ffffff;
border: none;
border-radius: 8px;
font-size: 15px;
font-weight: 500;
font-family: inherit;
cursor: pointer;
transition: background-color 0.2s ease;
width: 100%;
box-sizing: border-box;
`;
// Hover effects
btn.onmouseover = () => btn.style.backgroundColor = engine.hover;
btn.onmouseout = () => btn.style.backgroundColor = engine.color;
// Trigger the hidden form
btn.onclick = (e) => {
e.preventDefault();
form.submit();
};
buttonContainer.appendChild(btn);
});
if (addedCount === 0) {
buttonContainer.innerHTML = `<div style="text-align:center; color:#666; font-size:14px; padding:10px;">No search engines correctly matched '${includeEngines}'.</div>`;
}
return container;
}
Apply Changes