Please bookmark this page to avoid losing your image tool!

Image Product Packaging 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.
/**
 * Creates a 3D product packaging mockup from an image.
 *
 * This function takes an image and projects it onto the front face of a 3D box.
 * The box's perspective, color, and other attributes can be customized.
 *
 * @param {Image} originalImg The original JavaScript Image object to use for the packaging.
 * @param {string} boxColor The base color of the box in HEX format (e.g., '#ffffff').
 * @param {number} angle The angle of the box's perspective in degrees (0-90).
 * @param {number} depthRatio The depth of the box as a ratio of its width (e.g., 0.5 for a depth half the width).
 * @param {number} scale The scale of the image on the front face of the box (0-1).
 * @param {number} shadowOpacity The opacity of the drop shadow (0-1). 0 to disable.
 * @returns {HTMLCanvasElement} A canvas element containing the product packaging mockup.
 */
async function processImage(originalImg, boxColor = '#ffffff', angle = 30, depthRatio = 0.5, scale = 0.9, shadowOpacity = 0.3) {

    /**
     * Internal helper to lighten or darken a HEX color.
     * @param {string} color The HEX color string.
     * @param {number} percent A value from -1 (black) to 1 (white).
     * @returns {string} The new shaded HEX color string.
     */
    const 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.0 + percent));
        G = parseInt(G * (1.0 + percent));
        B = parseInt(B * (1.0 + percent));

        R = (R < 255) ? R : 255;
        G = (G < 255) ? G : 255;
        B = (B < 255) ? B : 255;
        
        R = (R > 0) ? R : 0;
        G = (G > 0) ? G : 0;
        B = (B > 0) ? B : 0;

        const RR = ((R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16));
        const GG = ((G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16));
        const BB = ((B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16));

        return "#" + RR + GG + BB;
    };

    const imgW = originalImg.width;
    const imgH = originalImg.height;
    const rad = parseFloat(angle) * Math.PI / 180;
    const boxDepth = imgW * parseFloat(depthRatio);

    const dx = boxDepth * Math.cos(rad);
    const dy = boxDepth * Math.sin(rad);

    // Define the 8 vertices of the box in projected 2D space
    const points = {
        p0: { x: 0,         y: 0 },         // front top left
        p1: { x: imgW,      y: 0 },         // front top right
        p2: { x: imgW,      y: imgH },      // front bottom right
        p3: { x: 0,         y: imgH },      // front bottom left
        p4: { x: dx,        y: -dy },       // back top left
        p5: { x: imgW + dx, y: -dy },       // back top right
        p6: { x: imgW + dx, y: imgH - dy }, // back bottom right
        p7: { x: dx,        y: imgH - dy }  // back bottom left
    };

    // Find bounding box to determine canvas size
    const allPoints = Object.values(points);
    const minX = Math.min(...allPoints.map(p => p.x));
    const maxX = Math.max(...allPoints.map(p => p.x));
    const minY = Math.min(...allPoints.map(p => p.y));
    const maxY = Math.max(...allPoints.map(p => p.y));

    const padding = 50;
    const shadowBlur = 20;
    const shadowOffsetY = 30;

    const canvasWidth = maxX - minX + padding * 2;
    const canvasHeight = maxY - minY + padding * 2 + shadowOffsetY + shadowBlur;

    // Offset to center the box in the canvas
    const offsetX = -minX + padding;
    const offsetY = -minY + padding;

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

    // Apply global translation to center the drawing
    ctx.translate(offsetX, offsetY);
    
    // --- Draw Shadow ---
    if (shadowOpacity > 0) {
        ctx.save();
        ctx.beginPath();
        // Shadow is the projection of the bottom face, slightly offset and blurred
        ctx.moveTo(points.p3.x, points.p3.y + shadowOffsetY);
        ctx.lineTo(points.p2.x, points.p2.y + shadowOffsetY);
        ctx.lineTo(points.p6.x, points.p6.y + shadowOffsetY);
        ctx.lineTo(points.p7.x, points.p7.y + shadowOffsetY);
        ctx.closePath();
        
        ctx.fillStyle = `rgba(0, 0, 0, ${shadowOpacity})`;
        ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
        ctx.shadowBlur = shadowBlur;
        ctx.shadowOffsetY = 5;
        ctx.fill();
        ctx.restore();
    }

    // --- Draw Box Faces (from back to front) ---
    // Right side face (darker)
    ctx.fillStyle = shadeColor(boxColor, -0.20);
    ctx.beginPath();
    ctx.moveTo(points.p1.x, points.p1.y);
    ctx.lineTo(points.p5.x, points.p5.y);
    ctx.lineTo(points.p6.x, points.p6.y);
    ctx.lineTo(points.p2.x, points.p2.y);
    ctx.closePath();
    ctx.fill();

    // Top face (lighter)
    ctx.fillStyle = shadeColor(boxColor, 0.10);
    ctx.beginPath();
    ctx.moveTo(points.p0.x, points.p0.y);
    ctx.lineTo(points.p4.x, points.p4.y);
    ctx.lineTo(points.p5.x, points.p5.y);
    ctx.lineTo(points.p1.x, points.p1.y);
    ctx.closePath();
    ctx.fill();

    // Front face (base color and image)
    ctx.fillStyle = boxColor;
    ctx.fillRect(points.p0.x, points.p0.y, imgW, imgH);
    
    // Draw the product image on the front face
    const s = parseFloat(scale);
    const scaledW = imgW * s;
    const scaledH = imgH * s;
    const imgX = (imgW - scaledW) / 2;
    const imgY = (imgH - scaledH) / 2;
    ctx.drawImage(originalImg, imgX, imgY, scaledW, scaledH);
    
    // --- Draw Outlines for definition ---
    ctx.strokeStyle = shadeColor(boxColor, -0.40);
    ctx.lineWidth = 1;
    ctx.lineJoin = 'round';

    // Right face outline
    ctx.beginPath();
    ctx.moveTo(points.p1.x, points.p1.y);
    ctx.lineTo(points.p5.x, points.p5.y);
    ctx.lineTo(points.p6.x, points.p6.y);
    ctx.lineTo(points.p2.x, points.p2.y);
    ctx.closePath();
    ctx.stroke();

    // Top face outline
    ctx.beginPath();
    ctx.moveTo(points.p0.x, points.p0.y);
    ctx.lineTo(points.p4.x, points.p4.y);
    ctx.lineTo(points.p5.x, points.p5.y);
    ctx.lineTo(points.p1.x, points.p1.y);
    ctx.closePath();
    ctx.stroke();
    
    // Front face outline
    ctx.strokeRect(points.p0.x, points.p0.y, imgW, imgH);

    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 Product Packaging Creator is a versatile online tool designed for creating 3D product packaging mockups from images. Users can upload an image and apply it to the front face of a customizable 3D box. The tool allows for adjustments in box color, perspective angle, depth, size scaling of the image, and shadow opacity. This makes it ideal for graphic designers, product marketers, and e-commerce businesses looking to present their products in a professional and visually appealing manner. The generated mockups can be used for marketing materials, presentations, or online listings.

Leave a Reply

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