File size: 8,083 Bytes
d8b5ea1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2855cfe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cee54ce
 
9845c22
 
 
 
 
 
 
 
 
 
cee54ce
 
 
 
 
 
 
9845c22
 
 
 
 
 
 
cee54ce
 
9845c22
 
cee54ce
 
 
 
 
9845c22
2855cfe
 
 
 
 
9845c22
2855cfe
9845c22
 
 
2855cfe
 
 
 
 
9845c22
 
 
 
 
 
 
2855cfe
9845c22
2855cfe
9845c22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2855cfe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9845c22
 
 
2855cfe
9845c22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8b5ea1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// Theme toggle functionality
document.addEventListener('DOMContentLoaded', () => {
    const themeToggle = document.getElementById('themeToggle');
    const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
    
    // Check for saved theme preference or use system preference
    const currentTheme = localStorage.getItem('theme') || 
                         (prefersDarkScheme.matches ? 'dark' : 'light');
    
    // Apply the current theme
    if (currentTheme === 'dark') {
        document.documentElement.classList.add('dark');
        themeToggle.innerHTML = '<i data-feather="sun" class="mr-2"></i> Light Mode';
    } else {
        document.documentElement.classList.remove('dark');
        themeToggle.innerHTML = '<i data-feather="moon" class="mr-2"></i> Dark Mode';
    }
    
    // Set up the toggle button
    themeToggle.addEventListener('click', () => {
        const isDark = document.documentElement.classList.contains('dark');
        if (isDark) {
            document.documentElement.classList.remove('dark');
            localStorage.setItem('theme', 'light');
            themeToggle.innerHTML = '<i data-feather="moon" class="mr-2"></i> Dark Mode';
        } else {
            document.documentElement.classList.add('dark');
            localStorage.setItem('theme', 'dark');
            themeToggle.innerHTML = '<i data-feather="sun" class="mr-2"></i> Light Mode';
        }
        feather.replace();
    });
    // Watch for system theme changes
    prefersDarkScheme.addEventListener('change', e => {
        if (localStorage.getItem('theme') === null) {
            if (e.matches) {
                document.documentElement.classList.add('dark');
            } else {
                document.documentElement.classList.remove('dark');
            }
        }
    });
// MediaPipe Selfie Segmentation setup
let selfieSegmentation;
let segmentationActive = false;

async function setupSegmentation() {
    selfieSegmentation = new SelfieSegmentation({
        locateFile: (file) => {
            return `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`;
        }
    });
    
    selfieSegmentation.setOptions({
        modelSelection: 1, // 0 for general segmentation, 1 for landscape (better for full body)
        selfieMode: false
    });
    
    await selfieSegmentation.initialize();
}

// Image upload and clothing selection functionality
const imageUpload = document.getElementById('imageUpload');
    const imagePreview = document.getElementById('imagePreview');
    const previewImage = document.getElementById('previewImage');
    const toolsPanel = document.getElementById('toolsPanel');
    const selectClothesBtn = document.getElementById('selectClothes');
    const clearSelectionBtn = document.getElementById('clearSelection');
    const downloadSelectionBtn = document.getElementById('downloadSelection');
    const selectionCanvas = document.getElementById('selectionCanvas');
    const ctx = selectionCanvas.getContext('2d');

    let imageLoaded = false;
    let selectionMode = false;
    let selectionPoints = [];

    imageUpload.addEventListener('change', function(e) {
        const file = e.target.files[0];
        if (file) {
            const reader = new FileReader();
            
            reader.onload = function(event) {
                previewImage.onload = function() {
                    // Set canvas dimensions to match image
                    selectionCanvas.width = previewImage.width;
                    selectionCanvas.height = previewImage.height;
                    imageLoaded = true;
                    toolsPanel.classList.remove('hidden');
                };
                previewImage.src = event.target.result;
                imagePreview.classList.remove('hidden');
                selectionPoints = [];
                ctx.clearRect(0, 0, selectionCanvas.width, selectionCanvas.height);
            }
            
            reader.readAsDataURL(file);
        }
    });
    // Initialize clothing selection
    selectClothesBtn.addEventListener('click', async function() {
        if (!selfieSegmentation) {
            await setupSegmentation();
        }
        
        selectionMode = true;
        segmentationActive = true;
        selectionPoints = [];
        ctx.clearRect(0, 0, selectionCanvas.width, selectionCanvas.height);
        previewImage.style.cursor = 'crosshair';
        
        // Process image with segmentation model
        if (imageLoaded) {
            await processSegmentation();
        }
    });
    // Clear selection
    clearSelectionBtn.addEventListener('click', function() {
        selectionPoints = [];
        ctx.clearRect(0, 0, selectionCanvas.width, selectionCanvas.height);
        previewImage.style.cursor = 'default';
        selectionMode = false;
        segmentationActive = false;
    });
// Download selection
    downloadSelectionBtn.addEventListener('click', function() {
        if (selectionPoints.length > 0) {
            const tempCanvas = document.createElement('canvas');
            const tempCtx = tempCanvas.getContext('2d');
            tempCanvas.width = previewImage.width;
            tempCanvas.height = previewImage.height;
            
            // Draw the selected area
            tempCtx.drawImage(previewImage, 0, 0);
            
            // Create mask for selection
            tempCtx.globalCompositeOperation = 'destination-in';
            tempCtx.fillStyle = 'black';
            tempCtx.beginPath();
            tempCtx.moveTo(selectionPoints[0].x, selectionPoints[0].y);
            for (let i = 1; i < selectionPoints.length; i++) {
                tempCtx.lineTo(selectionPoints[i].x, selectionPoints[i].y);
            }
            tempCtx.closePath();
            tempCtx.fill();
            
            // Create download link
            const link = document.createElement('a');
            link.download = 'selected-clothing.png';
            link.href = tempCanvas.toDataURL('image/png');
            link.click();
        }
    });
    // Process image with segmentation model
    async function processSegmentation() {
        if (!selfieSegmentation || !imageLoaded) return;
        
        try {
            const result = await selfieSegmentation.send({image: previewImage});
            const mask = result.segmentationMask;
            
            // Draw the segmentation mask
            ctx.clearRect(0, 0, selectionCanvas.width, selectionCanvas.height);
            ctx.drawImage(mask, 0, 0, selectionCanvas.width, selectionCanvas.height);
            
            // Apply the mask to highlight clothing
            ctx.globalCompositeOperation = 'source-in';
            ctx.fillStyle = 'rgba(59, 130, 246, 0.5)';
            ctx.fillRect(0, 0, selectionCanvas.width, selectionCanvas.height);
            ctx.globalCompositeOperation = 'source-over';
            
        } catch (error) {
            console.error('Segmentation error:', error);
        }
    }

    // Handle selection drawing
    imagePreview.addEventListener('click', function(e) {
if (!selectionMode || !imageLoaded) return;
        
        const rect = previewImage.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        
        selectionPoints.push({x, y});
        
        // Draw selection
        ctx.clearRect(0, 0, selectionCanvas.width, selectionCanvas.height);
        ctx.strokeStyle = '#3B82F6';
        ctx.lineWidth = 2;
        ctx.fillStyle = 'rgba(59, 130, 246, 0.2)';
        
        if (selectionPoints.length > 0) {
            ctx.beginPath();
            ctx.moveTo(selectionPoints[0].x, selectionPoints[0].y);
            
            for (let i = 1; i < selectionPoints.length; i++) {
                ctx.lineTo(selectionPoints[i].x, selectionPoints[i].y);
            }
            
            if (selectionPoints.length > 2) {
                ctx.closePath();
                ctx.fill();
            }
            
            ctx.stroke();
        }
    });
});