File size: 7,396 Bytes
5c31853
0faaab6
f4b10b3
5c31853
0faaab6
 
c32023c
 
f5ea6fc
0faaab6
f4b10b3
 
 
 
c32023c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0faaab6
f4b10b3
 
 
 
 
 
 
0faaab6
f4b10b3
0faaab6
f4b10b3
0faaab6
 
 
 
 
 
 
 
 
 
f4b10b3
0faaab6
f4b10b3
0faaab6
 
 
 
 
 
 
 
 
f4b10b3
0faaab6
 
 
 
 
c32023c
0faaab6
f4b10b3
0faaab6
 
 
 
 
c32023c
 
 
 
 
 
0faaab6
5c31853
f4b10b3
5c31853
f4b10b3
c32023c
0faaab6
 
 
 
 
 
 
c32023c
 
 
5c31853
0faaab6
 
 
f4b10b3
 
0faaab6
 
 
 
 
f4b10b3
0faaab6
 
 
 
 
 
f4b10b3
0faaab6
 
 
f4b10b3
0faaab6
 
 
f4b10b3
0faaab6
 
 
 
c32023c
 
 
 
 
0faaab6
bfc39e7
0faaab6
 
c32023c
 
 
0faaab6
c32023c
 
05b5f7a
bfc39e7
c32023c
bfc39e7
 
 
c32023c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bfc39e7
 
 
c32023c
 
 
 
 
0faaab6
c32023c
 
 
 
 
 
 
 
 
 
 
 
 
5c31853
 
f4b10b3
 
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" type="image/png" href="/static/favicon.png">
    <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
    <title>Draw and Predict Handwritten Digits</title>
    <style>
        body {
            font-family: 'Montserrat', sans-serif;
        }

        #prediction-result {
        }

        .prediction-item {
            margin-bottom: 10px;
            display: flex;
        }

        .prediction-digit {
            font-size: 14px;
        }

        .progress-container {
            display: flex;
            align-items: center;
        }

        .progress-bar {
            width: 100px;
            height: 10px;
            background-color: #ccc;
            border-radius: 6px;
            margin-left: 10px;
        }

        .progress {
            height: 100%;
            border-radius: 5px;
            background-color: #088395;
            transition: width 0.3s ease-in-out;
        }

        #whiteboard {
            border: 3px solid #088395;
            /* Simple black border */
            border-radius: 10px;
            /* Rounded corners */
            box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
            /* Subtle shadow effect */
            background-color: #088395;
        }

        #capture-button {
            background-color: #071952;
            color: white;
            border: none;
            padding: 10px 20px;
            cursor: pointer;
            font-size: 16px;
            border-radius: 3px;
            margin-top: 10px;
            width: 190px;
            margin-right: 20px;
        }

        #clear-button {
            background-color: #F2F7A1;
            color: black;
            border: none;
            padding: 10px 20px;
            cursor: pointer;
            font-size: 16px;
            border-radius: 3px;
            margin-top: 10px;
            width: 190px;
        }

        #container {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            margin-right: 10px;
        }

        #btn-container {
            display: flex;
            flex-direction: row;
            align-items: center;
        }

        #parent {
            display: flex;
    justify-content: center;
    align-items: center;
        }
    </style>
</head>

<body>
    <h3 style="text-align:center;">Draw and Predict Handwritten Digits</h3>
    <div id="parent">
    <div id='container'>
        <canvas id="whiteboard" width="400" height="200"></canvas>
        <div id='btn-container'>
            <button id="capture-button">Predict</button>
            <button id="clear-button">Clear</button>
        </div>
    </div>
    <div id="prediction-result"></div>
</div>

    <script>
        var canvas = document.getElementById('whiteboard');
        var context = canvas.getContext('2d');
        var drawing = false;
        context.strokeStyle = 'white';

        canvas.addEventListener('mousedown', function (e) {
            drawing = true;
            context.beginPath();
            context.moveTo(e.clientX - canvas.getBoundingClientRect().left, e.clientY - canvas.getBoundingClientRect().top);
        });

        canvas.addEventListener('mousemove', function (e) {
            if (drawing) {
                context.lineTo(e.clientX - canvas.getBoundingClientRect().left, e.clientY - canvas.getBoundingClientRect().top);
                context.stroke();
            }
        });

        canvas.addEventListener('mouseup', function () {
            drawing = false;
        });

        canvas.addEventListener('mouseout', function () {
            drawing = false;
        });

        var clearButton = document.getElementById('clear-button');
        clearButton.addEventListener('click', function () {
            context.clearRect(0, 0, canvas.width, canvas.height);
        });
        function isCanvasEmpty(canvas) {
            const context = canvas.getContext('2d');
            const pixelBuffer = new Uint32Array(context.getImageData(0, 0, canvas.width, canvas.height).data.buffer);
            return !pixelBuffer.some(color => color !== 0);
        }

        var predictionResult = document.getElementById('prediction-result');
        var captureButton = document.getElementById('capture-button');
        captureButton.addEventListener('click', function () {
            captureButton.disabled = true
            captureButton.style.opacity = "0.5";
            captureButton.innerText = 'Loading...'
            var imageData = canvas.toDataURL("image/png");
            var formData = new FormData();
            formData.append("image", dataURLtoBlob(imageData), "image.png");
            fetch('/predict', {
                method: 'POST',
                body: formData,
            })
                .then(response => response.json())
                .then(data => {
                    predictionResult.innerHTML = '';
                    data.prediction.forEach(item => {
                        const digitItem = document.createElement('div');
                        digitItem.classList.add('prediction-item');

                        const digitText = document.createElement('div');
                        digitText.classList.add('prediction-digit');
                        digitText.textContent = `Digit ${item.digit}:`;

                        const progressContainer = document.createElement('div');
                        progressContainer.classList.add('progress-container');

                        const progressBar = document.createElement('div');
                        progressBar.classList.add('progress-bar');

                        const progress = document.createElement('div');
                        progress.classList.add('progress');
                        progress.style.width = item.prob;

                        progressBar.appendChild(progress);
                        progressContainer.appendChild(progressBar);

                        digitItem.appendChild(digitText);
                        digitItem.appendChild(progressContainer);

                        predictionResult.appendChild(digitItem);

                        captureButton.disabled = false
                        captureButton.style.opacity = "1";
                        captureButton.innerText = 'Predict'
                    });
                })
                .catch(error => {
                    console.error('Error:', error);
                    predictionResult.textContent = 'Something wentr wrong, try again.';
                    captureButton.disabled = false
                    captureButton.style.opacity = "1";
                    captureButton.innerText = 'Predict'
                });
        });

        // Function to convert a data URL to a Blob
        function dataURLtoBlob(dataURL) {
            var arr = dataURL.split(',');
            var mime = arr[0].match(/:(.*?);/)[1];
            var bstr = atob(arr[1]);
            var n = bstr.length;
            var u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mime });
        }
    </script>
</body>

</html>