Please bookmark this page to avoid losing your image tool!

Image Cave Painting 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, frameThickness = 50, frameBaseColor = "#8B4513", jaggedness = 15, numSegmentsPerSide = 10, applySepiaToImage = 1) {

    // Helper function to adjust HEX color brightness (for texture)
    // percent is -1.0 (black) to 1.0 (white), 0 is no change.
    function adjustHexColor(hex, percent) {
        let r = parseInt(hex.slice(1, 3), 16);
        let g = parseInt(hex.slice(3, 5), 16);
        let b = parseInt(hex.slice(5, 7), 16);

        r = Math.round(Math.min(255, Math.max(0, r * (1 + percent))));
        g = Math.round(Math.min(255, Math.max(0, g * (1 + percent))));
        b = Math.round(Math.min(255, Math.max(0, b * (1 + percent))));
        
        const rHex = r.toString(16).padStart(2, '0');
        const gHex = g.toString(16).padStart(2, '0');
        const bHex = b.toString(16).padStart(2, '0');

        return `#${rHex}${gHex}${bHex}`;
    }

    // Helper function to create a jagged rectangular path
    function createJaggedRectPath(ctx, x, y, w, h, numSegments, jaggednessAmount) {
        const rand = (scale = 1) => (Math.random() - 0.5) * jaggednessAmount * 2 * scale;

        ctx.moveTo(x + rand(0.5), y + rand(0.5)); // Start near top-left

        // Top edge
        for (let i = 1; i <= numSegments; i++) {
            // Distribute points somewhat evenly but with randomness
            const progress = i / numSegments;
            const targetX = x + w * progress;
            // Jitter points around the target X for this segment
            const currentX = targetX + rand(0.5 / numSegments); 
            ctx.lineTo(currentX, y + rand());
        }
        ctx.lineTo(x + w + rand(0.5), y + rand(0.5)); // Ensure near top-right

        // Right edge
        for (let i = 1; i <= numSegments; i++) {
            const progress = i / numSegments;
            const targetY = y + h * progress;
            const currentY = targetY + rand(0.5 / numSegments);
            ctx.lineTo(x + w + rand(), currentY);
        }
        ctx.lineTo(x + w + rand(0.5), y + h + rand(0.5)); // Ensure near bottom-right

        // Bottom edge
        for (let i = 1; i <= numSegments; i++) {
            const progress = i / numSegments;
            const targetX = x + w * (1 - progress); // Iterate from right to left
            const currentX = targetX + rand(0.5 / numSegments);
            ctx.lineTo(currentX, y + h + rand());
        }
        ctx.lineTo(x + rand(0.5), y + h + rand(0.5)); // Ensure near bottom-left
        
        // Left edge
        for (let i = 1; i <= numSegments; i++) {
            const progress = i / numSegments;
            const targetY = y + h * (1 - progress); // Iterate from bottom to top
            const currentY = targetY + rand(0.5 / numSegments);
            ctx.lineTo(x + rand(), currentY);
        }
        // closePath() will connect the last point to the initial moveTo point.
    }

    const imgW = originalImg.naturalWidth || originalImg.width;
    const imgH = originalImg.naturalHeight || originalImg.height;

    if (!(imgW > 0 && imgH > 0)) {
        console.error("Image has zero width or height. Cannot process.");
        const errCanvas = document.createElement('canvas');
        errCanvas.width = 100; errCanvas.height = 30;
        const errCtx = errCanvas.getContext('2d');
        errCtx.fillStyle = 'red';
        errCtx.fillRect(0,0,100,30);
        errCtx.fillStyle = 'white';
        errCtx.fillText("Invalid Image", 10, 20);
        return errCanvas;
    }

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

    // Adjust frameThickness if it's too large relative to image size
    const maxFrameThickness = Math.min(imgW / 2, imgH / 2, frameThickness);
    const actualFrameThickness = Math.max(0, maxFrameThickness);


    outCanvas.width = imgW + 2 * actualFrameThickness;
    outCanvas.height = imgH + 2 * actualFrameThickness;

    // 1. Draw Frame Background (Solid Color)
    outCtx.fillStyle = frameBaseColor;
    outCtx.fillRect(0, 0, outCanvas.width, outCanvas.height);

    // 2. Add Speckle Texture to Frame
    // Apply texture only to the frame area if frameThickness > 0
    if (actualFrameThickness > 0) {
        const numSpeckles = Math.floor((outCanvas.width * outCanvas.height - imgW * imgH) * 0.015); // Density relative to frame area
        for (let i = 0; i < numSpeckles; i++) {
            // Randomly pick a point. If it's not in the image area, draw speckle.
            const speckleX = Math.random() * outCanvas.width;
            const speckleY = Math.random() * outCanvas.height;

            if (speckleX < actualFrameThickness || speckleX >= outCanvas.width - actualFrameThickness ||
                speckleY < actualFrameThickness || speckleY >= outCanvas.height - actualFrameThickness) 
            {
                const colorVariation = (Math.random() * 0.5) - 0.25; // -25% to +25%
                const speckleColor = adjustHexColor(frameBaseColor, colorVariation);
                outCtx.fillStyle = speckleColor;
                const speckleSize = Math.random() * 2.5 + 0.5; 
                outCtx.fillRect(speckleX, speckleY, speckleSize, speckleSize);
            }
        }
    }


    // 3. Prepare Image (Apply Sepia if needed)
    let imageToDraw = originalImg;
    if (applySepiaToImage === 1) {
        const tempCanvas = document.createElement('canvas');
        const tempCtx = tempCanvas.getContext('2d');
        tempCanvas.width = imgW;
        tempCanvas.height = imgH;
        
        tempCtx.filter = 'sepia(1)';
        tempCtx.drawImage(originalImg, 0, 0, imgW, imgH);
        tempCtx.filter = 'none'; // Reset filter
        imageToDraw = tempCanvas;
    }
    
    // 4. Create Jagged Clipping Path and Draw Image
    outCtx.save();
    outCtx.beginPath();
    createJaggedRectPath(outCtx, 
        actualFrameThickness, 
        actualFrameThickness, 
        imgW, 
        imgH, 
        numSegmentsPerSide, 
        jaggedness
    );
    outCtx.closePath();
    outCtx.clip();
    
    outCtx.drawImage(imageToDraw, actualFrameThickness, actualFrameThickness, imgW, imgH);
    
    outCtx.restore(); // Remove clipping path effects

    // 5. Add inner shadow stroke to the edge of the image "opening"
    if (jaggedness > 0 && actualFrameThickness > 0) {
        outCtx.save(); 
        outCtx.beginPath();
        createJaggedRectPath(outCtx, actualFrameThickness, actualFrameThickness, imgW, imgH, numSegmentsPerSide, jaggedness);
        outCtx.closePath();

        outCtx.strokeStyle = 'rgba(0,0,0,0.3)'; 
        // Make shadow width relative to jaggedness but not too large, ensure it's at least 1px
        outCtx.lineWidth = Math.max(1, Math.min(jaggedness * 0.2, actualFrameThickness * 0.1)); 
        outCtx.stroke();
        
        outCtx.restore(); 
    }

    return outCanvas;
}

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 Cave Painting Frame Creator is a versatile online tool for enhancing images by adding a unique, jagged frame reminiscent of ancient cave paintings. Users can customize the frame’s thickness, base color, and jaggedness, as well as apply a sepia tone to the image for a vintage effect. This tool is ideal for artists, designers, and anyone looking to create visually striking images for presentations, social media, or personal projects. By transforming ordinary images into artistic pieces, it caters to both creative expression and fun experimentation.

