# 機能設計書 116-サムネイル生成

## 概要

本ドキュメントは、QuickerSite CMSにおける「サムネイル生成」機能の設計仕様を定義する。

### 本機能の処理概要

画像ファイルのサムネイル（縮小画像）を動的に生成する機能である。ASP.NET（VB.NET）で実装されており、System.Drawing名前空間を使用して画像のリサイズ、クロップ、特殊効果適用を行う。

**業務上の目的・背景**：CMSにおいて画像は重要なコンテンツ要素であるが、オリジナルサイズの画像をそのまま表示するとページ読み込み速度が低下し、ユーザー体験を損なう。サムネイル生成機能により、表示用途に応じた最適なサイズの画像を動的に提供し、パフォーマンスと視認性のバランスを保つ。

**機能の利用シーン**：
- リストアイテム画像のサムネイル表示
- ギャラリー画像の一覧表示
- カタログ商品画像のサムネイル表示
- 画像ポップアップウィンドウの生成
- Nivoスライダー等のスライドショー用画像リサイズ

**主要な処理内容**：
1. 画像ファイルの読み込み（Server.MapPath使用）
2. 最大サイズに基づくアスペクト比維持リサイズ
3. 固定幅・固定高さ指定によるリサイズ
4. 正方形クロップ（FSR=1）
5. 特殊効果適用（白黒、グレースケール、セピア）
6. JPEG/PNG形式での出力
7. ポップアップウィンドウHTML生成

**関連システム・外部連携**：
- リストアイテム画像管理
- ギャラリー機能
- カタログ機能
- アセットマネージャー

**権限による制御**：特になし。画像URLを知っていればアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 133 | リストアイテム画像編集 | 補助機能 | 画像サムネイルの自動生成 |
| 179 | リストアイテム画像（FS） | 補助機能 | サムネイル生成（最大270px表示） |
| 171 | カタログ処理 | 補助機能 | showPicでサムネイル生成 |
| 33 | ギャラリープレビュー | 補助機能 | サムネイル動的生成 |
| 41 | カタログアイテム画像 | 補助機能 | サムネイル表示 |

## 機能種別

画像処理 / サムネイル生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| img | String | Yes | 画像ファイルの相対パス | URLデコード後にServer.MapPathで解決 |
| maxSize | Integer | No | サムネイルの最大サイズ（ピクセル） | 数値チェック、最大2560px |
| FW | Integer | No | 固定幅（ピクセル） | URLデコード後に数値として使用 |
| FH | Integer | No | 固定高さ（ピクセル） | URLデコード後に数値として使用 |
| FSR | String | No | 正方形クロップフラグ（1=有効） | "1"の場合に正方形クロップ |
| SE | String | No | 特殊効果（1=白黒、2=グレースケール、3=セピア） | URLデコード後に判定 |
| close | String | No | ポップアップモード用テキスト | 指定時はHTMLポップアップ出力 |
| autoClose | Integer | No | 自動クローズ秒数 | ポップアップモード時に使用 |
| getWidthOnly | String | No | 幅のみ取得フラグ（true指定時） | "true"の場合は幅のみ返却 |
| pictureResizeSecCode | String | No | 画像保存用セキュリティコード | "qr"と一致時に画像保存処理 |
| resizePictureToPx | String | No | 画像保存時のリサイズサイズ | pictureResizeSecCode使用時 |

### 入力データソース

- URLクエリストリング
- ファイルシステム（画像ファイル）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 画像データ | Binary | リサイズ後のJPEG/PNG画像バイナリ |
| HTMLポップアップ | String | 画像ポップアップウィンドウのHTML（closeパラメータ指定時） |
| 画像幅 | Integer | 画像の幅（getWidthOnly=true時） |

### 出力先

- HTTPレスポンス（image/jpeg または image/png または text/html）

### Content-Type

- PNG画像の場合: image/png
- JPEG画像の場合: image/jpeg
- ポップアップモードの場合: text/html

## 処理フロー

### 処理シーケンス

```
1. showThumb.aspxアクセス
   └─ Page_Load開始
2. パラメータ取得
   ├─ img（画像パス）取得・URLデコード
   ├─ maxSize取得
   ├─ FW/FH取得（固定サイズ）
   ├─ FSR取得（正方形クロップ）
   └─ close取得（ポップアップモード判定）
3. 処理分岐
   ├─ close指定あり → ポップアップHTML生成
   └─ close指定なし → サムネイル画像生成
4. サムネイル画像生成
   ├─ 画像ファイル読み込み（Image.FromFile）
   ├─ getWidthOnly=true → 幅のみ返却して終了
   ├─ 新しいサイズ計算
   │   ├─ maxSize指定 → アスペクト比維持リサイズ
   │   ├─ FH/FW指定 → 固定サイズリサイズ
   │   └─ サイズ内 → リサイズなし
   ├─ FSR=1 → 正方形クロップ
   ├─ サムネイル生成（GetThumbnailImage）
   ├─ 特殊効果適用（SE=1/2/3）
   └─ 画像出力（Response.OutputStream）
5. リソース解放
   ├─ thumbNailImg.Dispose()
   └─ fullSizeImg.Dispose()
```

