You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, previewMaxWidth = "400") {
// Create the main wrapper container
const container = document.createElement('div');
container.style.fontFamily = 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
container.style.textAlign = 'center';
container.style.padding = '24px';
container.style.backgroundColor = '#ffffff';
container.style.borderRadius = '12px';
container.style.boxShadow = '0 4px 16px rgba(0,0,0,0.08)';
container.style.boxSizing = 'border-box';
container.style.maxWidth = '100%';
container.style.width = '600px';
container.style.margin = '0 auto';
container.style.border = '1px solid #eaeaea';
// Title & Description
const title = document.createElement('h2');
title.textContent = 'Reverse Image Search Tools';
title.style.marginTop = '0';
title.style.marginBottom = '8px';
title.style.color = '#333';
title.style.fontSize = '1.4rem';
container.appendChild(title);
const desc = document.createElement('p');
desc.textContent = 'Select a search engine below to find the source or visually similar versions of this image.';
desc.style.color = '#666';
desc.style.fontSize = '0.95rem';
desc.style.marginBottom = '24px';
desc.style.lineHeight = '1.4';
container.appendChild(desc);
// Image Preview Area
const previewCanvas = document.createElement('canvas');
const pWidth = parseInt(previewMaxWidth, 10) || 400;
const pScale = Math.min(1, pWidth / originalImg.naturalWidth);
const pvW = originalImg.naturalWidth * pScale;
const pvH = originalImg.naturalHeight * pScale;
previewCanvas.width = pvW;
previewCanvas.height = pvH;
const pctx = previewCanvas.getContext('2d');
pctx.drawImage(originalImg, 0, 0, pvW, pvH);
previewCanvas.style.border = '1px solid #e0e0e0';
previewCanvas.style.borderRadius = '8px';
previewCanvas.style.marginBottom = '24px';
previewCanvas.style.maxWidth = '100%';
previewCanvas.style.height = 'auto';
previewCanvas.style.backgroundColor = '#f8f9fa';
container.appendChild(previewCanvas);
// Button Container
const btnContainer = document.createElement('div');
btnContainer.style.display = 'flex';
btnContainer.style.flexWrap = 'wrap';
btnContainer.style.gap = '12px';
btnContainer.style.justifyContent = 'center';
container.appendChild(btnContainer);
// Loading prompt while processing blob
const loading = document.createElement('div');
loading.textContent = 'Optimizing image for search upload...';
loading.style.color = '#888';
loading.style.fontStyle = 'italic';
loading.style.width = '100%';
loading.style.margin = '10px 0';
btnContainer.appendChild(loading);
// Create a canvas specifically for generating the upload payload.
// We scale down excessively large images to max 1600px to speed up search upload limits
const searchCanvas = document.createElement('canvas');
let sWidth = originalImg.naturalWidth;
let sHeight = originalImg.naturalHeight;
const maxSearchDim = 1600;
if (sWidth > maxSearchDim || sHeight > maxSearchDim) {
const ratio = Math.min(maxSearchDim / sWidth, maxSearchDim / sHeight);
sWidth = Math.round(sWidth * ratio);
sHeight = Math.round(sHeight * ratio);
}
searchCanvas.width = sWidth;
searchCanvas.height = sHeight;
searchCanvas.getContext('2d').drawImage(originalImg, 0, 0, sWidth, sHeight);
// Convert processed canvas to Blob in the background
searchCanvas.toBlob((blob) => {
// Remove loading text
loading.remove();
let file;
try {
file = new File([blob], 'search_image.jpg', { type: 'image/jpeg' });
} catch(e) {
// Fallback for older environments
file = blob;
}
// Configuration for the reverse image search engines
const engines = [
{
name: 'Search on Google Lens',
action: 'https://lens.google.com/upload',
fileField: 'encoded_image',
bgColor: '#4285F4',
color: '#fff'
},
{
name: 'Search on TinEye',
action: 'https://tineye.com/search',
fileField: 'image',
bgColor: '#336699',
color: '#fff'
},
{
name: 'Search on Yandex',
action: 'https://yandex.com/images/search?rpt=imageview',
fileField: 'upfile',
bgColor: '#FFCC00',
color: '#000'
},
{
name: 'Search on Bing',
action: 'https://www.bing.com/images/search?view=detailv2&iss=sbi&FORM=SBIHMP',
fileField: 'imageBin',
bgColor: '#00809D',
color: '#fff'
}
];
// Generate hidden forms and visible buttons for each engine
engines.forEach(engine => {
// Hidden form
const form = document.createElement('form');
form.action = engine.action;
form.method = 'POST';
form.enctype = 'multipart/form-data';
form.target = '_blank'; // Opens search in a new tab
form.style.display = 'none';
// Hidden file input
const input = document.createElement('input');
input.type = 'file';
input.name = engine.fileField;
try {
const dt = new DataTransfer();
dt.items.add(file);
input.files = dt.files;
} catch (e) {
console.error("DataTransfer API unsupported:", e);
}
form.appendChild(input);
btnContainer.appendChild(form);
// Styled submit button
const btn = document.createElement('button');
btn.type = 'button';
btn.textContent = engine.name;
btn.style.flex = '1 1 calc(50% - 12px)';
btn.style.minWidth = '200px';
btn.style.padding = '14px 16px';
btn.style.border = 'none';
btn.style.borderRadius = '8px';
btn.style.backgroundColor = engine.bgColor;
btn.style.color = engine.color;
btn.style.fontSize = '15px';
btn.style.fontWeight = '600';
btn.style.cursor = 'pointer';
btn.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
btn.style.transition = 'transform 0.1s ease, box-shadow 0.2s ease, opacity 0.2s ease';
btn.onmouseover = () => {
btn.style.opacity = '0.9';
btn.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
};
btn.onmouseout = () => {
btn.style.opacity = '1';
btn.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
};
btn.onmousedown = () => btn.style.transform = 'scale(0.97)';
btn.onmouseup = () => btn.style.transform = 'scale(1)';
btn.onclick = (e) => {
e.preventDefault();
if (input.files.length > 0) {
form.submit();
} else {
alert("Image payload failed to attach. Your browser might not support programmatic file transfer.");
}
};
btnContainer.appendChild(btn);
});
}, 'image/jpeg', 0.85); // Compress at 85% to ensure reasonable upload speeds
return container;
}
Apply Changes