Leave a Reply

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

Other Image Tools:

Image Cryptozoology Specimen Card Creator

Image Impressionist Painting Frame Creator

Image Paleontological Specimen Label Creator

Image Wizard’s Magical Tome Creator

Image Space Bounty Hunter Poster Creator

Image Government Classified Document Creator

Image Evidence File Creator for Ghost Hunters

Image Multiverse Passport Creator

Celtic Illuminated Manuscript Image Creator

Image Occult Grimoire Page Creator

Image Steampunk Invention Blueprint Creator

Image Cathedral Window Frame Creator

Image 8-Bit Pixel Art Frame Creator

Image Revolutionary Manifesto Page Creator

Mythical Kingdom Image Document Creator

Image Role-Playing Game Character Sheet Creator

Baroque Portrait Frame Creator Tool

Image Royal Decree Proclamation Creator

Image Paranormal Investigation File Creator

Victorian Séance Invitation Image Creator

Image Vintage Apothecary Label Creator

Image Archaeological Discovery Document Creator

Image Witch’s Spell Book Page Creator

Image Expedition Map Creator

Image Sherlock Holmes Case File Creator

Image Time Traveler’s Document Creator

Image Cyberpunk Corporate ID Creator

Image Time Period Authentication Creator

Viking Runestone Frame Image Creator

Image Vintage Arcade Cabinet Art Creator

Byzantine Mosaic Frame Creator

Image Fighting Game Character Select Screen Creator

Image UFO Encounter Documentation Creator

Image Fantasy Realm Map Creator

Image Interdimensional Travel Permit Creator

Image Mad Scientist’s Laboratory Notes Creator

See All →