猫の手ツール

Step 4: Quality & Ethics

18. 端末内で画像処理をする理由:プライバシーと通信の確認

画像処理を端末内で行うことと、サイトが通信をしないことは別です。選択した画像のデータフローと、HTML・広告・ライブラリの取得を分けて確認します。画像変換ツールの実コードを例に、確認できる範囲と残る条件を説明します。

1. 「もし自分が使うなら」というシンプルで強固な問い

インターネット上には、無料で画像を加工できる便利なツールが溢れています。しかし、その中には、一度画像をサーバーへアップロードし、サーバー側で処理をしてから結果をダウンロードさせるものもあります。

画像をサーバーで扱う設計では、保管期間、アクセス権限、削除方法を確認する必要があります。端末内で処理する設計でも、入力を扱うスクリプトや依存関係を管理します。

2. 画像を送信しないことで減らせるリスク

インフラエンジニアは、日々「いかにデータを守るか」という難問と向き合っています。暗号化、ファイアウォール、アクセス制御……どれだけ堅牢な城を築いても、100%の安全を保証することは困難です。

画像をサーバーへ送らなければ、運営側の画像保管庫や画像転送経路から漏れるリスクを減らせます。ただし、端末上のマルウェア、ブラウザ拡張機能、配信スクリプトの改ざんなどのリスクは残ります。「端末内処理」と「100%安全」は同じ意味ではありません。

必要な情報だけを扱う設計は、データの保持や送信を減らす方法の一つです。利便性、対応形式、端末の負荷を要件に合わせて比較します。

3. 技術が自由を支える:Before / After

かつてはサーバーサイドで行うのが一般的だった画像処理も、現代のブラウザ性能(Canvas API、File APIなど)を駆使すれば、端末内で完結させることが可能です。

【比較1】画像データをサーバーへ送る方式

// ユーザーの画像をサーバーへ送信
const formData = new FormData();
formData.append('image', file);

// サーバーからの返答を待つ(この間にデータがネットワークを流れる)
const response = await fetch('https://api.example.com/process-image', {
  method: 'POST',
  body: formData
});

【比較2】画像をブラウザ内で描画する方式

// 画像をメモリ上でプレビュー(サーバー送信なし)
const objectUrl = URL.createObjectURL(file);
const img = new Image();
// canvas、targetWidth、targetHeight は事前に用意する
// Canvas APIで描画処理を実行
img.onload = () => {
  try {
    const ctx = canvas.getContext('2d');
    if (!ctx) throw new Error('Canvas 2Dを利用できません');
    ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
    // この描画処理では画像を送信しない
  } catch (error) {
    console.error('画像を描画できませんでした', error);
  } finally {
    URL.revokeObjectURL(objectUrl);
  }
};
img.onerror = () => {
  URL.revokeObjectURL(objectUrl);
  console.error('画像を読み込めませんでした');
};
img.src = objectUrl;

4. 注意点:端末内完結のトレードオフ

この設計は理想的ですが、開発においては特有の「落とし穴」もあります。

  • メモリ消費の増大: 高解像度の画像をブラウザ内で処理すると、タブのメモリ使用量が急増します。特にスマホなどの低スペック端末では、タブがクラッシュしないよう注意深いメモリ管理が求められます。
  • 処理時間のデバイス依存: サーバーの強力なCPUではなく、ユーザーの端末性能に依存するため、古い端末ではリサイズや合成に時間がかかる場合があります。
  • 実装の複雑化: 本来サーバーサイドのライブラリ(ImageMagickなど)で行えることを、ブラウザで動くJavaScriptやWebAssemblyのライブラリで実現する必要があり、対応形式、メモリ、ライセンスの確認が増えます。

画像の処理と、サイトの通信を分けて確認する

端末内で画像を加工するページでも、HTML・JavaScript・AIモデル・広告などの取得には通信が発生します。本サイトの記事にも広告スクリプトの読み込みがあります。「画像を送信しない」という説明は、サイトが通信しないという意味ではありません。

実装を確認するときは、ダミー画像を使い、開発者ツールのNetworkで選択前後のリクエストを比較します。ファイル名や画像本体が送信ペイロードへ含まれないかを確認し、フォーム送信、fetch、XHR、外部SDKの処理もコードと照合します。1回の確認で将来の変更やすべての動作を保証できるわけではないため、更新時にも確認する対象です。

画像変換の入力経路と、ページの外部通信は別に見る

画像変換ツールのhandleFile()は、選択したFileをローカルでデコードし、CanvasからJPEGのBlobを作ります。この関数には、入力をPOSTするfetchやXHRはありません。一方、同じページは外部の広告スクリプトを取得します。

確認する単位は「画像の送信経路」と「ページの通信」です。制作解説で処理の流れを読み、ダミー画像でNetworkの選択前後を比較します。今回の関数の確認を、すべての外部スクリプトや将来の更新の保証へ広げないようにします。

File APIに送信禁止の機能があるわけではありません。画像読み込みの教材のObject URLと、ブラウザのファイル選択権限を合わせて読むと、選択・処理・送信を区別できます。

5. まとめ:設計の範囲を説明する

画像の入力から保存までのデータフローを説明し、不要な送信や保持を減らす設計を選びます。端末内処理だけで100%の安全を保証するものではありません。

Canvas APIやFile APIは、入力画像をブラウザ内で加工するために使えます。APIの利用だけでサイト全体の通信内容が決まるわけではないため、コードと実行時の通信を照合します。

参考資料

制作時に確かめたこと

ツールを作る途中で実際に確認した症状と、変更を選んだ経緯です。日付は当時の記録日です。現在の実装や、このページの学習サンプルの検証とは分けて読んでください。

画像を送らなくても、配信スクリプトは確認が必要だった

外部スクリプトの参照先まで確認する

ブラウザ内の画像加工を説明する過程で、「実行するJavaScriptが改ざんされたらどうなるか」を確認しました。3月23日には外部URLのscriptを減らすべきかを問い、28日にはCDN経由のモジュールをnpmパッケージへ変え、型エラーも直す依頼をしています。

これは実際に改ざん被害を受けた記録ではなく、配信元と更新方法の変更を求めた判断の記録です。ローカル配信へ変えても、依存パッケージや管理アカウントの保護は残ります。また、広告などの外部通信がすべてなくなったという意味ではありません。

入力画像を送らないかを調べる時は、画像を扱う関数だけでなく、同じページで実行するコードも確認します。現行のデータフローと通信を説明することが、単に「ブラウザ完結だから安全」と述べるより検証しやすい案内になります。