web-dev-qa-db-ja.com

オンザフライのサイズ変更で画像を提供

私の会社は最近、ウェブサイトの画像処理で問題が発生し始めました。

DVDカバー、スナップショットなどの画像を表示するいくつかのWebサイト(アダルトエンターテインメント)があります。約100,000本の映画があり、映画ごとに平均30のスナップショットとカバーがあります。ほとんどすべての画像には、非会員向けのぼかしとオーバーレイを備えた追加バージョンがあります。これにより、映画ごとに約50枚の画像、または合計500万枚の基本画像が作成されます。各画像は、ページのどこに配置されているか(サムネイル、オリジナル、小さいプレビュー、それほど小さくないプレビュー、トップリストの小さい画像など)に応じて、いくつかのバージョンで利用できます。私は数えることを気にした。

サーバーを使用してオンザフライで画像を生成することを思いついたのは、すべての異なるページに対してすべての異なる画像を生成するのが非常に不器用になったためです(基本的に同じタスクで異なるページが異なる画像サイズを必要とする場合もあるため) 。

画像をオンザフライで縮小できる画像処理サーバーを知っている人はいますか?元の画像を提供するだけで、ウェブ担当者は必要なサイズをリクエストできますか?

要件:

  • 非常に高いパフォーマンス(1日あたり数千人のユーザー)
  • オンザフライのぼかしとオーバーレイの作成
  • オンザフライのサイズ変更(アスペクト比を維持する場合としない場合)
  • 何百万もの画像を処理できます
  • JPG、GIF、PNG、およびBMPを読み取り、それらの間で変換できる必要があります

