Please bookmark this page to avoid losing your image tool!

Image Photostrip 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.
/**
 * Creates a photostrip effect from a single image by repeating it in a strip.
 *
 * @param {HTMLImageElement} originalImg The original image object to be repeated in the strip.
 * @param {number} numFrames The total number of frames in the photostrip. Defaults to 4.
 * @param {string} orientation The orientation of the strip ('vertical' or 'horizontal'). Defaults to 'vertical'.
 * @param {number} spacing The space in pixels between each photo frame. Defaults to 10.
 * @param {string} stripColor A CSS color string for the background color of the photostrip film. Defaults to '#FFFFFF' (white).
 * @param {number} padding The padding in pixels around the photos, creating the border. Defaults to 25.
 * @param {string} addPerforations Whether to add film sprocket holes ('true' or 'false'). Defaults to 'true'.
 * @param {number} frameWidth The width of each individual photo frame. The height is calculated automatically to maintain the aspect ratio. Defaults to 250.
 * @returns {HTMLCanvasElement} A canvas element containing the generated photostrip image.
 */
function processImage(
    originalImg,
    numFrames = 4,
    orientation = 'vertical',
    spacing = 10,
    stripColor = '#FFFFFF',
    padding = 25,
    addPerforations = 'true',
    frameWidth = 250
) {
    // 1. Parameter Sanity Checks & Type Coercion
    const pNumFrames = parseInt(numFrames, 10) || 4;
    const pOrientation = String(orientation).toLowerCase();
    const pSpacing = Math.max(0, parseInt(spacing, 10) || 10);
    const pStripColor = String(stripColor);
    const pPadding = Math.max(0, parseInt(padding, 10) || 25);
    const pAddPerforations = String(addPerforations).toLowerCase() === 'true';
    const pFrameWidth = Math.max(1, parseInt(frameWidth, 10) || 250);

    // 2. Calculate Dimensions
    const aspectRatio = originalImg.naturalHeight / originalImg.naturalWidth;
    const frameHeight = pFrameWidth * aspectRatio;
    const totalPadding = 2 * pPadding;

    let canvasWidth, canvasHeight;
    if (pOrientation === 'horizontal') {
        canvasWidth = (pNumFrames * pFrameWidth) + ((pNumFrames - 1) * pSpacing) + totalPadding;
        canvasHeight = frameHeight + totalPadding;
    } else { // 'vertical' is the default
        canvasWidth = pFrameWidth + totalPadding;
        canvasHeight = (pNumFrames * frameHeight) + ((pNumFrames - 1) * pSpacing) + totalPadding;
    }

    // 3. Setup Canvas
    const canvas = document.createElement('canvas');
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    const ctx = canvas.getContext('2d');

    // 4. Draw Background
    ctx.fillStyle = pStripColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 5. Draw Image Frames
    for (let i = 0; i < pNumFrames; i++) {
        let x, y;
        if (pOrientation === 'horizontal') {
            x = pPadding + i * (pFrameWidth + pSpacing);
            y = pPadding;
        } else {
            x = pPadding;
            y = pPadding + i * (frameHeight + pSpacing);
        }

        // Add a subtle shadow for each photo for a 3D effect
        ctx.shadowColor = 'rgba(0, 0, 0, 0.4)';
        ctx.shadowBlur = 8;
        ctx.shadowOffsetX = 2;
        ctx.shadowOffsetY = 2;

        ctx.drawImage(originalImg, x, y, pFrameWidth, frameHeight);
        
        // Reset shadow for subsequent drawings
        ctx.shadowColor = 'transparent';
    }

    // 6. Draw Film Perforations (Sprocket Holes)
    if (pAddPerforations && pPadding >= 15) {
        ctx.fillStyle = '#444444';
        const holeSize = Math.max(4, Math.floor(pPadding / 5));
        const holeRadius = holeSize / 2;

        if (pOrientation === 'horizontal') {
            const yTop = pPadding / 2;
            const yBottom = canvas.height - pPadding / 2;
            // Draw a single perforation set above/below the center of each frame
            for (let i = 0; i < pNumFrames; i++) {
                 const x = pPadding + i * (pFrameWidth + pSpacing) + pFrameWidth / 2;
                 // Top hole
                 ctx.beginPath();
                 if (ctx.roundRect) {
                     ctx.roundRect(x - holeSize * 1.5, yTop - holeRadius, holeSize * 3, holeSize, holeRadius);
                 } else { // Fallback for older browsers
                     ctx.rect(x - holeSize * 1.5, yTop - holeRadius, holeSize * 3, holeSize);
                 }
                 ctx.fill();
                 // Bottom hole
                 ctx.beginPath();
                 if (ctx.roundRect) {
                     ctx.roundRect(x - holeSize * 1.5, yBottom - holeRadius, holeSize * 3, holeSize, holeRadius);
                 } else {
                     ctx.rect(x - holeSize * 1.5, yBottom - holeRadius, holeSize * 3, holeSize);
                 }
                 ctx.fill();
            }
        } else { // Vertical orientation
            const xLeft = pPadding / 2;
            const xRight = canvas.width - pPadding / 2;
            // Place perforations in the gaps between the photo frames
            for (let i = 0; i < pNumFrames - 1; i++) {
                const y = pPadding + (i + 1) * frameHeight + (i + 0.5) * pSpacing;
                
                // Left side hole
                ctx.beginPath();
                if (ctx.roundRect) {
                    ctx.roundRect(xLeft - holeRadius, y - holeSize * 1.5, holeSize, holeSize * 3, holeRadius);
                } else {
                    ctx.rect(xLeft - holeRadius, y - holeSize * 1.5, holeSize, holeSize * 3);
                }
                ctx.fill();
                
                // Right side hole
                ctx.beginPath();
                if (ctx.roundRect) {
                    ctx.roundRect(xRight - holeRadius, y - holeSize * 1.5, holeSize, holeSize * 3, holeRadius);
                } else {
                    ctx.rect(xRight - holeRadius, y - holeSize * 1.5, holeSize, holeSize * 3);
                }
                ctx.fill();
            }
        }
    }

    // 7. Return the completed canvas
    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 Photostrip Generator allows users to create a photostrip effect from a single image by repeating it in a series of frames. Users can customize the number of frames, the orientation of the strip (either horizontal or vertical), spacing between frames, background color, padding, and whether to add film perforations. This tool is ideal for creating visual displays for photo albums, social media graphics, or any project that benefits from a unique photo strip style.

Leave a Reply

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