# 04 画像処理との連携仕様

PHP 側と画像解析エンジン（`SkinDiagnosisSystem2.exe`）の連携仕様を記す。将来の移植・再実装時にここを仕様書として扱える粒度で記述する。

**Wine 構成についての補足:**

本構成では Linux 版 SkinDiagnosisSystem2 を直接実行するのではなく、Windows 版 SkinDiagnosisSystem2.exe を Wine 経由で実行している。
テクノホライズン提供の Linux 版画像解析エンジンも検証したが、現行 Ubuntu 22.04 LTS 環境では、本来取得される 7 項目の解析結果ではなく「-1」が返却され、正常な解析結果を取得できなかった。
一方、Windows 版 SkinDiagnosisSystem2.exe を Wine 経由で実行する構成では、旧 Windows Server 2008 環境と同一の診断結果が得られている。
そのため、本移行では、数年から 5 年程度の延命運用を目的とする現行採用構成として、**Windows 版 SkinDiagnosisSystem2.exe ＋ Wine 構成**を採用する。

---

## 1. 呼び出し元

| 項目 | 値 |
| --- | --- |
| 呼び出し元 PHP | `client/main/zip_upload.php`（標準・クレシエール系）、`client/main/zip_upload_panasonic.php`（Panasonic 系） |
| 使用定数 | `SKIN_DIAGNOSIS_SYSTEM_PATH`（`lib/config.php`） |
| 呼び出し関数 | PHP の `exec()` を使用 |

**クレシエール系（ID=10, 11）の確認:**
クレシエール系（ID=10 = crecher2、ID=11 = crecher）はともに通常の `client/main/zip_upload.php` を使用する。Panasonic 系のような専用アップロードファイルは存在しない。ただし `zip_upload.php` 内で `$client_id == CRECHER_ID`（定数値 11）の条件分岐が存在し、ID=11 に固有の DB 保存処理が含まれる。

---

## 2. 呼び出しコマンド

`SKIN_DIAGNOSIS_SYSTEM_PATH` 定義（本番環境）:

```
WINEPREFIX=/home/skin/.wine-skindiagnosis xvfb-run -a wine /home/skin/asp.hada-check.com/bin/SkinDiagnosisSystem/SkinDiagnosisSystem2.exe
```

実行時に引数を 2 つ付与する。

```bash
<SKIN_DIAGNOSIS_SYSTEM_PATH> <入力JPG絶対パス> <出力BMP絶対パス>
```

例:

```bash
WINEPREFIX=/home/skin/.wine-skindiagnosis xvfb-run -a wine \
  /home/skin/asp.hada-check.com/bin/SkinDiagnosisSystem/SkinDiagnosisSystem2.exe \
  /home/skin/asp.hada-check.com/files/uploaded_zip/10_20260420120000_1/KCheckerIng/Crop1/sample.jpg \
  /home/skin/asp.hada-check.com/files/uploaded_zip/10_20260420120000_1/KCheckerIng/Crop2/sample.bmp
```

---

## 3. 入力パラメータ

| # | 名前 | 型 | 意味 | 制約 |
| --- | --- | --- | --- | --- |
| 1 | 入力画像パス | 文字列（絶対パス） | 解析対象の 300×300 JPG | ImageMagick で事前生成した Crop1 画像を使用する |
| 2 | 出力画像パス | 文字列（絶対パス） | 二値化結果を書き出す BMP | 書き込み可能なディレクトリを渡すこと |

事前条件:

- 入力 JPG は `convert -gravity center -crop 300x300+0+0 ... -type truecolor` で生成されたものであること。
- 出力先ディレクトリは PHP（PM2 の実行ユーザー＝`skin`）が書き込み可能であること（`files/uploaded_zip/.../KCheckerIng/Crop2/`）。
- Wine プレフィックス `/home/skin/.wine-skindiagnosis/` が既に初期化済みであること。

---

## 4. 戻り値（標準出力）

標準出力にカンマ等の非数字区切りで **7 個の数値** が出力される。

7 値の意味（DB 保存キーと一致）:

| 順番 | PHP 側キー | 用途 |
| --- | --- | --- |
| 1 | `k_checker_score1` | 予備（旧計算式で使用） |
| 2 | `k_checker_score2` | 全体の厚さ判定に利用 |
| 3 | `k_checker_score3` | 予備 |
| 4 | `k_checker_score4` | 角片の数判定に利用 |
| 5 | `k_checker_score5` | 角片の形状判定に利用 |
| 6 | `k_checker_score6` | 角片の揃い方判定に利用 |
| 7 | `k_checker_score7` | 角片の大きさ判定に利用 |