### フローチャート

```mermaid
flowchart TD
    A[showThumb.aspxアクセス] --> B{closeパラメータ?}
    B -->|Yes| C[getImagePop呼び出し]
    C --> D[ポップアップHTML出力]
    B -->|No| E[画像ファイル読み込み]
    E --> F{getWidthOnly?}
    F -->|Yes| G[幅のみ返却]
    G --> Z[終了]
    F -->|No| H{maxSize/FH/FW<br>指定?}
    H -->|maxSize| I[アスペクト比維持<br>リサイズ計算]
    H -->|FH/FW| J[固定サイズ<br>リサイズ計算]
    H -->|なし| K[オリジナルサイズ]
    I --> L{FSR=1?}
    J --> L
    K --> L
    L -->|Yes| M[正方形クロップ]
    L -->|No| N[サムネイル生成]
    M --> N
    N --> O{SE指定?}
    O -->|1| P[白黒変換]
    O -->|2| Q[グレースケール]
    O -->|3| R[セピア変換]
    O -->|なし| S[画像出力]
    P --> S
    Q --> S
    R --> S
    S --> T[リソース解放]
    T --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-116-01 | 最大サイズ制限 | maxSizeは最大2560pxに制限 | maxSize指定時 |
| BR-116-02 | アスペクト比維持 | リサイズ時は元画像のアスペクト比を維持 | maxSizeリサイズ時 |
| BR-116-03 | PNG判定 | 拡張子が.pngの場合はPNG形式で出力 | 全出力 |
| BR-116-04 | 正方形クロップ | FSR=1の場合、中央を基準に正方形にクロップ | FSR=1指定時 |
| BR-116-05 | 品質向上処理 | リサイズ前にRotateFlip処理で品質向上 | リサイズ時 |
| BR-116-06 | 出力キャッシュ | 900秒（15分）のOutputCacheを適用 | 全リクエスト |

### 計算ロジック

#### アスペクト比維持リサイズ

```vb
If fullSizeImg.Width >= fullSizeImg.Height Then
    newWidth = maxSize
    newHeight = (fullSizeImg.Height / fullSizeImg.Width) * maxSize
Else
    newWidth = (fullSizeImg.Width / fullSizeImg.Height) * maxSize
    newHeight = maxSize
End If
```

#### 正方形クロップ計算

```vb
If newWidth < newHeight Then
    ' 縦長画像：上下をクロップ
    cropOffset = (newHeight - newWidth) / 2
Else
    ' 横長画像：左右をクロップ
    cropOffset = (newWidth - newHeight) / 2
