You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg) {
try {
// Ensure the image is fully loaded and has valid dimensions.
if (!originalImg.complete || originalImg.naturalWidth === 0) {
// If the image object has no source, it cannot be loaded.
if (!originalImg.src && !originalImg.currentSrc) { // currentSrc is for when src changes
console.error("Image has no src or currentSrc property to load.");
throw new Error("Image source empty.");
}
// Wait for the image to load if it's not already.
await new Promise((resolve, reject) => {
// Double-check if became complete while setting up listeners
if (originalImg.complete && originalImg.naturalWidth !== 0) {
resolve();
return;
}
originalImg.onload = resolve;
originalImg.onerror = () => reject(new Error(`Failed to load image from: ${originalImg.src || originalImg.currentSrc}`));
// Check if image is already in a completed but failed state (e.g. 0 dimensions)
if (originalImg.complete && (originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0)) {
reject(new Error(`Image loaded but has 0 dimension: ${originalImg.src || originalImg.currentSrc}`));
}
});
}
// Final check after loading attempt
if (originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0) {
throw new Error(`Image loaded with zero dimensions: ${originalImg.src || originalImg.currentSrc}`);
}
} catch (error) {
// Handle any errors during the image loading phase by returning an error canvas.
console.error("Error during image loading phase:", error.message);
const errorCanvas = document.createElement('canvas');
// Use image's explicit width/height if available, else default. Ensure > 0.
errorCanvas.width = Math.max(1, originalImg.width || 150);
errorCanvas.height = Math.max(1, originalImg.height || 50);
const errCtx = errorCanvas.getContext('2d');
if (errCtx) {
errCtx.font = "12px Arial";
const message = error && error.message ? error.message : "Failed to load image.";
// Basic text wrapping for longer messages
const maxTextWidth = errorCanvas.width - 10;
let line = '';
const words = message.split(' ');
let y = 20;
for(let n = 0; n < words.length; n++) {
const testLine = line + words[n] + ' ';
const metrics = errCtx.measureText(testLine);
const testWidth = metrics.width;
if (testWidth > maxTextWidth && n > 0) {
errCtx.fillText(line, 5, y);
line = words[n] + ' ';
y += 15; // Line height
} else {
line = testLine;
}
}
errCtx.fillText(line, 5, y);
}
return errorCanvas;
}
// Create a new canvas element.
const canvas = document.createElement('canvas');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
const ctx = canvas.getContext('2d');
if (!ctx) {
// This is a critical failure, e.g., browser doesn't support canvas or too many contexts.
console.error("Could not get 2D context.");
// Return an error canvas indicating this specific issue.
// Dimensions based on original image if possible, else defaults.
canvas.width = Math.max(1, originalImg.naturalWidth || 150);
canvas.height = Math.max(1, originalImg.naturalHeight || 50);
// Attempt to get context again for this new error canvas (ironic, but to draw text)
const errCtx = canvas.getContext('2d');
if(errCtx) {
errCtx.font = "12px Arial";
errCtx.fillText("Cannot initialize canvas context.", 5, 20);
}
return canvas; // Return the canvas, possibly with an error message
}
// Draw the original image onto the canvas.
try {
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
} catch (e) {
console.error("Error drawing image to canvas:", e);
// Clear canvas and draw error message. Use a fill to indicate error state.
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#CCCCCC';
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (canvas.width > 50 && canvas.height > 20) { // Check if canvas is large enough for text
ctx.fillStyle = 'black';
ctx.font = "12px Arial";
ctx.textAlign = "center";
ctx.fillText("Error drawing source image.", canvas.width / 2, canvas.height / 2);
}
return canvas;
}
// Get the ImageData object from the canvas.
let imageData;
try {
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
} catch (e) {
// This can happen due to cross-origin security restrictions (tainted canvas).
console.error("Could not get ImageData (e.g., CORS issue):", e.message);
// Return the canvas with the original image drawn, and an overlay message.
if (canvas.width > 100 && canvas.height > 20) {
ctx.fillStyle = "rgba(0,0,0,0.6)";
ctx.fillRect(0, canvas.height - Math.min(25, canvas.height), canvas.width, Math.min(25, canvas.height));
ctx.fillStyle = "#FFFF00"; // Yellow warning text
ctx.font = "12px Arial";
ctx.textAlign = "center";
ctx.fillText("Filter not applied (Image data inaccessible).", canvas.width / 2, canvas.height - (Math.min(25, canvas.height)/2) + 4);
}
return canvas;
}
const data = imageData.data;
const len = data.length;
// Bronze tone constants (derived from experimentation for a pleasing bronze look)
// These factors are applied to the luminance of each pixel.
const rFactor = 1.0, rAdd = 30; // Emphasize red channel
const gFactor = 0.8, gAdd = 10; // Moderate green for yellow/brown hues
const bFactor = 0.5, bAdd = -25;// Reduce blue for warmth, shift towards brown
// Iterate over each pixel (RGBA components).
for (let i = 0; i < len; i += 4) {
const r = data[i];
const g = data[i+1];
const b = data[i+2];
// Alpha channel (data[i+3]) is preserved.
// Standard luminance calculation (perceived brightness).
const L = 0.299 * r + 0.587 * g + 0.114 * b;
// Apply bronze tint transformation based on luminance.
let newR = L * rFactor + rAdd;
let newG = L * gFactor + gAdd;
let newB = L * bFactor + bAdd;
// Clamp results to the valid [0, 255] range.
data[i] = Math.max(0, Math.min(255, newR));
data[i+1] = Math.max(0, Math.min(255, newG));
data[i+2] = Math.max(0, Math.min(255, newB));
}
// Put the modified pixel data back onto the canvas.
ctx.putImageData(imageData, 0, 0);
// Return the canvas with the bronze tone effect.
return canvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The Image Bronze Tone Filter allows users to apply a bronze tone effect to their images, enhancing their visual appeal by modifying the color tones. This tool can be used for various purposes, such as transforming photographs to give them an artistic or vintage feel, creating unique visuals for graphic design projects, or adding a warm color palette to images for social media posts and presentations. Whether you are a photographer looking to enhance your portfolio or a designer seeking to create striking visuals, this tool offers an easy and effective way to achieve a bronze-toned aesthetic.