※ `score1` と `score3` は現行ロジックでは直接利用していないが、互換性のため 7 値として保存している。

---

## 5. 戻り値からの判定（サマリ）

各スコアの区分は `lib/promolib/skin_diagnosis.php` の `GetResult1〜5` で定義。

| 関数 | 入力スコア | 出力（1〜5） |
| --- | --- | --- |
| `GetResult1` | `score2` | 全体の厚さ |
| `GetResult2` | `score4` | 角片の数 |
| `GetResult3` | `score7` | 角片の大きさ |
| `GetResult4` | `score5` | 角片の形状 |
| `GetResult5` | `score6` | 角片の揃い方 |

5 つの結果を合計し 9 段階に丸めたものが「角質チェッカー値」（`GetKChecker`）。

### 5.1 現行の計算式（`GetMoistureCapacityDetail`）

現行コード（`lib/promolib/skin_diagnosis.php`）で**実際に使用されている式**:

```
TotalScorePoint = score2 * 100
                + score4 * 0
                + score7 * 20000
                + (3 / score5 * 100 - 300)
                + (score6 * 100 / 2)
```

コメントアウトされている旧計算式（現在は**使用されていない**）:

```
// TotalScorePoint = score2 * 85
//                 + 900 / score4 * 100
//                 + score7 * 15000
//                 + (5 / score5 * 100 - 300)
//                 + (score6 * 100 / 3)
```

当社で認識していた式（`output2*85+900/output4*100+output7*15000+(5/output5*100-300)+output6*100/3`）はコメントアウトされた旧計算式と一致する。現行コードで実際に使用されているのは上記の現行式（`score4*0` と `score6*100/2`）であるため、ドキュメントおよび認識の修正が必要。

総合評価点 → 総合点 → 水分レベル(1〜9) → 肌タイプ(A〜D) の順で変換する。

---

## 6. 出力ファイル（BMP）

- 第 2 引数のパスに二値化結果の BMP が保存される。
- この BMP は直後に PHP 側で JPG に変換され、`KCheckerIng/Crop3/` へ格納される。

```bash
convert <Crop2/xxx.bmp> -quality 100 -type truecolor <Crop3/xxx.jpg>
```

管理画面や結果表示では `Crop3/` の JPG を参照する。

---

## 7. エラー判定

- `exec()` の第 3 引数 `$return_var` が `0` の場合を成功とみなす。
    - ただし Windows 実行時（`IS_WINDOWS`）はこの値が信頼できないため、強制的に `0` として扱う実装になっている（現行 Linux 運用では影響なし）。
- 戻り値 7 個に満たない場合、または先頭値が負（`$output[0] >= 0` が偽）の場合、エラーメッセージ `処理に失敗しました。(b004)` を返して処理中断。
- `convert` 側のエラーコードは `(b001)〜(b003)` として区別する（詳細は 05_エラー対処.md）。

---

## 8. タイムアウト・同時実行

| 項目 | 現行の状況 |
| --- | --- |
| ZIP 内の想定最大枚数 | 特定の上限はコードで定義されていない。大量枚数の場合は処理時間が長くなる |
| 1 件あたりの想定処理時間 | Wine 経由の実行のため 1 枚あたり数秒〜10 秒程度（環境・画像による） |
| タイムアウト設定 | PHP CLI の `max_execution_time=0`（無制限）。現行は PHP 側でタイムアウトしない |
| nginx のタイムアウト | nginx のデフォルト `proxy_read_timeout`（60 秒）が適用される可能性。大量枚数の場合は nginx 設定で延長が必要 |

**同時実行時の注意:**

- 現行は `exec()` で同期実行し、画像 1 枚ごとに逐次処理する並列化なしの構成。
- 複数クライアントが同時に ZIP をアップロードすると、Wine プロセス（`SkinDiagnosisSystem2.exe`）が複数同時に起動する。
- ファイル名はクライアント ID と日時・マイクロ秒で一意化されているため（`{clientId}_{datetime}_{us}/`）、ファイル名の衝突は発生しない構成。
- ただし、サーバーリソース（CPU・メモリ）を複数の Wine プロセスが同時消費するため、同時実行数が増えると処理が遅延する可能性がある。
