C#を使用してTIFFファイルをブラウザに表示する方法

こんにちは、そうとです。
普段、C#を使用して業務システムの開発をしています。
今日は**C#を使用したTIFFファイルをブラウザに表示させる方法**について、解説していきます。
## 前説
**TIFFファイル (Tagged Image File Format)** は以下のような特徴を持っています。
**・高解像度・非圧縮画像**の保存可能。
**・複数ページを1つのファイル**に格納可能。

主にスキャンデータや医療画像などで利用されますが、モダンブラウザでは直接表示できません。そのため、**TIFFをPNGやJPEGに変換してからブラウザで表示**する必要があります。


## 必要な準備
**使用する技術スタック**
- **C#**: TIFF画像を変換する処理を実施します。
- **ASP.NET Core**: Web APIを構築し、クライアントとサーバー間の通信を管理します。
- **HTML + JavaScript**: 画像を表示します。

**必要なライブラリ**
TIFF画像を取り扱うために以下のパッケージを使用します。

**SixLabors.ImageSharp**  
軽量でモダンな画像処理ライブラリで、クロスプラットフォームに対応しています。
以下のコマンドでインストールできます。
```bash
dotnet add package SixLabors.ImageSharp
```

**System.Drawing**
.NET Framework互換性のために使用されるライブラリです。

::: note warn 
このコードは .NET Core 3.1以降 または .NET 5以上 で動作します。それ以前のバージョンでは正常に動作しない場合があります。
:::

## 手順
**手順1: サーバー側でTIFFをWeb対応の形式（PNGやJPEG）に変換する**
ブラウザはTIFF形式を直接表示できないため、サーバー側でPNG形式に変換します。これは、ImageSharpまたはSystem.Drawingを使用して実装します。

**手順2: サーバーで変換された画像をブラウザに表示する**
変換された画像をAPI経由でクライアントに送信し、HTMLとJavaScriptを使用して画像を表示します。

## C#でTIFFをPNGに変換するサンプルコード
以下に、ImageSharpおよびSystem.Drawingを用いた実装例を示します。

**ImageSharpを使用した例**
``` C#
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Processing;
using Microsoft.AspNetCore.Mvc;
using System.IO;

[ApiController]
[Route("api/tiff")]
public class TiffController : ControllerBase
{
    [HttpGet("convert")]
    public IActionResult ConvertTiffToPng()
    {
        // TIFFファイルのパスを指定
        string tiffPath = "path/to/your/file.tiff";

        try
        {
            // TIFF画像を読み込み
            using (var image = Image.Load(tiffPath))
            {
                using (var memoryStream = new MemoryStream())
                {
                    // PNG形式でメモリストリームに保存
                    image.Save(memoryStream, new PngEncoder());

                    // メモリストリームの内容をクライアントに返す
                    return File(memoryStream.ToArray(), "image/png");
                }
            }
        }
        catch (Exception ex)
        {
            // エラーメッセージを返す
            return BadRequest(new { message = "TIFFの変換に失敗しました", error = ex.Message });
        }
    }
}
```

**System.Drawingを使用した例**
``` C#
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.AspNetCore.Mvc;
using System.IO;

[ApiController]
[Route("api/tiff")]
public class TiffController : ControllerBase
{
    [HttpGet("convert")]
    public IActionResult ConvertTiffToPng()
    {
        // TIFFファイルのパスを指定
        string tiffPath = "path/to/your/file.tiff";

        try
        {
            // TIFF画像を読み込み
            using (Image tiffImage = Image.FromFile(tiffPath))
            using (MemoryStream memoryStream = new MemoryStream())
            {
                // PNG形式でメモリストリームに保存
                tiffImage.Save(memoryStream, ImageFormat.Png);

                // メモリストリームの内容をクライアントに返す
                return File(memoryStream.ToArray(), "image/png");
            }
        }
        catch (Exception ex)
        {
            // エラーメッセージを返す
            return BadRequest(new { message = "TIFFの変換に失敗しました", error = ex.Message });
        }
    }
}
```

## HTMLとJavaScriptで画像を表示
サーバーから送信された画像を表示するためのHTMLとJavaScriptのコードを以下に示します。

**HTML**

``` HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TIFF Viewer</title>
    <script src="app.js" defer></script>
</head>
<body>
    <h1>TIFF Viewer</h1>
    <!-- TIFF画像を表示するためのimg要素 -->
    <img id="tiffImage" alt="TIFF Image" style="max-width: 100%; height: auto;">
</body>
</html>
```

**JavaScript**
```js
// DOMが完全に読み込まれた後に画像読み込み関数を実行
document.addEventListener('DOMContentLoaded', () => {
    loadTiffImage();
});

// サーバーからTIFF画像を取得し、PNG形式で表示する非同期関数
async function loadTiffImage() {
    try {
        // サーバーのエンドポイントから画像データを取得
        const response = await fetch('/api/tiff/convert');

        // 正常に取得できた場合
        if (response.ok) {
            // 取得したデータをBlob形式に変換
            const blob = await response.blob();

            // HTML内のimg要素を取得
            const imgElement = document.getElementById('tiffImage');

            // BlobデータをObject URLとして設定し、画像を表示
            imgElement.src = URL.createObjectURL(blob);
        } else {
            alert('画像の読み込みに失敗しました。');
        }
    } catch (error) {
        alert('エラーが発生しました。ネットワークを確認してください。');
        console.error('An error occurred:', error);
    }
}
```

## まとめ
本記事では、C#を使ったTIFF画像の変換方法と、HTML/JavaScriptを使用した画像の表示方法を解説しました。
サーバー側でTIFFをWeb対応の形式に変換する方法は、ブラウザでのTIFF表示における実用的な解決策です。
システム要件に応じて、最適な方法を選択してください。