You can edit the below JavaScript code to customize the image tool.
/**
* Applies a romantic photo filter to an image.
*
* @param {Image} originalImg - The original JavaScript Image object. The image should be loaded.
* @param {number} [warmthPercent=25] - Sepia effect for warmth (0-100). 0 means no sepia. Higher values increase warmth.
* @param {number} [saturationPercent=130] - Saturation level (e.g., 100 is original, 130 is 30% more, 0 is grayscale).
* @param {number} [contrastPercent=110] - Contrast level (e.g., 100 is original, 110 is 10% more).
* @param {number} [brightnessPercent=105] - Brightness level (e.g., 100 is original, 105 is 5% more).
* @param {number} [softnessPx=0.5] - Gaussian blur radius in pixels for a dreamy effect (0 for no blur).
* @param {number} [vignetteStrength=0.6] - Strength of the vignette effect (0-1). 0 means no vignette. Controls both the size and opacity of the vignette.
* @param {number} [roseTintOpacity=0.1] - Opacity of the rose/pink tint overlay (0-1). 0 means no tint. Applied with 'soft-light' blend mode.
* @returns {HTMLCanvasElement} A canvas element with the filtered image.
*/
function processImage(
originalImg,
warmthPercent = 25,
saturationPercent = 130,
contrastPercent = 110,
brightnessPercent = 105,
softnessPx = 0.5,
vignetteStrength = 0.6,
roseTintOpacity = 0.1
) {
// Sanitize inputs to prevent issues, although CSS filters are quite robust
warmthPercent = Math.max(0, Math.min(100, warmthPercent));
saturationPercent = Math.max(0, saturationPercent);
contrastPercent = Math.max(0, contrastPercent);
brightnessPercent = Math.max(0, brightnessPercent);
softnessPx = Math.max(0, softnessPx);
vignetteStrength = Math.max(0, Math.min(1, vignetteStrength));
roseTintOpacity = Math.max(0, Math.min(1, roseTintOpacity));
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const natWidth = originalImg.naturalWidth;
const natHeight = originalImg.naturalHeight;
// If the image isn't loaded or has no dimensions, return an empty canvas.
// The caller should ensure originalImg is loaded.
if (natWidth === 0 || natHeight === 0) {
// Set a default small size for the canvas if image is not loaded or invalid
canvas.width = 1;
canvas.height = 1;
return canvas;
}
canvas.width = natWidth;
canvas.height = natHeight;
// 1. Apply base image filters using CSS filter syntax
let filterString = '';
if (warmthPercent > 0) {
filterString += `sepia(${warmthPercent}%) `;
}
if (saturationPercent !== 100) { // 100% is no change
filterString += `saturate(${saturationPercent}%) `;
}
if (contrastPercent !== 100) { // 100% is no change
filterString += `contrast(${contrastPercent}%) `;
}
if (brightnessPercent !== 100) { // 100% is no change
filterString += `brightness(${brightnessPercent}%) `;
}
if (softnessPx > 0) {
filterString += `blur(${softnessPx}px) `;
}
filterString = filterString.trim();
if (filterString) {
ctx.filter = filterString;
}
// Draw the original image onto the canvas. Filters are applied at this step.
ctx.drawImage(originalImg, 0, 0, natWidth, natHeight);
// Reset the filter property so it doesn't affect subsequent drawing operations (vignette, tint)
ctx.filter = 'none';
// 2. Apply Vignette
if (vignetteStrength > 0) {
const centerX = natWidth / 2;
const centerY = natHeight / 2;
// The outer radius of the gradient should typically cover the image diagonal
const outerRadius = Math.sqrt(Math.pow(centerX, 2) + Math.pow(centerY, 2));
// Calculate inner radius based on vignetteStrength.
// A higher strength leads Gass to a smaller clear central area.
// The 0.75 factor moderates how quickly the clear area shrinks.
const innerRadiusFactor = 1 - (vignetteStrength * 0.75);
const innerRadius = outerRadius * Math.max(0, innerRadiusFactor); // Ensure innerRadius is not negative
const gradient = ctx.createRadialGradient(centerX, centerY, innerRadius, centerX, centerY, outerRadius);
// Vignette color: A dark, warm, slightly desaturated red/brown is often used for romantic styles.
const R_V = 60, G_V = 30, B_V = 30; // Base color for vignette
// vignetteStrength controls the alpha (opacity) of the vignette color.
const vignetteEdgeAlpha = vignetteStrength;
const vignetteMidAlpha = vignetteStrength * 0.4; // Alpha at the mid-transition point for smoother falloff
gradient.addColorStop(0, `rgba(${R_V}, ${G_V}, ${B_V}, 0)`); // Center of vignette is transparent
// The 0.7 stop position means 70% of the way from innerRadius to outerRadius,
// the color reaches its mid-alpha. This defines the gradient's falloff curve.
gradient.addColorStop(0.7, `rgba(${R_V}, ${G_V}, ${B_V}, ${vignetteMidAlpha})`);
gradient.addColorStop(1, `rgba(${R_V}, ${G_V}, ${B_V}, ${vignetteEdgeAlpha})`); // Edges of vignette
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, natWidth, natHeight); // Apply vignette over the image
}
// 3. Apply Rose Tint Overlay
if (roseTintOpacity > 0) {
// 'soft-light' blend mode works well for subtle color tinting.
// Other options: 'overlay', 'color' (might be too strong), 'screen' with dark pink.
ctx.globalCompositeOperation = 'soft-light';
// Standard light pink color for the rose tint.
const R_T = 255, G_T = 192, B_T = 203;
ctx.fillStyle = `rgba(${R_T}, ${G_T}, ${B_T}, ${roseTintOpacity})`;
ctx.fillRect(0, 0, natWidth, natHeight); // Apply tint over the image (and vignette)
// Reset globalCompositeOperation to default
ctx.globalCompositeOperation = 'source-over';
}
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 Photo Romantic Filter Applicator is a web-based tool that allows users to enhance their images with a romantic filter effect. It applies a range of adjustments including warmth, saturation, contrast, brightness, softness, and a vignette effect to create a soft, dreamy appearance. Users can also add a subtle rose tint overlay to give their photos a romantic touch. This tool is ideal for personalizing photos for social media, enhancing portraits, or creating aesthetically pleasing images for special occasions such as weddings, anniversaries, or Valentine’s Day.