最初の問題は、任意の言語で画像のサイズを変更すると、処理に少し時間がかかることです。では、何千ものクライアントをどのようにサポートしますか?画像を1回生成するだけで済むように、キャッシュします。次に誰かがその画像を要求したとき、それがすでに生成されているかどうか、それがちょうどそれを返したかどうかを確認します。複数のアプリサーバーがある場合は、中央のファイルシステムにキャッシュして、キャッシュヒット率を高め、必要なスペースの量を減らす必要があります。
適切にキャッシュするには、画像を表示するさまざまな方法をすべて考慮した予測可能な命名規則を使用する必要があります。つまり、myimage_blurred_320x200.jpgのようなものを使用して、ぼかして300幅と200にサイズ変更したjpegを保存します。高さなど
もう1つのアプローチは、画像サーバーをプロキシサーバーの背後に配置することです。これにより、すべてのキャッシュロジックが自動的に実行され、画像は高速のネイティブWebサーバーによって提供されます。
他の方法で何百万ものサイズ変更された画像を提供することはできません。これがGoogleとBingマップのやり方です。適切なパフォーマンスを提供し、事前に生成された静止画像を返すことができるように、さまざまな事前設定された範囲で世界に必要なすべての画像を事前に生成します。
PHPが遅すぎる場合は、Javaまたは.NETの2Dグラフィックライブラリを使用することを検討してください。これらは非常に豊富で、すべての要件をサポートできます。Graphics 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;
}