You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, effectIntensity = 10, showTreasurePath = "yes") {
// Create a canvas to work with the image
const canvas = document.createElement("canvas");
const width = originalImg.width;
const height = originalImg.height;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
// Draw original image on the canvas
ctx.drawImage(originalImg, 0, 0, width, height);
// Fetch the image data to manipulate pixels
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
// Normalize intensity (0 to 1 scale based on 0-10 input)
const intensity = Math.max(0, Math.min(10, Number(effectIntensity))) / 10;
// Center coordinates and max distance for vignette effect
const cx = width / 2;
const cy = height / 2;
const maxDist = Math.sqrt(cx * cx + cy * cy);
// Process pixels to create an old parchment / treasure map effect
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// Sepia conversion math
const tr = Math.min(255, (r * 0.393) + (g * 0.769) + (b * 0.189));
const tg = Math.min(255, (r * 0.349) + (g * 0.686) + (b * 0.168));
const tb = Math.min(255, (r * 0.272) + (g * 0.534) + (b * 0.131));
// Blend the original with the sepia based on effect intensity
let finalR = r + (tr - r) * intensity;
let finalG = g + (tg - g) * intensity;
let finalB = b + (tb - b) * intensity;
// Add some noise/grain to simulate worn parchment paper
const noise = (Math.random() - 0.5) * 35 * intensity;
finalR += noise;
finalG += noise;
finalB += noise;
// Apply a vignette effect (darkened corners mapping to old paper aesthetics)
const x = (i / 4) % width;
const y = Math.floor((i / 4) / width);
const dx = x - cx;
const dy = y - cy;
const dist = Math.sqrt(dx * dx + dy * dy);
// Intensity reduces brightness near edges
const vignette = 1 - (dist / maxDist) * 0.65 * intensity;
data[i] = Math.min(255, Math.max(0, finalR * vignette));
data[i + 1] = Math.min(255, Math.max(0, finalG * vignette));
data[i + 2] = Math.min(255, Math.max(0, finalB * vignette));
}
// Put modified pixels back to the canvas
ctx.putImageData(imgData, 0, 0);
// Add a dark brownish border to emphasize the old map look
if (intensity > 0) {
ctx.save();
ctx.lineWidth = Math.max(8, width * 0.02);
ctx.strokeStyle = `rgba(70, 40, 20, ${0.85 * intensity})`;
ctx.strokeRect(0, 0, width, height);
ctx.restore();
}
// Draw the "Treasure Path" and the "X Marks the Spot"
if (showTreasurePath.trim().toLowerCase() === "yes") {
const pathStartX = width * 0.15;
const pathStartY = height * 0.85;
const pathEndX = width * 0.75;
const pathEndY = height * 0.20;
// Bezier control points to curve the path around the image naturally
const cp1X = width * 0.3;
const cp1Y = height * 0.9;
const cp2X = width * 0.6;
const cp2Y = height * 0.4;
ctx.save();
// Draw dashed trail
ctx.beginPath();
ctx.moveTo(pathStartX, pathStartY);
ctx.bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, pathEndX, pathEndY);
ctx.lineWidth = Math.max(3, width * 0.008);
ctx.setLineDash([width * 0.03, width * 0.02]);
ctx.lineCap = "round";
ctx.strokeStyle = "rgba(139, 0, 0, 0.85)"; // Dark red
ctx.stroke();
// Draw big Red "X" at the end point
ctx.beginPath();
const xSize = Math.max(15, width * 0.04);
ctx.setLineDash([]); // Reset line dash for solid X
ctx.moveTo(pathEndX - xSize, pathEndY - xSize);
ctx.lineTo(pathEndX + xSize, pathEndY + xSize);
ctx.moveTo(pathEndX + xSize, pathEndY - xSize);
ctx.lineTo(pathEndX - xSize, pathEndY + xSize);
ctx.lineWidth = Math.max(5, width * 0.015);
ctx.strokeStyle = "rgba(178, 34, 34, 1)"; // Firebrick Red
ctx.stroke();
ctx.restore();
}
return canvas;
}
Apply Changes