Please bookmark this page to avoid losing your image tool!

Image Ancient Roman Greek Tablet Frame Creator

(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.
function processImage(originalImg, frameWidth = 50, frameColor = "#B08D57", borderColor = "#70543E", cornerRadius = 20, textureDensityFactor = 5, crackCount = 10) {

    // Helper function to draw a rounded rectangle
    function drawRoundedRect(ctx, x, y, width, height, radius) {
        if (typeof radius === 'undefined') {
            radius = 5;
        }
        if (typeof radius === 'number') {
            radius = {tl: radius, tr: radius, br: radius, bl: radius};
        } else {
            const defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};
            for (let side in defaultRadius) {
                radius[side] = radius[side] || defaultRadius[side];
            }
        }

        // Ensure radius is not too large
        radius.tl = Math.min(radius.tl, height / 2, width / 2);
        radius.tr = Math.min(radius.tr, height / 2, width / 2);
        radius.br = Math.min(radius.br, height / 2, width / 2);
        radius.bl = Math.min(radius.bl, height / 2, width / 2);

        ctx.beginPath();
        ctx.moveTo(x + radius.tl, y);
        ctx.lineTo(x + width - radius.tr, y);
        ctx.arcTo(x + width, y, x + width, y + radius.tr, radius.tr);
        ctx.lineTo(x + width, y + height - radius.br);
        ctx.arcTo(x + width, y + height, x + width - radius.br, y + height, radius.br);
        ctx.lineTo(x + radius.bl, y + height);
        ctx.arcTo(x, y + height, x, y + height - radius.bl, radius.bl);
        ctx.lineTo(x, y + radius.tl);
        ctx.arcTo(x, y, x + radius.tl, y, radius.tl);
        ctx.closePath();
    }

    // Helper function to shade a color (lighten or darken)
    // percent is -1 to 1 (e.g., 0.1 for 10% lighter, -0.1 for 10% darker)
    function shadeColor(color, percent) {
        let R = parseInt(color.substring(1, 3), 16);
        let G = parseInt(color.substring(3, 5), 16);
        let B = parseInt(color.substring(5, 7), 16);

        R = parseInt(R * (1 + percent));
        G = parseInt(G * (1 + percent));
        B = parseInt(B * (1 + percent));

        R = Math.max(0, Math.min(255, R));
        G = Math.max(0, Math.min(255, G));
        B = Math.max(0, Math.min(255, B));

        const RR = R.toString(16).padStart(2, '0');
        const GG = G.toString(16).padStart(2, '0');
        const BB = B.toString(16).padStart(2, '0');

        return `#${RR}${GG}${BB}`;
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const canvasWidth = originalImg.width + 2 * frameWidth;
    const canvasHeight = originalImg.height + 2 * frameWidth;
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    const canvasArea = canvasWidth * canvasHeight;
    const numTextureDots = Math.floor(canvasArea * textureDensityFactor / 1000);

    // --- Start drawing ---

    ctx.save();

    // 1. Define Tablet Shape as Clip Path & Fill Base Color
    drawRoundedRect(ctx, 0, 0, canvasWidth, canvasHeight, cornerRadius);
    ctx.fillStyle = frameColor;
    ctx.fill(); // Fill it first
    ctx.clip(); // Then clip. Future draws are within this path.

    // 2. Image Placement (directly on base, within clipped area)
    ctx.drawImage(originalImg, frameWidth, frameWidth, originalImg.width, originalImg.height);

    // 3. Stone Texture Dots (within clip, over image and frame area)
    ctx.globalAlpha = 0.5; // Texture dots are semi-transparent
    for (let i = 0; i < numTextureDots; i++) {
        const randX = Math.random() * canvasWidth;
        const randY = Math.random() * canvasHeight;
        const dotColor = Math.random() > 0.5 ? shadeColor(frameColor, 0.15) : shadeColor(frameColor, -0.15);
        ctx.fillStyle = dotColor;
        ctx.beginPath();
        ctx.arc(randX, randY, Math.random() * 1.5 + 0.5, 0, Math.PI * 2);
        ctx.fill();
    }
    ctx.globalAlpha = 1.0; // Reset alpha

    // 4. Crack Lines (within clip, over image and frame area)
    ctx.globalAlpha = 0.6; // Cracks are also semi-transparent
    for (let i = 0; i < crackCount; i++) {
        ctx.strokeStyle = shadeColor(borderColor, -0.3); // Darker cracks
        ctx.lineWidth = Math.random() * 1.2 + 0.5;

        const sx = Math.random() * canvasWidth;
        const sy = Math.random() * canvasHeight;
        ctx.beginPath();
        ctx.moveTo(sx, sy);

        const numSegments = Math.floor(Math.random() * 3) + 2; // 2 to 4 segments
        let currX = sx;
        let currY = sy;
        const maxCrackSegmentLength = frameWidth > 0 ? frameWidth * 0.7 : canvasWidth * 0.1;

        for (let j = 0; j < numSegments; j++) {
            const nextX = currX + (Math.random() - 0.5) * maxCrackSegmentLength;
            const nextY = currY + (Math.random() - 0.5) * maxCrackSegmentLength;
            ctx.lineTo(nextX, nextY);
            currX = nextX;
            currY = nextY;
        }
        ctx.stroke();
    }
    ctx.globalAlpha = 1.0; // Reset alpha

    ctx.restore(); // Remove the clip path

    // 5. Outer Border Stroke for the Tablet
    const outerBorderWidth = Math.max(1.5, frameWidth * 0.06);
    drawRoundedRect(ctx, outerBorderWidth / 2, outerBorderWidth / 2, canvasWidth - outerBorderWidth, canvasHeight - outerBorderWidth, Math.max(0, cornerRadius - outerBorderWidth / 2));
    ctx.strokeStyle = borderColor;
    ctx.lineWidth = outerBorderWidth;
    ctx.stroke();
    
    // Optional: A very subtle inner highlight on the border for a bit more depth
    if (outerBorderWidth > 1) {
        const highlightWidth = outerBorderWidth * 0.3;
         drawRoundedRect(ctx, outerBorderWidth - highlightWidth/2 , outerBorderWidth - highlightWidth/2, canvasWidth - (outerBorderWidth*2) + highlightWidth, canvasHeight- (outerBorderWidth*2) + highlightWidth, Math.max(0, cornerRadius - outerBorderWidth));
        ctx.strokeStyle = shadeColor(borderColor, 0.25); // Lighter shade of border
        ctx.lineWidth = highlightWidth;
        ctx.stroke();
    }


    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 Ancient Roman Greek Tablet Frame Creator is a tool designed to enhance images by wrapping them in a stylized frame resembling ancient Roman or Greek tablets. Users can customize various aspects of the frame including width, color, texture, and borders to create a unique, aged look for their images. This tool is ideal for artists, historians, educators, or anyone interested in presenting images with a classical aesthetic, whether for projects, social media, or personal collections.

Leave a Reply

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