End If
```

#### セピア変換計算

```vb
iSepiaRed = Math.Min(iRed * 0.393 + iGreen * 0.769 + iBlue * 0.189, 255)
iSepiaGreen = Math.Min(iRed * 0.349 + iGreen * 0.686 + iBlue * 0.168, 255)
iSepiaBlue = Math.Min(iRed * 0.272 + iGreen * 0.534 + iBlue * 0.131, 255)
```

## データベース操作仕様

### 操作別データベース影響一覧

データベース操作なし（ファイルシステムベースの画像処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル不存在 | 指定パスに画像がない | On Error Resume Nextで継続、空レスポンス |
| - | 画像読み込み失敗 | 破損画像等 | Response.End()で終了 |
| - | メモリ不足 | 大きな画像処理時 | On Error Resume Nextで継続 |

### リトライ仕様

特になし

## トランザクション仕様

データベース操作を伴わないため、トランザクション管理は不要。

## パフォーマンス要件

- サムネイル生成処理: 1秒以内
- OutputCache: 900秒（15分）でVaryByParam="*"設定
- 最大サイズ制限: 2560pxを超える場合は2560pxに制限

## セキュリティ考慮事項

1. **パストラバーサル対策**: Server.MapPathを使用して相対パスを絶対パスに変換
2. **画像形式制限**: System.Drawing.Image.FromFileで読み込み可能な形式のみ処理
3. **サイズ制限**: maxSizeは2560pxに制限し、過大な画像生成を防止
4. **エラーハンドリング**: On Error Resume Nextで内部情報の漏洩を防止

## 備考

- ASP.NET（VB.NET）で実装されており、Classic ASPとは別のランタイムで動作
- System.Drawing名前空間を使用（GDI+ベース）
- OutputCacheディレクティブで15分間のキャッシュを実施
- Nivoスライダー対応のためQS 4.2で固定幅・高さ（FW/FH）パラメータを追加

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

サムネイル生成に使用するオブジェクト構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | showThumb.aspx | `showThumb.aspx` | System.Drawing.Image、Bitmapオブジェクトの使用 |

**読解のコツ**: fullSizeImg（元画像）とthumbNailImg（サムネイル）の2つのImageオブジェクトの関係を理解する。

#### Step 2: エントリーポイントを理解する

サムネイル生成の起点を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | showThumb.aspx | `showThumb.aspx` | Page_Loadイベントハンドラ（8-165行目） |

**主要処理フロー**:
1. **1行目**: OutputCacheディレクティブ（900秒キャッシュ）
2. **13行目**: imgパラメータ取得・URLデコード
3. **19-23行目**: PNG判定（拡張子チェック）
4. **25-30行目**: closeパラメータによるポップアップモード分岐
5. **44行目**: 画像ファイル読み込み（Image.FromFile）
6. **62-91行目**: サイズ計算（maxSize、FH/FW）
7. **114-128行目**: サムネイル生成（GetThumbnailImage）、正方形クロップ（FSR=1）
8. **131行目**: createOutput呼び出し

#### Step 3: 特殊効果処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | showThumb.aspx | `showThumb.aspx` | createOutput関数（167-192行目） |
| 3-2 | showThumb.aspx | `showThumb.aspx` | PureBW関数（281-310行目）- 白黒変換 |
| 3-3 | showThumb.aspx | `showThumb.aspx` | GrayScale関数（317-334行目）- グレースケール |
| 3-4 | showThumb.aspx | `showThumb.aspx` | PixelLoopConvert関数（336-356行目）- セピア変換 |

#### Step 4: 補助機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | showThumb.aspx | `showThumb.aspx` | CropImage関数（194-205行目）- 画像クロップ |
| 4-2 | showThumb.aspx | `showThumb.aspx` | getImagePop関数（208-273行目）- ポップアップHTML生成 |

### プログラム呼び出し階層図

```
showThumb.aspx
    │
    ├─ Page_Load (メイン処理)
    │      │
    │      ├─ HttpUtility.UrlDecode() ... パラメータデコード
    │      │
    │      ├─ System.Drawing.Image.FromFile() ... 画像読み込み
    │      │
    │      ├─ Image.GetThumbnailImage() ... サムネイル生成
    │      │
    │      ├─ CropImage() ... 正方形クロップ（FSR=1時）
    │      │
    │      ├─ createOutput()
    │      │      │
    │      │      ├─ PureBW() ... 白黒変換（SE=1）
    │      │      ├─ GrayScale() ... グレースケール（SE=2）
    │      │      ├─ PixelLoopConvert() ... セピア（SE=3）
    │      │      │
    │      │      └─ Image.Save() ... 画像出力
    │      │
    │      └─ getImagePop() ... ポップアップHTML（close指定時）
    │
    └─ ThumbnailCallback() ... サムネイル生成用コールバック
```

### データフロー図

```
[入力]                      [処理]                           [出力]

URLパラメータ ──────────> パラメータ解析 ─────────────> 処理方針決定
(img, maxSize, FH,          │
 FW, FSR, SE, close)        v
                      ファイルパス解決 ─────────────> 絶対パス
                      (Server.MapPath)
                            │
                            v
ファイルシステム ─────────> 画像読み込み ────────────> fullSizeImg
(画像ファイル)              (Image.FromFile)            (Imageオブジェクト)
                            │
                            v
                      サイズ計算 ─────────────────> newWidth, newHeight
                            │
                            v
                      サムネイル生成 ────────────> thumbNailImg
                      (GetThumbnailImage)           (Imageオブジェクト)
                            │
                            v
                      [正方形クロップ] ───────────> クロップ済み画像
                      (FSR=1時)
                            │
                            v
                      [特殊効果適用] ────────────> エフェクト済み画像
                      (SE=1/2/3時)
                            │
                            v
                      画像出力 ──────────────────> HTTPレスポンス
                      (Response.OutputStream)        (image/jpeg or png)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| showThumb.aspx | `showThumb.aspx` | ソース | サムネイル生成メイン処理（ASP.NET） |
| gallery.asp | `asp/includes/gallery.asp` | ソース | ギャラリー機能（showThumb呼び出し元） |
| catalogItem.asp | `asp/includes/catalogItem.asp` | ソース | カタログアイテム（showThumb呼び出し元） |
| fileexplorer.asp | `asp/includes/fileexplorer.asp` | ソース | ファイルエクスプローラー（showThumb呼び出し元） |
| feed.asp | `asp/includes/feed.asp` | ソース | フィード機能（showThumb呼び出し元） |
