syurein commited on
Commit
b6a3bf4
·
1 Parent(s): 45c8412

dotenvの問題の解決2

Browse files
Files changed (2) hide show
  1. requirements.txt +95 -77
  2. templates/index.html +500 -0
requirements.txt CHANGED
@@ -1,77 +1,95 @@
1
- annotated-types==0.7.0
2
- easyocr
3
- anyio==4.6.2.post1
4
- certifi==2024.8.30
5
- charset-normalizer==3.4.0
6
- click==8.1.7
7
- colorama==0.4.6
8
- contourpy==1.3.0
9
- cycler==0.12.1
10
- diffusers==0.31.0
11
- fastapi==0.115.4
12
- filelock==3.16.1
13
- fire==0.5.0
14
- fonttools==4.54.1
15
- fsspec==2024.10.0
16
- futures==3.0.5
17
- h11==0.14.0
18
- huggingface-hub==0.26.2
19
- idna==3.10
20
- importlib_metadata==8.5.0
21
- Jinja2==3.1.4
22
- joblib==1.4.2
23
- kiwisolver==1.4.7
24
- MarkupSafe==3.0.2
25
- matplotlib==3.9.2
26
- mpmath==1.3.0
27
- nest-asyncio==1.6.0
28
- networkx==3.4.2
29
- numpy==1.26.4
30
- opencv-python==4.10.0.84
31
- opencv-python-headless==4.10.0.84
32
- packaging==24.1
33
- pandas==2.2.3
34
- Pillow==9.5.0
35
- psutil==6.1.0
36
- py-cpuinfo==9.0.0
37
- pycocotools==2.0.8
38
- pydantic==2.9.2
39
- pydantic_core==2.23.4
40
- pyngrok==7.2.1
41
- pyparsing==3.2.0
42
- python-dateutil==2.9.0.post0
43
- python-multipart==0.0.17
44
- pytz==2024.2
45
- PyYAML==6.0.2
46
- regex==2024.9.11
47
- requests==2.32.3
48
- safetensors==0.4.5
49
- scikit-learn==1.5.2
50
- scipy==1.14.1
51
- seaborn==0.13.2
52
- setuptools==75.3.0
53
- simple-lama-inpainting==0.1.2
54
- six==1.16.0
55
- sniffio==1.3.1
56
- starlette==0.41.2
57
- supervision==0.9.0
58
- sympy==1.13.1
59
- termcolor==2.5.0
60
- threadpoolctl==3.5.0
61
- tokenizers==0.20.3
62
- torch==2.5.1
63
- torchvision==0.20.1
64
- tqdm==4.66.6
65
- transformers==4.46.2
66
- typing_extensions==4.12.2
67
- tzdata==2024.2
68
- ultralytics==8.3.23
69
- ultralytics-thop==2.0.10
70
- urllib3==2.2.3
71
- uvicorn==0.32.0
72
- zipp==3.20.2
73
- supervision
74
- onnxruntime
75
- google-genai
76
- python-dotenv
77
- moondream
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [cite_start]annotated-types==0.7.0 [cite: 1]
2
+ # easyocr はコメントアウトまたは削除し、新しいバージョンを試すか、依存関係の調整を試みます。
3
+ # easyocr # バージョン指定なしで最新版を試すか、Pillow/opencv-python-headlessと互換性のある特定のバージョンを指定する
4
+ # 例: easyocr==0.1.0 (ただし、これは古いバージョンで、他の依存関係と衝突する可能性あり)
5
+
6
+ [cite_start]anyio==4.6.2.post1 [cite: 1]
7
+ [cite_start]certifi==2024.8.30 [cite: 1]
8
+ [cite_start]charset-normalizer==3.4.0 [cite: 1]
9
+ [cite_start]click==8.1.7 [cite: 1]
10
+ [cite_start]colorama==0.4.6 [cite: 1]
11
+ [cite_start]contourpy==1.3.0 [cite: 1]
12
+ [cite_start]cycler==0.12.1 [cite: 1]
13
+ [cite_start]diffusers==0.31.0 [cite: 1]
14
+ [cite_start]fastapi==0.115.4 [cite: 1]
15
+ [cite_start]filelock==3.16.1 [cite: 1]
16
+ [cite_start]fire==0.5.0 [cite: 1]
17
+ [cite_start]fonttools==4.54.1 [cite: 1]
18
+ [cite_start]fsspec==2024.10.0 [cite: 1]
19
+ [cite_start]futures==3.0.5 [cite: 1]
20
+ [cite_start]h11==0.14.0 [cite: 1]
21
+ [cite_start]huggingface-hub==0.26.2 [cite: 1]
22
+ [cite_start]idna==3.10 [cite: 1]
23
+ [cite_start]importlib_metadata==8.5.0 [cite: 1]
24
+ [cite_start]Jinja2==3.1.4 [cite: 1]
25
+ [cite_start]joblib==1.4.2 [cite: 1]
26
+ [cite_start]kiwisolver==1.4.7 [cite: 1]
27
+ [cite_start]MarkupSafe==3.0.2 [cite: 1]
28
+ [cite_start]matplotlib==3.9.2 [cite: 1]
29
+ [cite_start]mpmath==1.3.0 [cite: 1]
30
+ [cite_start]nest-asyncio==1.6.0 [cite: 1]
31
+ [cite_start]networkx==3.4.2 [cite: 1]
32
+ [cite_start]numpy==1.26.4 [cite: 1]
33
+
34
+ # opencv-python と opencv-python-headless の両方が指定されているのは冗長です。
35
+ # どちらか一方(headless推奨、GUI不要なため)のみを残します。
36
+ # opencv-python-headless のバージョンは easyocr との互換性を考慮して調整が必要。
37
+ # 最新の easyocr (例えば 1.7.0 以上) はより新しい OpenCV に対応している可能性があります。
38
+ # ここでは一旦、衝突しない可能性のある新しい opencv-python-headless を残し、easyocr の調整で対応します。
39
+ # もし easyocr が動かない場合は、opencv-python-headless のバージョンを下げる必要があります。
40
+ # opencv-python==4.10.0.84 # コメントアウトまたは削除 (headlessを使用するため)
41
+ [cite_start]opencv-python-headless==4.10.0.84 [cite: 1]
42
+
43
+ [cite_start]packaging==24.1 [cite: 1]
44
+ [cite_start]pandas==2.2.3 [cite: 1]
45
+
46
+ # Pillow のバージョンも easyocr との競合が発生しています。
47
+ # easyocr のバージョンを更新することで解決を目指します。
48
+ [cite_start]Pillow==9.5.0 [cite: 1]
49
+
50
+ [cite_start]psutil==6.1.0 [cite: 1]
51
+ [cite_start]py-cpuinfo==9.0.0 [cite: 1]
52
+ [cite_start]pycocotools==2.0.8 [cite: 1]
53
+ [cite_start]pydantic==2.9.2 [cite: 1]
54
+ [cite_start]pydantic_core==2.23.4 [cite: 1]
55
+ [cite_start]pyngrok==7.2.1 [cite: 1]
56
+ [cite_start]pyparsing==3.2.0 [cite: 1]
57
+ [cite_start]python-dateutil==2.9.0.post0 [cite: 1]
58
+ [cite_start]python-multipart==0.0.17 [cite: 1]
59
+ [cite_start]pytz==2024.2 [cite: 1]
60
+ [cite_start]PyYAML==6.0.2 [cite: 1]
61
+ [cite_start]regex==2024.9.11 [cite: 1]
62
+ [cite_start]requests==2.32.3 [cite: 1]
63
+ [cite_start]safetensors==0.4.5 [cite: 1]
64
+ [cite_start]scikit-learn==1.5.2 [cite: 1]
65
+ [cite_start]scipy==1.14.1 [cite: 1]
66
+ [cite_start]seaborn==0.13.2 [cite: 1]
67
+ [cite_start]setuptools==75.3.0 [cite: 1]
68
+ [cite_start]simple-lama-inpainting==0.1.2 [cite: 1]
69
+ [cite_start]six==1.16.0 [cite: 1]
70
+ [cite_start]sniffio==1.3.1 [cite: 1]
71
+ [cite_start]starlette==0.41.2 [cite: 1]
72
+ [cite_start]supervision==0.9.0 [cite: 1] # 最後に重複しているので、ここではコ���ントアウトまたは削除
73
+ [cite_start]sympy==1.13.1 [cite: 1]
74
+ [cite_start]termcolor==2.5.0 [cite: 1]
75
+ [cite_start]threadpoolctl==3.5.0 [cite: 1]
76
+ [cite_start]tokenizers==0.20.3 [cite: 1]
77
+ [cite_start]torch==2.5.1 [cite: 1]
78
+ [cite_start]torchvision==0.20.1 [cite: 1]
79
+ [cite_start]tqdm==4.66.6 [cite: 1]
80
+ [cite_start]transformers==4.46.2 [cite: 1]
81
+ [cite_start]typing_extensions==4.12.2 [cite: 1]
82
+ [cite_start]tzdata==2024.2 [cite: 1]
83
+ [cite_start]ultralytics==8.3.23 [cite: 1]
84
+ [cite_start]ultralytics-thop==2.0.10 [cite: 1]
85
+ [cite_start]urllib3==2.2.3 [cite: 1]
86
+ [cite_start]uvicorn==0.32.0 [cite: 1]
87
+ [cite_start]zipp==3.20.2 [cite: 1]
88
+
89
+ # 重複を解消し、easyocr の依存関係を考慮して最後に配置
90
+ [cite_start]easyocr [cite: 1] # ここでeasyocrを最新版でインストールすることを試みる
91
+ [cite_start]supervision [cite: 1] # 重複を解消
92
+ [cite_start]onnxruntime [cite: 1]
93
+ [cite_start]google-genai [cite: 1]
94
+ [cite_start]python-dotenv [cite: 1] # dotenv ではなく python-dotenv に修正
95
+ [cite_start]moondream [cite: 1]
templates/index.html ADDED
@@ -0,0 +1,500 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>画像処理アプリ</title>
7
+ <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
9
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
10
+ <style>
11
+ /* 既存のスタイル */
12
+ body {
13
+ background-color: #f0f0f5;
14
+ color: #333;
15
+ padding: 40px 20px;
16
+ }
17
+ /* ... 他の既存のスタイル ... */
18
+
19
+ /* ヘルプボタンのスタイル */
20
+ .help-button {
21
+ position: fixed;
22
+ bottom: 20px;
23
+ right: 20px;
24
+ width: 50px;
25
+ height: 50px;
26
+ border-radius: 50%;
27
+ background-color: #007bff;
28
+ color: white;
29
+ border: none;
30
+ box-shadow: 0 2px 10px rgba(0,0,0,0.2);
31
+ z-index: 1000;
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ font-size: 1.5rem;
36
+ }
37
+
38
+ .help-button:hover {
39
+ background-color: #0056b3;
40
+ }
41
+
42
+ /* モーダル内のスタイル */
43
+ .help-section {
44
+ margin-bottom: 30px;
45
+ padding: 15px;
46
+ border-radius: 8px;
47
+ background-color: #f8f9fa;
48
+ }
49
+
50
+ .help-section h4 {
51
+ color: #007bff;
52
+ margin-bottom: 15px;
53
+ }
54
+
55
+ .step-list {
56
+ padding-left: 20px;
57
+ }
58
+
59
+ .step-list li {
60
+ margin-bottom: 10px;
61
+ }
62
+
63
+ .modal-body img {
64
+ max-width: 100%;
65
+ border-radius: 5px;
66
+ margin: 10px 0;
67
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
68
+ }
69
+ </style>
70
+
71
+
72
+ <style>
73
+ body {
74
+ background-color: #f0f0f5;
75
+ color: #333;
76
+ padding: 40px 20px;
77
+ }
78
+ h1 {
79
+ color: #555;
80
+ margin-bottom: 30px;
81
+ font-weight: bold;
82
+ text-align: center;
83
+ }
84
+ .image-preview, .processed-preview {
85
+ max-width: 100%;
86
+ height: auto;
87
+ border-radius: 10px;
88
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
89
+ margin-top: 20px;
90
+ }
91
+ #result {
92
+ margin-top: 40px;
93
+ display: none;
94
+ }
95
+ .slider-container {
96
+ text-align: left;
97
+ margin-top: 20px;
98
+ }
99
+ .slider-label {
100
+ font-size: 1.2rem;
101
+ color: #333;
102
+ }
103
+ .btn-primary {
104
+ background-color: #007bff;
105
+ border-color: #007bff;
106
+ font-size: 1.2rem;
107
+ padding: 10px 20px;
108
+ border-radius: 50px;
109
+ }
110
+ .btn-primary:hover {
111
+ background-color: #0056b3;
112
+ border-color: #004085;
113
+ }
114
+ .form-control, .custom-select {
115
+ border-radius: 20px;
116
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
117
+ }
118
+ .nav-tabs {
119
+ margin-bottom: 30px;
120
+ border-bottom: 2px solid #007bff;
121
+ }
122
+ .nav-tabs .nav-link {
123
+ border: none;
124
+ color: #555;
125
+ font-size: 1.1rem;
126
+ padding: 12px 25px;
127
+ border-radius: 10px 10px 0 0;
128
+ }
129
+ .nav-tabs .nav-link.active {
130
+ background-color: #007bff;
131
+ color: white;
132
+ }
133
+ .tab-content {
134
+ padding: 20px;
135
+ background: white;
136
+ border-radius: 0 0 10px 10px;
137
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
138
+ }
139
+ #loadingSpinner {
140
+ position: fixed;
141
+ top: 50%;
142
+ left: 50%;
143
+ transform: translate(-50%, -50%);
144
+ background: rgba(255,255,255,0.9);
145
+ padding: 20px;
146
+ border-radius: 10px;
147
+ box-shadow: 0 0 15px rgba(0,0,0,0.2);
148
+ z-index: 9999;
149
+ }
150
+ </style>
151
+ </head>
152
+ <body>
153
+ <div id="loadingSpinner" style="display: none;">
154
+ <i class="fas fa-spinner fa-spin fa-3x"></i>
155
+ <p>画像を処理中です。少々お待ちください...</p>
156
+ </div>
157
+ <div class="container">
158
+ <h1><i class="fas fa-image"></i> AIデンティファイ</h1>
159
+
160
+ <ul class="nav nav-tabs" role="tablist">
161
+ <li class="nav-item">
162
+ <a class="nav-link active" id="general-tab" data-toggle="tab" href="#general" role="tab">
163
+ <i class="fas fa-magic"></i> 個人情報保護モード
164
+ </a>
165
+ </li>
166
+ <li class="nav-item">
167
+ <a class="nav-link" id="face-tab" data-toggle="tab" href="#face" role="tab">
168
+ <i class="fas fa-user-circle"></i> 顔保護モード
169
+ </a>
170
+ </li>
171
+ </ul>
172
+ <div class="tab-content">
173
+ <!-- 一般処理モード -->
174
+ <div class="tab-pane fade show active" id="general" role="tabpanel">
175
+ <div class="form-group">
176
+ <label for="uploadImage1">画像をアップロード:</label>
177
+ <input type="file" id="uploadImage1" class="form-control-file" accept="image/*" onchange="previewAndResizeImage('uploadImage1', 'uploadedImage1')">
178
+ </div>
179
+ <img id="uploadedImage1" class="image-preview" src="#" alt="アップロードされた画像" style="display: none;">
180
+
181
+ <div class="form-group mt-4">
182
+ <label for="processingType">処理方法を選択:</label>
183
+ <select id="processingType" class="custom-select">
184
+ <option value="opencv">OpenCVインペイント</option>
185
+ <option value="simple_lama">Simple Lamaインペイント</option>
186
+ <option value="stamp">stampインペイント</option>
187
+ <option value="mosaic">mosaicインペイント</option>
188
+ </select>
189
+ </div>
190
+ <div class="slider-container">
191
+ <label for="riskLevel1" class="slider-label">リスクレベル (0-100): <span id="riskLevelLabel1">50</span></label>
192
+ <div id="slider1"></div>
193
+ </div>
194
+ <button class="btn btn-primary mt-4" onclick="processGeneralImage()">処理開始</button>
195
+ </div>
196
+ <!-- 顔照合モード -->
197
+ <div class="tab-pane fade" id="face" role="tabpanel">
198
+ <div class="form-group">
199
+ <label for="uploadImage2">処理する画像をアップロード:</label>
200
+ <input type="file" id="uploadImage2" class="form-control-file" accept="image/*" onchange="previewAndResizeImage('uploadImage2', 'uploadedImage2')">
201
+ </div>
202
+ <img id="uploadedImage2" class="image-preview" src="#" alt="アップロードされた画像" style="display: none;">
203
+ <div class="form-group mt-4">
204
+ <label for="faceOption">自分の顔の入力方法を選択:</label>
205
+ <select id="faceOption" class="custom-select" onchange="toggleFaceInput()">
206
+ <option value="upload">ファイルからアップロード</option>
207
+ <option value="camera">カメラで撮影</option>
208
+ </select>
209
+ </div>
210
+ <div class="form-group" id="uploadFaceGroup">
211
+ <label for="uploadFace">顔画像をアップロード:</label>
212
+ <input type="file" id="uploadFace" class="form-control-file" accept="image/*" onchange="previewFaceImage()">
213
+ <img id="facePreview" class="image-preview" src="#" alt="顔画像のプレビュー" style="display: none;">
214
+ </div>
215
+ <div class="form-group" id="cameraFaceGroup" style="display: none;">
216
+ <video id="cameraStream" width="100%" autoplay></video>
217
+ <button class="btn btn-secondary mt-2" onclick="captureFaceImage()">顔をキャプチャ</button>
218
+ <canvas id="cameraCanvas" style="display: none;"></canvas>
219
+ </div>
220
+ <div class="slider-container">
221
+ <label for="riskLevel2" class="slider-label">リスクレベル (0-100): <span id="riskLevelLabel2">50</span></label>
222
+ <div id="slider2"></div>
223
+ </div>
224
+ <button class="btn btn-primary mt-4" onclick="processFaceImage()">処理開始</button>
225
+ </div>
226
+ <!-- 処理結果(共通) -->
227
+ <div id="result" class="mt-5">
228
+ <h2>処理結果:</h2>
229
+ <img id="processedImage" class="processed-preview" src="" alt="">
230
+ <a id="downloadLink" class="btn btn-success mt-3" href="#" download="processed_image.jpg">処理された画像をダウンロード</a>
231
+ </div>
232
+ </div>
233
+ </div>
234
+
235
+
236
+ <!-- ヘルプボタン -->
237
+ <button class="help-button" data-toggle="modal" data-target="#helpModal">
238
+ <i class="fas fa-question"></i>
239
+ </button>
240
+
241
+ <!-- ヘルプモーダル -->
242
+ <div class="modal fade" id="helpModal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel" aria-hidden="true">
243
+ <div class="modal-dialog modal-lg" role="document">
244
+ <div class="modal-content">
245
+ <div class="modal-header">
246
+ <h5 class="modal-title" id="helpModalLabel">
247
+ <i class="fas fa-question-circle"></i> AIデンティファイの使い方
248
+ </h5>
249
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
250
+ <span aria-hidden="true">&times;</span>
251
+ </button>
252
+ </div>
253
+ <div class="modal-body">
254
+ <!-- 一般処理モードの説明 -->
255
+ <div class="help-section">
256
+ <h4><i class="fas fa-magic"></i> 個人情報保護モードの使い方</h4>
257
+ <ol class="step-list">
258
+   <li>このモードではあなたの個人情報を簡単に保護することができます</li>
259
+ <li>「画像をアップロード」ボタンをクリックして、処理したい画像を選択します。</li>
260
+ <li>処理方法を以下から選択します:
261
+ <ul>
262
+ <li><strong>OpenCVインペイント:</strong> 一般的な画像補正</li>
263
+ <li><strong>Simple Lamaインペイント:</strong> 高度な画像補正</li>
264
+ <li><strong>stampインペイント:</strong> スタンプによる画像加工</li>
265
+ <li><strong>mosaicインペイント:</strong> モザイクによる加工</li>
266
+ </ul>
267
+ </li>
268
+ <li>スライダーでリスクレベルを調整します(0-100):
269
+ <ul>
270
+ <li>値が高いほど、より強い保護が適用されます</li>
271
+ <li>推奨値は30前後です</li>
272
+ </ul>
273
+ </li>
274
+ <li>「処理開始」ボタンをクリックして処理を実行します。</li>
275
+ </ol>
276
+ </div>
277
+
278
+ <!-- 顔照合モードの説明 -->
279
+ <div class="help-section">
280
+ <h4><i class="fas fa-user-circle"></i> 顔保護モードの使い方</h4>
281
+ <ol class="step-list">
282
+   <li>このモードではあなたの顔以外を隠すことができます。</li>
283
+ <li>「処理する画像をアップロード」から、処理したい画像を選択します。</li>
284
+ <li>自分の顔の入力方法を選択します:
285
+ <ul>
286
+ <li><strong>ファイルからアップロード:</strong> 既存の顔写真を使用</li>
287
+ <li><strong>カメラで撮影:</strong> Webカメラを使用して顔写真を撮影</li>
288
+ </ul>
289
+ </li>
290
+ <li>選択した方法で顔画像を入力します。</li>
291
+ <li>スライダーでリスクレベルを調整します。</li>
292
+ <li>「処理開始」ボタンをクリックして処理を実行します。</li>
293
+ </ol>
294
+ </div>
295
+
296
+ <!-- 共通の注意事項 -->
297
+ <div class="help-section">
298
+ <h4><i class="fas fa-exclamation-triangle"></i> 注意事項</h4>
299
+ <ul>
300
+ <li>アップロードする画像は1200×1200ピクセル以下に自動でリサイズされます。</li>
301
+ <li>処理には数秒から30秒ほどかかる場合があります。</li>
302
+ <li>処理が完了すると、処理結果が表示され、画像のダウンロードが可能になります。</li>
303
+ <li>ブラウザのプライバシー設定によっては、カメラの使用許可が必要な場合があります。</li>
304
+ </ul>
305
+ </div>
306
+ </div>
307
+ <div class="modal-footer">
308
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
309
+ </div>
310
+ </div>
311
+ </div>
312
+ </div>
313
+
314
+ <!-- 既存のスクリプト -->
315
+ <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
316
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
317
+ <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
318
+ <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
319
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
320
+ <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
321
+ <script>
322
+ // スライダーの初期化
323
+ $(function() {
324
+ $("#slider1, #slider2").slider({
325
+ range: "min",
326
+ value: 50,
327
+ min: 0,
328
+ max: 100,
329
+ slide: function(event, ui) {
330
+ const labelId = $(this).attr('id') === 'slider1' ? 'riskLevelLabel1' : 'riskLevelLabel2';
331
+ $("#" + labelId).text(ui.value);
332
+ }
333
+ });
334
+ });
335
+ let resizedImageBlob1 = null;
336
+ let resizedImageBlob2 = null;
337
+ let faceImageBlob = null;
338
+ function previewAndResizeImage(inputId, imageId) {
339
+ const fileInput = document.getElementById(inputId);
340
+ const uploadedImage = document.getElementById(imageId);
341
+
342
+ if (fileInput.files && fileInput.files[0]) {
343
+ const reader = new FileReader();
344
+ reader.onload = function(e) {
345
+ const img = new Image();
346
+ img.onload = function() {
347
+ const maxWidth = 1200;
348
+ const maxHeight = 1200;
349
+ let width = img.width;
350
+ let height = img.height;
351
+ if (width > maxWidth || height > maxHeight) {
352
+ const ratio = Math.min(maxWidth / width, maxHeight / height);
353
+ width *= ratio;
354
+ height *= ratio;
355
+ }
356
+ const canvas = document.createElement('canvas');
357
+ canvas.width = width;
358
+ canvas.height = height;
359
+ const ctx = canvas.getContext('2d');
360
+ ctx.drawImage(img, 0, 0, width, height);
361
+ uploadedImage.src = canvas.toDataURL('image/jpeg');
362
+ uploadedImage.style.display = 'block';
363
+
364
+ canvas.toBlob((blob) => {
365
+ if (inputId === 'uploadImage1') {
366
+ resizedImageBlob1 = blob;
367
+ } else {
368
+ resizedImageBlob2 = blob;
369
+ }
370
+ }, 'image/jpeg');
371
+ };
372
+ img.src = e.target.result;
373
+ };
374
+ reader.readAsDataURL(fileInput.files[0]);
375
+ }
376
+ }
377
+ function previewFaceImage() {
378
+ const fileInput = document.getElementById('uploadFace');
379
+ if (fileInput.files && fileInput.files[0]) {
380
+ const reader = new FileReader();
381
+ reader.onload = function(e) {
382
+ document.getElementById('facePreview').src = e.target.result;
383
+ document.getElementById('facePreview').style.display = 'block';
384
+ };
385
+ reader.readAsDataURL(fileInput.files[0]);
386
+ faceImageBlob = fileInput.files[0];
387
+ }
388
+ }
389
+ function toggleFaceInput() {
390
+ const faceOption = document.getElementById('faceOption').value;
391
+ document.getElementById('uploadFaceGroup').style.display = faceOption === 'upload' ? 'block' : 'none';
392
+ document.getElementById('cameraFaceGroup').style.display = faceOption === 'camera' ? 'block' : 'none';
393
+ if (faceOption === 'camera') {
394
+ startCamera();
395
+ } else {
396
+ stopCamera();
397
+ }
398
+ }
399
+ function startCamera() {
400
+ const video = document.getElementById('cameraStream');
401
+ navigator.mediaDevices.getUserMedia({ video: true })
402
+ .then(stream => video.srcObject = stream)
403
+ .catch(error => console.error('カメラの起動に失敗しました:', error));
404
+ }
405
+ function stopCamera() {
406
+ const video = document.getElementById('cameraStream');
407
+ const stream = video.srcObject;
408
+ if (stream) {
409
+ stream.getTracks().forEach(track => track.stop());
410
+ video.srcObject = null;
411
+ }
412
+ }
413
+ function captureFaceImage() {
414
+ const video = document.getElementById('cameraStream');
415
+ const canvas = document.getElementById('cameraCanvas');
416
+ const context = canvas.getContext('2d');
417
+ canvas.width = video.videoWidth;
418
+ canvas.height = video.videoHeight;
419
+ context.drawImage(video, 0, 0, canvas.width, canvas.height);
420
+ canvas.toBlob(blob => faceImageBlob = blob, 'image/jpeg');
421
+ stopCamera();
422
+ }
423
+ function processGeneralImage() {
424
+ if (!resizedImageBlob1) {
425
+ alert("画像を選択してください。");
426
+ return;
427
+ }
428
+ const processingType = document.getElementById('processingType').value;
429
+ const riskLevel = $("#slider1").slider("value");
430
+ showLoadingSpinner();
431
+ const formData = new FormData();
432
+ formData.append('image', resizedImageBlob1, 'resized_image.jpg');
433
+ formData.append('risk_level', riskLevel);
434
+ let apiEndpoint;
435
+ if (processingType === "opencv") {
436
+ apiEndpoint = "/create-mask-and-inpaint-opencv";
437
+ } else if (processingType === "simple_lama") {
438
+ apiEndpoint = "/create-mask-and-inpaint-simple-lama";
439
+ } else if (processingType === "stamp") {
440
+ apiEndpoint = "/create-mask-and-inpaint-stamp";
441
+ } else if (processingType === "mosaic") {
442
+ apiEndpoint = "/create-mask-and-inpaint-mosaic";
443
+ }
444
+ processImageRequest(formData, "https://rein0421-aidentify.hf.space" + apiEndpoint);
445
+ }
446
+ function processFaceImage() {
447
+ if (!resizedImageBlob2 || !faceImageBlob) {
448
+ alert("処理する画像と顔画像の両方を設定してください。");
449
+ return;
450
+ }
451
+ const riskLevel = $("#slider2").slider("value");
452
+ showLoadingSpinner();
453
+ const formData = new FormData();
454
+ formData.append('reference_image', faceImageBlob, 'reference_image.jpg');
455
+ formData.append('test_image', resizedImageBlob2, 'test_image.jpg');
456
+ formData.append('risk_level', riskLevel);
457
+ processImageRequest(formData, "https://rein0421-aidentify.hf.space/mosaic_faces");
458
+ }
459
+ function processImageRequest(formData, url) {
460
+ fetch(url, {
461
+ method: 'POST',
462
+ body: formData
463
+ })
464
+ .then(response => {
465
+ if (!response.ok) throw new Error("Network response was not ok");
466
+ return response.blob();
467
+ })
468
+ .then(blob => {
469
+ const objectURL = URL.createObjectURL(blob);
470
+ document.getElementById('processedImage').src = objectURL;
471
+ document.getElementById('downloadLink').href = objectURL;
472
+ document.getElementById('result').style.display = "block";
473
+ })
474
+ .catch(error => {
475
+ console.error("画像処理に失敗しました。", error);
476
+ alert("画像処理に失敗しました。");
477
+ })
478
+ .finally(() => {
479
+ hideLoadingSpinner();
480
+ });
481
+ }
482
+ function showLoadingSpinner() {
483
+ document.getElementById('loadingSpinner').style.display = 'block';
484
+ }
485
+ function hideLoadingSpinner() {
486
+ document.getElementById('loadingSpinner').style.display = 'none';
487
+ }
488
+ // タブ切り替え時の処理
489
+ $('.nav-tabs a').on('shown.bs.tab', function (e) {
490
+ // 結果表示をリセット
491
+ document.getElementById('result').style.display = 'none';
492
+ document.getElementById('processedImage').src = '';
493
+ document.getElementById('downloadLink').href = '#';
494
+ });
495
+ </script>
496
+ <script>
497
+
498
+ </script>
499
+ </body>
500
+ </html>