Please bookmark this page to avoid losing your image tool!

Photo Memory Maker

(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, caption = "Фото на память", date = "2024", filterType = "vintage", frameColor = "#FAFAFA", textColor = "#222222") {
    // 1. Dynamically load Google Font "Caveat" for a handwriting effect
    const fontName = 'Caveat';
    if (!document.getElementById('memory-maker-font')) {
        const link = document.createElement('link');
        link.id = 'memory-maker-font';
        link.rel = 'stylesheet';
        link.href = `https://fonts.googleapis.com/css2?family=${fontName}:wght@400;700&display=swap`;
        document.head.appendChild(link);
    }
    
    // Yield execution to allow the browser to load the font
    try {
        await document.fonts.load(`700 16px "${fontName}"`);
        await document.fonts.load(`400 16px "${fontName}"`);
    } catch(e) {
        console.warn("Font loading failed, falling back to basic cursive.", e);
    }

    // 2. Define dimensions and scale down if image is too large 
    // to prevent extremely slow processing or exceeding max canvas limits.
    let w = originalImg.width;
    let h = originalImg.height;
    const maxDim = 1500;
    if (w > maxDim || h > maxDim) {
        const ratio = Math.min(maxDim / w, maxDim / h);
        w = Math.floor(w * ratio);
        h = Math.floor(h * ratio);
    }

    // 3. Calculate polaroid-style borders
    // Thick uniform side/top borders, heavily extended bottom border for text
    const border = Math.floor(Math.max(w, h) * 0.045);
    const paddingX = Math.max(border, 15);
    const paddingYTop = paddingX;
    const paddingYBot = Math.max(border * 4, 80);

    const canvasW = w + paddingX * 2;
    const canvasH = h + paddingYTop + paddingYBot;

    // 4. Set up Canvas
    const canvas = document.createElement('canvas');
    canvas.width = canvasW;
    canvas.height = canvasH;
    const ctx = canvas.getContext('2d');

    // Draw the main frame background
    ctx.fillStyle = frameColor;
    ctx.fillRect(0, 0, canvasW, canvasH);

    // Subtle outer border for the polaroid paper effect
    ctx.strokeStyle = "#D3D3D3";
    ctx.lineWidth = 1;
    ctx.strokeRect(0, 0, canvasW, canvasH);

    // 5. Configure Photo Filters
    const filters = {
        "vintage": "sepia(0.5) contrast(1.1) brightness(0.9) saturate(0.8) hue-rotate(-10deg)",
        "sepia": "sepia(0.8) contrast(1.1)",
        "grayscale": "grayscale(1) contrast(1.1)",
        "bw": "grayscale(1) contrast(1.3) brightness(1.1)",
        "black-and-white": "grayscale(1) contrast(1.3) brightness(1.1)",
        "none": "none"
    };
    
    const selectedFilter = filters[filterType.toLowerCase()] || "none";

    // Fill a black rectangle behind the image area to support original transparency
    ctx.fillStyle = "#000000"; 
    ctx.fillRect(paddingX, paddingYTop, w, h);

    // Draw original image with CSS filters active
    ctx.filter = selectedFilter;
    ctx.drawImage(originalImg, paddingX, paddingYTop, w, h);
    ctx.filter = "none";

    // 6. Draw vignette effect if a filter is applied (adds depth and vintage feel)
    if (selectedFilter !== "none") {
        ctx.globalCompositeOperation = 'multiply';
        const cx = paddingX + w / 2;
        const cy = paddingYTop + h / 2;
        const radius = Math.sqrt(Math.pow(w/2, 2) + Math.pow(h/2, 2));
        const gradient = ctx.createRadialGradient(cx, cy, radius * 0.4, cx, cy, radius);
        gradient.addColorStop(0, "rgba(0, 0, 0, 0)");
        gradient.addColorStop(1, "rgba(20, 10, 0, 0.45)"); // Sepia-tinted shadow
        ctx.fillStyle = gradient;
        ctx.fillRect(paddingX, paddingYTop, w, h);
        ctx.globalCompositeOperation = 'source-over';
    }

    // Inner shadow/border framing the image print itself
    ctx.strokeStyle = "rgba(0, 0, 0, 0.08)";
    ctx.lineWidth = 2;
    ctx.strokeRect(paddingX, paddingYTop, w, h);

    // 7. Render Text (Caption & Date)
    ctx.fillStyle = textColor;

    // Position in the vertical center of bottom spacing
    const textCenterY = canvasH - (paddingYBot / 2);
    
    // Auto-scale font size for caption so it doesn't overflow
    let fontSize = Math.max(Math.floor(paddingYBot * 0.35), 14);
    ctx.font = `700 ${fontSize}px "${fontName}", cursive`;
    
    let textWidth = ctx.measureText(caption).width;
    while (textWidth > canvasW * 0.85 && fontSize > 12) {
        fontSize -= 2;
        ctx.font = `700 ${fontSize}px "${fontName}", cursive`;
        textWidth = ctx.measureText(caption).width;
    }

    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(caption, canvasW / 2, textCenterY);

    // Position the date neatly in the bottom-right corner
    if (date.trim() !== "") {
        let dateFontSize = Math.max(Math.floor(paddingYBot * 0.18), 10);
        ctx.font = `400 ${dateFontSize}px "${fontName}", cursive`;
        ctx.textAlign = "right";
        ctx.textBaseline = "bottom";
        const dateBottomMargin = Math.max(paddingX * 0.5, 10);
        ctx.fillText(date, canvasW - paddingX, canvasH - dateBottomMargin);
    }

    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

Photo Memory Maker is an image editing tool that transforms your digital photos into nostalgic, Polaroid-style keepsakes. It allows you to apply various vintage filters—such as sepia, grayscale, and black-and-white—along with a vignette effect to give your images a classic aesthetic. You can customize the look by adding a personalized caption and date in a handwritten font style, and choosing different frame colors to suit your preference. This tool is perfect for creating sentimental social media posts, digital scrapbooking, or designing personalized keepsakes for special memories.

Leave a Reply

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