Please bookmark this page to avoid losing your image tool!

Photo Polaroid Effect Editor

(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.
/**
 * Applies a Polaroid effect to an image, complete with a frame, caption, rotation, and vintage filter.
 * This function returns a canvas element displaying the final image.
 *
 * @param {HTMLImageElement} originalImg The original image object to transform.
 * @param {string} [captionText='My Photo'] The text to display in the bottom margin of the polaroid.
 * @param {number} [rotation=-5] The rotation angle in degrees for a candid look.
 * @param {string} [fontFamily='Permanent Marker'] The font for the caption. It's best to use a Google Font or a web-safe font.
 * @param {number} [fontSize=24] The font size for the caption in pixels.
 * @param {string} [fontColor='#333333'] The color of the caption text.
 * @param {string} [backgroundColor='#fdfdfd'] The background color of the polaroid frame (typically off-white).
 * @param {number} [padding=15] The padding around the top and sides of the image within the frame.
 * @param {number} [bottomPadding=70] The padding at the bottom of the image, where the caption is written.
 * @returns {Promise<HTMLCanvasElement>} A promise that resolves with the canvas element containing the polaroid image.
 */
async function processImage(originalImg, captionText = 'My Photo', rotation = -5, fontFamily = 'Permanent Marker', fontSize = 24, fontColor = '#333333', backgroundColor = '#fdfdfd', padding = 15, bottomPadding = 70) {

    // 1. Dynamically load the specified font if it's not a standard web-safe font.
    // This ensures custom fonts from Google Fonts are available for rendering on the canvas.
    const fontId = `google-font-style-${fontFamily.replace(/\s/g, '-')}`;
    const isWebSafeFont = /^(arial|helvetica|times new roman|times|courier new|courier|verdana|georgia|palatino|garamond|bookman|comic sans ms|trebuchet ms|impact)$/i.test(fontFamily);

    if (!isWebSafeFont && !document.getElementById(fontId)) {
        const link = document.createElement('link');
        link.id = fontId;
        link.rel = 'stylesheet';
        link.href = `https://fonts.googleapis.com/css2?family=${fontFamily.replace(/\s/g, '+')}&display=swap`;
        document.head.appendChild(link);
    }
    
    // Wait for the font to be fully loaded and ready for use.
    try {
        await document.fonts.load(`${fontSize}px '${fontFamily}'`);
    } catch (e) {
        console.error(`Could not load font: "${fontFamily}". The browser will use a fallback font.`, e);
    }
    
    // 2. Calculate the dimensions of the polaroid and the final canvas.
    const polaroidWidth = originalImg.width + padding * 2;
    const polaroidHeight = originalImg.height + padding + bottomPadding;
    const shadowMargin = 25; // Extra space for the drop shadow to not be clipped.

    // Calculate the dimensions of the bounding box after rotation.
    const rad = Math.abs(rotation * Math.PI / 180);
    const bboxWidth = Math.ceil(polaroidWidth * Math.cos(rad) + polaroidHeight * Math.sin(rad));
    const bboxHeight = Math.ceil(polaroidWidth * Math.sin(rad) + polaroidHeight * Math.cos(rad));

    const canvasWidth = bboxWidth + shadowMargin * 2;
    const canvasHeight = bboxHeight + shadowMargin * 2;

    // 3. Create and configure the canvas element.
    const canvas = document.createElement('canvas');
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    const ctx = canvas.getContext('2d');

    // 4. Transform the context to draw the rotated polaroid in the center of the canvas.
    ctx.translate(canvasWidth / 2, canvasHeight / 2);
    ctx.rotate(rotation * Math.PI / 180);

    // Center the polaroid drawing operations around the new (0,0) origin.
    const startX = -polaroidWidth / 2;
    const startY = -polaroidHeight / 2;

    // 5. Draw the drop shadow for a 3D effect.
    ctx.shadowColor = 'rgba(0, 0, 0, 0.35)';
    ctx.shadowBlur = 18;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 8;
    
    // 6. Draw the polaroid frame.
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(startX, startY, polaroidWidth, polaroidHeight);
    
    // Reset shadow for all subsequent drawing operations.
    ctx.shadowColor = 'transparent';

    // 7. Draw the image with a subtle vintage filter for a more authentic look.
    const imgX = startX + padding;
    const imgY = startY + padding;
    ctx.filter = 'sepia(0.2) saturate(1.2) contrast(1.1) brightness(1.05)';
    ctx.drawImage(originalImg, imgX, imgY, originalImg.width, originalImg.height);
    ctx.filter = 'none';

    // Draw a subtle inner border to make the photo look slightly recessed.
    ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)';
    ctx.lineWidth = 1;
    ctx.strokeRect(imgX - 0.5, imgY - 0.5, originalImg.width + 1, originalImg.height + 1);

    // 8. Draw the caption text if it has been provided.
    if (captionText) {
        ctx.fillStyle = fontColor;
        ctx.font = `${fontSize}px '${fontFamily}'`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        // Calculate the position to center the text in the bottom margin area.
        const textX = 0; // The horizontal center of the rotated polaroid is our new origin.
        const textY = imgY + originalImg.height + (bottomPadding / 2);

        ctx.fillText(captionText, textX, textY);
    }
    
    // 9. Return the final canvas element.
    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 Photo Polaroid Effect Editor allows users to transform their images into stylized polaroid representations. The tool adds a classic polaroid frame around the image, features customizable captions, and includes options for rotation and vintage filters. This tool is perfect for creating nostalgic photo displays, enhancing social media posts, generating personalized prints, or simply adding a creative touch to digital images.

Leave a Reply

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