You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, sunColor = "255,255,150", shadowColor = "20,20,70", threshold = 128, blurRadius = 0) {
// 1. Parameter parsing and sanitization
const parseColorComponent = (strVal, defaultVal) => {
const num = parseInt(strVal, 10);
if (isNaN(num)) {
return defaultVal;
}
return Math.max(0, Math.min(255, num));
};
const parseColorString = (colorStr, defaultR, defaultG, defaultB) => {
const parts = colorStr.split(',');
if (parts.length === 3) {
return [
parseColorComponent(parts[0], defaultR),
parseColorComponent(parts[1], defaultG),
parseColorComponent(parts[2], defaultB)
];
}
return [defaultR, defaultG, defaultB]; // Fallback to defaults
};
const sunRGB = parseColorString(sunColor, 255, 255, 150);
const shadowRGB = parseColorString(shadowColor, 20, 20, 70);
const validThreshold = Math.max(0, Math.min(255, Number(threshold) || 0));
const validBlurRadius = Math.max(0, Number(blurRadius) || 0);
// 2. Canvas setup
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
canvas.width = imgWidth;
canvas.height = imgHeight;
// If image dimensions are zero, return an empty canvas
if (imgWidth === 0 || imgHeight === 0) {
console.warn("Image dimensions are zero. Returning an empty canvas.");
return canvas;
}
// 3. Draw image, applying blur if specified (simulating pinhole softness)
if (validBlurRadius > 0) {
ctx.filter = `blur(${validBlurRadius}px)`;
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
ctx.filter = 'none'; // Reset filter immediately after use
} else {
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
}
// 4. Get image data
let imageData;
try {
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
} catch (e) {
// This can happen due to tainted canvas if image is cross-origin
// and server doesn't allow CORS, or other canvas errors.
console.error("Could not get image data:", e);
// Create an error message on the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear previous drawing
ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Error: Could not process image.", canvas.width / 2, canvas.height / 2);
if (e.name === 'SecurityError') {
ctx.fillText("May be a cross-origin image issue.", canvas.width / 2, canvas.height / 2 + 20);
}
return canvas;
}
const data = imageData.data;
// 5. Pixel manipulation for Solargraphy effect
// This creates a high-contrast, two-tone effect based on luminance.
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// Alpha (data[i+3]) is preserved
// Calculate luminance from (potentially blurred) pixel
const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
if (luminance >= validThreshold) {
data[i] = sunRGB[0]; // Apply sun color to bright areas
data[i + 1] = sunRGB[1];
data[i + 2] = sunRGB[2];
} else {
data[i] = shadowRGB[0]; // Apply shadow color to dark areas
data[i + 1] = shadowRGB[1];
data[i + 2] = shadowRGB[2];
}
}
// 6. Put modified image data back
ctx.putImageData(imageData, 0, 0);
// 7. Return canvas
return canvas;
}
Apply Changes