You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, posterLevels = 5, borderColor = 'darkgoldenrod', overlayColor = 'rgba(218, 165, 32, 0.15)', lineThickness = 3) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.naturalWidth || originalImg.width;
canvas.height = originalImg.naturalHeight || originalImg.height;
// 1. Draw original image
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// 2. Posterization
// posterLevels = 1 or less would mean no change or cause division by zero issues with the formula.
// posterLevels = 256 or more is effectively no change.
if (posterLevels > 1 && posterLevels < 256) {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// The factor determines the size of each color step.
// (posterLevels - 1) because if posterLevels is 2, there's one step (255 / 1).
const factor = 255 / (posterLevels - 1);
for (let i = 0; i < data.length; i += 4) {
data[i] = Math.round(data[i] / factor) * factor; // Red
data[i + 1] = Math.round(data[i + 1] / factor) * factor; // Green
data[i + 2] = Math.round(data[i + 2] / factor) * factor; // Blue
}
ctx.putImageData(imageData, 0, 0);
}
// 3. Color Overlay
// Apply a tint using a global composite operation. 'overlay' works well for this.
if (overlayColor && overlayColor !== 'none' && overlayColor !== '') {
ctx.globalCompositeOperation = 'overlay';
ctx.fillStyle = overlayColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'source-over'; // Important to reset
}
// 4. Decorative Border setup
ctx.strokeStyle = borderColor;
ctx.lineWidth = lineThickness;
ctx.lineCap = 'round'; // For smoother ends of lines
ctx.lineJoin = 'round'; // For smoother joins between line segments
const w_canvas = canvas.width;
const h_canvas = canvas.height;
// Base size for flourishes, relative to canvas size for responsiveness.
const baseFlourishSize = Math.min(w_canvas, h_canvas) * 0.10; // Increased for more impact
// Margin from the edge of the canvas for placing flourishes.
// Ensures flourishes are visible and have some breathing room.
const outerMargin = Math.max(lineThickness * 3, baseFlourishSize * 0.5 + lineThickness);
/**
* Draws a single Art Nouveau-style flourish.
* The flourish is designed to emanate from (cx, cy) and its main direction
* is controlled by the 'angle' parameter.
* Its local +X axis (before rotation) is considered its primary direction.
* @param {CanvasRenderingContext2D} currentCtx - The drawing context.
* @param {number} cx - Center X of the flourish origin.
* @param {number} cy - Center Y of the flourish origin.
* @param {number} size - Base size of the flourish.
* @param {number} angle - Rotation angle in radians.
*/
function drawArtNouveauFlourish(currentCtx, cx, cy, size, angle) {
currentCtx.save();
currentCtx.translate(cx, cy); // Move to the flourish's anchor point
currentCtx.rotate(angle); // Rotate the entire flourish
currentCtx.beginPath();
// Stem 1 (main whiplash curve)
// Origin (0,0) -> curves towards positive X and negative Y (up-right locally)
currentCtx.moveTo(0, 0);
currentCtx.bezierCurveTo(size * 0.3, -size * 0.5, size * 0.8, -size * 0.3, size, -size * 0.8);
// Bud/leaf shape at the end of Stem 1
currentCtx.moveTo(size, -size * 0.8); // Start from end of stem 1
currentCtx.quadraticCurveTo(size * 0.95, -size * 0.95, size * 1.1, -size * 1.05); // Tip of bud
currentCtx.quadraticCurveTo(size * 1.25, -size * 0.95, size, -size * 0.8); // Curve back to form bud shape
// Stem 2 (smaller, contrasting curve)
// Origin (0,0) -> curves towards negative X and positive Y (down-left locally) for balance
currentCtx.moveTo(0, 0);
currentCtx.quadraticCurveTo(-size * 0.2, size * 0.4, -size * 0.1, size * 0.7);
// Small swirl/curl at the end of Stem 2
currentCtx.moveTo(-size * 0.1, size * 0.7); // Start from end of stem 2
// arc(x, y, radius, startAngle, endAngle, counterclockwise)
currentCtx.arc(-size * 0.1 - size * 0.05, size * 0.7, size * 0.07, Math.PI * 0.9, Math.PI * 0.4, true);
currentCtx.stroke(); // Draw all parts of this flourish
currentCtx.restore();
}
// Draw flourishes at corners. Angles are set so the flourish's local +X (main stem) points towards image center.
// Top-Left corner
drawArtNouveauFlourish(ctx, outerMargin, outerMargin, baseFlourishSize, Math.PI / 4);
// Top-Right corner
drawArtNouveauFlourish(ctx, w_canvas - outerMargin, outerMargin, baseFlourishSize, (3 * Math.PI) / 4);
// Bottom-Left corner
drawArtNouveauFlourish(ctx, outerMargin, h_canvas - outerMargin, baseFlourishSize, -Math.PI / 4);
// Bottom-Right corner
drawArtNouveauFlourish(ctx, w_canvas - outerMargin, h_canvas - outerMargin, baseFlourishSize, (-3 * Math.PI) / 4);
// Draw flourishes at mid-points, slightly smaller.
const midFlourishSize = baseFlourishSize * 0.80;
// Top-Mid (points downwards into the image)
drawArtNouveauFlourish(ctx, w_canvas / 2, outerMargin, midFlourishSize, Math.PI / 2);
// Bottom-Mid (points upwards into the image)
drawArtNouveauFlourish(ctx, w_canvas / 2, h_canvas - outerMargin, midFlourishSize, -Math.PI / 2);
// Left-Mid (points rightwards into the image)
drawArtNouveauFlourish(ctx, outerMargin, h_canvas / 2, midFlourishSize, 0);
// Right-Mid (points leftwards into the image)
drawArtNouveauFlourish(ctx, w_canvas - outerMargin, h_canvas / 2, midFlourishSize, Math.PI);
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 Art Nouveau Poster Creator is a tool designed to transform images into unique, stylized art pieces reminiscent of the Art Nouveau movement. It allows users to posterize the colors in their images, apply a subtle color overlay, and add decorative flourishes that enhance the overall aesthetic. This tool can be utilized for creating vibrant posters, artistic prints, or personalized gifts, making it suitable for artists, designers, and anyone looking to add an artistic touch to their images.