Please bookmark this page to avoid losing your image tool!

Image Illuminated Manuscript Frame Generator

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, frameWidth = 40, goldColor = "#DAA520", primaryBandColor = "#800000", patternColor = "#006400", detailLineColor = "#3A3B3C") {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    canvas.width = originalImg.width + 2 * frameWidth;
    canvas.height = originalImg.height + 2 * frameWidth;

    // Helper function for corner motifs
    function drawCornerMotif(ctx, cx, cy, size, motifMainColor, motifAccentColor) {
        // A simple four-petal flower design
        ctx.fillStyle = motifMainColor;
        const petalRadius = size * 0.33; // Radius of each petal circle
        const petalOffset = size * 0.22; // Offset of petal centers from main center

        // Top petal
        ctx.beginPath(); ctx.arc(cx, cy - petalOffset, petalRadius, 0, 2 * Math.PI); ctx.fill();
        // Bottom petal
        ctx.beginPath(); ctx.arc(cx, cy + petalOffset, petalRadius, 0, 2 * Math.PI); ctx.fill();
        // Left petal
        ctx.beginPath(); ctx.arc(cx - petalOffset, cy, petalRadius, 0, 2 * Math.PI); ctx.fill();
        // Right petal
        ctx.beginPath(); ctx.arc(cx + petalOffset, cy, petalRadius, 0, 2 * Math.PI); ctx.fill();

        // Center dot
        ctx.fillStyle = motifAccentColor;
        const centerRadius = size * 0.18;
        ctx.beginPath(); ctx.arc(cx, cy, centerRadius, 0, 2 * Math.PI); ctx.fill();
    }

    // Helper function for repeating edge elements
    function drawEdgeElement(ctx, cx, cy, size, elementColor) {
        ctx.fillStyle = elementColor;
        // Simple dot
        ctx.beginPath();
        ctx.arc(cx, cy, size / 2, 0, 2 * Math.PI);
        ctx.fill();
    }

    // Define band proportions
    const outerGoldThickness = frameWidth * 0.15;
    const primaryBandThickness = frameWidth * 0.70;
    // const innerGoldThickness = frameWidth * 0.15; // Implicitly frameWidth - outerGold - primaryBand

    // Define key positions for band boundaries (distance from edge of canvas)
    const pos1_primaryBandStart = outerGoldThickness;
    const pos2_primaryBandEnd = outerGoldThickness + primaryBandThickness; // Also start of inner gold band

    // 1. Fill entire canvas with gold (outermost band color)
    ctx.fillStyle = goldColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 2. Fill primary band area (e.g., red or blue)
    ctx.fillStyle = primaryBandColor;
    ctx.fillRect(
        pos1_primaryBandStart,
        pos1_primaryBandStart,
        canvas.width - 2 * pos1_primaryBandStart,
        canvas.height - 2 * pos1_primaryBandStart
    );

    // 3. Draw patterns on the primary band
    const stripActualThickness = primaryBandThickness; // This is the thickness of the band we are decorating
    const stripCenterFromEdge = pos1_primaryBandStart + stripActualThickness / 2;

    if (stripActualThickness > 5) { // Only draw patterns if the band is thick enough
        const motifSize = Math.max(5, stripActualThickness * 0.65);
        const elementSize = Math.max(2, stripActualThickness * 0.25);
        const elementSpacing = elementSize * 2.5;

        // Corner Motifs
        const corners = [
            { x: stripCenterFromEdge, y: stripCenterFromEdge }, // Top-Left
            { x: canvas.width - stripCenterFromEdge, y: stripCenterFromEdge }, // Top-Right
            { x: stripCenterFromEdge, y: canvas.height - stripCenterFromEdge }, // Bottom-Left
            { x: canvas.width - stripCenterFromEdge, y: canvas.height - stripCenterFromEdge } // Bottom-Right
        ];
        corners.forEach(corner => {
            drawCornerMotif(ctx, corner.x, corner.y, motifSize, patternColor, goldColor);
        });

        // Edge Elements
        // Top edge
        const topStartX = stripCenterFromEdge + motifSize / 2 + elementSpacing / 2;
        const topEndX = canvas.width - stripCenterFromEdge - motifSize / 2 - elementSpacing / 2;
        if (topStartX < topEndX) { // Ensure there's space for at least one element
            for (let x = topStartX; x <= topEndX; x += elementSpacing) {
                drawEdgeElement(ctx, x, stripCenterFromEdge, elementSize, patternColor);
            }
        }
        // Bottom edge
        if (topStartX < topEndX) {
            for (let x = topStartX; x <= topEndX; x += elementSpacing) {
                drawEdgeElement(ctx, x, canvas.height - stripCenterFromEdge, elementSize, patternColor);
            }
        }
        // Left edge
        const leftStartY = stripCenterFromEdge + motifSize / 2 + elementSpacing / 2;
        const leftEndY = canvas.height - stripCenterFromEdge - motifSize / 2 - elementSpacing / 2;
        if (leftStartY < leftEndY) {
            for (let y = leftStartY; y <= leftEndY; y += elementSpacing) {
                drawEdgeElement(ctx, stripCenterFromEdge, y, elementSize, patternColor);
            }
        }
        // Right edge
        if (leftStartY < leftEndY) {
            for (let y = leftStartY; y <= leftEndY; y += elementSpacing) {
                drawEdgeElement(ctx, canvas.width - stripCenterFromEdge, y, elementSize, patternColor);
            }
        }
    }

    // 4. Fill innermost gold band area (this will be the background for the image)
    ctx.fillStyle = goldColor;
    ctx.fillRect(
        pos2_primaryBandEnd,
        pos2_primaryBandEnd,
        canvas.width - 2 * pos2_primaryBandEnd,
        canvas.height - 2 * pos2_primaryBandEnd
    );

    // 5. Draw detail lines
    if (detailLineColor && detailLineColor.toLowerCase() !== "none" && detailLineColor !== "") {
        ctx.strokeStyle = detailLineColor;
        // Adaptive line width, 1px for small frames, up to 2px for larger ones
        ctx.lineWidth = Math.max(1, Math.min(2, Math.round(frameWidth * 0.03)));

        // Line between outer gold and primary band
        ctx.strokeRect(
            pos1_primaryBandStart,
            pos1_primaryBandStart,
            canvas.width - 2 * pos1_primaryBandStart,
            canvas.height - 2 * pos1_primaryBandStart
        );
        // Line between primary band and inner gold band
        ctx.strokeRect(
            pos2_primaryBandEnd,
            pos2_primaryBandEnd,
            canvas.width - 2 * pos2_primaryBandEnd,
            canvas.height - 2 * pos2_primaryBandEnd
        );
        // Line around the image itself (centers line on image border)
        ctx.strokeRect(
            frameWidth,
            frameWidth,
            originalImg.width,
            originalImg.height
        );
    }

    // 6. Draw the original image
    ctx.drawImage(originalImg, frameWidth, frameWidth, originalImg.width, originalImg.height);
    
    return canvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image Illuminated Manuscript Frame Generator is a creative tool designed to enhance images by adding intricate, decorative frames inspired by historical illuminated manuscripts. Users can customize frame dimensions, colors for different frame elements, and add detailed motifs along the edges and corners. This tool is ideal for artists, designers, and anyone looking to create visually engaging presentations or digital artwork, making their images stand out with a unique, ornamental border.

Leave a Reply

Your email address will not be published. Required fields are marked *