Please bookmark this page to avoid losing your image tool!

Image To AR Model Converter

(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, physicalWidthInMeters = "1.0", orientation = "upright") {
    try {
        // Dynamically import Three.js and the GLTFExporter
        const THREE = await import('https://cdn.jsdelivr.net/npm/three@0.136.0/build/three.module.js');
        const { GLTFExporter } = await import('https://cdn.jsdelivr.net/npm/three@0.136.0/examples/jsm/exporters/GLTFExporter.js');
        
        // 1. Prepare image on canvas and cap resolution for AR performance
        const maxDim = 2048;
        let width = originalImg.naturalWidth || originalImg.width;
        let height = originalImg.naturalHeight || originalImg.height;
        
        if (!width || !height) {
            throw new Error("Invalid image dimensions.");
        }
        
        const aspect = width / height;
        
        if (width > maxDim || height > maxDim) {
            const ratio = Math.min(maxDim / width, maxDim / height);
            width = Math.round(width * ratio);
            height = Math.round(height * ratio);
        }
        
        const canvas = document.createElement('canvas');
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(originalImg, 0, 0, width, height);
        
        // 2. Setup Three.js scene
        const scene = new THREE.Scene();
        const physicalWidth = parseFloat(physicalWidthInMeters) || 1.0;
        const physicalHeight = physicalWidth / aspect;
        
        const texture = new THREE.CanvasTexture(canvas);
        texture.encoding = THREE.sRGBEncoding;
        
        const material = new THREE.MeshStandardMaterial({
            map: texture,
            side: THREE.DoubleSide,
            transparent: true,
            alphaTest: 0.05, 
            roughness: 0.7,
            metalness: 0.1
        });
        
        const geometry = new THREE.PlaneGeometry(physicalWidth, physicalHeight);
        const plane = new THREE.Mesh(geometry, material);
        
        // Set up the orientation in AR space
        if (orientation.toLowerCase() === "flat") {
            // Laid flat on the floor (e.g., rug, mat)
            plane.rotation.x = -Math.PI / 2;
        } else {
            // Standing upright on the floor (e.g., portrait, poster)
            plane.position.y = physicalHeight / 2;
        }
        
        scene.add(plane);
        
        // 3. Export to binary GLB format
        const exporter = new GLTFExporter();
        
        return new Promise((resolve, reject) => {
            exporter.parse(
                scene,
                function (gltfArrayBuffer) {
                    try {
                        const blob = new Blob([gltfArrayBuffer], { type: 'model/gltf-binary' });
                        const url = URL.createObjectURL(blob);
                        
                        // Load Google's model-viewer script dynamically if not present
                        if (!document.querySelector('script[src*="model-viewer"]')) {
                            const script = document.createElement('script');
                            script.type = 'module';
                            script.src = 'https://ajax.googleapis.com/ajax/libs/model-viewer/3.3.0/model-viewer.min.js';
                            document.head.appendChild(script);
                        }
                        
                        // 4. Construct the UI container
                        const container = document.createElement('div');
                        container.style.width = '100%';
                        container.style.height = '100%';
                        container.style.minHeight = '400px';
                        container.style.backgroundColor = '#f4f4f5';
                        container.style.borderRadius = '8px';
                        container.style.overflow = 'hidden';
                        container.style.display = 'flex';
                        container.style.flexDirection = 'column';
                        container.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)';
                        
                        // Setup inner 3D interactive viewer element
                        const mv = document.createElement('model-viewer');
                        mv.setAttribute('src', url);
                        mv.setAttribute('ar', 'true');
                        mv.setAttribute('ar-modes', 'webxr scene-viewer quick-look');
                        mv.setAttribute('camera-controls', 'true');
                        mv.setAttribute('auto-rotate', 'true');
                        mv.setAttribute('shadow-intensity', '1');
                        mv.style.width = '100%';
                        mv.style.height = '100%';
                        mv.style.flexGrow = '1';
                        
                        const footer = document.createElement('div');
                        footer.style.padding = '12px 16px';
                        footer.style.textAlign = 'center';
                        footer.style.fontFamily = 'system-ui, -apple-system, sans-serif';
                        footer.style.fontSize = '14px';
                        footer.style.color = '#3f3f46';
                        footer.style.backgroundColor = '#ffffff';
                        footer.style.borderTop = '1px solid #e4e4e7';
                        footer.innerText = 'Drag to rotate • Scroll to zoom • Click the AR button to preview in your space';
                        
                        container.appendChild(mv);
                        container.appendChild(footer);
                        
                        resolve(container);
                    } catch (e) {
                        reject(e);
                    }
                },
                function (error) {
                    reject(error);
                },
                { binary: true }
            );
        }).catch(err => {
            return getErrorElement(err);
        });
        
    } catch (err) {
        return getErrorElement(err);
    }
    
    // Fallback UI generator for errors
    function getErrorElement(err) {
        const div = document.createElement('div');
        div.style.padding = '20px';
        div.style.color = '#b91c1c';
        div.style.backgroundColor = '#fef2f2';
        div.style.border = '1px solid #f87171';
        div.style.borderRadius = '6px';
        div.style.fontFamily = 'system-ui, -apple-system, sans-serif';
        div.innerText = 'Unable to generate AR model: ' + err.message;
        return div;
    }
}

Free Image Tool Creator

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

Description

This tool converts 2D images into 3D AR (Augmented Reality) models in GLB format. It allows users to transform photos, posters, or textures into digital assets that can be viewed in a 3D space or placed into the real world using AR-compatible devices. Users can specify the physical dimensions and choose between an upright orientation (like a portrait or poster) or a flat orientation (like a rug or mat). This is ideal for interior designers previewing artwork on walls, decorators visualizing floor coverings, or digital artists creating assets for augmented reality experiences.

Leave a Reply

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