Please bookmark this page to avoid losing your image tool!

Image Pet Shop On A Couch

(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, couchColor = '#D2691E', wallColor = '#ADD8E6', petName = 'My Pet', price = 99.99) {

    /**
     * Dynamically loads a font from Google Fonts and waits for it to be ready for canvas use.
     * @param {string} fontFamily The name of the font family to load.
     */
    const loadGoogleFont = async (fontFamily) => {
        const fontId = `google-font-${fontFamily.replace(/ /g, '-')}`;
        // Check if the font's <link> tag is already added
        if (document.getElementById(fontId)) {
            try {
                // If so, just ensure it's loaded for the canvas context
                await document.fonts.load(`12px "${fontFamily}"`);
            } catch (e) {
                console.warn(`Font ${fontFamily} might not be available for canvas.`);
            }
            return;
        }

        const link = document.createElement('link');
        link.id = fontId;
        link.rel = 'stylesheet';
        link.href = `https://fonts.googleapis.com/css2?family=${fontFamily.replace(/ /g, '+')}&display=swap`;

        const fontPromise = new Promise((resolve) => {
            link.onload = resolve;
            link.onerror = () => {
                console.error(`Failed to load Google Font: ${fontFamily}`);
                resolve(); // Resolve anyway to not block the process
            };
        });

        document.head.appendChild(link);
        await fontPromise;

        // After the stylesheet is loaded, wait for the font to be ready for drawing
        try {
            await document.fonts.load(`12px "${fontFamily}"`);
        } catch (e) {
            console.warn(`Font ${fontFamily} could not be loaded for canvas rendering.`);
        }
    };

    /**
     * Adjusts a hex color by a given amount.
     * @param {string} color - The hex color string (e.g., '#RRGGBB').
     * @param {number} amount - The amount to adjust each channel by (-255 to 255).
     * @returns {string} The adjusted hex color string.
     */
    const adjustColor = (color, amount) => {
        return '#' + color.replace(/^#/, '').replace(/../g, c => ('0' + Math.min(255, Math.max(0, parseInt(c, 16) + amount)).toString(16)).substr(-2));
    };

    // Load fonts needed for the scene
    await Promise.all([
        loadGoogleFont('Caveat'),
        loadGoogleFont('Patrick Hand')
    ]);

    // Canvas Setup
    const canvas = document.createElement('canvas');
    const canvasWidth = 800;
    const canvasHeight = 600;
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    const ctx = canvas.getContext('2d');
    ctx.textBaseline = 'middle';
    ctx.textAlign = 'center';

    // --- Draw Scene ---

    // 1. Background (Wall and Floor)
    const floorY = 450;
    ctx.fillStyle = wallColor;
    ctx.fillRect(0, 0, canvasWidth, floorY);

    ctx.fillStyle = '#C2B280'; // Floor color
    ctx.fillRect(0, floorY, canvasWidth, canvasHeight - floorY);

    ctx.fillStyle = '#FFFFFF'; // Baseboard
    ctx.fillRect(0, floorY - 10, canvasWidth, 10);
    ctx.fillStyle = '#E0E0E0';
    ctx.fillRect(0, floorY - 3, canvasWidth, 3);

    // 2. Pet Shop Shelves and Products
    const shelfColor = '#8B4513';
    ctx.fillStyle = shelfColor;
    ctx.fillRect(50, 150, 700, 15); // Top shelf
    ctx.fillStyle = adjustColor(shelfColor, -20);
    ctx.fillRect(50, 165, 700, 5);

    ctx.fillStyle = shelfColor;
    ctx.fillRect(50, 300, 700, 15); // Bottom shelf
    ctx.fillStyle = adjustColor(shelfColor, -20);
    ctx.fillRect(50, 315, 700, 5);

    // Products on shelves
    ctx.fillStyle = '#DC143C'; // Red ball
    ctx.beginPath();
    ctx.arc(100, 140, 10, 0, 2 * Math.PI);
    ctx.fill();
    ctx.fillStyle = 'rgba(255,255,255,0.3)';
    ctx.beginPath();
    ctx.arc(95, 135, 3, 0, 2 * Math.PI);
    ctx.fill();

    ctx.fillStyle = '#4682B4'; // Toy box
    ctx.fillRect(500, 100, 60, 50);
    ctx.fillStyle = '#5F9EA0';
    ctx.font = '14px Arial';
    ctx.fillText('TOYS', 530, 125);

    ctx.fillStyle = '#FFD700'; // Food bag
    ctx.fillRect(150, 250, 50, 50);
    ctx.fillStyle = '#000000';
    ctx.font = '12px "Patrick Hand", sans-serif';
    ctx.fillText('FOOD', 175, 275);

    // 3. The Couch
    const couch_x = 150;
    const couch_y = 380;
    const couch_w = 500;

    const highlightColor = adjustColor(couchColor, 20);
    const shadowColor = adjustColor(couchColor, -30);

    // Couch Base shadow
    ctx.fillStyle = 'rgba(0,0,0,0.1)';
    ctx.fillRect(couch_x - 40, couch_y + 150, couch_w + 80, 20);

    // Structure
    ctx.fillStyle = couchColor;
    ctx.fillRect(couch_x, couch_y, couch_w, 80); // Backrest
    ctx.fillRect(couch_x - 40, couch_y + 20, 40, 60); // Left arm
    ctx.fillRect(couch_x + couch_w, couch_y + 20, 40, 60); // Right arm

    // Highlights
    ctx.fillStyle = highlightColor;
    ctx.fillRect(couch_x, couch_y, couch_w, 10); // Backrest top
    ctx.fillRect(couch_x - 40, couch_y + 20, 40, 10); // Left arm top
    ctx.fillRect(couch_x + couch_w, couch_y + 20, 40, 10); // Right arm top
    ctx.fillRect(couch_x, couch_y + 60, couch_w, 60); // Seat

    // Base & Legs
    ctx.fillStyle = shadowColor;
    ctx.fillRect(couch_x - 40, couch_y + 120, couch_w + 80, 30);
    ctx.fillStyle = adjustColor(shelfColor, -40);
    ctx.fillRect(couch_x - 20, couch_y + 150, 20, 20); // Left leg
    ctx.fillRect(couch_x + couch_w, couch_y + 150, 20, 20); // Right leg

    // 4. The Pet (originalImg)
    const maxWidth = couch_w - 40;
    const maxHeight = 280;
    const ratio = Math.min(maxWidth / originalImg.width, maxHeight / originalImg.height);
    const petWidth = originalImg.width * ratio;
    const petHeight = originalImg.height * ratio;

    const petX = couch_x + (couch_w - petWidth) / 2;
    const petBottom = couch_y + 115;
    const petY = petBottom - petHeight;

    // Pet shadow
    ctx.save();
    ctx.filter = 'blur(8px)';
    ctx.fillStyle = 'rgba(0, 0, 0, 0.35)';
    ctx.beginPath();
    ctx.ellipse(petX + petWidth / 2, petBottom + 5, petWidth / 2 * 0.9, 10, 0, 0, 2 * Math.PI);
    ctx.fill();
    ctx.restore();

    // Draw the image
    ctx.drawImage(originalImg, petX, petY, petWidth, petHeight);

    // 5. Price Tag
    const tagX = 670, tagY = 410, tagW = 100, tagH = 50;
    ctx.strokeStyle = '#000';
    ctx.lineWidth = 1.5;
    ctx.fillStyle = '#F5DEB3';
    ctx.beginPath();
    ctx.moveTo(tagX, tagY);
    ctx.lineTo(tagX + tagW - 15, tagY);
    ctx.lineTo(tagX + tagW, tagY + tagH / 2);
    ctx.lineTo(tagX + tagW - 15, tagY + tagH);
    ctx.lineTo(tagX, tagY + tagH);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();

    ctx.beginPath(); // Tag hole
    ctx.arc(tagX + 10, tagY + 15, 4, 0, 2 * Math.PI);
    ctx.stroke();

    ctx.beginPath(); // String
    ctx.moveTo(tagX + 10, tagY + 15);
    ctx.quadraticCurveTo(tagX + 30, tagY - 20, 680, 420);
    ctx.stroke();

    ctx.fillStyle = '#8B0000';
    ctx.font = `28px "Caveat", cursive`;
    ctx.fillText(`$${price.toFixed(2)}`, tagX + tagW / 2 + 5, tagY + tagH / 2 + 3);

    // 6. Pet Name Tag
    if (petName.trim() !== '') {
        const heartSize = Math.max(15, Math.min(25, petWidth / 10));
        const hx = petX + petWidth / 2;
        const hy = petY + Math.min(petHeight * 0.3, heartSize * 2.5);

        ctx.lineWidth = 2;
        ctx.strokeStyle = "gold";
        ctx.fillStyle = '#E32636';

        ctx.beginPath();
        const topCurveHeight = heartSize * 0.3;
        const bottomCurveHeight = heartSize*1.4;
        ctx.moveTo(hx, hy - topCurveHeight);
        ctx.bezierCurveTo(hx, hy - topCurveHeight, hx - heartSize/2, hy - topCurveHeight, hx - heartSize/2, hy);
        ctx.bezierCurveTo(hx - heartSize, hy, hx- heartSize, hy + bottomCurveHeight/2, hx, hy + bottomCurveHeight);
        ctx.bezierCurveTo(hx, hy + bottomCurveHeight, hx + heartSize, hy + bottomCurveHeight/2, hx+ heartSize, hy);
        ctx.bezierCurveTo(hx + heartSize, hy - topCurveHeight, hx, hy - topCurveHeight, hx, hy- topCurveHeight);
        ctx.closePath();

        ctx.fill();
        ctx.stroke();
        
        const fontSize = Math.floor(heartSize * 0.8);
        ctx.font = `${fontSize}px "Patrick Hand", sans-serif`;
        ctx.fillStyle = '#FFFFFF';
        ctx.fillText(petName, hx, hy + heartSize * 0.4, heartSize * 1.8);
    }

    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

Image Pet Shop on a Couch is an online tool that allows users to create a customized digital scene featuring a pet sitting on a couch. Users can upload an image of their pet, choose the colors of the couch and wall, set a name for the pet, and display a price tag. This tool is ideal for pet owners looking to create unique visuals for social media shares, greeting cards, or promotional materials about pets for sale. It combines art and technology, making the process of pet representation fun and engaging.

Leave a Reply

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