Please bookmark this page to avoid losing your image tool!

AI Powered Image Website 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.
function processImage(originalImg, siteTitle = "My Awesome Website", theme = "auto") {

    // --- Helper: Color Analysis & Manipulation ---

    /**
     * Extracts a color palette from an image using color quantization.
     * @param {HTMLImageElement} img The source image.
     * @param {number} count The number of colors to return.
     * @returns {Array<object>} An array of color objects like {r, g, b}.
     */
    const getPalette = (img, count = 6) => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d', { willReadFrequently: true });
        // Downscale image for performance
        const maxDim = 100;
        const scale = Math.min(maxDim / img.width, maxDim / img.height, 1);
        canvas.width = img.width * scale;
        canvas.height = img.height * scale;
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
        const colorCounts = {};
        const colorSums = {};
        // Quantize colors to 4 bits per channel (12-bit color space)
        const bitShift = 4;

        for (let i = 0; i < imageData.length; i += 4) {
            const r = imageData[i];
            const g = imageData[i + 1];
            const b = imageData[i + 2];
            const alpha = imageData[i + 3];

            // Ignore transparent or near-transparent pixels
            if (alpha < 128) {
                continue;
            }

            // Create a quantized color key
            const rKey = r >> bitShift;
            const gKey = g >> bitShift;
            const bKey = b >> bitShift;
            const key = (rKey << 8) | (gKey << 4) | bKey;

            if (!colorCounts[key]) {
                colorCounts[key] = 0;
                colorSums[key] = { r: 0, g: 0, b: 0 };
            }
            colorCounts[key]++;
            colorSums[key].r += r;
            colorSums[key].g += g;
            colorSums[key].b += b;
        }

        const sortedKeys = Object.keys(colorCounts).sort((a, b) => colorCounts[b] - colorCounts[a]);
        const palette = [];
        for (let i = 0; i < Math.min(sortedKeys.length, count * 2); i++) {
            const key = sortedKeys[i];
            const numPixels = colorCounts[key];
            const sum = colorSums[key];
            const avgColor = {
                r: Math.round(sum.r / numPixels),
                g: Math.round(sum.g / numPixels),
                b: Math.round(sum.b / numPixels),
            };
            palette.push(avgColor);
        }
        return palette.slice(0, count);
    };

    /**
     * Calculates the relative luminance of an RGB color.
     * @param {number} r Red value (0-255).
     * @param {number} g Green value (0-255).
     * @param {number} b Blue value (0-255).
     * @returns {number} Luminance (0-1).
     */
    const getLuminance = (r, g, b) => {
        const a = [r, g, b].map(v => {
            v /= 255;
            return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
        });
        return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
    };

    /**
     * Calculates the contrast ratio between two RGB colors.
     * @param {object} rgb1 First color {r, g, b}.
     * @param {object} rgb2 Second color {r, g, b}.
     * @returns {number} The contrast ratio.
     */
    const getContrast = (rgb1, rgb2) => {
        const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b);
        const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b);
        const brightest = Math.max(lum1, lum2);
        const darkest = Math.min(lum1, lum2);
        return (brightest + 0.05) / (darkest + 0.05);
    };

    /**
     * Converts an RGB color object to a CSS rgb() string.
     */
    const rgbToCss = (rgb) => `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;

    /**
     * Converts an RGB color to HSL.
     */
    const rgbToHsl = (r, g, b) => {
        r /= 255; g /= 255; b /= 255;
        const max = Math.max(r, g, b), min = Math.min(r, g, b);
        let h = 0, s = 0, l = (max + min) / 2;
        if (max !== min) {
            const d = max - min;
            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
            switch (max) {
                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                case g: h = (b - r) / d + 2; break;
                case b: h = (r - g) / d + 4; break;
            }
            h /= 6;
        }
        return { h: h * 360, s: s * 100, l: l * 100 };
    };

    // --- Main "AI" Logic ---

    // 1. Analyze Image to get color palette
    const rawPalette = getPalette(originalImg, 10);
    const paletteWithMeta = rawPalette.map(c => ({
        ...c,
        luminance: getLuminance(c.r, c.g, c.b),
        hsl: rgbToHsl(c.r, c.g, c.b)
    }));
    
    // 2. Select theme colors based on the palette
    let themeToUse = theme;
    if (theme === "auto") {
        const averageLuminance = paletteWithMeta.reduce((acc, c) => acc + c.luminance, 0) / paletteWithMeta.length;
        themeToUse = averageLuminance > 0.5 ? "light" : "dark";
    }

    paletteWithMeta.sort((a, b) => a.luminance - b.luminance);
    
    let bgColor, textColor;
    const darkFallback = {r: 18, g: 18, b: 18};
    const lightFallback = {r: 250, g: 250, b: 250};

    if (themeToUse === 'dark') {
        bgColor = paletteWithMeta[0] || darkFallback;
        textColor = paletteWithMeta[paletteWithMeta.length - 1] || lightFallback;
    } else {
        bgColor = paletteWithMeta[paletteWithMeta.length - 1] || lightFallback;
        textColor = paletteWithMeta[0] || darkFallback;
    }
    
    // Ensure sufficient contrast for base text (WCAG AA)
    if (getContrast(bgColor, textColor) < 4.5) {
        textColor = getLuminance(bgColor.r, bgColor.g, bgColor.b) > 0.5 ? darkFallback : lightFallback;
    }

    // Pick primary and accent colors from the remaining palette
    const remainingColors = paletteWithMeta.filter(c => c !== bgColor && c !== textColor);
    // Sort by saturation to find vibrant colors
    remainingColors.sort((a,b) => b.hsl.s - a.hsl.s);
    
    let primaryColor = remainingColors[0] || textColor;
    if (getContrast(bgColor, primaryColor) < 3) { // Ensure headings are readable (WCAG AA for large text)
         primaryColor = textColor;
    }
    
    let accentColor = remainingColors[1] || primaryColor;
    if (getContrast(bgColor, accentColor) < 3) {
        accentColor = primaryColor;
    }
    
    // Choose the best text color (black or white) for the accent button
    const accentContrastLight = getContrast(accentColor, {r:255,g:255,b:255});
    const accentContrastDark = getContrast(accentColor, {r:0,g:0,b:0});
    let accentTextColor = accentContrastLight > accentContrastDark ? lightFallback : darkFallback;


    // 3. Import Google Font
    const fontName = 'Montserrat';
    const fontUrl = `https://fonts.googleapis.com/css2?family=${fontName.replace(' ', '+')}:wght@400;700&display=swap`;
    if (!document.querySelector(`link[href="${fontUrl}"]`)) {
        const link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = fontUrl;
        document.head.appendChild(link);
    }
    
    // 4. Create CSS styles
    const css = `
        .ai-website, .ai-website * {
            box-sizing: border-box;
        }
        .ai-website {
            --bg-color: ${rgbToCss(bgColor)};
            --text-color: ${rgbToCss(textColor)};
            --primary-color: ${rgbToCss(primaryColor)};
            --accent-color: ${rgbToCss(accentColor)};
            --accent-text-color: ${rgbToCss(accentTextColor)};
            --font-family: '${fontName}', sans-serif;

            all: revert;
            font-family: var(--font-family);
            background-color: var(--bg-color);
            color: var(--text-color);
            text-align: center;
            line-height: 1.6;
            width: 100%;
            overflow: hidden;
            border: 1px solid rgba(128,128,128,0.2);
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
            border-radius: 8px;
        }
        .ai-website h1, .ai-website h2, .ai-website h3 { margin: 0; padding: 0; line-height: 1.2; }
        .ai-website p { margin: 0; }
        .ai-website a { color: var(--primary-color); text-decoration: none; }
        .ai-website-header { padding: 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(128,128,128,0.1); }
        .ai-website-header h1 { font-size: 1.5em; color: var(--primary-color); }
        .ai-website-nav a { color: var(--text-color); margin: 0 15px; opacity: 0.8; transition: opacity 0.3s ease; }
        .ai-website-nav a:hover { opacity: 1; color: var(--primary-color); }
        .ai-website-hero { padding: 60px 20px; background-image: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)), url(${originalImg.src}); background-size: cover; background-position: center; color: white; text-shadow: 2px 2px 4px rgba(0,0,0,0.5); }
        .ai-website-hero h2 { font-size: 2.5em; margin-bottom: 20px; color: white; }
        .ai-website .btn { background-color: var(--accent-color); color: var(--accent-text-color) !important; padding: 12px 25px; border-radius: 5px; font-weight: bold; display: inline-block; margin-top: 20px; border: none; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; }
        .ai-website .btn:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.2); }
        .ai-website-section { padding: 50px 20px; max-width: 800px; margin: 0 auto; }
        .ai-website-section h3 { font-size: 2em; color: var(--primary-color); margin-bottom: 20px; }
        .ai-website-gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; padding: 20px; }
        .ai-website-gallery img { width: 100%; height: 180px; object-fit: cover; border-radius: 5px; transition: transform 0.3s ease, filter 0.3s ease; }
        .ai-website-gallery img:hover { transform: scale(1.05); filter: brightness(1.1); }
        .ai-website-footer { padding: 20px; margin-top: 40px; border-top: 1px solid rgba(128,128,128,0.1); font-size: 0.9em; opacity: 0.7; }
    `;

    // 5. Create HTML Structure
    const html = `
      <header class="ai-website-header">
        <h1>${siteTitle}</h1>
        <nav class="ai-website-nav">
          <a href="#">Home</a>
          <a href="#">About</a>
          <a href="#">Contact</a>
        </nav>
      </header>
      <main>
        <section class="ai-website-hero">
          <h2>Crafted by AI, Inspired by Your Vision</h2>
          <p>A seamless digital experience, generated in seconds from your image.</p>
          <a href="#" class="btn">Learn More</a>
        </section>
        <section class="ai-website-section">
          <h3>Discover Our Story</h3>
          <p>Our intelligent design system analyzed your image to create a unique and compelling visual narrative. By extracting key colors, themes, and moods, we've built a foundation for a website that truly represents your brand. This is a journey into digital creativity.</p>
        </section>
        <section class="ai-website-section">
            <h3>Gallery</h3>
            <div class="ai-website-gallery">
                <img src="${originalImg.src}" alt="Gallery image 1" style="filter: saturate(1.2);">
                <img src="${originalImg.src}" alt="Gallery image 2" style="filter: grayscale(1);">
                <img src="${originalImg.src}" alt="Gallery image 3" style="filter: sepia(0.8);">
                <img src="${originalImg.src}" alt="Gallery image 4" style="filter: hue-rotate(90deg);">
            </div>
        </section>
      </main>
      <footer class="ai-website-footer">
        <p>&copy; ${new Date().getFullYear()} ${siteTitle}. Powered by AI.</p>
      </footer>
    `;

    // 6. Combine and Return the final element
    const container = document.createElement('div');
    container.className = 'ai-website';
    
    // Using a shadow DOM would be ideal for encapsulation, but for simple display, 
    // injecting a scoped style tag is sufficient and works everywhere.
    const styleElement = document.createElement('style');
    styleElement.textContent = css;
    
    const contentWrapper = document.createElement('div');
    contentWrapper.innerHTML = html;
    
    container.appendChild(styleElement);
    container.appendChild(contentWrapper);

    return container;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The AI Powered Image Website Creator is an innovative tool that allows users to create visually appealing websites based on their images. By analyzing the uploaded image to extract a color palette, the tool generates a themed website layout complete with HTML and CSS styling. Users can customize the title of their site and choose between light or dark themes. This tool is ideal for artists, photographers, and small business owners looking to quickly establish an online presence that reflects their visual style through automatic color selections and responsive design. Create your personalized web experience in seconds, effortlessly combining aesthetics with functionality.

Leave a Reply

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