File size: 4,864 Bytes
c4a13f7
 
 
 
 
d1d7665
 
 
 
 
c4a13f7
 
 
 
d1d7665
 
 
c4a13f7
 
d1d7665
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c4a13f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d1d7665
c4a13f7
 
 
 
 
d1d7665
 
 
c4a13f7
 
d1d7665
 
 
 
c4a13f7
 
 
 
 
 
 
d1d7665
c4a13f7
 
 
d1d7665
c4a13f7
 
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
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Captioning — Pretrained vs Fine-Tuned BLIP</title>
    <link rel="stylesheet" href="/static/style.css?v=20260724_3">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@400;500;600;700&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
</head>
<body>
    <div class="container">
        <header>
            <h1>🖼️ Image Captioning Studio</h1>
            <p class="subtitle">Upload an image & compare Pretrained vs. Fine-Tuned BLIP models</p>
            <div id="model-badge" class="model-badge hidden">Loading models...</div>
        </header>

        <!-- Model Selector Control Bar -->
        <div class="selector-container">
            <label class="selector-label">Select Model Mode:</label>
            <div class="segmented-control">
                <input type="radio" name="model_choice" id="mode-both" value="both" checked>
                <label for="mode-both" class="control-btn">
                    <span class="icon"></span> Compare Both
                </label>

                <input type="radio" name="model_choice" id="mode-finetuned" value="fine-tuned">
                <label for="mode-finetuned" class="control-btn">
                    <span class="icon">🎯</span> Fine-Tuned (Flickr8k)
                </label>

                <input type="radio" name="model_choice" id="mode-pretrained" value="pretrained">
                <label for="mode-pretrained" class="control-btn">
                    <span class="icon">🌐</span> Pretrained BLIP
                </label>
            </div>
        </div>

        <!-- Language Selector Control Bar -->
        <div class="selector-container">
            <label class="selector-label">Caption Language:</label>
            <div class="segmented-control">
                <input type="radio" name="lang_choice" id="lang-both" value="both" checked>
                <label for="lang-both" class="control-btn">
                    <span class="icon">🌐</span> ทั้งสองภาษา (EN+TH)
                </label>

                <input type="radio" name="lang_choice" id="lang-th" value="th">
                <label for="lang-th" class="control-btn">
                    <span class="icon">🇹🇭</span> ภาษาไทย
                </label>

                <input type="radio" name="lang_choice" id="lang-en" value="en">
                <label for="lang-en" class="control-btn">
                    <span class="icon">🇺🇸</span> English
                </label>
            </div>
        </div>

        <main>
            <!-- Upload Area -->
            <div id="drop-zone" class="drop-zone">
                <div class="drop-zone-content">
                    <svg class="upload-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
                        <polyline points="17 8 12 3 7 8"/>
                        <line x1="12" y1="3" x2="12" y2="15"/>
                    </svg>
                    <p class="drop-text"><strong>Drag & drop</strong> an image here</p>
                    <p class="drop-hint">or click to browse (JPG, PNG, GIF, WebP)</p>
                    <input type="file" id="file-input" accept="image/*" hidden>
                </div>
            </div>

            <!-- Preview & Results Container -->
            <div id="result-area" class="result-area hidden">
                <div class="preview-card">
                    <img id="preview-img" src="" alt="Uploaded preview">
                </div>
                
                <div id="loading-spinner" class="spinner">
                    <div class="spinner-ring"></div>
                    <p class="spinner-text">Generating captions with AI models...</p>
                </div>

                <!-- Results Grid (Dynamic: 1 or 2 columns) -->
                <div id="results-grid" class="results-grid"></div>

                <button id="clear-btn" class="clear-btn">✨ Upload Another Image</button>
            </div>

            <!-- Error Message -->
            <div id="error-msg" class="error-msg hidden"></div>
        </main>

        <footer>
            <p>Powered by <a href="https://huggingface.co/Salesforce/blip-image-captioning-base" target="_blank">Salesforce BLIP</a> + <a href="https://huggingface.co/facebook/nllb-200-distilled-600M" target="_blank">NLLB-200</a> + PyTorch + FastAPI</p>
        </footer>
    </div>

    <script src="/static/app.js?v=20260724_3"></script>
</body>
</html>