セキュリティはそれほど問題ではありません。つまり、ぼやけていない画像はURL操作によってすでに到達可能であり、より多くのセキュリティがあればいいのですが、それは必須ではなく、率直に言って私は気にかけなくなりました(同僚の頭に入るのに失敗した後、なぜ(私たちの小さな再販業者のためにページ) http://example.com/view_image.php?filename=/data/images/01020304.jpg を使用して画像を表示することはお勧めできません)。

PHPスクリプトでこれを実行しようとしましたが、この多くのユーザーにとってパフォーマンスが遅すぎました。

あなたが持っている提案を事前に感謝します。

23
Morfildur

画像のサイズ変更を処理して最終結果を提供するために、専用のWebサーバーをセットアップすることをお勧めします。規模ははるかに小さいですが、私は似たようなことをしました。基本的に、キャッシュをチェックするプロセスが不要になります。

それはこのように動作します:

  • http://imageserver/someimage.150x120.jpgのようにファイル名に必要なサイズを追加する画像をリクエストします
  • 画像が存在する場合、他の処理なしで返されます(これが要点であり、キャッシュチェックは暗黙的です)
  • 画像が存在しない場合は、.htaccessで見つからない404を処理し、必要なサイズの画像を生成するスクリプトにリクエストを再ルーティングします
  • スクリプトで許可されるサイズのリストを指定して、サーバーをシャットダウンするために可能なすべてのサイズを要求するスクリプトなどの攻撃を回避します
  • 不要なトラフィックを最小限に抑えるために、これをCookieなしのドメインに保持します

編集:PHPこの場合のスクリプトは最小限に抑えられているため、PHP自体がプロセスを大幅に遅くするとは思わない:画像のスケーリングはCで書かれた組み込みライブラリによって行われます。何をするにしても、このようなライブラリ(Gdやlibmagickなど)を使用する必要があるため、避けられません。少なくとも私のシステムでは、キャッシュをチェックするオーバーヘッドを完全にスキップするため、さらにPHPの相互作用を減らす。これは既存のサーバーに実装できるので、予算に適したソリューションだと思います。

28
Matteo Riva

に基づく

PHPスクリプトでこれを実行しようとしましたが、この多くのユーザーにとってパフォーマンスが遅すぎました。

結果をキャッシュしていなかったと仮定します。結果の画像を1〜2日キャッシュすることをお勧めします(つまり、サムネイルが既に生成されているかどうかをスクリプトで確認し、生成されている場合は、その場で生成されていない場合は使用します)。

これにより、メイン/スタートページのヒット数がランダムビデオXよりもはるかに多いと想像できるため、パフォーマンスが劇的に向上します。したがって、メインページを表示するときに、キャッシュされる画像を作成する必要はありません。ユーザーYがMovieXを表示すると、その1ページを生成するだけなので、遅延にそれほど気付くことはありません。

「オンザフライサイズ変更」の側面については、帯域幅はあなたにとってどのくらい重要ですか?私はあなたが映画をたくさん経験しているので、リクエストごとに画像の数キロバイトを追加してもそれほど害はないと思います。その場合は、より大きな画像を使用して幅と高さを設定し、ブラウザにスケーリングを任せることができます。

7
BarrettJ

ImageCache および Image Exact SizesDrupalコミュニティのソリューションがこれを行う可能性があります。ソリューションOSSは ImageMagik のライブラリを使用します

画像のスケーリングを行うためのAmazonEC2サービス用のAMI画像がいくつかあります。画像ストレージ、オリジナル、スケールにAmazon S3を使用し、AmazonのCDNサービス(Cloud Front)にフィードスルーできました。利用可能なものについてはEC2サイトを確認してください

別のオプションはGoogleです。 Googleドキュメントですべてのファイルタイプがサポートされるようになったため、画像をGoogleドキュメントフォルダに読み込んで、そのフォルダを共有してパブリックアクセスできるようになりました。 URLはちょっと長いです。

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I

= sパラメータを追加して、画像を拡大縮小します。例えば幅200ピクセルの場合

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I=s2

Googleは20GBに対して年間5米ドルのみを請求します。ドキュメントなどをアップロードするための完全なAPIがあります

SO サーバー外で画像のサイズを変更する最善の方法 に関するその他の回答

4
TFD

最初の問題は、任意の言語で画像のサイズを変更すると、処理に少し時間がかかることです。では、何千ものクライアントをどのようにサポートしますか?画像を1回生成するだけで済むように、キャッシュします。次回誰かがその画像を要求したとき、それがすでに生成されているかどうか、それがちょうどそれを返したかどうかを確認してください。複数のアプリサーバーがある場合は、中央のファイルシステムにキャッシュして、キャッシュヒット率を高め、必要なスペースの量を減らす必要があります。

適切にキャッシュするには、画像を表示するさまざまな方法をすべて考慮した予測可能な命名規則を使用する必要があります。つまり、myimage_blurred_320x200.jpgのようなものを使用して、ぼかして300幅と200にサイズ変更したjpegを保存します。高さなど.

もう1つのアプローチは、イメージサーバーをプロキシサーバーの背後に配置することです。これにより、すべてのキャッシュロジックが自動的に実行され、イメージは高速のネイティブWebサーバーによって提供されます。

他の方法で何百万ものサイズ変更された画像を提供することはできません。これがGoogleとBingマップのやり方です。適切なパフォーマンスを提供し、事前に生成された静止画像を返すことができるように、さまざまな事前設定された範囲で世界に必要なすべての画像を事前に生成します。

Phpが遅すぎる場合は、Javaまたは.NETの2Dグラフィックライブラリを使用することを検討してください。これらは非常に豊富で、すべての要件をサポートできます。グラフィックAPIのフレーバーを取得するには、次のようにします。画像を指定された新しい幅または高さにサイズ変更する.NETのメソッド。高さまたは幅を省略すると、正しいアスペクト比を維持しながらサイズが変更されます。注画像はJPG、GIF、PNG、またはBMPから作成できます。

// Creates a re-sized image from the SourceFile provided that retails the same aspect ratio of the SourceImage. 
// -    If either the width or height dimensions is not provided then the resized image will use the 
//      proportion of the provided dimension to calculate the missing one.
// -    If both the width and height are provided then the resized image will have the dimensions provided 
//      with the sides of the excess portions clipped from the center of the image.
public static Image ResizeImage(Image sourceImage, int? newWidth, int? newHeight)
{
    bool doNotScale = newWidth == null || newHeight == null; ;

    if (newWidth == null)
    {
        newWidth = (int)(sourceImage.Width * ((float)newHeight / sourceImage.Height));
    }
    else if (newHeight == null)
    {
        newHeight = (int)(sourceImage.Height * ((float)newWidth) / sourceImage.Width);
    }

    var targetImage = new Bitmap(newWidth.Value, newHeight.Value);

    Rectangle srcRect;
    var desRect = new Rectangle(0, 0, newWidth.Value, newHeight.Value);

    if (doNotScale)
    {
        srcRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
    }
    else
    {
        if (sourceImage.Height > sourceImage.Width)
        {
            // clip the height
            int delta = sourceImage.Height - sourceImage.Width;
            srcRect = new Rectangle(0, delta / 2, sourceImage.Width, sourceImage.Width);
        }
        else
        {
            // clip the width
            int delta = sourceImage.Width - sourceImage.Height;
            srcRect = new Rectangle(delta / 2, 0, sourceImage.Height, sourceImage.Height);
        }
    }

    using (var g = Graphics.FromImage(targetImage))
    {
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        g.DrawImage(sourceImage, desRect, srcRect, GraphicsUnit.Pixel);
    }

    return targetImage;
}
2
mythz

あなたが探しているものは、Thumbor http://thumbor.readthedocs.org/en/latest/index.html に最もよく一致します。これはオープンソースであり、巨大な会社に支えられています(つまり、明日消えます)、トリミング時に画像上で重要なものを検出するなど、多くの優れた機能が付属しています。

低コストとCDNの場合は、CloudfrontおよびAWSストレージ、またはCloudflareなどの無料のCDNと同等のソリューションを組み合わせることをお勧めします。これらは最高のパフォーマンスのCDNプロバイダーではないかもしれませんが、少なくとも1台のサーバーよりもパフォーマンスが高く、イメージサーバーを安価にオフロードすることもできます。さらに、帯域幅のコストを大幅に節約できます。

1
nico gawenda

この質問がなされたとき、この正確な問題に対処するためにいくつかの会社が生まれました。それはあなたやあなたの会社に限定された問題ではありません。多くの企業は、画像処理のニーズに対してより永続的なソリューションを探す必要がある段階に達しています。

imgix のようなサービスは、オーバーレイのサイズ変更や適用などの画像操作のプロキシおよびCDNとして機能します。 URLを操作することで、各画像に異なる変換を適用できます。 imgixは、1日あたり数十億のリクエストを処理します。

自分でサービスを立ち上げて、CDNの背後に置くこともできます。 imageproxy のようなオープンソースプロジェクトはこれに適しています。これにより、運用チームにメンテナンスの負担がかかります。

(免責事項:私はimgixで働いています。)

1
Kelly Sutton

それぞれの異なる画像が単一のURLで一意に識別できる場合は、AKAMAIなどのCDNを使用します。 PHPスクリプトに処理を任せ、AKAMAIにロードを処理させます。

この種のビジネスは通常予算の問題がないので、それが私が見る唯一の場所でしょう。

編集:これは、この種のコンテンツを提供するCDNが見つかった場合にのみ機能します。

0
cherouvim

これとまったく同じ問題は、このタスク専用の画像サイズ変更サービスによって解決されています。これらは次の機能を提供します。

  1. ビルドされたCDNでは-画像の配布について心配する必要はありません
  2. その場で画像のサイズを変更-必要なサイズを選択できます
  3. ストレージは必要ありません-ベースイメージを保存するだけで、すべてのバリアントはサービスによって処理されます
  4. エコシステムライブラリ-JavaScriptを含めるだけで、すべてのデバイスとすべてのブラウザで作業が完了します。

そのようなサービスの1つは Gumlet です。また、その場で画像のサイズを変更できるnginxプラグインなどのオープンソースの代替手段を試すこともできます。

(私はGumletで働いています。)

0
adityap