動的に画像のサイズを調整する
『画像サイズのダイナミック調整』
ウェブアーキテクトとして、数多くの課題の1つが資産管理です。そして、資産において最も重要な問題は画像です。素朴なアプローチは画像を設定し、ブラウザによるCSSを使用して画像のリサイズを行う方法です:
ただし、これは元の画像をダウンロードすることを意味します。これには2つの問題があります。元の画像のサイズと、ブラウザによる最適でないリサイズです。
この投稿では、2つの代替案である従来の方法と最新の解決策について説明します。
事前リサイズ
単一の画像ソースに対する従来の解決策は、事前リサイズです。リリース前に、デザイナーはさまざまな解像度の複数の画像バージョンを用意するための時間をかけます。このブログでは、私はこのテクニックを使用しています。背景画像として、投稿のメイン画像を異なるコンテキストで表示するために3つの解像度を提供しています:
- 「モノのインターネット」から「すべてのインターネット」へ:AIと6Gの融合によるつながる知性
- ミッドジャーニーV5:ミッドジャーニーの最新バージョン
- 「CG ギークが VFX を楽々に作ります 今週の ‘NVIDIA Studio’」
- 投稿ページの大きい画像
- ホームページの投稿用VoAGI
- 投稿ページの関連投稿用の小さい画像
さらに、JPEGメタデータも削除してさらなるサイズ削減を図っています。
従来のアプローチでは、HTMLのpicture
タグを活用する方法があります:
<picture>
HTML要素には、0個以上の<source>
要素と1つの<img>
要素が含まれ、さまざまなディスプレイ/デバイスシナリオに対して画像の代替バージョンを提供します。ブラウザは、各
<source>
要素を考慮し、それらの中から最適なマッチを選択します。マッチが見つからない場合やブラウザが<picture>
要素をサポートしていない場合、<img>
要素のsrc属性のURLが選択されます。選択された画像は、<img>
要素が占めるスペースに表示されます。
この方法は長年機能してきましたが、2つの問題があります。まず、各画像に複数の解像度を提供するためには時間がかかります。プロセスを自動化し、AIを使用して良い結果を得ることもできます。
ただし、必要なストレージ量は、作成される追加解像度の数に応じて元の画像のサイズの2倍または3倍になる場合があります。アセットが豊富な環境、例えばeコマースの場合は費用が著しく増加します。
リアルタイムリサイズ
最近、リアルタイムで画像をリサイズするコンポーネントであるimgproxy
に出くわしました:
imgproxyは、ウェブサイトやアプリを高速化し、ストレージとSaaSのコストを削減します
このコンポーネントでは、エンコードされたURLを送信して以下を定義するエンドポイントが提供されます:
- リサイズする画像とその場所(ローカル、HTTP URL、S3バケットなど)
- 寸法、フィットするか埋めるかなどの異なるサイズパラメータ
- 形式。JPEGやPNGなどの標準的な形式のほか、WebPやAVIFなどのより現代的な形式もサポートしています。また、’Accept’ヘッダーに基づいて最適な形式を選択することもできます。
- ウォーターマーク、フィルタリング、回転など他の多くのオプション
imgproxy
には、オープンソースの無料バージョンと有料バージョンの両方があり、この投稿の内容は前者に含まれます。
ウェブ開発者がHTMLにそれぞれのimgproxy
URLをコーディングする解決策としては以下のようなものがあります:
それはウェブページに関連する詳細を漏洩しますし、メンテナンスが困難な解決策ではありません。この問題を逆プロキシまたはAPI Gatewayで解決することができます。私は明らかな理由からApache APISIXを使用します。
このアプローチでは、上記のHTMLははるかに簡潔になります:
Apache APISIXは/resize
から始まるリクエストをインターセプトし、imgproxy
のためにURLを書き換え、書き換えられたURLをimgproxy
に転送します。全体のフローは次のようになります:
対応するApache APISIXの設定は次のようになります:
/resize
で始まるリクエストをマッチする- URLを書き換える
- 正規表現で幅とイメージをキャッチする
imgproxy
用のURLをフォーマットする。http://server:3000
はオリジナルのイメージをホストするサーバーを示しており、@webp
はWebPフォーマットを好むことを示す(ブラウザがサポートしている場合)
上記の設定により、/resize/200/ai-generated.jpg
がApache APISIXで/rs:fill/w:200/plain/http://server:3000/ai-generated.jpg@webp
に書き換えられ、imgproxy
に送信されます。
テスト
Docker Composeで小さなテストサンプルを作成できます:
- HTMLとメインのイメージをホストするシンプルなウェブサーバー
上記のセットアップは、ブラウザの開発者ツールを使用して、例えばiPhone SEのような小さな画面デバイスをエミュレートしてテストできます。テスト結果は以下の通りです:
- 画面解像度の関係で、リクエストされるイメージは元のものではなく、幅400pxのものです。リクエストのURLで確認できます。
- 返されるイメージはWebP形式で、サイズは14.4kbです。
- 元のJPEGイメージのサイズは154kbで、10倍以上の容量です。ネットワーク帯域幅の節約になります!
議論
ストレージコストを10分の1に削減できるのは素晴らしい利点ですが、全てが簡単なものではありません。リサイズされたイメージの計算はコンピューティングコストが高く、それぞれのリクエストに対してCPU時間がかかります。また、imgproxy
がどれだけ効率的であっても、イメージの作成には時間がかかります。ストレージコストと引き換えにCPUコストが発生し、パフォーマンスにわずかな影響が生じます。
これを修正するには、前面にキャッシングレイヤーが必要です。カスタムのものか、おそらくはCDNを使用するでしょう。アセットを再度保存することになることに反対するかもしれませんが、重要な違いは、キャッシュが 使用された イメージのみで機能する点です。つまり、最初のソリューションではすべてのイメージのストレージコストを支払っていましたが、キャッシュは需要のあるイメージにのみ適用されるのです。また、イメージグループが高い需要があることがわかっている場合(例:イベント前)、予測キャッシュなどの既知のキャッシュのレシピを適用することもできます。
結論
この記事では、Apache APISIXを使用してimgproxy
を使って複数の解像度のイメージのストレージコストを削減する方法について説明しました。上にキャッシュを追加することで、全体のアーキテクチャにはさらなるコンポーネントが追加されますが、ストレージコストは削減されます。
この記事はAndreas Lehr氏の StackConfでの講演を元にしています。
この記事の完全なソースコードは GitHub で見つけることができます。
さらに進むには
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles